"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
Object.defineProperty(exports, "transactionBundleHandler", {
    enumerable: true,
    get: function() {
        return transactionBundleHandler;
    }
});
const _expressasynchandler = /*#__PURE__*/ _interop_require_default(require("express-async-handler"));
const _constants = require("@tamanu/constants");
const _fhirTypes = require("@tamanu/shared/services/fhirTypes");
const _fhir = require("@tamanu/shared/utils/fhir");
const _resources = require("@tamanu/shared/utils/fhir/resources");
const _create = require("../create");
const _fhirPermissions = require("../fhirPermissions");
function _interop_require_default(obj) {
    return obj && obj.__esModule ? obj : {
        default: obj
    };
}
const transactionBundleHandler = ()=>{
    return (0, _expressasynchandler.default)(async (req, res)=>{
        const { settings, store } = req;
        let validatedBundle;
        try {
            validatedBundle = await _fhirTypes.FhirTransactionBundle.SCHEMA().validate(req.body);
        } catch (err) {
            return res.status(400).send(_fhir.OperationOutcome.fromYupError(err));
        }
        const creatableResources = (0, _resources.resourcesThatCanDo)(store.models, _constants.FHIR_INTERACTIONS.TYPE.CREATE);
        // Run all operations in a database transaction to ensure atomicity
        const responses = [];
        try {
            await store.sequelize.transaction(async ()=>{
                for (const { resource: rawResource } of validatedBundle.entry){
                    const FhirResource = creatableResources.find((r)=>r.fhirName === rawResource.resourceType);
                    if (!FhirResource) {
                        throw new _fhir.Invalid(`Resource type ${rawResource.resourceType} not found`);
                    }
                    (0, _fhirPermissions.checkFhirWritePermissionForResource)(req.ability, rawResource.resourceType);
                    const hydratedResource = FhirResource.hydrateRawResourceFromBundle(validatedBundle, rawResource);
                    await (0, _create.createResource)(store, FhirResource, hydratedResource, req.user?.id, settings);
                    responses.push({
                        response: {
                            status: '201'
                        }
                    });
                }
            });
        } catch (err) {
            const oo = new _fhir.OperationOutcome([
                err
            ]);
            return res.status(oo.status()).send(oo.asFhir());
        }
        const responseBundle = new _fhirTypes.FhirTransactionResponseBundle({
            resourceType: 'Bundle',
            type: _constants.FHIR_BUNDLE_TYPES.TRANSACTION_RESPONSE,
            entry: responses
        });
        res.status(200).send(responseBundle);
    });
};

//# sourceMappingURL=transactionBundle.js.map