@openhi/constructs 0.0.4 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.js +27 -4
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +27 -4
- package/lib/index.mjs.map +1 -1
- package/lib/rest-api-lambda.handler.js +468 -4
- package/lib/rest-api-lambda.handler.js.map +1 -1
- package/lib/rest-api-lambda.handler.mjs +472 -4
- package/lib/rest-api-lambda.handler.mjs.map +1 -1
- package/package.json +5 -4
|
@@ -38,7 +38,7 @@ var import_serverless_express = __toESM(require("@codegenie/serverless-express")
|
|
|
38
38
|
// src/data/rest-api/rest-api.ts
|
|
39
39
|
var import_path = __toESM(require("path"));
|
|
40
40
|
var import_cors = __toESM(require("cors"));
|
|
41
|
-
var
|
|
41
|
+
var import_express3 = __toESM(require("express"));
|
|
42
42
|
|
|
43
43
|
// src/data/middleware/open-hi-context.ts
|
|
44
44
|
var STATIC_TENANT_ID = "tenant-1";
|
|
@@ -655,18 +655,482 @@ async function deletePatient(req, res) {
|
|
|
655
655
|
}
|
|
656
656
|
router.delete("/:id", deletePatient);
|
|
657
657
|
|
|
658
|
+
// src/data/rest-api/ohi/Configuration.ts
|
|
659
|
+
var import_express2 = __toESM(require("express"));
|
|
660
|
+
|
|
661
|
+
// src/data/rest-api/ohi/dynamic-configuration.ts
|
|
662
|
+
var import_client_ssm = require("@aws-sdk/client-ssm");
|
|
663
|
+
var BASE_PATH2 = "/ohi/Configuration";
|
|
664
|
+
var TAG_KEY_BRANCH = "openhi:branch-name";
|
|
665
|
+
var TAG_KEY_HTTP_API_PARAM = "openhi:param-name";
|
|
666
|
+
function getSsmDynamicConfigEnvFilter() {
|
|
667
|
+
const branchTagValue = process.env.BRANCH_TAG_VALUE;
|
|
668
|
+
const httpApiTagValue = process.env.HTTP_API_TAG_VALUE;
|
|
669
|
+
if (branchTagValue == null || branchTagValue === "" || httpApiTagValue == null || httpApiTagValue === "") {
|
|
670
|
+
return null;
|
|
671
|
+
}
|
|
672
|
+
return { branchTagValue, httpApiTagValue };
|
|
673
|
+
}
|
|
674
|
+
async function getDynamicConfigurationEntries(context) {
|
|
675
|
+
const envFilter = getSsmDynamicConfigEnvFilter();
|
|
676
|
+
if (envFilter == null) {
|
|
677
|
+
return getStaticDummyEntry(context);
|
|
678
|
+
}
|
|
679
|
+
const region = process.env.AWS_REGION ?? process.env.AWS_DEFAULT_REGION;
|
|
680
|
+
const client3 = new import_client_ssm.SSMClient({ region });
|
|
681
|
+
try {
|
|
682
|
+
const describeResult = await client3.send(
|
|
683
|
+
new import_client_ssm.DescribeParametersCommand({
|
|
684
|
+
ParameterFilters: [
|
|
685
|
+
{
|
|
686
|
+
Key: `tag:${TAG_KEY_BRANCH}`,
|
|
687
|
+
Option: "Equals",
|
|
688
|
+
Values: [envFilter.branchTagValue]
|
|
689
|
+
},
|
|
690
|
+
{
|
|
691
|
+
Key: `tag:${TAG_KEY_HTTP_API_PARAM}`,
|
|
692
|
+
Option: "Equals",
|
|
693
|
+
Values: [envFilter.httpApiTagValue]
|
|
694
|
+
}
|
|
695
|
+
],
|
|
696
|
+
MaxResults: 50
|
|
697
|
+
})
|
|
698
|
+
);
|
|
699
|
+
const names = (describeResult.Parameters ?? []).map((p) => p.Name).filter((n) => n != null);
|
|
700
|
+
if (names.length === 0) {
|
|
701
|
+
return getStaticDummyEntry(context);
|
|
702
|
+
}
|
|
703
|
+
const parameters = [];
|
|
704
|
+
for (let i = 0; i < names.length; i += 10) {
|
|
705
|
+
const batch = names.slice(i, i + 10);
|
|
706
|
+
const getResult = await client3.send(
|
|
707
|
+
new import_client_ssm.GetParametersCommand({
|
|
708
|
+
Names: batch,
|
|
709
|
+
WithDecryption: true
|
|
710
|
+
})
|
|
711
|
+
);
|
|
712
|
+
for (const p of getResult.Parameters ?? []) {
|
|
713
|
+
const name = p.Name;
|
|
714
|
+
const value = p.Value;
|
|
715
|
+
if (name != null && value != null) {
|
|
716
|
+
parameters.push({ name, value });
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
const parameterList = parameters.map((p) => {
|
|
721
|
+
const shortName = p.name.includes("/") ? p.name.split("/").slice(-1)[0] : p.name;
|
|
722
|
+
return { name: shortName, valueString: p.value };
|
|
723
|
+
});
|
|
724
|
+
const entry = {
|
|
725
|
+
fullUrl: `${BASE_PATH2}/ssm-dynamic`,
|
|
726
|
+
resource: {
|
|
727
|
+
resourceType: "Configuration",
|
|
728
|
+
id: "ssm-dynamic",
|
|
729
|
+
key: "ssm-dynamic",
|
|
730
|
+
resource: {
|
|
731
|
+
parameter: parameterList
|
|
732
|
+
},
|
|
733
|
+
meta: {
|
|
734
|
+
lastUpdated: (/* @__PURE__ */ new Date()).toISOString(),
|
|
735
|
+
versionId: "1"
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
};
|
|
739
|
+
return [entry];
|
|
740
|
+
} catch (err) {
|
|
741
|
+
console.error("getDynamicConfigurationEntries SSM error:", err);
|
|
742
|
+
return getStaticDummyEntry(context);
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
function getStaticDummyEntry(_context) {
|
|
746
|
+
const dummy = {
|
|
747
|
+
fullUrl: `${BASE_PATH2}/dynamic-dummy`,
|
|
748
|
+
resource: {
|
|
749
|
+
resourceType: "Configuration",
|
|
750
|
+
id: "dynamic-dummy",
|
|
751
|
+
key: "dynamic-dummy",
|
|
752
|
+
resource: {
|
|
753
|
+
parameter: [
|
|
754
|
+
{
|
|
755
|
+
name: "description",
|
|
756
|
+
valueString: "Statically generated dummy configuration (not from DynamoDB)."
|
|
757
|
+
},
|
|
758
|
+
{ name: "source", valueString: "dynamic-configuration" }
|
|
759
|
+
]
|
|
760
|
+
},
|
|
761
|
+
meta: {
|
|
762
|
+
lastUpdated: (/* @__PURE__ */ new Date()).toISOString(),
|
|
763
|
+
versionId: "1"
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
};
|
|
767
|
+
return [dummy];
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
// src/data/dynamo/ohi/ohi-data-service.ts
|
|
771
|
+
var import_client_dynamodb2 = require("@aws-sdk/client-dynamodb");
|
|
772
|
+
var import_electrodb4 = require("electrodb");
|
|
773
|
+
|
|
774
|
+
// src/data/dynamo/ohi/Configuration.ts
|
|
775
|
+
var import_electrodb3 = require("electrodb");
|
|
776
|
+
var Configuration = new import_electrodb3.Entity({
|
|
777
|
+
model: {
|
|
778
|
+
entity: "configuration",
|
|
779
|
+
service: "ohi",
|
|
780
|
+
version: "01"
|
|
781
|
+
},
|
|
782
|
+
attributes: {
|
|
783
|
+
/** Sort key. "CURRENT" for current version; version history in S3. */
|
|
784
|
+
sk: {
|
|
785
|
+
type: "string",
|
|
786
|
+
required: true,
|
|
787
|
+
default: "CURRENT"
|
|
788
|
+
},
|
|
789
|
+
/** Tenant scope. Use "BASELINE" when the config is baseline default (no tenant). */
|
|
790
|
+
tenantId: {
|
|
791
|
+
type: "string",
|
|
792
|
+
required: true,
|
|
793
|
+
default: "BASELINE"
|
|
794
|
+
},
|
|
795
|
+
/** Workspace scope. Use "-" when absent. */
|
|
796
|
+
workspaceId: {
|
|
797
|
+
type: "string",
|
|
798
|
+
required: true,
|
|
799
|
+
default: "-"
|
|
800
|
+
},
|
|
801
|
+
/** User scope. Use "-" when absent. */
|
|
802
|
+
userId: {
|
|
803
|
+
type: "string",
|
|
804
|
+
required: true,
|
|
805
|
+
default: "-"
|
|
806
|
+
},
|
|
807
|
+
/** Role scope. Use "-" when absent. */
|
|
808
|
+
roleId: {
|
|
809
|
+
type: "string",
|
|
810
|
+
required: true,
|
|
811
|
+
default: "-"
|
|
812
|
+
},
|
|
813
|
+
/** Config type (category), e.g. endpoints, branding, display. */
|
|
814
|
+
key: {
|
|
815
|
+
type: "string",
|
|
816
|
+
required: true
|
|
817
|
+
},
|
|
818
|
+
/** FHIR Resource.id; logical id in URL and for the Configuration resource. */
|
|
819
|
+
id: {
|
|
820
|
+
type: "string",
|
|
821
|
+
required: true
|
|
822
|
+
},
|
|
823
|
+
/** Payload as JSON string. JSON.stringify(resource) on write; JSON.parse(item.resource) on read. */
|
|
824
|
+
resource: {
|
|
825
|
+
type: "string",
|
|
826
|
+
required: true
|
|
827
|
+
},
|
|
828
|
+
/** Version id (e.g. ULID). Tracks current version; S3 history key. */
|
|
829
|
+
vid: {
|
|
830
|
+
type: "string",
|
|
831
|
+
required: true
|
|
832
|
+
},
|
|
833
|
+
lastUpdated: {
|
|
834
|
+
type: "string",
|
|
835
|
+
required: true
|
|
836
|
+
},
|
|
837
|
+
deleted: {
|
|
838
|
+
type: "boolean",
|
|
839
|
+
required: false
|
|
840
|
+
},
|
|
841
|
+
bundleId: {
|
|
842
|
+
type: "string",
|
|
843
|
+
required: false
|
|
844
|
+
},
|
|
845
|
+
msgId: {
|
|
846
|
+
type: "string",
|
|
847
|
+
required: false
|
|
848
|
+
}
|
|
849
|
+
},
|
|
850
|
+
indexes: {
|
|
851
|
+
/** Base table: PK, SK (data store key names). PK is built from tenantId, workspaceId, userId, roleId; SK is built from key and sk. Do not supply PK or SK from outside. */
|
|
852
|
+
record: {
|
|
853
|
+
pk: {
|
|
854
|
+
field: "PK",
|
|
855
|
+
composite: ["tenantId", "workspaceId", "userId", "roleId"],
|
|
856
|
+
template: "OHI#CONFIG#TID#${tenantId}#WID#${workspaceId}#UID#${userId}#RID#${roleId}"
|
|
857
|
+
},
|
|
858
|
+
sk: {
|
|
859
|
+
field: "SK",
|
|
860
|
+
composite: ["key", "sk"],
|
|
861
|
+
template: "KEY#${key}#SK#${sk}"
|
|
862
|
+
}
|
|
863
|
+
},
|
|
864
|
+
/** GSI4 — Resource Type Index: list all Configuration in a tenant or workspace (no scan). Use for "list configs scoped to this tenant" (workspaceId = "-") or "list configs scoped to this workspace". Does not support hierarchical resolution in one query; use base table GetItem in fallback order (user → workspace → tenant → baseline) for that. */
|
|
865
|
+
gsi4: {
|
|
866
|
+
index: "GSI4",
|
|
867
|
+
condition: () => true,
|
|
868
|
+
pk: {
|
|
869
|
+
field: "GSI4PK",
|
|
870
|
+
composite: ["tenantId", "workspaceId"],
|
|
871
|
+
template: "TID#${tenantId}#WID#${workspaceId}#RT#Configuration"
|
|
872
|
+
},
|
|
873
|
+
sk: {
|
|
874
|
+
field: "GSI4SK",
|
|
875
|
+
composite: ["key", "sk"],
|
|
876
|
+
template: "KEY#${key}#SK#${sk}"
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
});
|
|
881
|
+
|
|
882
|
+
// src/data/dynamo/ohi/ohi-data-service.ts
|
|
883
|
+
var table2 = process.env.DYNAMO_TABLE_NAME ?? "jesttesttable";
|
|
884
|
+
var client2 = new import_client_dynamodb2.DynamoDBClient({
|
|
885
|
+
...process.env.MOCK_DYNAMODB_ENDPOINT && {
|
|
886
|
+
endpoint: process.env.MOCK_DYNAMODB_ENDPOINT,
|
|
887
|
+
sslEnabled: false,
|
|
888
|
+
region: "local"
|
|
889
|
+
}
|
|
890
|
+
});
|
|
891
|
+
var entities2 = { configuration: Configuration };
|
|
892
|
+
var OhiDataService = new import_electrodb4.Service(entities2, { table: table2, client: client2 });
|
|
893
|
+
function getOhiDataService(tableName) {
|
|
894
|
+
return new import_electrodb4.Service(entities2, { table: tableName, client: client2 });
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
// src/data/rest-api/ohi/Configuration.ts
|
|
898
|
+
var BASE_PATH3 = "/ohi/Configuration";
|
|
899
|
+
var router2 = import_express2.default.Router();
|
|
900
|
+
var SK3 = "CURRENT";
|
|
901
|
+
var TABLE_NAME2 = process.env.DYNAMO_TABLE_NAME ?? "jesttesttable";
|
|
902
|
+
async function listConfigurations(req, res) {
|
|
903
|
+
const { tenantId, workspaceId } = req.openhiContext;
|
|
904
|
+
const service = getOhiDataService(TABLE_NAME2);
|
|
905
|
+
try {
|
|
906
|
+
const result = await service.entities.configuration.query.gsi4({ tenantId, workspaceId }).go();
|
|
907
|
+
const dynamoEntries = (result.data ?? []).map((item) => {
|
|
908
|
+
const resource = JSON.parse(decompressResource(item.resource));
|
|
909
|
+
return {
|
|
910
|
+
fullUrl: `${BASE_PATH3}/${item.key}`,
|
|
911
|
+
resource: { ...resource, id: item.id, key: item.key }
|
|
912
|
+
};
|
|
913
|
+
});
|
|
914
|
+
const dynamicEntries = await getDynamicConfigurationEntries({
|
|
915
|
+
tenantId,
|
|
916
|
+
workspaceId
|
|
917
|
+
});
|
|
918
|
+
const entries = [...dynamoEntries, ...dynamicEntries];
|
|
919
|
+
const bundle = {
|
|
920
|
+
resourceType: "Bundle",
|
|
921
|
+
type: "searchset",
|
|
922
|
+
total: entries.length,
|
|
923
|
+
link: [{ relation: "self", url: BASE_PATH3 }],
|
|
924
|
+
entry: entries
|
|
925
|
+
};
|
|
926
|
+
return res.json(bundle);
|
|
927
|
+
} catch (err) {
|
|
928
|
+
console.error("GET /Configuration list error:", err);
|
|
929
|
+
return res.status(500).json({
|
|
930
|
+
resourceType: "OperationOutcome",
|
|
931
|
+
issue: [
|
|
932
|
+
{
|
|
933
|
+
severity: "error",
|
|
934
|
+
code: "exception",
|
|
935
|
+
diagnostics: String(err)
|
|
936
|
+
}
|
|
937
|
+
]
|
|
938
|
+
});
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
router2.get("/", listConfigurations);
|
|
942
|
+
async function getConfigurationByKey(req, res) {
|
|
943
|
+
const key = String(req.params.key);
|
|
944
|
+
const ctx = req.openhiContext;
|
|
945
|
+
const { tenantId, workspaceId, userId } = ctx;
|
|
946
|
+
const roleId = "roleId" in ctx && typeof ctx.roleId === "string" ? ctx.roleId : "-";
|
|
947
|
+
const service = getOhiDataService(TABLE_NAME2);
|
|
948
|
+
try {
|
|
949
|
+
const result = await service.entities.configuration.get({ tenantId, workspaceId, userId, roleId, key, sk: SK3 }).go();
|
|
950
|
+
if (!result.data) {
|
|
951
|
+
return res.status(404).json({
|
|
952
|
+
resourceType: "OperationOutcome",
|
|
953
|
+
issue: [
|
|
954
|
+
{
|
|
955
|
+
severity: "error",
|
|
956
|
+
code: "not-found",
|
|
957
|
+
diagnostics: `Configuration ${key} not found`
|
|
958
|
+
}
|
|
959
|
+
]
|
|
960
|
+
});
|
|
961
|
+
}
|
|
962
|
+
const resource = JSON.parse(
|
|
963
|
+
decompressResource(result.data.resource)
|
|
964
|
+
);
|
|
965
|
+
return res.json({
|
|
966
|
+
...resource,
|
|
967
|
+
resourceType: "Configuration",
|
|
968
|
+
id: result.data.id,
|
|
969
|
+
key: result.data.key
|
|
970
|
+
});
|
|
971
|
+
} catch (err) {
|
|
972
|
+
console.error("GET Configuration error:", err);
|
|
973
|
+
return res.status(500).json({
|
|
974
|
+
resourceType: "OperationOutcome",
|
|
975
|
+
issue: [
|
|
976
|
+
{
|
|
977
|
+
severity: "error",
|
|
978
|
+
code: "exception",
|
|
979
|
+
diagnostics: String(err)
|
|
980
|
+
}
|
|
981
|
+
]
|
|
982
|
+
});
|
|
983
|
+
}
|
|
984
|
+
}
|
|
985
|
+
router2.get("/:key", getConfigurationByKey);
|
|
986
|
+
async function createConfiguration(req, res) {
|
|
987
|
+
const ctx = req.openhiContext;
|
|
988
|
+
const {
|
|
989
|
+
tenantId: ctxTenantId,
|
|
990
|
+
workspaceId: ctxWorkspaceId,
|
|
991
|
+
userId: ctxUserId,
|
|
992
|
+
date
|
|
993
|
+
} = ctx;
|
|
994
|
+
const body = req.body;
|
|
995
|
+
const key = body?.key;
|
|
996
|
+
if (!key || typeof key !== "string") {
|
|
997
|
+
return res.status(400).json({
|
|
998
|
+
resourceType: "OperationOutcome",
|
|
999
|
+
issue: [
|
|
1000
|
+
{
|
|
1001
|
+
severity: "error",
|
|
1002
|
+
code: "required",
|
|
1003
|
+
diagnostics: "Configuration key is required"
|
|
1004
|
+
}
|
|
1005
|
+
]
|
|
1006
|
+
});
|
|
1007
|
+
}
|
|
1008
|
+
const id = body?.id ?? `config-${key}-${Date.now()}`;
|
|
1009
|
+
const resourcePayload = body?.resource;
|
|
1010
|
+
const resourceStr = typeof resourcePayload === "string" ? resourcePayload : JSON.stringify(resourcePayload ?? {});
|
|
1011
|
+
const tenantId = body?.tenantId ?? ctxTenantId;
|
|
1012
|
+
const workspaceId = body?.workspaceId ?? ctxWorkspaceId;
|
|
1013
|
+
const userId = body?.userId ?? ctxUserId ?? "-";
|
|
1014
|
+
const roleId = body?.roleId ?? "-";
|
|
1015
|
+
const vid = body?.vid ?? (date.replace(/[-:T.Z]/g, "").slice(0, 12) || Date.now().toString(36));
|
|
1016
|
+
const lastUpdated = body?.lastUpdated ?? date;
|
|
1017
|
+
const service = getOhiDataService(TABLE_NAME2);
|
|
1018
|
+
try {
|
|
1019
|
+
await service.entities.configuration.put({
|
|
1020
|
+
tenantId,
|
|
1021
|
+
workspaceId,
|
|
1022
|
+
userId,
|
|
1023
|
+
roleId,
|
|
1024
|
+
key,
|
|
1025
|
+
id,
|
|
1026
|
+
resource: compressResource(resourceStr),
|
|
1027
|
+
vid,
|
|
1028
|
+
lastUpdated,
|
|
1029
|
+
sk: SK3
|
|
1030
|
+
}).go();
|
|
1031
|
+
const config = {
|
|
1032
|
+
resourceType: "Configuration",
|
|
1033
|
+
id,
|
|
1034
|
+
key,
|
|
1035
|
+
resource: typeof resourcePayload === "object" ? resourcePayload : JSON.parse(resourceStr),
|
|
1036
|
+
meta: { lastUpdated, versionId: vid }
|
|
1037
|
+
};
|
|
1038
|
+
return res.status(201).location(`${BASE_PATH3}/${key}`).json(config);
|
|
1039
|
+
} catch (err) {
|
|
1040
|
+
console.error("POST Configuration error:", err);
|
|
1041
|
+
return res.status(500).json({
|
|
1042
|
+
resourceType: "OperationOutcome",
|
|
1043
|
+
issue: [
|
|
1044
|
+
{ severity: "error", code: "exception", diagnostics: String(err) }
|
|
1045
|
+
]
|
|
1046
|
+
});
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
router2.post("/", createConfiguration);
|
|
1050
|
+
async function updateConfiguration(req, res) {
|
|
1051
|
+
const key = String(req.params.key);
|
|
1052
|
+
const ctx = req.openhiContext;
|
|
1053
|
+
const { tenantId, workspaceId, userId, date } = ctx;
|
|
1054
|
+
const roleId = "roleId" in ctx && typeof ctx.roleId === "string" ? ctx.roleId : "-";
|
|
1055
|
+
const body = req.body;
|
|
1056
|
+
const resourcePayload = body?.resource;
|
|
1057
|
+
const resourceStr = typeof resourcePayload === "string" ? resourcePayload : JSON.stringify(resourcePayload ?? {});
|
|
1058
|
+
const lastUpdated = body?.lastUpdated ?? date;
|
|
1059
|
+
const service = getOhiDataService(TABLE_NAME2);
|
|
1060
|
+
try {
|
|
1061
|
+
const existing = await service.entities.configuration.get({ tenantId, workspaceId, userId, roleId, key, sk: SK3 }).go();
|
|
1062
|
+
if (!existing.data) {
|
|
1063
|
+
return res.status(404).json({
|
|
1064
|
+
resourceType: "OperationOutcome",
|
|
1065
|
+
issue: [
|
|
1066
|
+
{
|
|
1067
|
+
severity: "error",
|
|
1068
|
+
code: "not-found",
|
|
1069
|
+
diagnostics: `Configuration ${key} not found`
|
|
1070
|
+
}
|
|
1071
|
+
]
|
|
1072
|
+
});
|
|
1073
|
+
}
|
|
1074
|
+
const nextVid = existing.data.vid != null ? String(Number(existing.data.vid) + 1) : date.replace(/[-:T.Z]/g, "").slice(0, 12) || "2";
|
|
1075
|
+
await service.entities.configuration.patch({ tenantId, workspaceId, userId, roleId, key, sk: SK3 }).set({
|
|
1076
|
+
resource: compressResource(resourceStr),
|
|
1077
|
+
lastUpdated,
|
|
1078
|
+
vid: nextVid
|
|
1079
|
+
}).go();
|
|
1080
|
+
const config = {
|
|
1081
|
+
resourceType: "Configuration",
|
|
1082
|
+
id: existing.data.id,
|
|
1083
|
+
key: existing.data.key,
|
|
1084
|
+
resource: typeof resourcePayload === "object" ? resourcePayload : JSON.parse(resourceStr),
|
|
1085
|
+
meta: { lastUpdated, versionId: nextVid }
|
|
1086
|
+
};
|
|
1087
|
+
return res.json(config);
|
|
1088
|
+
} catch (err) {
|
|
1089
|
+
console.error("PUT Configuration error:", err);
|
|
1090
|
+
return res.status(500).json({
|
|
1091
|
+
resourceType: "OperationOutcome",
|
|
1092
|
+
issue: [
|
|
1093
|
+
{ severity: "error", code: "exception", diagnostics: String(err) }
|
|
1094
|
+
]
|
|
1095
|
+
});
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1098
|
+
router2.put("/:key", updateConfiguration);
|
|
1099
|
+
async function deleteConfiguration(req, res) {
|
|
1100
|
+
const key = String(req.params.key);
|
|
1101
|
+
const ctx = req.openhiContext;
|
|
1102
|
+
const { tenantId, workspaceId, userId } = ctx;
|
|
1103
|
+
const roleId = "roleId" in ctx && typeof ctx.roleId === "string" ? ctx.roleId : "-";
|
|
1104
|
+
const service = getOhiDataService(TABLE_NAME2);
|
|
1105
|
+
try {
|
|
1106
|
+
await service.entities.configuration.delete({ tenantId, workspaceId, userId, roleId, key, sk: SK3 }).go();
|
|
1107
|
+
return res.status(204).send();
|
|
1108
|
+
} catch (err) {
|
|
1109
|
+
console.error("DELETE Configuration error:", err);
|
|
1110
|
+
return res.status(500).json({
|
|
1111
|
+
resourceType: "OperationOutcome",
|
|
1112
|
+
issue: [
|
|
1113
|
+
{ severity: "error", code: "exception", diagnostics: String(err) }
|
|
1114
|
+
]
|
|
1115
|
+
});
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
router2.delete("/:key", deleteConfiguration);
|
|
1119
|
+
|
|
658
1120
|
// src/data/rest-api/rest-api.ts
|
|
659
|
-
var app = (0,
|
|
1121
|
+
var app = (0, import_express3.default)();
|
|
660
1122
|
app.set("view engine", "ejs");
|
|
661
1123
|
app.set("views", import_path.default.join(__dirname, "views"));
|
|
662
1124
|
app.use((0, import_cors.default)());
|
|
663
|
-
app.use(
|
|
664
|
-
app.use(
|
|
1125
|
+
app.use(import_express3.default.json());
|
|
1126
|
+
app.use(import_express3.default.urlencoded({ extended: true }));
|
|
665
1127
|
app.get("/", (_req, res) => {
|
|
666
1128
|
return res.status(200).json({ message: "POC App is running" });
|
|
667
1129
|
});
|
|
668
1130
|
app.use("/ehr", openHiContextMiddleware);
|
|
1131
|
+
app.use("/ohi", openHiContextMiddleware);
|
|
669
1132
|
app.use("/ehr/r4/Patient", router);
|
|
1133
|
+
app.use("/ohi/Configuration", router2);
|
|
670
1134
|
|
|
671
1135
|
// src/data/lambda/rest-api-lambda.handler.ts
|
|
672
1136
|
var handler = (0, import_serverless_express.default)({ app });
|