export function putDocument()

in src/governance/ccf-app/js/src/endpoints/documents.ts [46:142]


export function putDocument(request: ccfapp.Request<PutDocumentRequest>) {
  const id = request.params.documentId;
  // Check if the document is already accepted.
  if (acceptedDocumentsStore.has(id)) {
    return {
      statusCode: 405,
      body: new ErrorResponse(
        "DocumentAlreadyAccepted",
        "An accepted document cannot be changed."
      )
    };
  }

  const contractId = request.body.json().contractId;
  if (!contractId) {
    return {
      statusCode: 400,
      body: new ErrorResponse(
        "ContractIdMissing",
        "ContractId must be specified in document payload."
      )
    };
  }

  const data = request.body.json().data;
  if (!data) {
    return {
      statusCode: 400,
      body: new ErrorResponse(
        "DataMissing",
        "data key must be present in document payload."
      )
    };
  }

  // A contract must exist. We don't check the accepted contract store as the state of the contract
  // is not considered. Mere presence of a contract in the store sufficient.
  const contractsStore = ccfapp.typedKv(
    "public:contracts",
    ccfapp.string,
    ccfapp.json<ContractStoreItem>()
  );
  if (!contractsStore.has(contractId)) {
    return {
      statusCode: 404,
      body: new ErrorResponse(
        "ContractNotFound",
        "A contract with the specified id was not found."
      )
    };
  }

  const incomingVersion = request.body.json().version;
  if (documentsStore.has(id)) {
    const seqno = documentsStore.getVersionOfPreviousWrite(id);
    const view = ccf.consensus.getViewForSeqno(seqno);
    if (view == null) {
      return {
        statusCode: 503,
        body: new ErrorResponse(
          "ViewNotKnown",
          "View for given sequence number not known to the node at this time."
        )
      };
    }

    if (!incomingVersion) {
      return {
        statusCode: 409,
        body: new ErrorResponse(
          "DocumentAlreadyExists",
          "The specified document already exists. If the intent was to update the " +
            "existing document then retry the " +
            "request after reading the latest version of the resource and setting the version on " +
            "the request."
        )
      };
    }

    const version = view + "." + seqno;
    if (version != incomingVersion) {
      return {
        statusCode: 412,
        body: new ErrorResponse(
          "PreconditionFailed",
          "The operation specified a version that is different from the version " +
            "available at the server, that is, an optimistic concurrency error. Retry the " +
            "request after reading the latest version of the resource and updating the version on " +
            "the request."
        )
      };
    }
  }

  documentsStore.set(id, { contractId: contractId, data: data });
  return {};
}