How can I get the previous data of a document before it is updated via replicated data

Retained<C4Document> putDocument(const C4DocPutRequest& rq, size_t* outCommonAncestorIndex,
                                         C4Error* outError) override {
            dbImpl()->mustBeInTransaction();
            if ( rq.docID.buf && !C4Document::isValidDocID(rq.docID) ) error::_throw(error::BadDocID);
            if ( rq.existingRevision || rq.historyCount > 0 ) AssertParam(rq.docID.buf, "Missing docID");
            if ( rq.existingRevision ) {
                AssertParam(rq.historyCount > 0, "No history");
            } else {
                AssertParam(rq.historyCount <= 1, "Too much history");
                AssertParam(rq.historyCount > 0 || !(rq.revFlags & kRevDeleted),
                            "Can't create a new already-deleted document");
                AssertParam(rq.remoteDBID == 0, "remoteDBID cannot be used when existingRevision=false");
            }

            int                  commonAncestorIndex = 0;
            Retained<C4Document> doc;
            if ( rq.save && isNewDocPutRequest(rq) ) {
                // As an optimization, write the doc assuming there is no prior record in the db:
                std::tie(doc, commonAncestorIndex) = putNewDoc(rq);
                // If there's already a record, doc will be null, so we'll continue down regular path.
            }
            if ( !doc ) {
                if ( rq.existingRevision ) {
                    // Insert existing revision:
                    doc = getDocument(rq.docID, false, kDocGetAll);
                    
                    auto previousData = doc->bodyAsJSON();
                    C4Error err;
                    
                    commonAncestorIndex = doc->putExistingRevision(rq, &err);
                    if ( commonAncestorIndex < 0 ) {
                        throwIfUnexpected(err, outError);
                        doc                 = nullptr;
                        commonAncestorIndex = 0;
                    }
                } else {
                    // Create new revision:
                    alloc_slice docID = (rq.docID.buf) ? alloc_slice(rq.docID) : C4Document::createDocID();

                    slice parentRevID;
                    if ( rq.historyCount > 0 ) parentRevID = rq.history[0];

                    doc = getDocument(docID, false, kDocGetAll);
                    auto previousData = doc->bodyAsJSON();
                    C4Error err;
                    if ( !doc->checkNewRev(parentRevID, rq.revFlags, rq.allowConflict, &err)
                         || !doc->putNewRevision(rq, &err) ) {
                        throwIfUnexpected(err, outError);
                        doc = nullptr;
                    }
                    commonAncestorIndex = 0;
                }
            }

            Assert(commonAncestorIndex >= 0, "Unexpected conflict in c4doc_put");
            if ( outCommonAncestorIndex ) *outCommonAncestorIndex = commonAncestorIndex;
            return doc;
        }

here’s the method which is calling when replication pull insert any revision.
I am calling this auto previousData = doc->bodyAsJSON(); to get the body before updating it’s content but it’s returning null.

could you please explain it.

Looks like your code is doing a local write/put. you could do this. 2 writes.

are you talking about creating separate db?

Yea , or put it into a separate scope/collection in the same DB1. I would putt a TTL on the old revs 7 days ->30Days , how every long they are useful. If you keep them for a long time 3 month to 18 months. I would put them in a separate db2.

Can’t we simply send the previous doc before updating it locally. If we need to maintain separate db in that case we don’t need to work on core library. Also I think it will make the database size 2x larger.

if it where me I would not make it so I have to do a READ before I WRITE. It’s just simpler to write twice. Will it make your second db X 2 bigger… Yes , but you have a complete audit trail of the document. for xyz days/weeks/months.

Actually my concern is if I use multiple database then syncing those data will take for time. And I don’t want to do that that’s why I was asking for reading the value before writing while new replicated data comes from server.