"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
Object.defineProperty(exports, "snapshotOutgoingChanges", {
    enumerable: true,
    get: function() {
        return snapshotOutgoingChanges;
    }
});
const _sequelize = require("sequelize");
const _log = require("@tamanu/shared/services/logging/log");
const _sync = require("@tamanu/database/sync");
const _withConfig = require("@tamanu/shared/utils/withConfig");
const _constants = require("@tamanu/constants");
const snapshotChangesForModel = async (model, since, transaction)=>{
    const recordsChanged = await model.findAll({
        where: {
            updatedAtSyncTick: {
                [_sequelize.Op.gt]: since
            }
        },
        raw: true,
        paranoid: false,
        transaction
    });
    _log.log.debug(`snapshotChangesForModel: Found ${recordsChanged.length} for model ${model.tableName} since ${since}`);
    return recordsChanged.map((r)=>({
            direction: _sync.SYNC_SESSION_DIRECTION.OUTGOING,
            isDeleted: !!r.deletedAt,
            recordType: model.tableName,
            recordId: r.id,
            data: (0, _sync.sanitizeRecord)(r)
        }));
};
const snapshotOutgoingChanges = (0, _withConfig.withConfig)(async (sequelize, models, since)=>{
    const invalidModelNames = Object.values(models).filter((m)=>![
            _constants.SYNC_DIRECTIONS.BIDIRECTIONAL,
            _constants.SYNC_DIRECTIONS.PUSH_TO_CENTRAL,
            _constants.SYNC_DIRECTIONS.PUSH_TO_CENTRAL_THEN_DELETE
        ].includes(m.syncDirection)).map((m)=>m.tableName);
    if (invalidModelNames.length) {
        throw new Error(`Invalid sync direction(s) when pushing these models from facility: ${invalidModelNames}`);
    }
    // snapshot inside a "repeatable read" transaction, so that other changes made while this snapshot
    // is underway aren't included (as this could lead to a pair of foreign records with the child in
    // the snapshot and its parent missing)
    // as the snapshot only contains read queries, there will be no concurrent update issues :)
    return sequelize.transaction({
        isolationLevel: _sequelize.Transaction.ISOLATION_LEVELS.REPEATABLE_READ
    }, async (transaction)=>{
        let outgoingChanges = [];
        for (const model of Object.values(models)){
            const changesForModel = await snapshotChangesForModel(model, since, transaction);
            outgoingChanges = outgoingChanges.concat(changesForModel);
        }
        return outgoingChanges;
    });
});

//# sourceMappingURL=snapshotOutgoingChanges.js.map