@mrtdown/core 2.0.0-alpha.4 → 2.0.0-alpha.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/dist/index.d.ts +20 -27
- package/dist/index.js +20 -27
- package/dist/index.js.map +1 -1
- package/dist/schema/Landmark.js.map +1 -1
- package/dist/schema/Line.js.map +1 -1
- package/dist/schema/Operator.js.map +1 -1
- package/dist/schema/Service.js.map +1 -1
- package/dist/schema/Station.js.map +1 -1
- package/dist/schema/Town.js.map +1 -1
- package/dist/schema/common.js.map +1 -1
- package/dist/schema/issue/bundle.js.map +1 -1
- package/dist/schema/issue/cause.js.map +1 -1
- package/dist/schema/issue/claim.js.map +1 -1
- package/dist/schema/issue/entity.js.map +1 -1
- package/dist/schema/issue/evidence.js +1 -1
- package/dist/schema/issue/evidence.js.map +1 -1
- package/dist/schema/issue/facilityEffect.js.map +1 -1
- package/dist/schema/issue/id.js.map +1 -1
- package/dist/schema/issue/impactEvent.js.map +1 -1
- package/dist/schema/issue/issue.js +1 -1
- package/dist/schema/issue/issue.js.map +1 -1
- package/dist/schema/issue/issueType.js.map +1 -1
- package/dist/schema/issue/period.js.map +1 -1
- package/dist/schema/issue/serviceEffect.js.map +1 -1
- package/dist/schema/issue/serviceScope.js.map +1 -1
- package/package.json +19 -53
- package/README.md +0 -107
- package/dist/cli/commands/create.d.ts +0 -30
- package/dist/cli/commands/create.js +0 -189
- package/dist/cli/commands/create.js.map +0 -1
- package/dist/cli/commands/list.d.ts +0 -6
- package/dist/cli/commands/list.js +0 -106
- package/dist/cli/commands/list.js.map +0 -1
- package/dist/cli/commands/show.d.ts +0 -6
- package/dist/cli/commands/show.js +0 -156
- package/dist/cli/commands/show.js.map +0 -1
- package/dist/cli/commands/validate.d.ts +0 -6
- package/dist/cli/commands/validate.js +0 -19
- package/dist/cli/commands/validate.js.map +0 -1
- package/dist/cli/index.d.ts +0 -2
- package/dist/cli/index.js +0 -162
- package/dist/cli/index.js.map +0 -1
- package/dist/constants.d.ts +0 -10
- package/dist/constants.js +0 -11
- package/dist/constants.js.map +0 -1
- package/dist/helpers/calculateDurationWithinServiceHours.d.ts +0 -2
- package/dist/helpers/calculateDurationWithinServiceHours.js +0 -13
- package/dist/helpers/calculateDurationWithinServiceHours.js.map +0 -1
- package/dist/helpers/calculateDurationWithinServiceHours.test.d.ts +0 -1
- package/dist/helpers/calculateDurationWithinServiceHours.test.js +0 -83
- package/dist/helpers/calculateDurationWithinServiceHours.test.js.map +0 -1
- package/dist/helpers/computeImpactFromEvidenceClaims.d.ts +0 -21
- package/dist/helpers/computeImpactFromEvidenceClaims.js +0 -293
- package/dist/helpers/computeImpactFromEvidenceClaims.js.map +0 -1
- package/dist/helpers/computeImpactFromEvidenceClaims.test.d.ts +0 -1
- package/dist/helpers/computeImpactFromEvidenceClaims.test.js +0 -544
- package/dist/helpers/computeImpactFromEvidenceClaims.test.js.map +0 -1
- package/dist/helpers/computeStartOfDaysWithinInterval.d.ts +0 -2
- package/dist/helpers/computeStartOfDaysWithinInterval.js +0 -15
- package/dist/helpers/computeStartOfDaysWithinInterval.js.map +0 -1
- package/dist/helpers/computeStartOfDaysWithinInterval.test.d.ts +0 -1
- package/dist/helpers/computeStartOfDaysWithinInterval.test.js +0 -126
- package/dist/helpers/computeStartOfDaysWithinInterval.test.js.map +0 -1
- package/dist/helpers/estimateOpenAICost.d.ts +0 -40
- package/dist/helpers/estimateOpenAICost.js +0 -55
- package/dist/helpers/estimateOpenAICost.js.map +0 -1
- package/dist/helpers/keyForAffectedEntity.d.ts +0 -7
- package/dist/helpers/keyForAffectedEntity.js +0 -14
- package/dist/helpers/keyForAffectedEntity.js.map +0 -1
- package/dist/helpers/normalizeRecurringPeriod.d.ts +0 -7
- package/dist/helpers/normalizeRecurringPeriod.js +0 -118
- package/dist/helpers/normalizeRecurringPeriod.js.map +0 -1
- package/dist/helpers/normalizeRecurringPeriod.test.d.ts +0 -1
- package/dist/helpers/normalizeRecurringPeriod.test.js +0 -93
- package/dist/helpers/normalizeRecurringPeriod.test.js.map +0 -1
- package/dist/helpers/resolvePeriods.d.ts +0 -224
- package/dist/helpers/resolvePeriods.js +0 -207
- package/dist/helpers/resolvePeriods.js.map +0 -1
- package/dist/helpers/resolvePeriods.test.d.ts +0 -1
- package/dist/helpers/resolvePeriods.test.js +0 -239
- package/dist/helpers/resolvePeriods.test.js.map +0 -1
- package/dist/helpers/splitIntervalByServiceHours.d.ts +0 -2
- package/dist/helpers/splitIntervalByServiceHours.js +0 -30
- package/dist/helpers/splitIntervalByServiceHours.js.map +0 -1
- package/dist/helpers/splitIntervalByServiceHours.test.d.ts +0 -1
- package/dist/helpers/splitIntervalByServiceHours.test.js +0 -152
- package/dist/helpers/splitIntervalByServiceHours.test.js.map +0 -1
- package/dist/helpers/sumIntervalDuration.d.ts +0 -2
- package/dist/helpers/sumIntervalDuration.js +0 -9
- package/dist/helpers/sumIntervalDuration.js.map +0 -1
- package/dist/llm/client.d.ts +0 -2
- package/dist/llm/client.js +0 -5
- package/dist/llm/client.js.map +0 -1
- package/dist/llm/common/MemoryStore.d.ts +0 -21
- package/dist/llm/common/MemoryStore.js +0 -100
- package/dist/llm/common/MemoryStore.js.map +0 -1
- package/dist/llm/common/MemoryStore.test.d.ts +0 -1
- package/dist/llm/common/MemoryStore.test.js +0 -225
- package/dist/llm/common/MemoryStore.test.js.map +0 -1
- package/dist/llm/common/formatCurrentState.d.ts +0 -10
- package/dist/llm/common/formatCurrentState.js +0 -342
- package/dist/llm/common/formatCurrentState.js.map +0 -1
- package/dist/llm/common/tool.d.ts +0 -32
- package/dist/llm/common/tool.js +0 -6
- package/dist/llm/common/tool.js.map +0 -1
- package/dist/llm/functions/extractClaimsFromNewEvidence/eval.test.d.ts +0 -1
- package/dist/llm/functions/extractClaimsFromNewEvidence/eval.test.js +0 -433
- package/dist/llm/functions/extractClaimsFromNewEvidence/eval.test.js.map +0 -1
- package/dist/llm/functions/extractClaimsFromNewEvidence/index.d.ts +0 -18
- package/dist/llm/functions/extractClaimsFromNewEvidence/index.js +0 -153
- package/dist/llm/functions/extractClaimsFromNewEvidence/index.js.map +0 -1
- package/dist/llm/functions/extractClaimsFromNewEvidence/prompt.d.ts +0 -1
- package/dist/llm/functions/extractClaimsFromNewEvidence/prompt.js +0 -168
- package/dist/llm/functions/extractClaimsFromNewEvidence/prompt.js.map +0 -1
- package/dist/llm/functions/extractClaimsFromNewEvidence/tools/FindLinesTool.d.ts +0 -19
- package/dist/llm/functions/extractClaimsFromNewEvidence/tools/FindLinesTool.js +0 -65
- package/dist/llm/functions/extractClaimsFromNewEvidence/tools/FindLinesTool.js.map +0 -1
- package/dist/llm/functions/extractClaimsFromNewEvidence/tools/FindServicesTool.d.ts +0 -21
- package/dist/llm/functions/extractClaimsFromNewEvidence/tools/FindServicesTool.js +0 -115
- package/dist/llm/functions/extractClaimsFromNewEvidence/tools/FindServicesTool.js.map +0 -1
- package/dist/llm/functions/extractClaimsFromNewEvidence/tools/FindStationsTool.d.ts +0 -24
- package/dist/llm/functions/extractClaimsFromNewEvidence/tools/FindStationsTool.js +0 -110
- package/dist/llm/functions/extractClaimsFromNewEvidence/tools/FindStationsTool.js.map +0 -1
- package/dist/llm/functions/generateIssueTitleAndSlug/index.d.ts +0 -14
- package/dist/llm/functions/generateIssueTitleAndSlug/index.js +0 -38
- package/dist/llm/functions/generateIssueTitleAndSlug/index.js.map +0 -1
- package/dist/llm/functions/generateIssueTitleAndSlug/prompt.d.ts +0 -1
- package/dist/llm/functions/generateIssueTitleAndSlug/prompt.js +0 -23
- package/dist/llm/functions/generateIssueTitleAndSlug/prompt.js.map +0 -1
- package/dist/llm/functions/translate/index.d.ts +0 -1
- package/dist/llm/functions/translate/index.js +0 -59
- package/dist/llm/functions/translate/index.js.map +0 -1
- package/dist/llm/functions/triageNewEvidence/eval.test.d.ts +0 -1
- package/dist/llm/functions/triageNewEvidence/eval.test.js +0 -139
- package/dist/llm/functions/triageNewEvidence/eval.test.js.map +0 -1
- package/dist/llm/functions/triageNewEvidence/index.d.ts +0 -37
- package/dist/llm/functions/triageNewEvidence/index.js +0 -121
- package/dist/llm/functions/triageNewEvidence/index.js.map +0 -1
- package/dist/llm/functions/triageNewEvidence/prompt.d.ts +0 -1
- package/dist/llm/functions/triageNewEvidence/prompt.js +0 -60
- package/dist/llm/functions/triageNewEvidence/prompt.js.map +0 -1
- package/dist/llm/functions/triageNewEvidence/tools/FindIssuesTool.d.ts +0 -19
- package/dist/llm/functions/triageNewEvidence/tools/FindIssuesTool.js +0 -65
- package/dist/llm/functions/triageNewEvidence/tools/FindIssuesTool.js.map +0 -1
- package/dist/llm/functions/triageNewEvidence/tools/GetIssueTool.d.ts +0 -19
- package/dist/llm/functions/triageNewEvidence/tools/GetIssueTool.js +0 -37
- package/dist/llm/functions/triageNewEvidence/tools/GetIssueTool.js.map +0 -1
- package/dist/repo/MRTDownRepository.d.ts +0 -23
- package/dist/repo/MRTDownRepository.js +0 -28
- package/dist/repo/MRTDownRepository.js.map +0 -1
- package/dist/repo/common/FileStore.d.ts +0 -12
- package/dist/repo/common/FileStore.js +0 -27
- package/dist/repo/common/FileStore.js.map +0 -1
- package/dist/repo/common/StandardRepository.d.ts +0 -32
- package/dist/repo/common/StandardRepository.js +0 -58
- package/dist/repo/common/StandardRepository.js.map +0 -1
- package/dist/repo/common/store.d.ts +0 -29
- package/dist/repo/common/store.js +0 -2
- package/dist/repo/common/store.js.map +0 -1
- package/dist/repo/issue/IssueRepository.d.ts +0 -36
- package/dist/repo/issue/IssueRepository.js +0 -177
- package/dist/repo/issue/IssueRepository.js.map +0 -1
- package/dist/repo/issue/helpers/deriveCurrentState.d.ts +0 -51
- package/dist/repo/issue/helpers/deriveCurrentState.js +0 -113
- package/dist/repo/issue/helpers/deriveCurrentState.js.map +0 -1
- package/dist/repo/issue/helpers/deriveCurrentState.test.d.ts +0 -1
- package/dist/repo/issue/helpers/deriveCurrentState.test.js +0 -477
- package/dist/repo/issue/helpers/deriveCurrentState.test.js.map +0 -1
- package/dist/repo/landmark/LandmarkRepository.d.ts +0 -7
- package/dist/repo/landmark/LandmarkRepository.js +0 -12
- package/dist/repo/landmark/LandmarkRepository.js.map +0 -1
- package/dist/repo/line/LineRepository.d.ts +0 -13
- package/dist/repo/line/LineRepository.js +0 -32
- package/dist/repo/line/LineRepository.js.map +0 -1
- package/dist/repo/operator/OperatorRepository.d.ts +0 -7
- package/dist/repo/operator/OperatorRepository.js +0 -12
- package/dist/repo/operator/OperatorRepository.js.map +0 -1
- package/dist/repo/service/ServiceRepository.d.ts +0 -19
- package/dist/repo/service/ServiceRepository.js +0 -39
- package/dist/repo/service/ServiceRepository.js.map +0 -1
- package/dist/repo/station/StationRepository.d.ts +0 -13
- package/dist/repo/station/StationRepository.js +0 -30
- package/dist/repo/station/StationRepository.js.map +0 -1
- package/dist/repo/town/TownRepository.d.ts +0 -7
- package/dist/repo/town/TownRepository.js +0 -12
- package/dist/repo/town/TownRepository.js.map +0 -1
- package/dist/scripts/ingestViaWebhook.d.ts +0 -1
- package/dist/scripts/ingestViaWebhook.js +0 -9
- package/dist/scripts/ingestViaWebhook.js.map +0 -1
- package/dist/util/assert.d.ts +0 -1
- package/dist/util/assert.js +0 -6
- package/dist/util/assert.js.map +0 -1
- package/dist/util/ingestContent/helpers/getSlugDateTimeFromClaims.d.ts +0 -7
- package/dist/util/ingestContent/helpers/getSlugDateTimeFromClaims.js +0 -24
- package/dist/util/ingestContent/helpers/getSlugDateTimeFromClaims.js.map +0 -1
- package/dist/util/ingestContent/index.d.ts +0 -12
- package/dist/util/ingestContent/index.js +0 -171
- package/dist/util/ingestContent/index.js.map +0 -1
- package/dist/util/ingestContent/types.d.ts +0 -32
- package/dist/util/ingestContent/types.js +0 -2
- package/dist/util/ingestContent/types.js.map +0 -1
- package/dist/validators/buildContext.d.ts +0 -7
- package/dist/validators/buildContext.js +0 -164
- package/dist/validators/buildContext.js.map +0 -1
- package/dist/validators/index.d.ts +0 -17
- package/dist/validators/index.js +0 -58
- package/dist/validators/index.js.map +0 -1
- package/dist/validators/issue.d.ts +0 -13
- package/dist/validators/issue.js +0 -220
- package/dist/validators/issue.js.map +0 -1
- package/dist/validators/landmark.d.ts +0 -7
- package/dist/validators/landmark.js +0 -43
- package/dist/validators/landmark.js.map +0 -1
- package/dist/validators/line.d.ts +0 -8
- package/dist/validators/line.js +0 -87
- package/dist/validators/line.js.map +0 -1
- package/dist/validators/operator.d.ts +0 -7
- package/dist/validators/operator.js +0 -43
- package/dist/validators/operator.js.map +0 -1
- package/dist/validators/service.d.ts +0 -8
- package/dist/validators/service.js +0 -87
- package/dist/validators/service.js.map +0 -1
- package/dist/validators/station.d.ts +0 -8
- package/dist/validators/station.js +0 -93
- package/dist/validators/station.js.map +0 -1
- package/dist/validators/town.d.ts +0 -7
- package/dist/validators/town.js +0 -43
- package/dist/validators/town.js.map +0 -1
- package/dist/validators/types.d.ts +0 -19
- package/dist/validators/types.js +0 -2
- package/dist/validators/types.js.map +0 -1
- package/dist/validators/utils.d.ts +0 -2
- package/dist/validators/utils.js +0 -9
- package/dist/validators/utils.js.map +0 -1
- package/dist/write/MRTDownWriter.d.ts +0 -27
- package/dist/write/MRTDownWriter.js +0 -27
- package/dist/write/MRTDownWriter.js.map +0 -1
- package/dist/write/common/FileWriteStore.d.ts +0 -13
- package/dist/write/common/FileWriteStore.js +0 -31
- package/dist/write/common/FileWriteStore.js.map +0 -1
- package/dist/write/common/StandardWriter.d.ts +0 -14
- package/dist/write/common/StandardWriter.js +0 -17
- package/dist/write/common/StandardWriter.js.map +0 -1
- package/dist/write/common/store.d.ts +0 -32
- package/dist/write/common/store.js +0 -2
- package/dist/write/common/store.js.map +0 -1
- package/dist/write/id/IdGenerator.d.ts +0 -18
- package/dist/write/id/IdGenerator.js +0 -23
- package/dist/write/id/IdGenerator.js.map +0 -1
- package/dist/write/issue/IssueWriter.d.ts +0 -12
- package/dist/write/issue/IssueWriter.js +0 -33
- package/dist/write/issue/IssueWriter.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"computeImpactFromEvidenceClaims.js","sourceRoot":"/","sources":["helpers/computeImpactFromEvidenceClaims.ts"],"names":[],"mappings":"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","sourcesContent":["import { deepStrictEqual } from 'node:assert';\nimport { DateTime } from 'luxon';\nimport {\n deriveCurrentState,\n type IssueBundleState,\n} from '../repo/issue/helpers/deriveCurrentState.js';\nimport type { IssueBundle } from '../schema/issue/bundle.js';\nimport type {\n Claim,\n ClaimStatusSignal,\n ClaimTimeHints,\n} from '../schema/issue/claim.js';\nimport type { ImpactEvent } from '../schema/issue/impactEvent.js';\nimport type { Period } from '../schema/issue/period.js';\nimport { assert } from '../util/assert.js';\nimport { IdGenerator } from '../write/id/IdGenerator.js';\nimport { keyForAffectedEntity } from './keyForAffectedEntity.js';\n\ntype Params = {\n issueBundle: IssueBundle;\n evidenceId: string;\n evidenceTs: string;\n claims: Claim[];\n};\n\ntype Result = {\n newState: IssueBundleState;\n newImpactEvents: ImpactEvent[];\n};\n\n/**\n * Compute the impact from the evidence claims.\n * @param params - The parameters.\n * @returns The result.\n */\nexport function computeImpactFromEvidenceClaims(params: Params): Result {\n const result: Result = {\n newState: {\n services: {},\n servicesProvenance: {},\n facilities: {},\n facilitiesProvenance: {},\n impactEventIds: [],\n },\n newImpactEvents: [],\n };\n\n const eventTs = params.evidenceTs;\n const eventDateTime = DateTime.fromISO(eventTs);\n assert(eventDateTime.isValid, `Invalid date: ${eventTs}`);\n\n const currentState = deriveCurrentState(params.issueBundle);\n\n const claimsKeyedByAffectedEntity: Record<string, Claim> = Object.fromEntries(\n params.claims.map((claim) => [keyForAffectedEntity(claim.entity), claim]),\n );\n\n for (const [key, claim] of Object.entries(claimsKeyedByAffectedEntity)) {\n switch (claim.entity.type) {\n case 'service': {\n const currentServiceState = currentState.services[key] ?? {\n effect: null,\n scopes: [],\n periods: [],\n causes: [],\n };\n const currentServiceProvenance =\n currentState.servicesProvenance[key] ?? {};\n\n if (\n claim.effect?.service != null &&\n !isEqual(currentServiceState.effect, claim.effect.service)\n ) {\n currentServiceState.effect = claim.effect.service;\n currentServiceProvenance.effect = {\n evidenceId: params.evidenceId,\n };\n result.newImpactEvents.push({\n id: IdGenerator.impactEventId(eventDateTime),\n type: 'service_effects.set',\n ts: eventTs,\n basis: { evidenceId: params.evidenceId },\n entity: claim.entity,\n effect: claim.effect.service,\n });\n }\n\n switch (params.issueBundle.issue.type) {\n case 'disruption': {\n const isCleared = currentServiceState.periods.every(\n (period) => period.kind === 'fixed' && period.endAt != null,\n );\n\n let currentStatus: ClaimStatusSignal = 'open';\n\n if (isCleared) {\n currentStatus = 'cleared';\n }\n\n if (currentStatus !== claim.statusSignal) {\n switch (claim.statusSignal) {\n case 'open': {\n break;\n }\n case 'cleared': {\n break;\n }\n }\n }\n break;\n }\n }\n\n if (claim.timeHints != null) {\n const { newPeriods, hasChanged } = reconcilePeriodsWithTimeHints(\n currentServiceState.periods,\n claim.timeHints,\n );\n if (hasChanged) {\n currentServiceState.periods = newPeriods;\n currentServiceProvenance.periods = {\n evidenceId: params.evidenceId,\n };\n result.newImpactEvents.push({\n id: IdGenerator.impactEventId(eventDateTime),\n type: 'periods.set',\n ts: eventTs,\n basis: { evidenceId: params.evidenceId },\n entity: claim.entity,\n periods: currentServiceState.periods,\n });\n }\n }\n\n if (\n claim.scopes?.service != null &&\n !isEqual(currentServiceState.scopes, claim.scopes.service)\n ) {\n currentServiceState.scopes = claim.scopes.service;\n currentServiceProvenance.scopes = {\n evidenceId: params.evidenceId,\n };\n result.newImpactEvents.push({\n id: IdGenerator.impactEventId(eventDateTime),\n type: 'service_scopes.set',\n ts: eventTs,\n basis: { evidenceId: params.evidenceId },\n entity: claim.entity,\n serviceScopes: claim.scopes.service,\n });\n }\n\n if (\n claim.causes != null &&\n !isEqual(currentServiceState.causes, claim.causes)\n ) {\n currentServiceState.causes = claim.causes;\n currentServiceProvenance.causes = {\n evidenceId: params.evidenceId,\n };\n result.newImpactEvents.push({\n id: IdGenerator.impactEventId(eventDateTime),\n type: 'causes.set',\n ts: eventTs,\n basis: { evidenceId: params.evidenceId },\n entity: claim.entity,\n causes: claim.causes,\n });\n }\n\n result.newState.services[key] = currentServiceState;\n result.newState.servicesProvenance[key] = currentServiceProvenance;\n\n break;\n }\n case 'facility': {\n const currentFacilityState = currentState.facilities[key] ?? {\n effect: null,\n periods: [],\n };\n const currentFacilityProvenance =\n currentState.facilitiesProvenance[key] ?? {};\n\n if (\n claim.effect?.facility != null &&\n !isEqual(currentFacilityState.effect, claim.effect.facility)\n ) {\n currentFacilityState.effect = claim.effect.facility;\n currentFacilityProvenance.effect = {\n evidenceId: params.evidenceId,\n };\n result.newImpactEvents.push({\n id: IdGenerator.impactEventId(eventDateTime),\n type: 'facility_effects.set',\n ts: eventTs,\n basis: { evidenceId: params.evidenceId },\n entity: claim.entity,\n effect: claim.effect.facility,\n });\n }\n\n if (claim.timeHints != null) {\n const { newPeriods, hasChanged } = reconcilePeriodsWithTimeHints(\n currentFacilityState.periods,\n claim.timeHints,\n );\n if (hasChanged) {\n currentFacilityState.periods = newPeriods;\n currentFacilityProvenance.periods = {\n evidenceId: params.evidenceId,\n };\n result.newImpactEvents.push({\n id: IdGenerator.impactEventId(eventDateTime),\n type: 'periods.set',\n ts: eventTs,\n basis: { evidenceId: params.evidenceId },\n entity: claim.entity,\n periods: currentFacilityState.periods,\n });\n }\n }\n\n if (\n claim.causes != null &&\n !isEqual(currentFacilityState.causes, claim.causes)\n ) {\n currentFacilityState.causes = claim.causes;\n currentFacilityProvenance.causes = {\n evidenceId: params.evidenceId,\n };\n result.newImpactEvents.push({\n id: IdGenerator.impactEventId(eventDateTime),\n type: 'causes.set',\n ts: eventTs,\n basis: { evidenceId: params.evidenceId },\n entity: claim.entity,\n causes: claim.causes,\n });\n }\n\n result.newState.facilities[key] = currentFacilityState;\n result.newState.facilitiesProvenance[key] = currentFacilityProvenance;\n\n break;\n }\n }\n }\n\n return result;\n}\n\ntype ReconcilePeriodsWithTimeHintsResults = {\n newPeriods: Period[];\n hasChanged: boolean;\n};\n\n/**\n * Reconcile the periods with the time hints.\n * @param currentPeriods - The current periods.\n * @param timeHints - The time hints.\n * @returns The new periods and whether the periods have changed.\n */\nfunction reconcilePeriodsWithTimeHints(\n currentPeriods: Period[],\n timeHints: ClaimTimeHints,\n): ReconcilePeriodsWithTimeHintsResults {\n switch (timeHints.kind) {\n case 'fixed': {\n return {\n newPeriods: [timeHints],\n hasChanged: true,\n };\n }\n case 'recurring': {\n return {\n newPeriods: [timeHints],\n hasChanged: true,\n };\n }\n case 'start-only': {\n let hasChanged = false;\n const newPeriods: Period[] = [];\n if (currentPeriods.length === 0) {\n newPeriods.push({\n kind: 'fixed',\n startAt: timeHints.startAt,\n endAt: null,\n });\n hasChanged = true;\n return { newPeriods, hasChanged };\n }\n for (const period of currentPeriods) {\n switch (period.kind) {\n case 'fixed': {\n newPeriods.push({\n ...period,\n startAt: timeHints.startAt,\n });\n hasChanged = true;\n break;\n }\n case 'recurring': {\n const newPeriod: Period = {\n ...period,\n startAt: timeHints.startAt,\n };\n if (newPeriod.timeWindow != null) {\n const startAt = DateTime.fromISO(timeHints.startAt);\n assert(startAt.isValid);\n newPeriod.timeWindow.startAt = startAt.toFormat('HH:mm:ss');\n }\n newPeriods.push(newPeriod);\n hasChanged = true;\n break;\n }\n }\n }\n return {\n newPeriods,\n hasChanged,\n };\n }\n case 'end-only': {\n let hasChanged = false;\n const newPeriods: Period[] = [];\n for (const period of currentPeriods) {\n switch (period.kind) {\n case 'fixed': {\n newPeriods.push({\n ...period,\n endAt: timeHints.endAt,\n });\n hasChanged = true;\n break;\n }\n case 'recurring': {\n const newPeriod: Period = {\n ...period,\n endAt: timeHints.endAt,\n };\n if (newPeriod.timeWindow != null) {\n const endAt = DateTime.fromISO(timeHints.endAt);\n assert(endAt.isValid);\n newPeriod.timeWindow.endAt = endAt.toFormat('HH:mm:ss');\n }\n newPeriods.push(newPeriod);\n hasChanged = true;\n break;\n }\n }\n }\n return {\n newPeriods,\n hasChanged,\n };\n }\n }\n}\n\nfunction isEqual(a: unknown, b: unknown): boolean {\n try {\n deepStrictEqual(a, b);\n return true;\n } catch (error) {\n return false;\n }\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,544 +0,0 @@
|
|
|
1
|
-
import { beforeEach, describe, expect, test, vi } from 'vitest';
|
|
2
|
-
import { IdGenerator } from '../write/id/IdGenerator.js';
|
|
3
|
-
import { computeImpactFromEvidenceClaims } from './computeImpactFromEvidenceClaims.js';
|
|
4
|
-
import { keyForAffectedEntity } from './keyForAffectedEntity.js';
|
|
5
|
-
vi.mock('../write/id/IdGenerator.js', () => ({
|
|
6
|
-
IdGenerator: {
|
|
7
|
-
impactEventId: vi.fn(),
|
|
8
|
-
evidenceId: vi.fn(),
|
|
9
|
-
},
|
|
10
|
-
}));
|
|
11
|
-
function createMockBundle(impactEvents) {
|
|
12
|
-
return {
|
|
13
|
-
issue: {
|
|
14
|
-
id: '2025-01-01-test-issue',
|
|
15
|
-
type: 'disruption',
|
|
16
|
-
title: {
|
|
17
|
-
'en-SG': 'Test Issue',
|
|
18
|
-
'zh-Hans': null,
|
|
19
|
-
ms: null,
|
|
20
|
-
ta: null,
|
|
21
|
-
},
|
|
22
|
-
titleMeta: {
|
|
23
|
-
source: 'test',
|
|
24
|
-
},
|
|
25
|
-
},
|
|
26
|
-
evidence: [],
|
|
27
|
-
impactEvents,
|
|
28
|
-
path: 'test/path',
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
function createServiceClaim(overrides = {}) {
|
|
32
|
-
return {
|
|
33
|
-
entity: { type: 'service', serviceId: 'NSL' },
|
|
34
|
-
effect: null,
|
|
35
|
-
scopes: { service: null },
|
|
36
|
-
statusSignal: null,
|
|
37
|
-
timeHints: null,
|
|
38
|
-
causes: null,
|
|
39
|
-
...overrides,
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
function createFacilityClaim(overrides = {}) {
|
|
43
|
-
return {
|
|
44
|
-
entity: { type: 'facility', stationId: 'NS1', kind: 'lift' },
|
|
45
|
-
effect: null,
|
|
46
|
-
scopes: { service: null },
|
|
47
|
-
statusSignal: null,
|
|
48
|
-
timeHints: null,
|
|
49
|
-
causes: null,
|
|
50
|
-
...overrides,
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
describe('computeImpactFromEvidenceClaims', () => {
|
|
54
|
-
beforeEach(() => {
|
|
55
|
-
let idCounter = 0;
|
|
56
|
-
vi.mocked(IdGenerator.impactEventId).mockImplementation(() => {
|
|
57
|
-
idCounter += 1;
|
|
58
|
-
return `ie_test_${String(idCounter).padStart(3, '0')}`;
|
|
59
|
-
});
|
|
60
|
-
});
|
|
61
|
-
test('returns empty result when no claims are provided', () => {
|
|
62
|
-
const result = computeImpactFromEvidenceClaims({
|
|
63
|
-
issueBundle: createMockBundle([]),
|
|
64
|
-
evidenceId: '2025-01-01T10:00:00+08:00',
|
|
65
|
-
evidenceTs: '2025-01-01T10:00:00+08:00',
|
|
66
|
-
claims: [],
|
|
67
|
-
});
|
|
68
|
-
expect(result).toEqual({
|
|
69
|
-
newState: {
|
|
70
|
-
services: {},
|
|
71
|
-
servicesProvenance: {},
|
|
72
|
-
facilities: {},
|
|
73
|
-
facilitiesProvenance: {},
|
|
74
|
-
impactEventIds: [],
|
|
75
|
-
},
|
|
76
|
-
newImpactEvents: [],
|
|
77
|
-
});
|
|
78
|
-
});
|
|
79
|
-
test('creates service effect and periods events for fixed time hints', () => {
|
|
80
|
-
const claim = createServiceClaim({
|
|
81
|
-
effect: {
|
|
82
|
-
service: { kind: 'delay', duration: null },
|
|
83
|
-
facility: null,
|
|
84
|
-
},
|
|
85
|
-
statusSignal: 'open',
|
|
86
|
-
timeHints: {
|
|
87
|
-
kind: 'fixed',
|
|
88
|
-
startAt: '2025-01-01T10:00:00+08:00',
|
|
89
|
-
endAt: '2025-01-01T12:00:00+08:00',
|
|
90
|
-
},
|
|
91
|
-
});
|
|
92
|
-
const evidenceId = '2025-01-01T10:05:00+08:00';
|
|
93
|
-
const result = computeImpactFromEvidenceClaims({
|
|
94
|
-
issueBundle: createMockBundle([]),
|
|
95
|
-
evidenceId,
|
|
96
|
-
evidenceTs: evidenceId,
|
|
97
|
-
claims: [claim],
|
|
98
|
-
});
|
|
99
|
-
const serviceKey = keyForAffectedEntity(claim.entity);
|
|
100
|
-
expect(result.newState.services[serviceKey]).toEqual({
|
|
101
|
-
effect: { kind: 'delay', duration: null },
|
|
102
|
-
scopes: [],
|
|
103
|
-
periods: [
|
|
104
|
-
{
|
|
105
|
-
kind: 'fixed',
|
|
106
|
-
startAt: '2025-01-01T10:00:00+08:00',
|
|
107
|
-
endAt: '2025-01-01T12:00:00+08:00',
|
|
108
|
-
},
|
|
109
|
-
],
|
|
110
|
-
causes: [],
|
|
111
|
-
});
|
|
112
|
-
expect(result.newState.servicesProvenance[serviceKey]).toEqual({
|
|
113
|
-
effect: { evidenceId },
|
|
114
|
-
periods: { evidenceId },
|
|
115
|
-
});
|
|
116
|
-
expect(result.newImpactEvents).toEqual([
|
|
117
|
-
{
|
|
118
|
-
id: 'ie_test_001',
|
|
119
|
-
type: 'service_effects.set',
|
|
120
|
-
ts: evidenceId,
|
|
121
|
-
basis: { evidenceId },
|
|
122
|
-
entity: claim.entity,
|
|
123
|
-
effect: { kind: 'delay', duration: null },
|
|
124
|
-
},
|
|
125
|
-
{
|
|
126
|
-
id: 'ie_test_002',
|
|
127
|
-
type: 'periods.set',
|
|
128
|
-
ts: evidenceId,
|
|
129
|
-
basis: { evidenceId },
|
|
130
|
-
entity: claim.entity,
|
|
131
|
-
periods: [
|
|
132
|
-
{
|
|
133
|
-
kind: 'fixed',
|
|
134
|
-
startAt: '2025-01-01T10:00:00+08:00',
|
|
135
|
-
endAt: '2025-01-01T12:00:00+08:00',
|
|
136
|
-
},
|
|
137
|
-
],
|
|
138
|
-
},
|
|
139
|
-
]);
|
|
140
|
-
});
|
|
141
|
-
test('deduplicates claims by affected entity and keeps the last claim', () => {
|
|
142
|
-
const firstClaim = createServiceClaim({
|
|
143
|
-
effect: {
|
|
144
|
-
service: { kind: 'delay', duration: null },
|
|
145
|
-
facility: null,
|
|
146
|
-
},
|
|
147
|
-
});
|
|
148
|
-
const secondClaim = createServiceClaim({
|
|
149
|
-
effect: {
|
|
150
|
-
service: { kind: 'no-service' },
|
|
151
|
-
facility: null,
|
|
152
|
-
},
|
|
153
|
-
});
|
|
154
|
-
const result = computeImpactFromEvidenceClaims({
|
|
155
|
-
issueBundle: createMockBundle([]),
|
|
156
|
-
evidenceId: '2025-01-01T11:00:00+08:00',
|
|
157
|
-
evidenceTs: '2025-01-01T11:00:00+08:00',
|
|
158
|
-
claims: [firstClaim, secondClaim],
|
|
159
|
-
});
|
|
160
|
-
expect(result.newImpactEvents).toHaveLength(1);
|
|
161
|
-
expect(result.newImpactEvents[0]).toMatchObject({
|
|
162
|
-
id: 'ie_test_001',
|
|
163
|
-
type: 'service_effects.set',
|
|
164
|
-
effect: { kind: 'no-service' },
|
|
165
|
-
});
|
|
166
|
-
});
|
|
167
|
-
test('creates service scopes state, provenance, and event', () => {
|
|
168
|
-
const claim = createServiceClaim({
|
|
169
|
-
scopes: {
|
|
170
|
-
service: [
|
|
171
|
-
{ type: 'service.whole' },
|
|
172
|
-
{
|
|
173
|
-
type: 'service.segment',
|
|
174
|
-
fromStationId: 'NS1',
|
|
175
|
-
toStationId: 'NS3',
|
|
176
|
-
},
|
|
177
|
-
],
|
|
178
|
-
},
|
|
179
|
-
});
|
|
180
|
-
const evidenceId = '2025-01-02T09:00:00+08:00';
|
|
181
|
-
const result = computeImpactFromEvidenceClaims({
|
|
182
|
-
issueBundle: createMockBundle([]),
|
|
183
|
-
evidenceId,
|
|
184
|
-
evidenceTs: evidenceId,
|
|
185
|
-
claims: [claim],
|
|
186
|
-
});
|
|
187
|
-
const serviceKey = keyForAffectedEntity(claim.entity);
|
|
188
|
-
expect(result.newState.services[serviceKey]).toEqual({
|
|
189
|
-
effect: null,
|
|
190
|
-
scopes: [
|
|
191
|
-
{ type: 'service.whole' },
|
|
192
|
-
{
|
|
193
|
-
type: 'service.segment',
|
|
194
|
-
fromStationId: 'NS1',
|
|
195
|
-
toStationId: 'NS3',
|
|
196
|
-
},
|
|
197
|
-
],
|
|
198
|
-
periods: [],
|
|
199
|
-
causes: [],
|
|
200
|
-
});
|
|
201
|
-
expect(result.newState.servicesProvenance[serviceKey]).toEqual({
|
|
202
|
-
scopes: { evidenceId },
|
|
203
|
-
});
|
|
204
|
-
expect(result.newImpactEvents).toEqual([
|
|
205
|
-
{
|
|
206
|
-
id: 'ie_test_001',
|
|
207
|
-
type: 'service_scopes.set',
|
|
208
|
-
ts: evidenceId,
|
|
209
|
-
basis: { evidenceId },
|
|
210
|
-
entity: claim.entity,
|
|
211
|
-
serviceScopes: [
|
|
212
|
-
{ type: 'service.whole' },
|
|
213
|
-
{
|
|
214
|
-
type: 'service.segment',
|
|
215
|
-
fromStationId: 'NS1',
|
|
216
|
-
toStationId: 'NS3',
|
|
217
|
-
},
|
|
218
|
-
],
|
|
219
|
-
},
|
|
220
|
-
]);
|
|
221
|
-
});
|
|
222
|
-
test('emits effects, periods, then scopes when all are present', () => {
|
|
223
|
-
const claim = createServiceClaim({
|
|
224
|
-
effect: {
|
|
225
|
-
service: { kind: 'reduced-service' },
|
|
226
|
-
facility: null,
|
|
227
|
-
},
|
|
228
|
-
timeHints: {
|
|
229
|
-
kind: 'fixed',
|
|
230
|
-
startAt: '2025-01-10T20:00:00+08:00',
|
|
231
|
-
endAt: '2025-01-10T22:00:00+08:00',
|
|
232
|
-
},
|
|
233
|
-
scopes: {
|
|
234
|
-
service: [{ type: 'service.point', stationId: 'NS5' }],
|
|
235
|
-
},
|
|
236
|
-
});
|
|
237
|
-
const evidenceId = '2025-01-10T20:05:00+08:00';
|
|
238
|
-
const result = computeImpactFromEvidenceClaims({
|
|
239
|
-
issueBundle: createMockBundle([]),
|
|
240
|
-
evidenceId,
|
|
241
|
-
evidenceTs: evidenceId,
|
|
242
|
-
claims: [claim],
|
|
243
|
-
});
|
|
244
|
-
expect(result.newImpactEvents.map((event) => event.type)).toEqual([
|
|
245
|
-
'service_effects.set',
|
|
246
|
-
'periods.set',
|
|
247
|
-
'service_scopes.set',
|
|
248
|
-
]);
|
|
249
|
-
});
|
|
250
|
-
test('emits causes events for service and facility claims', () => {
|
|
251
|
-
const serviceClaim = createServiceClaim({
|
|
252
|
-
causes: ['signal.fault', 'delay'],
|
|
253
|
-
});
|
|
254
|
-
const facilityClaim = createFacilityClaim({
|
|
255
|
-
causes: ['elevator.outage'],
|
|
256
|
-
});
|
|
257
|
-
const evidenceId = '2025-01-10T23:00:00+08:00';
|
|
258
|
-
const result = computeImpactFromEvidenceClaims({
|
|
259
|
-
issueBundle: createMockBundle([]),
|
|
260
|
-
evidenceId,
|
|
261
|
-
evidenceTs: evidenceId,
|
|
262
|
-
claims: [serviceClaim, facilityClaim],
|
|
263
|
-
});
|
|
264
|
-
const serviceKey = keyForAffectedEntity(serviceClaim.entity);
|
|
265
|
-
const facilityKey = keyForAffectedEntity(facilityClaim.entity);
|
|
266
|
-
expect(result.newState.services[serviceKey].causes).toEqual([
|
|
267
|
-
'signal.fault',
|
|
268
|
-
'delay',
|
|
269
|
-
]);
|
|
270
|
-
expect(result.newState.servicesProvenance[serviceKey]).toEqual({
|
|
271
|
-
causes: { evidenceId },
|
|
272
|
-
});
|
|
273
|
-
expect(result.newState.facilities[facilityKey].causes).toEqual([
|
|
274
|
-
'elevator.outage',
|
|
275
|
-
]);
|
|
276
|
-
expect(result.newState.facilitiesProvenance[facilityKey]).toEqual({
|
|
277
|
-
causes: { evidenceId },
|
|
278
|
-
});
|
|
279
|
-
expect(result.newImpactEvents.map((event) => event.type)).toEqual([
|
|
280
|
-
'causes.set',
|
|
281
|
-
'causes.set',
|
|
282
|
-
]);
|
|
283
|
-
});
|
|
284
|
-
test('does not emit events when effect, scopes, and causes are unchanged', () => {
|
|
285
|
-
const serviceEntity = { type: 'service', serviceId: 'NSL' };
|
|
286
|
-
const issueBundle = createMockBundle([
|
|
287
|
-
{
|
|
288
|
-
id: 'ie_seed_effect',
|
|
289
|
-
type: 'service_effects.set',
|
|
290
|
-
entity: serviceEntity,
|
|
291
|
-
ts: '2025-01-01T09:00:00+08:00',
|
|
292
|
-
basis: { evidenceId: 'seed_effect' },
|
|
293
|
-
effect: { kind: 'delay', duration: null },
|
|
294
|
-
},
|
|
295
|
-
{
|
|
296
|
-
id: 'ie_seed_scopes',
|
|
297
|
-
type: 'service_scopes.set',
|
|
298
|
-
entity: serviceEntity,
|
|
299
|
-
ts: '2025-01-01T09:01:00+08:00',
|
|
300
|
-
basis: { evidenceId: 'seed_scopes' },
|
|
301
|
-
serviceScopes: [{ type: 'service.point', stationId: 'NS4' }],
|
|
302
|
-
},
|
|
303
|
-
{
|
|
304
|
-
id: 'ie_seed_causes',
|
|
305
|
-
type: 'causes.set',
|
|
306
|
-
entity: serviceEntity,
|
|
307
|
-
ts: '2025-01-01T09:02:00+08:00',
|
|
308
|
-
basis: { evidenceId: 'seed_causes' },
|
|
309
|
-
causes: ['signal.fault'],
|
|
310
|
-
},
|
|
311
|
-
]);
|
|
312
|
-
const claim = createServiceClaim({
|
|
313
|
-
entity: serviceEntity,
|
|
314
|
-
effect: {
|
|
315
|
-
service: { kind: 'delay', duration: null },
|
|
316
|
-
facility: null,
|
|
317
|
-
},
|
|
318
|
-
scopes: {
|
|
319
|
-
service: [{ type: 'service.point', stationId: 'NS4' }],
|
|
320
|
-
},
|
|
321
|
-
causes: ['signal.fault'],
|
|
322
|
-
});
|
|
323
|
-
const evidenceId = '2025-01-01T10:00:00+08:00';
|
|
324
|
-
const result = computeImpactFromEvidenceClaims({
|
|
325
|
-
issueBundle,
|
|
326
|
-
evidenceId,
|
|
327
|
-
evidenceTs: evidenceId,
|
|
328
|
-
claims: [claim],
|
|
329
|
-
});
|
|
330
|
-
const serviceKey = keyForAffectedEntity(serviceEntity);
|
|
331
|
-
expect(result.newState.servicesProvenance[serviceKey]).toEqual({
|
|
332
|
-
effect: { evidenceId: 'seed_effect' },
|
|
333
|
-
scopes: { evidenceId: 'seed_scopes' },
|
|
334
|
-
causes: { evidenceId: 'seed_causes' },
|
|
335
|
-
});
|
|
336
|
-
expect(result.newImpactEvents).toEqual([]);
|
|
337
|
-
});
|
|
338
|
-
test('deduplicates scope claims and keeps scopes from last claim', () => {
|
|
339
|
-
const firstClaim = createServiceClaim({
|
|
340
|
-
scopes: {
|
|
341
|
-
service: [{ type: 'service.whole' }],
|
|
342
|
-
},
|
|
343
|
-
});
|
|
344
|
-
const secondClaim = createServiceClaim({
|
|
345
|
-
scopes: {
|
|
346
|
-
service: [{ type: 'service.point', stationId: 'NS9' }],
|
|
347
|
-
},
|
|
348
|
-
});
|
|
349
|
-
const evidenceId = '2025-01-11T08:00:00+08:00';
|
|
350
|
-
const result = computeImpactFromEvidenceClaims({
|
|
351
|
-
issueBundle: createMockBundle([]),
|
|
352
|
-
evidenceId,
|
|
353
|
-
evidenceTs: evidenceId,
|
|
354
|
-
claims: [firstClaim, secondClaim],
|
|
355
|
-
});
|
|
356
|
-
const serviceKey = keyForAffectedEntity(secondClaim.entity);
|
|
357
|
-
expect(result.newState.services[serviceKey].scopes).toEqual([
|
|
358
|
-
{ type: 'service.point', stationId: 'NS9' },
|
|
359
|
-
]);
|
|
360
|
-
expect(result.newState.servicesProvenance[serviceKey]).toEqual({
|
|
361
|
-
scopes: { evidenceId },
|
|
362
|
-
});
|
|
363
|
-
expect(result.newImpactEvents).toEqual([
|
|
364
|
-
{
|
|
365
|
-
id: 'ie_test_001',
|
|
366
|
-
type: 'service_scopes.set',
|
|
367
|
-
ts: evidenceId,
|
|
368
|
-
basis: { evidenceId },
|
|
369
|
-
entity: secondClaim.entity,
|
|
370
|
-
serviceScopes: [{ type: 'service.point', stationId: 'NS9' }],
|
|
371
|
-
},
|
|
372
|
-
]);
|
|
373
|
-
});
|
|
374
|
-
test('applies start-only hints to recurring periods and updates window start', () => {
|
|
375
|
-
const serviceEntity = { type: 'service', serviceId: 'NSL' };
|
|
376
|
-
const issueBundle = createMockBundle([
|
|
377
|
-
{
|
|
378
|
-
id: 'ie_seed_01',
|
|
379
|
-
type: 'periods.set',
|
|
380
|
-
entity: serviceEntity,
|
|
381
|
-
ts: '2025-01-01T08:00:00+08:00',
|
|
382
|
-
basis: { evidenceId: 'seed' },
|
|
383
|
-
periods: [
|
|
384
|
-
{
|
|
385
|
-
kind: 'recurring',
|
|
386
|
-
frequency: 'daily',
|
|
387
|
-
startAt: '2025-01-01T06:00:00+08:00',
|
|
388
|
-
endAt: '2025-01-07T06:00:00+08:00',
|
|
389
|
-
daysOfWeek: null,
|
|
390
|
-
timeWindow: {
|
|
391
|
-
startAt: '06:00:00',
|
|
392
|
-
endAt: '08:00:00',
|
|
393
|
-
},
|
|
394
|
-
timeZone: 'Asia/Singapore',
|
|
395
|
-
excludedDates: null,
|
|
396
|
-
},
|
|
397
|
-
],
|
|
398
|
-
},
|
|
399
|
-
]);
|
|
400
|
-
const claim = createServiceClaim({
|
|
401
|
-
entity: serviceEntity,
|
|
402
|
-
timeHints: {
|
|
403
|
-
kind: 'start-only',
|
|
404
|
-
startAt: '2025-01-02T11:30:00+08:00',
|
|
405
|
-
},
|
|
406
|
-
});
|
|
407
|
-
const evidenceId = '2025-01-02T11:35:00+08:00';
|
|
408
|
-
const result = computeImpactFromEvidenceClaims({
|
|
409
|
-
issueBundle,
|
|
410
|
-
evidenceId,
|
|
411
|
-
evidenceTs: evidenceId,
|
|
412
|
-
claims: [claim],
|
|
413
|
-
});
|
|
414
|
-
const serviceKey = keyForAffectedEntity(serviceEntity);
|
|
415
|
-
expect(result.newState.services[serviceKey].periods).toEqual([
|
|
416
|
-
{
|
|
417
|
-
kind: 'recurring',
|
|
418
|
-
frequency: 'daily',
|
|
419
|
-
startAt: '2025-01-02T11:30:00+08:00',
|
|
420
|
-
endAt: '2025-01-07T06:00:00+08:00',
|
|
421
|
-
daysOfWeek: null,
|
|
422
|
-
timeWindow: {
|
|
423
|
-
startAt: '11:30:00',
|
|
424
|
-
endAt: '08:00:00',
|
|
425
|
-
},
|
|
426
|
-
timeZone: 'Asia/Singapore',
|
|
427
|
-
excludedDates: null,
|
|
428
|
-
},
|
|
429
|
-
]);
|
|
430
|
-
expect(result.newImpactEvents).toEqual([
|
|
431
|
-
{
|
|
432
|
-
id: 'ie_test_001',
|
|
433
|
-
type: 'periods.set',
|
|
434
|
-
ts: evidenceId,
|
|
435
|
-
basis: { evidenceId },
|
|
436
|
-
entity: serviceEntity,
|
|
437
|
-
periods: result.newState.services[serviceKey].periods,
|
|
438
|
-
},
|
|
439
|
-
]);
|
|
440
|
-
});
|
|
441
|
-
test('applies end-only hints to facility recurring periods and updates window end', () => {
|
|
442
|
-
const facilityEntity = {
|
|
443
|
-
type: 'facility',
|
|
444
|
-
stationId: 'NS1',
|
|
445
|
-
kind: 'lift',
|
|
446
|
-
};
|
|
447
|
-
const issueBundle = createMockBundle([
|
|
448
|
-
{
|
|
449
|
-
id: 'ie_seed_02',
|
|
450
|
-
type: 'periods.set',
|
|
451
|
-
entity: facilityEntity,
|
|
452
|
-
ts: '2025-01-01T08:00:00+08:00',
|
|
453
|
-
basis: { evidenceId: 'seed' },
|
|
454
|
-
periods: [
|
|
455
|
-
{
|
|
456
|
-
kind: 'recurring',
|
|
457
|
-
frequency: 'weekly',
|
|
458
|
-
startAt: '2025-01-01T06:00:00+08:00',
|
|
459
|
-
endAt: '2025-02-01T06:00:00+08:00',
|
|
460
|
-
daysOfWeek: ['MO', 'WE'],
|
|
461
|
-
timeWindow: {
|
|
462
|
-
startAt: '06:00:00',
|
|
463
|
-
endAt: '09:00:00',
|
|
464
|
-
},
|
|
465
|
-
timeZone: 'Asia/Singapore',
|
|
466
|
-
excludedDates: ['2025-01-15'],
|
|
467
|
-
},
|
|
468
|
-
],
|
|
469
|
-
},
|
|
470
|
-
]);
|
|
471
|
-
const claim = createFacilityClaim({
|
|
472
|
-
entity: facilityEntity,
|
|
473
|
-
timeHints: {
|
|
474
|
-
kind: 'end-only',
|
|
475
|
-
endAt: '2025-01-25T23:15:00+08:00',
|
|
476
|
-
},
|
|
477
|
-
});
|
|
478
|
-
const evidenceId = '2025-01-03T12:00:00+08:00';
|
|
479
|
-
const result = computeImpactFromEvidenceClaims({
|
|
480
|
-
issueBundle,
|
|
481
|
-
evidenceId,
|
|
482
|
-
evidenceTs: evidenceId,
|
|
483
|
-
claims: [claim],
|
|
484
|
-
});
|
|
485
|
-
const facilityKey = keyForAffectedEntity(facilityEntity);
|
|
486
|
-
expect(result.newState.facilities[facilityKey].periods).toEqual([
|
|
487
|
-
{
|
|
488
|
-
kind: 'recurring',
|
|
489
|
-
frequency: 'weekly',
|
|
490
|
-
startAt: '2025-01-01T06:00:00+08:00',
|
|
491
|
-
endAt: '2025-01-25T23:15:00+08:00',
|
|
492
|
-
daysOfWeek: ['MO', 'WE'],
|
|
493
|
-
timeWindow: {
|
|
494
|
-
startAt: '06:00:00',
|
|
495
|
-
endAt: '23:15:00',
|
|
496
|
-
},
|
|
497
|
-
timeZone: 'Asia/Singapore',
|
|
498
|
-
excludedDates: ['2025-01-15'],
|
|
499
|
-
},
|
|
500
|
-
]);
|
|
501
|
-
expect(result.newImpactEvents).toEqual([
|
|
502
|
-
{
|
|
503
|
-
id: 'ie_test_001',
|
|
504
|
-
type: 'periods.set',
|
|
505
|
-
ts: evidenceId,
|
|
506
|
-
basis: { evidenceId },
|
|
507
|
-
entity: facilityEntity,
|
|
508
|
-
periods: result.newState.facilities[facilityKey].periods,
|
|
509
|
-
},
|
|
510
|
-
]);
|
|
511
|
-
});
|
|
512
|
-
test('start-only with no current periods creates an open fixed period', () => {
|
|
513
|
-
const claim = createServiceClaim({
|
|
514
|
-
timeHints: {
|
|
515
|
-
kind: 'start-only',
|
|
516
|
-
startAt: '2025-01-05T01:00:00+08:00',
|
|
517
|
-
},
|
|
518
|
-
});
|
|
519
|
-
const evidenceId = '2025-01-05T01:05:00+08:00';
|
|
520
|
-
const result = computeImpactFromEvidenceClaims({
|
|
521
|
-
issueBundle: createMockBundle([]),
|
|
522
|
-
evidenceId,
|
|
523
|
-
evidenceTs: evidenceId,
|
|
524
|
-
claims: [claim],
|
|
525
|
-
});
|
|
526
|
-
expect(result.newImpactEvents).toEqual([
|
|
527
|
-
{
|
|
528
|
-
id: 'ie_test_001',
|
|
529
|
-
type: 'periods.set',
|
|
530
|
-
ts: evidenceId,
|
|
531
|
-
basis: { evidenceId },
|
|
532
|
-
entity: claim.entity,
|
|
533
|
-
periods: [
|
|
534
|
-
{
|
|
535
|
-
kind: 'fixed',
|
|
536
|
-
startAt: '2025-01-05T01:00:00+08:00',
|
|
537
|
-
endAt: null,
|
|
538
|
-
},
|
|
539
|
-
],
|
|
540
|
-
},
|
|
541
|
-
]);
|
|
542
|
-
});
|
|
543
|
-
});
|
|
544
|
-
//# sourceMappingURL=computeImpactFromEvidenceClaims.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"computeImpactFromEvidenceClaims.test.js","sourceRoot":"/","sources":["helpers/computeImpactFromEvidenceClaims.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { beforeEach, describe, expect, test, vi } from 'vitest';\nimport type { IssueBundle } from '../schema/issue/bundle.js';\nimport type { Claim } from '../schema/issue/claim.js';\nimport type { ImpactEvent } from '../schema/issue/impactEvent.js';\nimport { IdGenerator } from '../write/id/IdGenerator.js';\nimport { computeImpactFromEvidenceClaims } from './computeImpactFromEvidenceClaims.js';\nimport { keyForAffectedEntity } from './keyForAffectedEntity.js';\n\nvi.mock('../write/id/IdGenerator.js', () => ({\n IdGenerator: {\n impactEventId: vi.fn(),\n evidenceId: vi.fn(),\n },\n}));\n\nfunction createMockBundle(impactEvents: ImpactEvent[]): IssueBundle {\n return {\n issue: {\n id: '2025-01-01-test-issue',\n type: 'disruption',\n title: {\n 'en-SG': 'Test Issue',\n 'zh-Hans': null,\n ms: null,\n ta: null,\n },\n titleMeta: {\n source: 'test',\n },\n },\n evidence: [],\n impactEvents,\n path: 'test/path',\n };\n}\n\nfunction createServiceClaim(overrides: Partial<Claim> = {}): Claim {\n return {\n entity: { type: 'service', serviceId: 'NSL' },\n effect: null,\n scopes: { service: null },\n statusSignal: null,\n timeHints: null,\n causes: null,\n ...overrides,\n };\n}\n\nfunction createFacilityClaim(overrides: Partial<Claim> = {}): Claim {\n return {\n entity: { type: 'facility', stationId: 'NS1', kind: 'lift' },\n effect: null,\n scopes: { service: null },\n statusSignal: null,\n timeHints: null,\n causes: null,\n ...overrides,\n };\n}\n\ndescribe('computeImpactFromEvidenceClaims', () => {\n beforeEach(() => {\n let idCounter = 0;\n vi.mocked(IdGenerator.impactEventId).mockImplementation(() => {\n idCounter += 1;\n return `ie_test_${String(idCounter).padStart(3, '0')}`;\n });\n });\n\n test('returns empty result when no claims are provided', () => {\n const result = computeImpactFromEvidenceClaims({\n issueBundle: createMockBundle([]),\n evidenceId: '2025-01-01T10:00:00+08:00',\n evidenceTs: '2025-01-01T10:00:00+08:00',\n claims: [],\n });\n\n expect(result).toEqual({\n newState: {\n services: {},\n servicesProvenance: {},\n facilities: {},\n facilitiesProvenance: {},\n impactEventIds: [],\n },\n newImpactEvents: [],\n });\n });\n\n test('creates service effect and periods events for fixed time hints', () => {\n const claim = createServiceClaim({\n effect: {\n service: { kind: 'delay', duration: null },\n facility: null,\n },\n statusSignal: 'open',\n timeHints: {\n kind: 'fixed',\n startAt: '2025-01-01T10:00:00+08:00',\n endAt: '2025-01-01T12:00:00+08:00',\n },\n });\n\n const evidenceId = '2025-01-01T10:05:00+08:00';\n const result = computeImpactFromEvidenceClaims({\n issueBundle: createMockBundle([]),\n evidenceId,\n evidenceTs: evidenceId,\n claims: [claim],\n });\n\n const serviceKey = keyForAffectedEntity(claim.entity);\n\n expect(result.newState.services[serviceKey]).toEqual({\n effect: { kind: 'delay', duration: null },\n scopes: [],\n periods: [\n {\n kind: 'fixed',\n startAt: '2025-01-01T10:00:00+08:00',\n endAt: '2025-01-01T12:00:00+08:00',\n },\n ],\n causes: [],\n });\n expect(result.newState.servicesProvenance[serviceKey]).toEqual({\n effect: { evidenceId },\n periods: { evidenceId },\n });\n expect(result.newImpactEvents).toEqual([\n {\n id: 'ie_test_001',\n type: 'service_effects.set',\n ts: evidenceId,\n basis: { evidenceId },\n entity: claim.entity,\n effect: { kind: 'delay', duration: null },\n },\n {\n id: 'ie_test_002',\n type: 'periods.set',\n ts: evidenceId,\n basis: { evidenceId },\n entity: claim.entity,\n periods: [\n {\n kind: 'fixed',\n startAt: '2025-01-01T10:00:00+08:00',\n endAt: '2025-01-01T12:00:00+08:00',\n },\n ],\n },\n ]);\n });\n\n test('deduplicates claims by affected entity and keeps the last claim', () => {\n const firstClaim = createServiceClaim({\n effect: {\n service: { kind: 'delay', duration: null },\n facility: null,\n },\n });\n const secondClaim = createServiceClaim({\n effect: {\n service: { kind: 'no-service' },\n facility: null,\n },\n });\n\n const result = computeImpactFromEvidenceClaims({\n issueBundle: createMockBundle([]),\n evidenceId: '2025-01-01T11:00:00+08:00',\n evidenceTs: '2025-01-01T11:00:00+08:00',\n claims: [firstClaim, secondClaim],\n });\n\n expect(result.newImpactEvents).toHaveLength(1);\n expect(result.newImpactEvents[0]).toMatchObject({\n id: 'ie_test_001',\n type: 'service_effects.set',\n effect: { kind: 'no-service' },\n });\n });\n\n test('creates service scopes state, provenance, and event', () => {\n const claim = createServiceClaim({\n scopes: {\n service: [\n { type: 'service.whole' },\n {\n type: 'service.segment',\n fromStationId: 'NS1',\n toStationId: 'NS3',\n },\n ],\n },\n });\n const evidenceId = '2025-01-02T09:00:00+08:00';\n\n const result = computeImpactFromEvidenceClaims({\n issueBundle: createMockBundle([]),\n evidenceId,\n evidenceTs: evidenceId,\n claims: [claim],\n });\n\n const serviceKey = keyForAffectedEntity(claim.entity);\n expect(result.newState.services[serviceKey]).toEqual({\n effect: null,\n scopes: [\n { type: 'service.whole' },\n {\n type: 'service.segment',\n fromStationId: 'NS1',\n toStationId: 'NS3',\n },\n ],\n periods: [],\n causes: [],\n });\n expect(result.newState.servicesProvenance[serviceKey]).toEqual({\n scopes: { evidenceId },\n });\n expect(result.newImpactEvents).toEqual([\n {\n id: 'ie_test_001',\n type: 'service_scopes.set',\n ts: evidenceId,\n basis: { evidenceId },\n entity: claim.entity,\n serviceScopes: [\n { type: 'service.whole' },\n {\n type: 'service.segment',\n fromStationId: 'NS1',\n toStationId: 'NS3',\n },\n ],\n },\n ]);\n });\n\n test('emits effects, periods, then scopes when all are present', () => {\n const claim = createServiceClaim({\n effect: {\n service: { kind: 'reduced-service' },\n facility: null,\n },\n timeHints: {\n kind: 'fixed',\n startAt: '2025-01-10T20:00:00+08:00',\n endAt: '2025-01-10T22:00:00+08:00',\n },\n scopes: {\n service: [{ type: 'service.point', stationId: 'NS5' }],\n },\n });\n const evidenceId = '2025-01-10T20:05:00+08:00';\n\n const result = computeImpactFromEvidenceClaims({\n issueBundle: createMockBundle([]),\n evidenceId,\n evidenceTs: evidenceId,\n claims: [claim],\n });\n\n expect(result.newImpactEvents.map((event) => event.type)).toEqual([\n 'service_effects.set',\n 'periods.set',\n 'service_scopes.set',\n ]);\n });\n\n test('emits causes events for service and facility claims', () => {\n const serviceClaim = createServiceClaim({\n causes: ['signal.fault', 'delay'],\n });\n const facilityClaim = createFacilityClaim({\n causes: ['elevator.outage'],\n });\n const evidenceId = '2025-01-10T23:00:00+08:00';\n\n const result = computeImpactFromEvidenceClaims({\n issueBundle: createMockBundle([]),\n evidenceId,\n evidenceTs: evidenceId,\n claims: [serviceClaim, facilityClaim],\n });\n\n const serviceKey = keyForAffectedEntity(serviceClaim.entity);\n const facilityKey = keyForAffectedEntity(facilityClaim.entity);\n\n expect(result.newState.services[serviceKey].causes).toEqual([\n 'signal.fault',\n 'delay',\n ]);\n expect(result.newState.servicesProvenance[serviceKey]).toEqual({\n causes: { evidenceId },\n });\n expect(result.newState.facilities[facilityKey].causes).toEqual([\n 'elevator.outage',\n ]);\n expect(result.newState.facilitiesProvenance[facilityKey]).toEqual({\n causes: { evidenceId },\n });\n expect(result.newImpactEvents.map((event) => event.type)).toEqual([\n 'causes.set',\n 'causes.set',\n ]);\n });\n\n test('does not emit events when effect, scopes, and causes are unchanged', () => {\n const serviceEntity = { type: 'service' as const, serviceId: 'NSL' };\n const issueBundle = createMockBundle([\n {\n id: 'ie_seed_effect',\n type: 'service_effects.set',\n entity: serviceEntity,\n ts: '2025-01-01T09:00:00+08:00',\n basis: { evidenceId: 'seed_effect' },\n effect: { kind: 'delay', duration: null },\n },\n {\n id: 'ie_seed_scopes',\n type: 'service_scopes.set',\n entity: serviceEntity,\n ts: '2025-01-01T09:01:00+08:00',\n basis: { evidenceId: 'seed_scopes' },\n serviceScopes: [{ type: 'service.point', stationId: 'NS4' }],\n },\n {\n id: 'ie_seed_causes',\n type: 'causes.set',\n entity: serviceEntity,\n ts: '2025-01-01T09:02:00+08:00',\n basis: { evidenceId: 'seed_causes' },\n causes: ['signal.fault'],\n },\n ]);\n const claim = createServiceClaim({\n entity: serviceEntity,\n effect: {\n service: { kind: 'delay', duration: null },\n facility: null,\n },\n scopes: {\n service: [{ type: 'service.point', stationId: 'NS4' }],\n },\n causes: ['signal.fault'],\n });\n const evidenceId = '2025-01-01T10:00:00+08:00';\n\n const result = computeImpactFromEvidenceClaims({\n issueBundle,\n evidenceId,\n evidenceTs: evidenceId,\n claims: [claim],\n });\n\n const serviceKey = keyForAffectedEntity(serviceEntity);\n expect(result.newState.servicesProvenance[serviceKey]).toEqual({\n effect: { evidenceId: 'seed_effect' },\n scopes: { evidenceId: 'seed_scopes' },\n causes: { evidenceId: 'seed_causes' },\n });\n expect(result.newImpactEvents).toEqual([]);\n });\n\n test('deduplicates scope claims and keeps scopes from last claim', () => {\n const firstClaim = createServiceClaim({\n scopes: {\n service: [{ type: 'service.whole' }],\n },\n });\n const secondClaim = createServiceClaim({\n scopes: {\n service: [{ type: 'service.point', stationId: 'NS9' }],\n },\n });\n const evidenceId = '2025-01-11T08:00:00+08:00';\n\n const result = computeImpactFromEvidenceClaims({\n issueBundle: createMockBundle([]),\n evidenceId,\n evidenceTs: evidenceId,\n claims: [firstClaim, secondClaim],\n });\n\n const serviceKey = keyForAffectedEntity(secondClaim.entity);\n expect(result.newState.services[serviceKey].scopes).toEqual([\n { type: 'service.point', stationId: 'NS9' },\n ]);\n expect(result.newState.servicesProvenance[serviceKey]).toEqual({\n scopes: { evidenceId },\n });\n expect(result.newImpactEvents).toEqual([\n {\n id: 'ie_test_001',\n type: 'service_scopes.set',\n ts: evidenceId,\n basis: { evidenceId },\n entity: secondClaim.entity,\n serviceScopes: [{ type: 'service.point', stationId: 'NS9' }],\n },\n ]);\n });\n\n test('applies start-only hints to recurring periods and updates window start', () => {\n const serviceEntity = { type: 'service' as const, serviceId: 'NSL' };\n const issueBundle = createMockBundle([\n {\n id: 'ie_seed_01',\n type: 'periods.set',\n entity: serviceEntity,\n ts: '2025-01-01T08:00:00+08:00',\n basis: { evidenceId: 'seed' },\n periods: [\n {\n kind: 'recurring',\n frequency: 'daily',\n startAt: '2025-01-01T06:00:00+08:00',\n endAt: '2025-01-07T06:00:00+08:00',\n daysOfWeek: null,\n timeWindow: {\n startAt: '06:00:00',\n endAt: '08:00:00',\n },\n timeZone: 'Asia/Singapore',\n excludedDates: null,\n },\n ],\n },\n ]);\n\n const claim = createServiceClaim({\n entity: serviceEntity,\n timeHints: {\n kind: 'start-only',\n startAt: '2025-01-02T11:30:00+08:00',\n },\n });\n const evidenceId = '2025-01-02T11:35:00+08:00';\n\n const result = computeImpactFromEvidenceClaims({\n issueBundle,\n evidenceId,\n evidenceTs: evidenceId,\n claims: [claim],\n });\n\n const serviceKey = keyForAffectedEntity(serviceEntity);\n expect(result.newState.services[serviceKey].periods).toEqual([\n {\n kind: 'recurring',\n frequency: 'daily',\n startAt: '2025-01-02T11:30:00+08:00',\n endAt: '2025-01-07T06:00:00+08:00',\n daysOfWeek: null,\n timeWindow: {\n startAt: '11:30:00',\n endAt: '08:00:00',\n },\n timeZone: 'Asia/Singapore',\n excludedDates: null,\n },\n ]);\n expect(result.newImpactEvents).toEqual([\n {\n id: 'ie_test_001',\n type: 'periods.set',\n ts: evidenceId,\n basis: { evidenceId },\n entity: serviceEntity,\n periods: result.newState.services[serviceKey].periods,\n },\n ]);\n });\n\n test('applies end-only hints to facility recurring periods and updates window end', () => {\n const facilityEntity = {\n type: 'facility' as const,\n stationId: 'NS1',\n kind: 'lift' as const,\n };\n const issueBundle = createMockBundle([\n {\n id: 'ie_seed_02',\n type: 'periods.set',\n entity: facilityEntity,\n ts: '2025-01-01T08:00:00+08:00',\n basis: { evidenceId: 'seed' },\n periods: [\n {\n kind: 'recurring',\n frequency: 'weekly',\n startAt: '2025-01-01T06:00:00+08:00',\n endAt: '2025-02-01T06:00:00+08:00',\n daysOfWeek: ['MO', 'WE'],\n timeWindow: {\n startAt: '06:00:00',\n endAt: '09:00:00',\n },\n timeZone: 'Asia/Singapore',\n excludedDates: ['2025-01-15'],\n },\n ],\n },\n ]);\n\n const claim = createFacilityClaim({\n entity: facilityEntity,\n timeHints: {\n kind: 'end-only',\n endAt: '2025-01-25T23:15:00+08:00',\n },\n });\n const evidenceId = '2025-01-03T12:00:00+08:00';\n\n const result = computeImpactFromEvidenceClaims({\n issueBundle,\n evidenceId,\n evidenceTs: evidenceId,\n claims: [claim],\n });\n\n const facilityKey = keyForAffectedEntity(facilityEntity);\n expect(result.newState.facilities[facilityKey].periods).toEqual([\n {\n kind: 'recurring',\n frequency: 'weekly',\n startAt: '2025-01-01T06:00:00+08:00',\n endAt: '2025-01-25T23:15:00+08:00',\n daysOfWeek: ['MO', 'WE'],\n timeWindow: {\n startAt: '06:00:00',\n endAt: '23:15:00',\n },\n timeZone: 'Asia/Singapore',\n excludedDates: ['2025-01-15'],\n },\n ]);\n expect(result.newImpactEvents).toEqual([\n {\n id: 'ie_test_001',\n type: 'periods.set',\n ts: evidenceId,\n basis: { evidenceId },\n entity: facilityEntity,\n periods: result.newState.facilities[facilityKey].periods,\n },\n ]);\n });\n\n test('start-only with no current periods creates an open fixed period', () => {\n const claim = createServiceClaim({\n timeHints: {\n kind: 'start-only',\n startAt: '2025-01-05T01:00:00+08:00',\n },\n });\n const evidenceId = '2025-01-05T01:05:00+08:00';\n\n const result = computeImpactFromEvidenceClaims({\n issueBundle: createMockBundle([]),\n evidenceId,\n evidenceTs: evidenceId,\n claims: [claim],\n });\n\n expect(result.newImpactEvents).toEqual([\n {\n id: 'ie_test_001',\n type: 'periods.set',\n ts: evidenceId,\n basis: { evidenceId },\n entity: claim.entity,\n periods: [\n {\n kind: 'fixed',\n startAt: '2025-01-05T01:00:00+08:00',\n endAt: null,\n },\n ],\n },\n ]);\n });\n});\n"]}
|