feat(foundry): add map zones v2 consumer policy
This commit is contained in:
@@ -67,6 +67,23 @@ for (const policy of consumerPolicies) {
|
||||
requireValue(Array.isArray(policy.terminalStatuses) && policy.terminalStatuses.every((value) => typeof value === "string" && /^[a-z0-9_-]{1,64}$/.test(value)), `invalid terminal statuses: ${policy.id ?? "unknown"}`);
|
||||
requireValue(policy.removeMode === "canonical-tombstone-or-snapshot-rebase", `invalid remove mode: ${policy.id ?? "unknown"}`);
|
||||
requireValue(["none", "observed-at"].includes(freshness), `invalid freshness mode: ${policy.id ?? "unknown"}`);
|
||||
if (policy.consumerContract !== undefined) {
|
||||
const contract = policy.consumerContract;
|
||||
const keys = contract && typeof contract === "object" && !Array.isArray(contract) ? Object.keys(contract).sort() : [];
|
||||
requireValue(JSON.stringify(keys) === JSON.stringify(["deliveryMode", "fieldProjection", "fieldTypes", "geometryTypes", "ontologyRevision", "patchMode", "semanticTypes", "snapshotMode", "subjectIdentity"]), `invalid consumer contract keys: ${policy.id ?? "unknown"}`);
|
||||
requireValue(typeof contract?.ontologyRevision === "string" && /^[A-Za-z0-9._:-]{1,160}$/.test(contract.ontologyRevision), `invalid consumer ontology revision: ${policy.id ?? "unknown"}`);
|
||||
requireValue(contract?.deliveryMode === "snapshot+patch", `invalid consumer delivery mode: ${policy.id ?? "unknown"}`);
|
||||
requireValue(Array.isArray(contract?.semanticTypes) && contract.semanticTypes.length >= 1 && new Set(contract.semanticTypes).size === contract.semanticTypes.length, `invalid consumer semantic types: ${policy.id ?? "unknown"}`);
|
||||
requireValue(contract?.semanticTypes?.every((value) => typeof value === "string" && /^[A-Za-z0-9._:-]{1,160}$/.test(value)), `invalid consumer semantic type: ${policy.id ?? "unknown"}`);
|
||||
requireValue(Array.isArray(contract?.fieldProjection) && contract.fieldProjection.length >= 1 && new Set(contract.fieldProjection).size === contract.fieldProjection.length, `invalid consumer field projection: ${policy.id ?? "unknown"}`);
|
||||
requireValue(contract?.fieldProjection?.every((value) => typeof value === "string" && /^[A-Za-z][A-Za-z0-9_.-]{0,127}$/.test(value)), `invalid consumer projection field: ${policy.id ?? "unknown"}`);
|
||||
requireValue(contract?.fieldTypes && typeof contract.fieldTypes === "object" && !Array.isArray(contract.fieldTypes), `invalid consumer field types: ${policy.id ?? "unknown"}`);
|
||||
requireValue(JSON.stringify(Object.keys(contract?.fieldTypes ?? {})) === JSON.stringify(contract?.fieldProjection ?? []), `consumer field type order/scope mismatch: ${policy.id ?? "unknown"}`);
|
||||
requireValue(Object.values(contract?.fieldTypes ?? {}).every((value) => ["string", "number", "boolean"].includes(value)), `invalid consumer field type: ${policy.id ?? "unknown"}`);
|
||||
requireValue(JSON.stringify(contract?.geometryTypes) === JSON.stringify(["Polygon", "MultiPolygon"]), `invalid consumer geometry types: ${policy.id ?? "unknown"}`);
|
||||
requireValue(contract?.subjectIdentity === "semantic-type+source-id", `invalid consumer subject identity: ${policy.id ?? "unknown"}`);
|
||||
requireValue(contract?.snapshotMode === "atomic-replace" && contract?.patchMode === "atomic", `invalid consumer commit modes: ${policy.id ?? "unknown"}`);
|
||||
}
|
||||
if (statusContract === undefined) {
|
||||
requireValue(
|
||||
freshness === "none"
|
||||
@@ -93,6 +110,27 @@ requireValue(movingObjectV4Policy?.statusContract?.attribute === "signal_state",
|
||||
requireValue(JSON.stringify(movingObjectV4Policy?.statusContract?.allowedValues) === JSON.stringify(["active", "inactive"]), "fleet.positions.current.v4 signal states must remain closed active/inactive");
|
||||
requireValue(movingObjectV4Policy?.statusContract?.freshness === "none" && movingObjectV4Policy?.staleAfterMs === null, "fleet.positions.current.v4 must not invent freshness states");
|
||||
|
||||
const zoneV1Policy = consumerPolicies.find((policy) => policy.dataProductId === "map.zones.current.v1" && policy.productVersion === "1.0.0");
|
||||
requireValue(JSON.stringify(zoneV1Policy) === JSON.stringify({
|
||||
id: "map-zone-current-v1",
|
||||
version: "1.0.0",
|
||||
dataProductId: "map.zones.current.v1",
|
||||
productVersion: "1.0.0",
|
||||
freshness: "none",
|
||||
staleAfterMs: null,
|
||||
terminalStatuses: [],
|
||||
removeMode: "canonical-tombstone-or-snapshot-rebase",
|
||||
}), "historical map.zones.current.v1 consumer policy changed");
|
||||
|
||||
const zoneV2Policy = consumerPolicies.find((policy) => policy.dataProductId === "map.zones.current.v2" && policy.productVersion === "2.0.0");
|
||||
const zoneV2Projection = ["display_name", "geometry_kind", "max_speed_kph", "schedule_timezone", "applies_to_couriers", "applies_to_kicksharing"];
|
||||
requireValue(zoneV2Policy?.id === "map-zone-current-v2" && zoneV2Policy?.version === "2.0.0", "map.zones.current.v2 consumer policy is missing");
|
||||
requireValue(zoneV2Policy?.freshness === "none" && zoneV2Policy?.staleAfterMs === null, "map.zones.current.v2 must not invent freshness states");
|
||||
requireValue(JSON.stringify(zoneV2Policy?.consumerContract?.semanticTypes) === JSON.stringify(["map.zone"]), "map.zones.current.v2 semantic scope must be exact");
|
||||
requireValue(JSON.stringify(zoneV2Policy?.consumerContract?.fieldProjection) === JSON.stringify(zoneV2Projection), "map.zones.current.v2 field projection must be exact");
|
||||
requireValue(JSON.stringify(zoneV2Policy?.consumerContract?.geometryTypes) === JSON.stringify(["Polygon", "MultiPolygon"]), "map.zones.current.v2 geometry contract must be Polygon/MultiPolygon");
|
||||
requireValue(!/(provider|tenant|connection|endpoint|credential|token|secret|authorization)/i.test(JSON.stringify(zoneV2Policy)), "map.zones.current.v2 consumer policy crosses the transport/secret boundary");
|
||||
|
||||
const ids = components.components.map((component) => component.id);
|
||||
requireValue(new Set(ids).size === ids.length, "component ids must be unique");
|
||||
const candidateIds = candidates.candidates.map((component) => component.id);
|
||||
|
||||
Reference in New Issue
Block a user