@choiceapps/communityservices-sdk 0.1.0
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/AGENTS.md +43 -0
- package/API.md +86 -0
- package/CHANGELOG.md +12 -0
- package/LICENSE +201 -0
- package/NOTICE +11 -0
- package/README.md +100 -0
- package/SSVF.md +131 -0
- package/browser/attachment-conflict.mjs +6 -0
- package/browser/case-plans-ui.mjs +23 -0
- package/browser/case-plans.d.mts +20 -0
- package/browser/case-plans.mjs +89 -0
- package/browser/client-creation.d.mts +16 -0
- package/browser/client-creation.mjs +60 -0
- package/browser/client-profile-ui.mjs +59 -0
- package/browser/client-profile.d.mts +24 -0
- package/browser/client-profile.mjs +94 -0
- package/browser/client-workflows.mjs +135 -0
- package/browser/connection.d.mts +4 -0
- package/browser/connection.mjs +41 -0
- package/browser/current-living-situation.d.mts +44 -0
- package/browser/current-living-situation.mjs +161 -0
- package/browser/date-of-birth-ui.mjs +68 -0
- package/browser/date-of-birth.d.mts +28 -0
- package/browser/date-of-birth.mjs +112 -0
- package/browser/enrollment-workflow.d.mts +174 -0
- package/browser/enrollment-workflow.mjs +518 -0
- package/browser/exit-details.mjs +21 -0
- package/browser/file-store.mjs +32 -0
- package/browser/gwt-mapped.mjs +46 -0
- package/browser/household-exit.d.mts +34 -0
- package/browser/household-exit.mjs +102 -0
- package/browser/households-ui.mjs +20 -0
- package/browser/households.d.mts +22 -0
- package/browser/households.mjs +115 -0
- package/browser/index.d.mts +78 -0
- package/browser/index.mjs +46 -0
- package/browser/member-entry-date.d.mts +30 -0
- package/browser/member-entry-date.mjs +71 -0
- package/browser/need-recording.d.mts +37 -0
- package/browser/need-recording.mjs +68 -0
- package/browser/need-ui.mjs +138 -0
- package/browser/page-lock.mjs +11 -0
- package/browser/password-recovery.mjs +49 -0
- package/browser/playwright-session.mjs +196 -0
- package/browser/program-discovery.d.mts +22 -0
- package/browser/program-discovery.mjs +80 -0
- package/browser/recovery-diagnostics.mjs +9 -0
- package/browser/service-recording.d.mts +45 -0
- package/browser/service-recording.mjs +148 -0
- package/browser/service-ui.mjs +160 -0
- package/browser/session-authentication.mjs +40 -0
- package/browser/shelter-inventory.d.mts +103 -0
- package/browser/shelter-inventory.mjs +273 -0
- package/browser/shelter-ui.mjs +382 -0
- package/browser/shelters.d.mts +139 -0
- package/browser/shelters.mjs +425 -0
- package/browser/ssvf-rules.d.mts +21 -0
- package/browser/ssvf-rules.mjs +145 -0
- package/browser/ui-login.mjs +135 -0
- package/dist/cjs/bulk.d.ts +33 -0
- package/dist/cjs/bulk.d.ts.map +1 -0
- package/dist/cjs/bulk.js +42 -0
- package/dist/cjs/bulk.js.map +1 -0
- package/dist/cjs/control.d.ts +35 -0
- package/dist/cjs/control.d.ts.map +1 -0
- package/dist/cjs/control.js +141 -0
- package/dist/cjs/control.js.map +1 -0
- package/dist/cjs/effective-date.d.ts +3 -0
- package/dist/cjs/effective-date.d.ts.map +1 -0
- package/dist/cjs/effective-date.js +27 -0
- package/dist/cjs/effective-date.js.map +1 -0
- package/dist/cjs/encoding.d.ts +32 -0
- package/dist/cjs/encoding.d.ts.map +1 -0
- package/dist/cjs/encoding.js +121 -0
- package/dist/cjs/encoding.js.map +1 -0
- package/dist/cjs/enrollment-verifications.d.ts +39 -0
- package/dist/cjs/enrollment-verifications.d.ts.map +1 -0
- package/dist/cjs/enrollment-verifications.js +96 -0
- package/dist/cjs/enrollment-verifications.js.map +1 -0
- package/dist/cjs/errors.d.ts +33 -0
- package/dist/cjs/errors.d.ts.map +1 -0
- package/dist/cjs/errors.js +45 -0
- package/dist/cjs/errors.js.map +1 -0
- package/dist/cjs/generated/v2-models.d.ts +1482 -0
- package/dist/cjs/generated/v2-models.d.ts.map +1 -0
- package/dist/cjs/generated/v2-models.js +3 -0
- package/dist/cjs/generated/v2-models.js.map +1 -0
- package/dist/cjs/generated/v2.d.ts +1149 -0
- package/dist/cjs/generated/v2.d.ts.map +1 -0
- package/dist/cjs/generated/v2.js +252 -0
- package/dist/cjs/generated/v2.js.map +1 -0
- package/dist/cjs/generated/v3-models.d.ts +1420 -0
- package/dist/cjs/generated/v3-models.d.ts.map +1 -0
- package/dist/cjs/generated/v3-models.js +3 -0
- package/dist/cjs/generated/v3-models.js.map +1 -0
- package/dist/cjs/generated/v3.d.ts +1149 -0
- package/dist/cjs/generated/v3.d.ts.map +1 -0
- package/dist/cjs/generated/v3.js +252 -0
- package/dist/cjs/generated/v3.js.map +1 -0
- package/dist/cjs/gwt-enrollments.d.ts +131 -0
- package/dist/cjs/gwt-enrollments.d.ts.map +1 -0
- package/dist/cjs/gwt-enrollments.js +280 -0
- package/dist/cjs/gwt-enrollments.js.map +1 -0
- package/dist/cjs/index.d.ts +3 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +19 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/metadata.d.ts +100 -0
- package/dist/cjs/metadata.d.ts.map +1 -0
- package/dist/cjs/metadata.js +165 -0
- package/dist/cjs/metadata.js.map +1 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/program-discovery.d.ts +28 -0
- package/dist/cjs/program-discovery.d.ts.map +1 -0
- package/dist/cjs/program-discovery.js +58 -0
- package/dist/cjs/program-discovery.js.map +1 -0
- package/dist/cjs/race.d.ts +4 -0
- package/dist/cjs/race.d.ts.map +1 -0
- package/dist/cjs/race.js +40 -0
- package/dist/cjs/race.js.map +1 -0
- package/dist/cjs/runtime.d.ts +108 -0
- package/dist/cjs/runtime.d.ts.map +1 -0
- package/dist/cjs/runtime.js +38 -0
- package/dist/cjs/runtime.js.map +1 -0
- package/dist/cjs/subassessments.d.ts +29 -0
- package/dist/cjs/subassessments.d.ts.map +1 -0
- package/dist/cjs/subassessments.js +107 -0
- package/dist/cjs/subassessments.js.map +1 -0
- package/dist/cjs/testing.d.ts +45 -0
- package/dist/cjs/testing.d.ts.map +1 -0
- package/dist/cjs/testing.js +66 -0
- package/dist/cjs/testing.js.map +1 -0
- package/dist/cjs/transport.d.ts +19 -0
- package/dist/cjs/transport.d.ts.map +1 -0
- package/dist/cjs/transport.js +373 -0
- package/dist/cjs/transport.js.map +1 -0
- package/dist/cjs/v2.d.ts +13 -0
- package/dist/cjs/v2.d.ts.map +1 -0
- package/dist/cjs/v2.js +29 -0
- package/dist/cjs/v2.js.map +1 -0
- package/dist/cjs/v3.d.ts +13 -0
- package/dist/cjs/v3.d.ts.map +1 -0
- package/dist/cjs/v3.js +29 -0
- package/dist/cjs/v3.js.map +1 -0
- package/dist/cjs/validation.d.ts +33 -0
- package/dist/cjs/validation.d.ts.map +1 -0
- package/dist/cjs/validation.js +77 -0
- package/dist/cjs/validation.js.map +1 -0
- package/dist/cjs/verification.d.ts +82 -0
- package/dist/cjs/verification.d.ts.map +1 -0
- package/dist/cjs/verification.js +122 -0
- package/dist/cjs/verification.js.map +1 -0
- package/dist/esm/bulk.d.ts +33 -0
- package/dist/esm/bulk.d.ts.map +1 -0
- package/dist/esm/bulk.js +39 -0
- package/dist/esm/bulk.js.map +1 -0
- package/dist/esm/control.d.ts +35 -0
- package/dist/esm/control.d.ts.map +1 -0
- package/dist/esm/control.js +132 -0
- package/dist/esm/control.js.map +1 -0
- package/dist/esm/effective-date.d.ts +3 -0
- package/dist/esm/effective-date.d.ts.map +1 -0
- package/dist/esm/effective-date.js +24 -0
- package/dist/esm/effective-date.js.map +1 -0
- package/dist/esm/encoding.d.ts +32 -0
- package/dist/esm/encoding.d.ts.map +1 -0
- package/dist/esm/encoding.js +117 -0
- package/dist/esm/encoding.js.map +1 -0
- package/dist/esm/enrollment-verifications.d.ts +39 -0
- package/dist/esm/enrollment-verifications.d.ts.map +1 -0
- package/dist/esm/enrollment-verifications.js +93 -0
- package/dist/esm/enrollment-verifications.js.map +1 -0
- package/dist/esm/errors.d.ts +33 -0
- package/dist/esm/errors.d.ts.map +1 -0
- package/dist/esm/errors.js +33 -0
- package/dist/esm/errors.js.map +1 -0
- package/dist/esm/generated/v2-models.d.ts +1482 -0
- package/dist/esm/generated/v2-models.d.ts.map +1 -0
- package/dist/esm/generated/v2-models.js +2 -0
- package/dist/esm/generated/v2-models.js.map +1 -0
- package/dist/esm/generated/v2.d.ts +1149 -0
- package/dist/esm/generated/v2.d.ts.map +1 -0
- package/dist/esm/generated/v2.js +247 -0
- package/dist/esm/generated/v2.js.map +1 -0
- package/dist/esm/generated/v3-models.d.ts +1420 -0
- package/dist/esm/generated/v3-models.d.ts.map +1 -0
- package/dist/esm/generated/v3-models.js +2 -0
- package/dist/esm/generated/v3-models.js.map +1 -0
- package/dist/esm/generated/v3.d.ts +1149 -0
- package/dist/esm/generated/v3.d.ts.map +1 -0
- package/dist/esm/generated/v3.js +247 -0
- package/dist/esm/generated/v3.js.map +1 -0
- package/dist/esm/gwt-enrollments.d.ts +131 -0
- package/dist/esm/gwt-enrollments.d.ts.map +1 -0
- package/dist/esm/gwt-enrollments.js +274 -0
- package/dist/esm/gwt-enrollments.js.map +1 -0
- package/dist/esm/index.d.ts +3 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +3 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/metadata.d.ts +100 -0
- package/dist/esm/metadata.d.ts.map +1 -0
- package/dist/esm/metadata.js +157 -0
- package/dist/esm/metadata.js.map +1 -0
- package/dist/esm/program-discovery.d.ts +28 -0
- package/dist/esm/program-discovery.d.ts.map +1 -0
- package/dist/esm/program-discovery.js +55 -0
- package/dist/esm/program-discovery.js.map +1 -0
- package/dist/esm/race.d.ts +4 -0
- package/dist/esm/race.d.ts.map +1 -0
- package/dist/esm/race.js +37 -0
- package/dist/esm/race.js.map +1 -0
- package/dist/esm/runtime.d.ts +108 -0
- package/dist/esm/runtime.d.ts.map +1 -0
- package/dist/esm/runtime.js +33 -0
- package/dist/esm/runtime.js.map +1 -0
- package/dist/esm/subassessments.d.ts +29 -0
- package/dist/esm/subassessments.d.ts.map +1 -0
- package/dist/esm/subassessments.js +103 -0
- package/dist/esm/subassessments.js.map +1 -0
- package/dist/esm/testing.d.ts +45 -0
- package/dist/esm/testing.d.ts.map +1 -0
- package/dist/esm/testing.js +60 -0
- package/dist/esm/testing.js.map +1 -0
- package/dist/esm/transport.d.ts +19 -0
- package/dist/esm/transport.d.ts.map +1 -0
- package/dist/esm/transport.js +369 -0
- package/dist/esm/transport.js.map +1 -0
- package/dist/esm/v2.d.ts +13 -0
- package/dist/esm/v2.d.ts.map +1 -0
- package/dist/esm/v2.js +13 -0
- package/dist/esm/v2.js.map +1 -0
- package/dist/esm/v3.d.ts +13 -0
- package/dist/esm/v3.d.ts.map +1 -0
- package/dist/esm/v3.js +13 -0
- package/dist/esm/v3.js.map +1 -0
- package/dist/esm/validation.d.ts +33 -0
- package/dist/esm/validation.d.ts.map +1 -0
- package/dist/esm/validation.js +72 -0
- package/dist/esm/validation.js.map +1 -0
- package/dist/esm/verification.d.ts +82 -0
- package/dist/esm/verification.d.ts.map +1 -0
- package/dist/esm/verification.js +117 -0
- package/dist/esm/verification.js.map +1 -0
- package/docs/README.md +56 -0
- package/docs/assessments.md +103 -0
- package/docs/browser-session.md +129 -0
- package/docs/capabilities.md +75 -0
- package/docs/configuration.md +81 -0
- package/docs/current-living-situation.md +56 -0
- package/docs/dates-and-answers.md +40 -0
- package/docs/development.md +81 -0
- package/docs/durable-records.md +156 -0
- package/docs/enrollments.md +217 -0
- package/docs/files-and-notes.md +39 -0
- package/docs/getting-started.md +56 -0
- package/docs/independent-needs.md +77 -0
- package/docs/integration-methods.md +60 -0
- package/docs/profiles.md +68 -0
- package/docs/reference.md +64 -0
- package/docs/rest-client.md +97 -0
- package/docs/services.md +66 -0
- package/docs/shelter-inventory.md +64 -0
- package/docs/shelters.md +75 -0
- package/docs/troubleshooting.md +61 -0
- package/docs/using-the-sdk.md +203 -0
- package/docs/vendor-issues/README.md +46 -0
- package/docs/vendor-issues/api-coverage.md +27 -0
- package/docs/vendor-issues/attachment-authentication.md +40 -0
- package/docs/vendor-issues/date-semantics.md +51 -0
- package/docs/vendor-issues/empty-service-list-404.md +51 -0
- package/docs/vendor-issues/enrollment-complete-target-error.md +178 -0
- package/docs/vendor-issues/enrollment-effective-date-column.md +112 -0
- package/docs/vendor-issues/household-head-validation.md +26 -0
- package/docs/vendor-issues/write-contracts.md +51 -0
- package/examples/README.md +41 -0
- package/examples/current-living-situation.mts +27 -0
- package/examples/durable-records.mts +78 -0
- package/examples/enrollment-workflow.mts +46 -0
- package/examples/gwt-enrollment-session.ts +17 -0
- package/examples/gwt-file-store.mjs +2 -0
- package/examples/household-enrollment-workflow.mts +43 -0
- package/examples/household-exit-workflow.mts +35 -0
- package/examples/household-lifecycle-workflow.mts +34 -0
- package/examples/independent-needs.mts +30 -0
- package/examples/program-discovery.ts +19 -0
- package/examples/quickstart.mjs +13 -0
- package/examples/shelter-inventory.mts +30 -0
- package/examples/shelters.mts +33 -0
- package/examples/usage.ts +23 -0
- package/examples/verification-snapshot.ts +9 -0
- package/llms.txt +26 -0
- package/package.json +103 -0
- package/specs/provenance.json +17 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"control.js","sourceRoot":"","sources":["../../src/control.ts"],"names":[],"mappings":"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","sourcesContent":["import { WellSkyError } from \"./runtime.js\";\nimport type { ClientEvent, ClientHealth, ClientOptions } from \"./runtime.js\";\nimport { CooldownError } from \"./errors.js\";\n\ninterface Waiter { grant: () => void; signal: AbortSignal; abort: () => void }\nexport class Semaphore {\n active = 0;\n readonly #capacity: number;\n readonly #queue: Waiter[] = [];\n constructor(capacity: number) { this.#capacity = capacity; }\n get queued(): number { return this.#queue.length; }\n acquire(signal: AbortSignal, operation: string): Promise<() => void> {\n return new Promise((resolve, reject) => {\n let released = false;\n const grant = () => {\n signal.removeEventListener(\"abort\", abort);\n this.active++;\n resolve(() => {\n if (released) return;\n released = true; this.active--;\n this.#queue.shift()?.grant();\n });\n };\n const abort = () => {\n const index = this.#queue.indexOf(waiter);\n if (index >= 0) this.#queue.splice(index, 1);\n reject(new WellSkyError(signal.reason instanceof DOMException && signal.reason.name === \"TimeoutError\" ? \"timeout\" : \"aborted\", operation));\n };\n const waiter: Waiter = { grant, signal, abort };\n if (signal.aborted) { abort(); return; }\n if (this.active < this.#capacity) grant();\n else { this.#queue.push(waiter); signal.addEventListener(\"abort\", abort, { once: true }); }\n });\n }\n}\n\nexport interface SharedAuthentication {\n cached?: { token: string; expiresAt: number } | undefined;\n inFlight?: Promise<string> | undefined;\n}\nconst identities = new WeakMap<object, number>();\nlet nextIdentity = 1;\nexport function identity(value: object): number {\n const prior = identities.get(value);\n if (prior !== undefined) return prior;\n const id = nextIdentity++; identities.set(value, id); return id;\n}\nconst authentication = new Map<string, SharedAuthentication>();\n/** Credentials are hashed for cache identity and never exposed in keys or diagnostics. */\nexport async function sharedAuthentication(scope: string, auth: ClientOptions[\"auth\"]): Promise<SharedAuthentication> {\n const descriptor = auth.kind === \"credentials\" ? [scope, auth.kind, auth.username, auth.password] : auth.kind === \"provider\" ? [scope, auth.kind, identity(auth.getToken)] : [scope, auth.kind];\n const digest = await crypto.subtle.digest(\"SHA-256\", new TextEncoder().encode(JSON.stringify(descriptor)));\n const key = Array.from(new Uint8Array(digest), byte => byte.toString(16).padStart(2, \"0\")).join(\"\");\n const prior = authentication.get(key);\n if (prior) return prior;\n const state: SharedAuthentication = {};\n authentication.set(key, state);\n return state;\n}\nexport const tokenMintQueue = new Semaphore(1);\n\nexport class RequestControl {\n readonly semaphore: Semaphore;\n readonly #settings: { threshold: number; windowMs: number; durationMs: number };\n #failures: number[] = [];\n #until = 0;\n tokenMintCount = 0;\n constructor(concurrency: number, settings: { threshold: number; windowMs: number; durationMs: number }) {\n for (const value of [concurrency, settings.threshold, settings.windowMs, settings.durationMs]) if (!Number.isSafeInteger(value) || value < 1) throw new TypeError(\"Concurrency and cooldown settings must be positive integers\");\n this.semaphore = new Semaphore(concurrency); this.#settings = { ...settings };\n }\n check(operation: string): void {\n if (this.#until > Date.now()) throw new CooldownError(operation, this.#until);\n if (this.#until !== 0) { this.#until = 0; this.#failures = []; }\n }\n failed(status: number): number | undefined {\n if (status !== 401 && status !== 403 && status !== 429 && status < 500) return undefined;\n const now = Date.now();\n this.#failures = this.#failures.filter(time => time > now - this.#settings.windowMs);\n this.#failures.push(now);\n if (this.#failures.length >= this.#settings.threshold && this.#until <= now) { this.#until = now + this.#settings.durationMs; return this.#until; }\n return undefined;\n }\n health(): ClientHealth {\n return { state: this.#until > Date.now() ? \"open\" : \"closed\", until: this.#until > Date.now() ? new Date(this.#until).toISOString() : null, activeRequests: this.semaphore.active, queuedRequests: this.semaphore.queued, tokenMintCount: this.tokenMintCount };\n }\n}\nconst controls = new Map<string, { signature: string; value: RequestControl }>();\nexport function requestControl(scope: string, options: ClientOptions): RequestControl {\n const concurrency = options.maxConcurrency ?? 8;\n const cooldown = options.cooldown ?? { threshold: 5, windowMs: 10_000, durationMs: 30_000 };\n const signature = JSON.stringify([concurrency, cooldown.threshold, cooldown.windowMs, cooldown.durationMs]);\n const existing = controls.get(scope);\n if (existing && existing.signature !== signature) throw new TypeError(\"Clients sharing a tenant and transport must use the same concurrency/cooldown settings\");\n if (existing) return existing.value;\n const value = new RequestControl(concurrency, cooldown);\n controls.set(scope, { signature, value }); return value;\n}\n\nexport function emit(options: Pick<ClientOptions, \"hooks\" | \"logger\">, event: ClientEvent): void {\n const hooks = options.hooks;\n const handler = event.type === \"request\" ? hooks?.onRequest : event.type === \"response\" ? hooks?.onResponse : event.type === \"tokenMint\" ? hooks?.onTokenMint : event.type === \"throttle\" ? hooks?.onThrottle : hooks?.onCooldown;\n const safe = Object.freeze({ ...event });\n // Observers must not turn a completed write into a thrown error or a replay.\n try { void Promise.resolve(handler?.(safe)).catch(() => {}); } catch { /* Observer failures cannot change request outcomes. */ }\n try { void Promise.resolve(options.logger?.(safe)).catch(() => {}); } catch { /* Same boundary for user-supplied loggers. */ }\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"effective-date.d.ts","sourceRoot":"","sources":["../../src/effective-date.ts"],"names":[],"mappings":"AAEA,uFAAuF;AACvF,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAcrG"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { ValidationError } from "./errors.js";
|
|
2
|
+
/** Explicit deployment correction for an observed upstream mobile-write date shift. */
|
|
3
|
+
export function correctMobileEffectiveDate(value, minutes, operation) {
|
|
4
|
+
const invalid = () => new ValidationError(operation, ["dateEffective"]);
|
|
5
|
+
if (typeof value !== "string")
|
|
6
|
+
throw invalid();
|
|
7
|
+
const parts = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.(\d{1,3}))?(Z|[+-]\d{2}:\d{2})$/.exec(value);
|
|
8
|
+
if (!parts)
|
|
9
|
+
throw invalid();
|
|
10
|
+
const [, year, month, day, hour, minute, second, , zone] = parts;
|
|
11
|
+
const date = new Date(`${year}-${month}-${day}T00:00:00.000Z`);
|
|
12
|
+
if (!Number.isFinite(date.getTime()) || date.toISOString().slice(0, 10) !== `${year}-${month}-${day}` || Number(hour) > 23 || Number(minute) > 59 || Number(second) > 59)
|
|
13
|
+
throw invalid();
|
|
14
|
+
if (zone !== "Z" && (!zone || Number(zone.slice(1, 3)) > 14 || Number(zone.slice(4)) > 59 || (Number(zone.slice(1, 3)) === 14 && Number(zone.slice(4)) !== 0)))
|
|
15
|
+
throw invalid();
|
|
16
|
+
const corrected = Date.parse(value) + minutes * 60_000;
|
|
17
|
+
if (!Number.isFinite(corrected))
|
|
18
|
+
throw invalid();
|
|
19
|
+
const encoded = new Date(corrected).toISOString();
|
|
20
|
+
if (!/^\d{4}-/.test(encoded))
|
|
21
|
+
throw invalid();
|
|
22
|
+
return encoded;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=effective-date.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"effective-date.js","sourceRoot":"","sources":["../../src/effective-date.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C,uFAAuF;AACvF,MAAM,UAAU,0BAA0B,CAAC,KAAc,EAAE,OAAe,EAAE,SAAiB;IAC3F,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,IAAI,eAAe,CAAC,SAAS,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC;IACxE,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,MAAM,OAAO,EAAE,CAAC;IAC/C,MAAM,KAAK,GAAG,sFAAsF,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACjH,IAAI,CAAC,KAAK;QAAE,MAAM,OAAO,EAAE,CAAC;IAC5B,MAAM,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,AAAD,EAAG,IAAI,CAAC,GAAG,KAAK,CAAC;IACjE,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,GAAG,IAAI,IAAI,KAAK,IAAI,GAAG,gBAAgB,CAAC,CAAC;IAC/D,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,GAAG,IAAI,IAAI,KAAK,IAAI,GAAG,EAAE,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE;QAAE,MAAM,OAAO,EAAE,CAAC;IAC1L,IAAI,IAAI,KAAK,GAAG,IAAI,CAAC,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;QAAE,MAAM,OAAO,EAAE,CAAC;IAChL,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,OAAO,GAAG,MAAM,CAAC;IACvD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC;QAAE,MAAM,OAAO,EAAE,CAAC;IACjD,MAAM,OAAO,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,CAAC;IAClD,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,MAAM,OAAO,EAAE,CAAC;IAC9C,OAAO,OAAO,CAAC;AACjB,CAAC","sourcesContent":["import { ValidationError } from \"./errors.js\";\n\n/** Explicit deployment correction for an observed upstream mobile-write date shift. */\nexport function correctMobileEffectiveDate(value: unknown, minutes: number, operation: string): string {\n const invalid = () => new ValidationError(operation, [\"dateEffective\"]);\n if (typeof value !== \"string\") throw invalid();\n const parts = /^(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2})(?:\\.(\\d{1,3}))?(Z|[+-]\\d{2}:\\d{2})$/.exec(value);\n if (!parts) throw invalid();\n const [, year, month, day, hour, minute, second, , zone] = parts;\n const date = new Date(`${year}-${month}-${day}T00:00:00.000Z`);\n if (!Number.isFinite(date.getTime()) || date.toISOString().slice(0, 10) !== `${year}-${month}-${day}` || Number(hour) > 23 || Number(minute) > 59 || Number(second) > 59) throw invalid();\n if (zone !== \"Z\" && (!zone || Number(zone.slice(1, 3)) > 14 || Number(zone.slice(4)) > 59 || (Number(zone.slice(1, 3)) === 14 && Number(zone.slice(4)) !== 0))) throw invalid();\n const corrected = Date.parse(value) + minutes * 60_000;\n if (!Number.isFinite(corrected)) throw invalid();\n const encoded = new Date(corrected).toISOString();\n if (!/^\\d{4}-/.test(encoded)) throw invalid();\n return encoded;\n}\n"]}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { PicklistOption, PicklistSelector, QuestionDefinition } from "./metadata.js";
|
|
2
|
+
export type AnswerState = "client_doesnt_know" | "client_refused" | "data_not_collected";
|
|
3
|
+
export type AnswerValue = {
|
|
4
|
+
value: string | number | boolean | string[];
|
|
5
|
+
} | {
|
|
6
|
+
state: AnswerState;
|
|
7
|
+
} | {
|
|
8
|
+
option: PicklistSelector;
|
|
9
|
+
} | {
|
|
10
|
+
options: readonly PicklistSelector[];
|
|
11
|
+
};
|
|
12
|
+
export type Answers = Record<string, AnswerValue>;
|
|
13
|
+
export interface EncodingOptions {
|
|
14
|
+
endpoint: "standalone" | "enrollment" | "mobile";
|
|
15
|
+
/** Tenant-verified display labels, including exact whitespace/HUD suffixes, for label-based endpoints. */
|
|
16
|
+
writeLabel?: (question: QuestionDefinition, option: PicklistOption) => string | undefined;
|
|
17
|
+
/** Application configuration supplies the relevant option codes. No answer-state labels are guessed. */
|
|
18
|
+
stateCodes?: Partial<Record<AnswerState, readonly string[]>>;
|
|
19
|
+
multiValue?: (question: QuestionDefinition, values: readonly string[]) => string;
|
|
20
|
+
}
|
|
21
|
+
export interface EncodedQuestion {
|
|
22
|
+
question_id: number;
|
|
23
|
+
question_type: string;
|
|
24
|
+
virt_field_name: string;
|
|
25
|
+
answer_value: string;
|
|
26
|
+
}
|
|
27
|
+
export declare function encodeAnswers(questions: readonly QuestionDefinition[], answers: Answers, options: EncodingOptions): EncodedQuestion[];
|
|
28
|
+
/** Builds one new row only. Never accepts or echoes an existing recordset ID. */
|
|
29
|
+
export declare function encodeNewSubassessmentRow(parent: QuestionDefinition, answers: Answers, options: EncodingOptions): {
|
|
30
|
+
subAssessments: EncodedQuestion[];
|
|
31
|
+
};
|
|
32
|
+
//# sourceMappingURL=encoding.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encoding.d.ts","sourceRoot":"","sources":["../../src/encoding.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAK1F,MAAM,MAAM,WAAW,GAAG,oBAAoB,GAAG,gBAAgB,GAAG,oBAAoB,CAAC;AACzF,MAAM,MAAM,WAAW,GAAG;IAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,EAAE,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,WAAW,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,gBAAgB,CAAA;CAAE,GAAG;IAAE,OAAO,EAAE,SAAS,gBAAgB,EAAE,CAAA;CAAE,CAAC;AAC7K,MAAM,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;AAClD,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,YAAY,GAAG,YAAY,GAAG,QAAQ,CAAC;IACjD,0GAA0G;IAC1G,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,kBAAkB,EAAE,MAAM,EAAE,cAAc,KAAK,MAAM,GAAG,SAAS,CAAC;IAC1F,wGAAwG;IACxG,UAAU,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC,CAAC;IAC7D,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,kBAAkB,EAAE,MAAM,EAAE,SAAS,MAAM,EAAE,KAAK,MAAM,CAAC;CAClF;AACD,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;CACtB;AA2DD,wBAAgB,aAAa,CAAC,SAAS,EAAE,SAAS,kBAAkB,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,eAAe,GAAG,eAAe,EAAE,CAgBrI;AAED,iFAAiF;AACjF,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,kBAAkB,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,eAAe,GAAG;IAAE,cAAc,EAAE,eAAe,EAAE,CAAA;CAAE,CAUvJ"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { resolvePicklistOption } from "./metadata.js";
|
|
2
|
+
import { ValidationError } from "./errors.js";
|
|
3
|
+
import { resolveRaceCombination } from "./race.js";
|
|
4
|
+
function encodeValue(question, answer, options) {
|
|
5
|
+
const field = question.fieldName ?? `#${question.questionId}`;
|
|
6
|
+
if (["label", "blank", "sub_assessment"].includes(question.questionType))
|
|
7
|
+
throw new ValidationError("assessment encoding", [field]);
|
|
8
|
+
if (question.questionType === "provider" && options.endpoint === "mobile")
|
|
9
|
+
throw new ValidationError("mobile provider answers are unsupported", [field]);
|
|
10
|
+
if ("state" in answer) {
|
|
11
|
+
if (question.questionType !== "lookup")
|
|
12
|
+
return undefined;
|
|
13
|
+
const codes = options.stateCodes?.[answer.state];
|
|
14
|
+
if (!codes)
|
|
15
|
+
throw new ValidationError("answer-state code configuration required", [field]);
|
|
16
|
+
const found = question.options.filter(option => option.code !== null && codes.includes(option.code));
|
|
17
|
+
if (!found.length)
|
|
18
|
+
return undefined;
|
|
19
|
+
if (found.length !== 1 || !found[0])
|
|
20
|
+
throw new ValidationError("ambiguous answer-state option", [field]);
|
|
21
|
+
const option = question.fieldName === "HUD_RACEETHNICITY" && found[0].code !== null
|
|
22
|
+
? resolveRaceCombination(question, [{ code: found[0].code }]) : found[0];
|
|
23
|
+
return lookupLabel(question, option, options);
|
|
24
|
+
}
|
|
25
|
+
if (question.questionType === "lookup") {
|
|
26
|
+
if (question.fieldName === "HUD_RACEETHNICITY") {
|
|
27
|
+
const selectors = "options" in answer ? answer.options : "option" in answer ? [answer.option]
|
|
28
|
+
: typeof answer.value === "string" ? [{ name: answer.value }]
|
|
29
|
+
: Array.isArray(answer.value) ? answer.value.map(name => ({ name })) : undefined;
|
|
30
|
+
if (!selectors)
|
|
31
|
+
throw new ValidationError("race requires category selectors", [field]);
|
|
32
|
+
return lookupLabel(question, resolveRaceCombination(question, selectors), options);
|
|
33
|
+
}
|
|
34
|
+
if ("options" in answer)
|
|
35
|
+
throw new ValidationError("multiple options require a supported combination field", [field]);
|
|
36
|
+
if ("option" in answer)
|
|
37
|
+
return lookupLabel(question, resolvePicklistOption(question, answer.option), options);
|
|
38
|
+
if (typeof answer.value !== "string")
|
|
39
|
+
throw new ValidationError("lookup requires a code or name selector", [field]);
|
|
40
|
+
return lookupLabel(question, resolvePicklistOption(question, { name: answer.value }), options);
|
|
41
|
+
}
|
|
42
|
+
if (!("value" in answer))
|
|
43
|
+
throw new ValidationError("picklist selector on a non-lookup question", [field]);
|
|
44
|
+
const value = answer.value;
|
|
45
|
+
if (Array.isArray(value)) {
|
|
46
|
+
if (!options.multiValue)
|
|
47
|
+
throw new ValidationError("multi-value encoding requires an explicit encoder", [field]);
|
|
48
|
+
return options.multiValue(question, value);
|
|
49
|
+
}
|
|
50
|
+
switch (question.questionType) {
|
|
51
|
+
case "yes_no":
|
|
52
|
+
if (value === true || value === "Yes")
|
|
53
|
+
return "Yes";
|
|
54
|
+
if (value === false || value === "No")
|
|
55
|
+
return "No";
|
|
56
|
+
throw new ValidationError("yes_no encoding", [field]);
|
|
57
|
+
case "int":
|
|
58
|
+
case "provider":
|
|
59
|
+
if ((typeof value !== "number" && typeof value !== "string") || value === "" || !Number.isSafeInteger(Number(value)))
|
|
60
|
+
throw new ValidationError("integer encoding", [field]);
|
|
61
|
+
return String(value);
|
|
62
|
+
case "money":
|
|
63
|
+
if ((typeof value !== "number" && typeof value !== "string") || value === "" || !Number.isFinite(Number(value)))
|
|
64
|
+
throw new ValidationError("money encoding", [field]);
|
|
65
|
+
return String(value);
|
|
66
|
+
case "date":
|
|
67
|
+
case "textbox":
|
|
68
|
+
case "textarea": return String(value);
|
|
69
|
+
default: throw new ValidationError("unsupported question type", [field]);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
function lookupLabel(question, option, options) {
|
|
73
|
+
if (options.endpoint === "mobile")
|
|
74
|
+
return String(option.id);
|
|
75
|
+
const label = options.writeLabel?.(question, option);
|
|
76
|
+
if (!label)
|
|
77
|
+
throw new ValidationError("verified lookup write label required", [question.fieldName ?? `#${question.questionId}`]);
|
|
78
|
+
return label;
|
|
79
|
+
}
|
|
80
|
+
export function encodeAnswers(questions, answers, options) {
|
|
81
|
+
const index = new Map();
|
|
82
|
+
for (const question of questions)
|
|
83
|
+
if (question.fieldName) {
|
|
84
|
+
if (index.has(question.fieldName))
|
|
85
|
+
throw new ValidationError("ambiguous question field", [question.fieldName]);
|
|
86
|
+
index.set(question.fieldName, question);
|
|
87
|
+
}
|
|
88
|
+
const unknown = Object.keys(answers).filter(field => !index.has(field));
|
|
89
|
+
if (unknown.length)
|
|
90
|
+
throw new ValidationError("unknown assessment fields", unknown);
|
|
91
|
+
const result = [];
|
|
92
|
+
for (const [field, answer] of Object.entries(answers)) {
|
|
93
|
+
const question = index.get(field);
|
|
94
|
+
if (!question)
|
|
95
|
+
throw new ValidationError("unknown assessment fields", [field]);
|
|
96
|
+
const value = encodeValue(question, answer, options);
|
|
97
|
+
if (value !== undefined)
|
|
98
|
+
result.push({ question_id: question.questionId, question_type: question.questionType, virt_field_name: field, answer_value: value });
|
|
99
|
+
}
|
|
100
|
+
return result;
|
|
101
|
+
}
|
|
102
|
+
/** Builds one new row only. Never accepts or echoes an existing recordset ID. */
|
|
103
|
+
export function encodeNewSubassessmentRow(parent, answers, options) {
|
|
104
|
+
if (parent.questionType !== "sub_assessment")
|
|
105
|
+
throw new ValidationError("subassessment parent required");
|
|
106
|
+
const encoded = encodeAnswers(parent.children, answers, options);
|
|
107
|
+
const included = new Set(encoded.map(q => q.virt_field_name));
|
|
108
|
+
for (const question of parent.children) {
|
|
109
|
+
if (!question.fieldName || included.has(question.fieldName) || ["label", "blank", "yes_no"].includes(question.questionType))
|
|
110
|
+
continue;
|
|
111
|
+
if (question.questionType === "provider" && options.endpoint === "mobile")
|
|
112
|
+
throw new ValidationError("mobile provider answers are unsupported", [question.fieldName]);
|
|
113
|
+
encoded.push({ question_id: question.questionId, question_type: question.questionType, virt_field_name: question.fieldName, answer_value: "" });
|
|
114
|
+
}
|
|
115
|
+
return { subAssessments: encoded };
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=encoding.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encoding.js","sourceRoot":"","sources":["../../src/encoding.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AAoBnD,SAAS,WAAW,CAAC,QAA4B,EAAE,MAAmB,EAAE,OAAwB;IAC9F,MAAM,KAAK,GAAG,QAAQ,CAAC,SAAS,IAAI,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC;IAC9D,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,YAAY,CAAC;QAAE,MAAM,IAAI,eAAe,CAAC,qBAAqB,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IACpI,IAAI,QAAQ,CAAC,YAAY,KAAK,UAAU,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ;QAAE,MAAM,IAAI,eAAe,CAAC,yCAAyC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IACzJ,IAAI,OAAO,IAAI,MAAM,EAAE,CAAC;QACtB,IAAI,QAAQ,CAAC,YAAY,KAAK,QAAQ;YAAE,OAAO,SAAS,CAAC;QACzD,MAAM,KAAK,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACjD,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,eAAe,CAAC,0CAA0C,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;QAC3F,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,IAAI,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;QACrG,IAAI,CAAC,KAAK,CAAC,MAAM;YAAE,OAAO,SAAS,CAAC;QACpC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;YAAE,MAAM,IAAI,eAAe,CAAC,+BAA+B,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;QACzG,MAAM,MAAM,GAAG,QAAQ,CAAC,SAAS,KAAK,mBAAmB,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI;YACjF,CAAC,CAAC,sBAAsB,CAAC,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC3E,OAAO,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IAChD,CAAC;IACD,IAAI,QAAQ,CAAC,YAAY,KAAK,QAAQ,EAAE,CAAC;QACvC,IAAI,QAAQ,CAAC,SAAS,KAAK,mBAAmB,EAAE,CAAC;YAC/C,MAAM,SAAS,GAAG,SAAS,IAAI,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC;gBAC3F,CAAC,CAAC,OAAO,MAAM,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC;oBAC7D,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YACnF,IAAI,CAAC,SAAS;gBAAE,MAAM,IAAI,eAAe,CAAC,kCAAkC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;YACvF,OAAO,WAAW,CAAC,QAAQ,EAAE,sBAAsB,CAAC,QAAQ,EAAE,SAAS,CAAC,EAAE,OAAO,CAAC,CAAC;QACrF,CAAC;QACD,IAAI,SAAS,IAAI,MAAM;YAAE,MAAM,IAAI,eAAe,CAAC,wDAAwD,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;QACtH,IAAI,QAAQ,IAAI,MAAM;YAAE,OAAO,WAAW,CAAC,QAAQ,EAAE,qBAAqB,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC;QAC9G,IAAI,OAAO,MAAM,CAAC,KAAK,KAAK,QAAQ;YAAE,MAAM,IAAI,eAAe,CAAC,yCAAyC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;QACpH,OAAO,WAAW,CAAC,QAAQ,EAAE,qBAAqB,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;IACjG,CAAC;IACD,IAAI,CAAC,CAAC,OAAO,IAAI,MAAM,CAAC;QAAE,MAAM,IAAI,eAAe,CAAC,4CAA4C,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IAC3G,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;IAC3B,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,IAAI,CAAC,OAAO,CAAC,UAAU;YAAE,MAAM,IAAI,eAAe,CAAC,mDAAmD,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;QACjH,OAAO,OAAO,CAAC,UAAU,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAC7C,CAAC;IACD,QAAQ,QAAQ,CAAC,YAAY,EAAE,CAAC;QAC9B,KAAK,QAAQ;YACX,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,KAAK;gBAAE,OAAO,KAAK,CAAC;YACpD,IAAI,KAAK,KAAK,KAAK,IAAI,KAAK,KAAK,IAAI;gBAAE,OAAO,IAAI,CAAC;YACnD,MAAM,IAAI,eAAe,CAAC,iBAAiB,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;QACxD,KAAK,KAAK,CAAC;QAAC,KAAK,UAAU;YACzB,IAAI,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ,CAAC,IAAI,KAAK,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBAAE,MAAM,IAAI,eAAe,CAAC,kBAAkB,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;YAC7K,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;QACvB,KAAK,OAAO;YACV,IAAI,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ,CAAC,IAAI,KAAK,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBAAE,MAAM,IAAI,eAAe,CAAC,gBAAgB,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;YACtK,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;QACvB,KAAK,MAAM,CAAC;QAAC,KAAK,SAAS,CAAC;QAAC,KAAK,UAAU,CAAC,CAAC,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;QACnE,OAAO,CAAC,CAAC,MAAM,IAAI,eAAe,CAAC,2BAA2B,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IAC3E,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAAC,QAA4B,EAAE,MAAsB,EAAE,OAAwB;IACjG,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC5D,MAAM,KAAK,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACrD,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,eAAe,CAAC,sCAAsC,EAAE,CAAC,QAAQ,CAAC,SAAS,IAAI,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;IACjI,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,SAAwC,EAAE,OAAgB,EAAE,OAAwB;IAChH,MAAM,KAAK,GAAG,IAAI,GAAG,EAA8B,CAAC;IACpD,KAAK,MAAM,QAAQ,IAAI,SAAS;QAAE,IAAI,QAAQ,CAAC,SAAS,EAAE,CAAC;YACzD,IAAI,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC;gBAAE,MAAM,IAAI,eAAe,CAAC,0BAA0B,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;YAC/G,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;QAC1C,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;IACxE,IAAI,OAAO,CAAC,MAAM;QAAE,MAAM,IAAI,eAAe,CAAC,2BAA2B,EAAE,OAAO,CAAC,CAAC;IACpF,MAAM,MAAM,GAAsB,EAAE,CAAC;IACrC,KAAK,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACtD,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAClC,IAAI,CAAC,QAAQ;YAAE,MAAM,IAAI,eAAe,CAAC,2BAA2B,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;QAC/E,MAAM,KAAK,GAAG,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;QACrD,IAAI,KAAK,KAAK,SAAS;YAAE,MAAM,CAAC,IAAI,CAAC,EAAE,WAAW,EAAE,QAAQ,CAAC,UAAU,EAAE,aAAa,EAAE,QAAQ,CAAC,YAAY,EAAE,eAAe,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,CAAC;IAChK,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,yBAAyB,CAAC,MAA0B,EAAE,OAAgB,EAAE,OAAwB;IAC9G,IAAI,MAAM,CAAC,YAAY,KAAK,gBAAgB;QAAE,MAAM,IAAI,eAAe,CAAC,+BAA+B,CAAC,CAAC;IACzG,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IACjE,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC;IAC9D,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QACvC,IAAI,CAAC,QAAQ,CAAC,SAAS,IAAI,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,YAAY,CAAC;YAAE,SAAS;QACtI,IAAI,QAAQ,CAAC,YAAY,KAAK,UAAU,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ;YAAE,MAAM,IAAI,eAAe,CAAC,yCAAyC,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;QACtK,OAAO,CAAC,IAAI,CAAC,EAAE,WAAW,EAAE,QAAQ,CAAC,UAAU,EAAE,aAAa,EAAE,QAAQ,CAAC,YAAY,EAAE,eAAe,EAAE,QAAQ,CAAC,SAAS,EAAE,YAAY,EAAE,EAAE,EAAE,CAAC,CAAC;IAClJ,CAAC;IACD,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC;AACrC,CAAC","sourcesContent":["import type { PicklistOption, PicklistSelector, QuestionDefinition } from \"./metadata.js\";\nimport { resolvePicklistOption } from \"./metadata.js\";\nimport { ValidationError } from \"./errors.js\";\nimport { resolveRaceCombination } from \"./race.js\";\n\nexport type AnswerState = \"client_doesnt_know\" | \"client_refused\" | \"data_not_collected\";\nexport type AnswerValue = { value: string | number | boolean | string[] } | { state: AnswerState } | { option: PicklistSelector } | { options: readonly PicklistSelector[] };\nexport type Answers = Record<string, AnswerValue>;\nexport interface EncodingOptions {\n endpoint: \"standalone\" | \"enrollment\" | \"mobile\";\n /** Tenant-verified display labels, including exact whitespace/HUD suffixes, for label-based endpoints. */\n writeLabel?: (question: QuestionDefinition, option: PicklistOption) => string | undefined;\n /** Application configuration supplies the relevant option codes. No answer-state labels are guessed. */\n stateCodes?: Partial<Record<AnswerState, readonly string[]>>;\n multiValue?: (question: QuestionDefinition, values: readonly string[]) => string;\n}\nexport interface EncodedQuestion {\n question_id: number;\n question_type: string;\n virt_field_name: string;\n answer_value: string;\n}\n\nfunction encodeValue(question: QuestionDefinition, answer: AnswerValue, options: EncodingOptions): string | undefined {\n const field = question.fieldName ?? `#${question.questionId}`;\n if ([\"label\", \"blank\", \"sub_assessment\"].includes(question.questionType)) throw new ValidationError(\"assessment encoding\", [field]);\n if (question.questionType === \"provider\" && options.endpoint === \"mobile\") throw new ValidationError(\"mobile provider answers are unsupported\", [field]);\n if (\"state\" in answer) {\n if (question.questionType !== \"lookup\") return undefined;\n const codes = options.stateCodes?.[answer.state];\n if (!codes) throw new ValidationError(\"answer-state code configuration required\", [field]);\n const found = question.options.filter(option => option.code !== null && codes.includes(option.code));\n if (!found.length) return undefined;\n if (found.length !== 1 || !found[0]) throw new ValidationError(\"ambiguous answer-state option\", [field]);\n const option = question.fieldName === \"HUD_RACEETHNICITY\" && found[0].code !== null\n ? resolveRaceCombination(question, [{ code: found[0].code }]) : found[0];\n return lookupLabel(question, option, options);\n }\n if (question.questionType === \"lookup\") {\n if (question.fieldName === \"HUD_RACEETHNICITY\") {\n const selectors = \"options\" in answer ? answer.options : \"option\" in answer ? [answer.option]\n : typeof answer.value === \"string\" ? [{ name: answer.value }]\n : Array.isArray(answer.value) ? answer.value.map(name => ({ name })) : undefined;\n if (!selectors) throw new ValidationError(\"race requires category selectors\", [field]);\n return lookupLabel(question, resolveRaceCombination(question, selectors), options);\n }\n if (\"options\" in answer) throw new ValidationError(\"multiple options require a supported combination field\", [field]);\n if (\"option\" in answer) return lookupLabel(question, resolvePicklistOption(question, answer.option), options);\n if (typeof answer.value !== \"string\") throw new ValidationError(\"lookup requires a code or name selector\", [field]);\n return lookupLabel(question, resolvePicklistOption(question, { name: answer.value }), options);\n }\n if (!(\"value\" in answer)) throw new ValidationError(\"picklist selector on a non-lookup question\", [field]);\n const value = answer.value;\n if (Array.isArray(value)) {\n if (!options.multiValue) throw new ValidationError(\"multi-value encoding requires an explicit encoder\", [field]);\n return options.multiValue(question, value);\n }\n switch (question.questionType) {\n case \"yes_no\":\n if (value === true || value === \"Yes\") return \"Yes\";\n if (value === false || value === \"No\") return \"No\";\n throw new ValidationError(\"yes_no encoding\", [field]);\n case \"int\": case \"provider\":\n if ((typeof value !== \"number\" && typeof value !== \"string\") || value === \"\" || !Number.isSafeInteger(Number(value))) throw new ValidationError(\"integer encoding\", [field]);\n return String(value);\n case \"money\":\n if ((typeof value !== \"number\" && typeof value !== \"string\") || value === \"\" || !Number.isFinite(Number(value))) throw new ValidationError(\"money encoding\", [field]);\n return String(value);\n case \"date\": case \"textbox\": case \"textarea\": return String(value);\n default: throw new ValidationError(\"unsupported question type\", [field]);\n }\n}\n\nfunction lookupLabel(question: QuestionDefinition, option: PicklistOption, options: EncodingOptions): string {\n if (options.endpoint === \"mobile\") return String(option.id);\n const label = options.writeLabel?.(question, option);\n if (!label) throw new ValidationError(\"verified lookup write label required\", [question.fieldName ?? `#${question.questionId}`]);\n return label;\n}\n\nexport function encodeAnswers(questions: readonly QuestionDefinition[], answers: Answers, options: EncodingOptions): EncodedQuestion[] {\n const index = new Map<string, QuestionDefinition>();\n for (const question of questions) if (question.fieldName) {\n if (index.has(question.fieldName)) throw new ValidationError(\"ambiguous question field\", [question.fieldName]);\n index.set(question.fieldName, question);\n }\n const unknown = Object.keys(answers).filter(field => !index.has(field));\n if (unknown.length) throw new ValidationError(\"unknown assessment fields\", unknown);\n const result: EncodedQuestion[] = [];\n for (const [field, answer] of Object.entries(answers)) {\n const question = index.get(field);\n if (!question) throw new ValidationError(\"unknown assessment fields\", [field]);\n const value = encodeValue(question, answer, options);\n if (value !== undefined) result.push({ question_id: question.questionId, question_type: question.questionType, virt_field_name: field, answer_value: value });\n }\n return result;\n}\n\n/** Builds one new row only. Never accepts or echoes an existing recordset ID. */\nexport function encodeNewSubassessmentRow(parent: QuestionDefinition, answers: Answers, options: EncodingOptions): { subAssessments: EncodedQuestion[] } {\n if (parent.questionType !== \"sub_assessment\") throw new ValidationError(\"subassessment parent required\");\n const encoded = encodeAnswers(parent.children, answers, options);\n const included = new Set(encoded.map(q => q.virt_field_name));\n for (const question of parent.children) {\n if (!question.fieldName || included.has(question.fieldName) || [\"label\", \"blank\", \"yes_no\"].includes(question.questionType)) continue;\n if (question.questionType === \"provider\" && options.endpoint === \"mobile\") throw new ValidationError(\"mobile provider answers are unsupported\", [question.fieldName]);\n encoded.push({ question_id: question.questionId, question_type: question.questionType, virt_field_name: question.fieldName, answer_value: \"\" });\n }\n return { subAssessments: encoded };\n}\n"]}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { WellSkyClient } from "./generated/v3.js";
|
|
2
|
+
import type { SubAssessmentAnswer } from "./generated/v3-models.js";
|
|
3
|
+
import type { RequestOptions } from "./runtime.js";
|
|
4
|
+
/** Structural interface accepted by both V2 and V3 clients. Only a GET is used. */
|
|
5
|
+
export interface VerificationAssessmentReader {
|
|
6
|
+
assessments: Pick<WellSkyClient["assessments"], "get">;
|
|
7
|
+
}
|
|
8
|
+
export interface EnrollmentVerificationRequest extends RequestOptions {
|
|
9
|
+
clientId: number;
|
|
10
|
+
/** An instrument exposing all four standard verification groups. */
|
|
11
|
+
assessmentCode: string;
|
|
12
|
+
/** Exact enrollment instant with Z or a numeric offset. No host timezone is inferred. */
|
|
13
|
+
enrollmentDate: string;
|
|
14
|
+
}
|
|
15
|
+
export type VerificationField = "MONTHLYINCOME" | "SVP_NONCASHBENEFITS" | "HUDHEALTHINSURANCESUBA" | "DISABILITIES_1";
|
|
16
|
+
export type VerificationRecord = SubAssessmentAnswer & {
|
|
17
|
+
recordset_id: number;
|
|
18
|
+
};
|
|
19
|
+
export interface VerificationGroupSnapshot {
|
|
20
|
+
fieldName: VerificationField;
|
|
21
|
+
records: VerificationRecord[];
|
|
22
|
+
excluded: {
|
|
23
|
+
record: VerificationRecord;
|
|
24
|
+
reason: "not_started" | "ended";
|
|
25
|
+
}[];
|
|
26
|
+
}
|
|
27
|
+
export interface EnrollmentVerificationSnapshot {
|
|
28
|
+
clientId: number;
|
|
29
|
+
assessmentCode: string;
|
|
30
|
+
enrollmentDate: string;
|
|
31
|
+
/** Current recorded versions filtered by row dates, not an answer-history reconstruction. */
|
|
32
|
+
source: "current-assessment";
|
|
33
|
+
groups: VerificationGroupSnapshot[];
|
|
34
|
+
}
|
|
35
|
+
/** Read current recorded verification rows and select start <= enrollment <= end.
|
|
36
|
+
* Never writes, changes dates, applies a seven-hour correction, or treats isActive as a date filter.
|
|
37
|
+
* Missing groups, ambiguous rows and invalid/zoneless dates fail rather than imply no records. */
|
|
38
|
+
export declare function readEnrollmentVerifications(client: VerificationAssessmentReader, input: EnrollmentVerificationRequest): Promise<EnrollmentVerificationSnapshot>;
|
|
39
|
+
//# sourceMappingURL=enrollment-verifications.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"enrollment-verifications.d.ts","sourceRoot":"","sources":["../../src/enrollment-verifications.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAGpE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEnD,mFAAmF;AACnF,MAAM,WAAW,4BAA4B;IAC3C,WAAW,EAAE,IAAI,CAAC,aAAa,CAAC,aAAa,CAAC,EAAE,KAAK,CAAC,CAAC;CACxD;AACD,MAAM,WAAW,6BAA8B,SAAQ,cAAc;IACnE,QAAQ,EAAE,MAAM,CAAC;IACjB,oEAAoE;IACpE,cAAc,EAAE,MAAM,CAAC;IACvB,yFAAyF;IACzF,cAAc,EAAE,MAAM,CAAC;CACxB;AACD,MAAM,MAAM,iBAAiB,GAAG,eAAe,GAAG,qBAAqB,GAAG,wBAAwB,GAAG,gBAAgB,CAAC;AACtH,MAAM,MAAM,kBAAkB,GAAG,mBAAmB,GAAG;IAAE,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC;AAChF,MAAM,WAAW,yBAAyB;IACxC,SAAS,EAAE,iBAAiB,CAAC;IAC7B,OAAO,EAAE,kBAAkB,EAAE,CAAC;IAC9B,QAAQ,EAAE;QAAE,MAAM,EAAE,kBAAkB,CAAC;QAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAA;KAAE,EAAE,CAAC;CAC7E;AACD,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,6FAA6F;IAC7F,MAAM,EAAE,oBAAoB,CAAC;IAC7B,MAAM,EAAE,yBAAyB,EAAE,CAAC;CACrC;AAsCD;;kGAEkG;AAClG,wBAAsB,2BAA2B,CAAC,MAAM,EAAE,4BAA4B,EAAE,KAAK,EAAE,6BAA6B,GAAG,OAAO,CAAC,8BAA8B,CAAC,CAoCrK"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { ValidationError } from "./errors.js";
|
|
2
|
+
import { toItems, WellSkyError } from "./runtime.js";
|
|
3
|
+
const fields = [
|
|
4
|
+
{ field: "MONTHLYINCOME", start: "MONTHLYINCOMESTART", end: "MONTHLYINCOMEEND" },
|
|
5
|
+
{ field: "SVP_NONCASHBENEFITS", start: "SVP_NONCASHBENEFITSSTART", end: "SVP_NONCASHBENEFITSEND" },
|
|
6
|
+
{ field: "HUDHEALTHINSURANCESUBA", start: "HUDHEALTHINSURANCESUBASTART", end: "HUDHEALTHINSURANCESUBAEND" },
|
|
7
|
+
{ field: "DISABILITIES_1", start: "DISABILITIES_1START", end: "DISABILITIES_1END" },
|
|
8
|
+
];
|
|
9
|
+
/** Parses ISO and WellSky's offset-bearing SQL date strings without local-time conversion.
|
|
10
|
+
* Nanoseconds preserve fractional boundaries instead of rounding a future row into the snapshot. */
|
|
11
|
+
function verificationInstant(value) {
|
|
12
|
+
if (typeof value !== "string")
|
|
13
|
+
return undefined;
|
|
14
|
+
const parts = /^(\d{4}-\d{2}-\d{2})[T ](\d{2}):(\d{2}):(\d{2})(?:\.(\d{1,9}))?(Z|[+-]\d{2}(?::?\d{2})?)$/.exec(value);
|
|
15
|
+
if (!parts)
|
|
16
|
+
return undefined;
|
|
17
|
+
const [, calendar, hour, minute, second, fraction = "", zone] = parts;
|
|
18
|
+
if (!calendar || !zone || Number(hour) > 23 || Number(minute) > 59 || Number(second) > 59)
|
|
19
|
+
return undefined;
|
|
20
|
+
const day = new Date(`${calendar}T00:00:00Z`);
|
|
21
|
+
if (!Number.isFinite(day.getTime()) || day.toISOString().slice(0, 10) !== calendar)
|
|
22
|
+
return undefined;
|
|
23
|
+
const offset = zone.slice(1).replace(":", "");
|
|
24
|
+
const offsetHours = zone === "Z" ? 0 : Number(offset.slice(0, 2));
|
|
25
|
+
const offsetMinutes = zone === "Z" ? 0 : Number(offset.slice(2) || "0");
|
|
26
|
+
if (offsetHours > 14 || offsetMinutes > 59 || (offsetHours === 14 && offsetMinutes !== 0))
|
|
27
|
+
return undefined;
|
|
28
|
+
const signedOffset = (zone.startsWith("-") ? -1 : 1) * (offsetHours * 60 + offsetMinutes);
|
|
29
|
+
const millis = day.getTime() + (Number(hour) * 3600 + Number(minute) * 60 + Number(second) - signedOffset * 60) * 1000;
|
|
30
|
+
return BigInt(millis) * 1000000n + BigInt(fraction.padEnd(9, "0"));
|
|
31
|
+
}
|
|
32
|
+
function recordDate(record, field) {
|
|
33
|
+
const matches = record.sub_assessment_list?.filter(q => q.virt_field_name === field) ?? [];
|
|
34
|
+
const question = matches[0];
|
|
35
|
+
if (matches.length !== 1 || !question || question.question_type !== "date")
|
|
36
|
+
throw new WellSkyError("protocol", `verification date field ${field}`);
|
|
37
|
+
const value = question.answer_value;
|
|
38
|
+
if (value === null || value === undefined || value === "")
|
|
39
|
+
return null;
|
|
40
|
+
if (typeof value !== "string")
|
|
41
|
+
throw new WellSkyError("protocol", `verification date field ${field}`);
|
|
42
|
+
return value;
|
|
43
|
+
}
|
|
44
|
+
/** Read current recorded verification rows and select start <= enrollment <= end.
|
|
45
|
+
* Never writes, changes dates, applies a seven-hour correction, or treats isActive as a date filter.
|
|
46
|
+
* Missing groups, ambiguous rows and invalid/zoneless dates fail rather than imply no records. */
|
|
47
|
+
export async function readEnrollmentVerifications(client, input) {
|
|
48
|
+
const operation = "read enrollment verifications";
|
|
49
|
+
const at = verificationInstant(input.enrollmentDate);
|
|
50
|
+
if (at === undefined)
|
|
51
|
+
throw new ValidationError(operation, ["enrollmentDate"]);
|
|
52
|
+
if (!Number.isSafeInteger(input.clientId) || input.clientId < 1)
|
|
53
|
+
throw new ValidationError(operation, ["clientId"]);
|
|
54
|
+
if (typeof input.assessmentCode !== "string" || !input.assessmentCode.trim())
|
|
55
|
+
throw new ValidationError(operation, ["assessmentCode"]);
|
|
56
|
+
// Do not send dateEffective: it can suppress backdated rows needed for this projection.
|
|
57
|
+
const response = await client.assessments.get({
|
|
58
|
+
path: { clientId: input.clientId, assessmentCode: input.assessmentCode },
|
|
59
|
+
...(input.signal === undefined ? {} : { signal: input.signal }),
|
|
60
|
+
...(input.timeoutMs === undefined ? {} : { timeoutMs: input.timeoutMs }),
|
|
61
|
+
...(input.correlationId === undefined ? {} : { correlationId: input.correlationId }),
|
|
62
|
+
});
|
|
63
|
+
const questions = toItems(response);
|
|
64
|
+
const groups = [];
|
|
65
|
+
const seenIds = new Set();
|
|
66
|
+
for (const { field, start, end } of fields) {
|
|
67
|
+
const matches = questions.filter(q => q.virt_field_name === field);
|
|
68
|
+
const parent = matches[0];
|
|
69
|
+
if (matches.length !== 1 || !parent || parent.question_type !== "sub_assessment" || !Array.isArray(parent.sub_assessment_answer_list))
|
|
70
|
+
throw new WellSkyError("protocol", `verification group ${field}`);
|
|
71
|
+
const group = { fieldName: field, records: [], excluded: [] };
|
|
72
|
+
for (const raw of parent.sub_assessment_answer_list) {
|
|
73
|
+
const id = raw.recordset_id;
|
|
74
|
+
if (typeof id !== "number" || !Number.isSafeInteger(id) || id < 1 || seenIds.has(id))
|
|
75
|
+
throw new WellSkyError("protocol", "verification record identity");
|
|
76
|
+
seenIds.add(id);
|
|
77
|
+
const record = { ...structuredClone(raw), recordset_id: id };
|
|
78
|
+
const startValue = recordDate(record, start), endValue = recordDate(record, end);
|
|
79
|
+
const from = verificationInstant(startValue), through = endValue === null ? null : verificationInstant(endValue);
|
|
80
|
+
if (from === undefined || through === undefined || (through !== null && through < from))
|
|
81
|
+
throw new WellSkyError("protocol", `verification interval ${field}`);
|
|
82
|
+
if (from > at)
|
|
83
|
+
group.excluded.push({ record, reason: "not_started" });
|
|
84
|
+
else if (through !== null && through < at)
|
|
85
|
+
group.excluded.push({ record, reason: "ended" });
|
|
86
|
+
else
|
|
87
|
+
group.records.push(record);
|
|
88
|
+
}
|
|
89
|
+
groups.push(group);
|
|
90
|
+
}
|
|
91
|
+
return { clientId: input.clientId, assessmentCode: input.assessmentCode, enrollmentDate: input.enrollmentDate, source: "current-assessment", groups };
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=enrollment-verifications.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"enrollment-verifications.js","sourceRoot":"","sources":["../../src/enrollment-verifications.ts"],"names":[],"mappings":"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","sourcesContent":["import type { WellSkyClient } from \"./generated/v3.js\";\nimport type { SubAssessmentAnswer } from \"./generated/v3-models.js\";\nimport { ValidationError } from \"./errors.js\";\nimport { toItems, WellSkyError } from \"./runtime.js\";\nimport type { RequestOptions } from \"./runtime.js\";\n\n/** Structural interface accepted by both V2 and V3 clients. Only a GET is used. */\nexport interface VerificationAssessmentReader {\n assessments: Pick<WellSkyClient[\"assessments\"], \"get\">;\n}\nexport interface EnrollmentVerificationRequest extends RequestOptions {\n clientId: number;\n /** An instrument exposing all four standard verification groups. */\n assessmentCode: string;\n /** Exact enrollment instant with Z or a numeric offset. No host timezone is inferred. */\n enrollmentDate: string;\n}\nexport type VerificationField = \"MONTHLYINCOME\" | \"SVP_NONCASHBENEFITS\" | \"HUDHEALTHINSURANCESUBA\" | \"DISABILITIES_1\";\nexport type VerificationRecord = SubAssessmentAnswer & { recordset_id: number };\nexport interface VerificationGroupSnapshot {\n fieldName: VerificationField;\n records: VerificationRecord[];\n excluded: { record: VerificationRecord; reason: \"not_started\" | \"ended\" }[];\n}\nexport interface EnrollmentVerificationSnapshot {\n clientId: number;\n assessmentCode: string;\n enrollmentDate: string;\n /** Current recorded versions filtered by row dates, not an answer-history reconstruction. */\n source: \"current-assessment\";\n groups: VerificationGroupSnapshot[];\n}\n\nconst fields: { field: VerificationField; start: string; end: string }[] = [\n { field: \"MONTHLYINCOME\", start: \"MONTHLYINCOMESTART\", end: \"MONTHLYINCOMEEND\" },\n { field: \"SVP_NONCASHBENEFITS\", start: \"SVP_NONCASHBENEFITSSTART\", end: \"SVP_NONCASHBENEFITSEND\" },\n { field: \"HUDHEALTHINSURANCESUBA\", start: \"HUDHEALTHINSURANCESUBASTART\", end: \"HUDHEALTHINSURANCESUBAEND\" },\n { field: \"DISABILITIES_1\", start: \"DISABILITIES_1START\", end: \"DISABILITIES_1END\" },\n];\n\n/** Parses ISO and WellSky's offset-bearing SQL date strings without local-time conversion.\n * Nanoseconds preserve fractional boundaries instead of rounding a future row into the snapshot. */\nfunction verificationInstant(value: unknown): bigint | undefined {\n if (typeof value !== \"string\") return undefined;\n const parts = /^(\\d{4}-\\d{2}-\\d{2})[T ](\\d{2}):(\\d{2}):(\\d{2})(?:\\.(\\d{1,9}))?(Z|[+-]\\d{2}(?::?\\d{2})?)$/.exec(value);\n if (!parts) return undefined;\n const [, calendar, hour, minute, second, fraction = \"\", zone] = parts;\n if (!calendar || !zone || Number(hour) > 23 || Number(minute) > 59 || Number(second) > 59) return undefined;\n const day = new Date(`${calendar}T00:00:00Z`);\n if (!Number.isFinite(day.getTime()) || day.toISOString().slice(0, 10) !== calendar) return undefined;\n const offset = zone.slice(1).replace(\":\", \"\");\n const offsetHours = zone === \"Z\" ? 0 : Number(offset.slice(0, 2));\n const offsetMinutes = zone === \"Z\" ? 0 : Number(offset.slice(2) || \"0\");\n if (offsetHours > 14 || offsetMinutes > 59 || (offsetHours === 14 && offsetMinutes !== 0)) return undefined;\n const signedOffset = (zone.startsWith(\"-\") ? -1 : 1) * (offsetHours * 60 + offsetMinutes);\n const millis = day.getTime() + (Number(hour) * 3600 + Number(minute) * 60 + Number(second) - signedOffset * 60) * 1000;\n return BigInt(millis) * 1_000_000n + BigInt(fraction.padEnd(9, \"0\"));\n}\n\nfunction recordDate(record: VerificationRecord, field: string): string | null {\n const matches = record.sub_assessment_list?.filter(q => q.virt_field_name === field) ?? [];\n const question = matches[0];\n if (matches.length !== 1 || !question || question.question_type !== \"date\") throw new WellSkyError(\"protocol\", `verification date field ${field}`);\n const value = question.answer_value;\n if (value === null || value === undefined || value === \"\") return null;\n if (typeof value !== \"string\") throw new WellSkyError(\"protocol\", `verification date field ${field}`);\n return value;\n}\n\n/** Read current recorded verification rows and select start <= enrollment <= end.\n * Never writes, changes dates, applies a seven-hour correction, or treats isActive as a date filter.\n * Missing groups, ambiguous rows and invalid/zoneless dates fail rather than imply no records. */\nexport async function readEnrollmentVerifications(client: VerificationAssessmentReader, input: EnrollmentVerificationRequest): Promise<EnrollmentVerificationSnapshot> {\n const operation = \"read enrollment verifications\";\n const at = verificationInstant(input.enrollmentDate);\n if (at === undefined) throw new ValidationError(operation, [\"enrollmentDate\"]);\n if (!Number.isSafeInteger(input.clientId) || input.clientId < 1) throw new ValidationError(operation, [\"clientId\"]);\n if (typeof input.assessmentCode !== \"string\" || !input.assessmentCode.trim()) throw new ValidationError(operation, [\"assessmentCode\"]);\n // Do not send dateEffective: it can suppress backdated rows needed for this projection.\n const response = await client.assessments.get({\n path: { clientId: input.clientId, assessmentCode: input.assessmentCode },\n ...(input.signal === undefined ? {} : { signal: input.signal }),\n ...(input.timeoutMs === undefined ? {} : { timeoutMs: input.timeoutMs }),\n ...(input.correlationId === undefined ? {} : { correlationId: input.correlationId }),\n });\n const questions = toItems(response);\n const groups: VerificationGroupSnapshot[] = [];\n const seenIds = new Set<number>();\n for (const { field, start, end } of fields) {\n const matches = questions.filter(q => q.virt_field_name === field);\n const parent = matches[0];\n if (matches.length !== 1 || !parent || parent.question_type !== \"sub_assessment\" || !Array.isArray(parent.sub_assessment_answer_list)) throw new WellSkyError(\"protocol\", `verification group ${field}`);\n const group: VerificationGroupSnapshot = { fieldName: field, records: [], excluded: [] };\n for (const raw of parent.sub_assessment_answer_list) {\n const id = raw.recordset_id;\n if (typeof id !== \"number\" || !Number.isSafeInteger(id) || id < 1 || seenIds.has(id)) throw new WellSkyError(\"protocol\", \"verification record identity\");\n seenIds.add(id);\n const record: VerificationRecord = { ...structuredClone(raw), recordset_id: id };\n const startValue = recordDate(record, start), endValue = recordDate(record, end);\n const from = verificationInstant(startValue), through = endValue === null ? null : verificationInstant(endValue);\n if (from === undefined || through === undefined || (through !== null && through < from)) throw new WellSkyError(\"protocol\", `verification interval ${field}`);\n if (from > at) group.excluded.push({ record, reason: \"not_started\" });\n else if (through !== null && through < at) group.excluded.push({ record, reason: \"ended\" });\n else group.records.push(record);\n }\n groups.push(group);\n }\n return { clientId: input.clientId, assessmentCode: input.assessmentCode, enrollmentDate: input.enrollmentDate, source: \"current-assessment\", groups };\n}\n"]}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { WellSkyError } from "./runtime.js";
|
|
2
|
+
export declare class TenantMismatchError extends WellSkyError {
|
|
3
|
+
constructor(operation: string);
|
|
4
|
+
}
|
|
5
|
+
export declare class AuthError extends WellSkyError {
|
|
6
|
+
constructor(operation: string, status?: number);
|
|
7
|
+
}
|
|
8
|
+
export declare class ThrottledError extends WellSkyError {
|
|
9
|
+
constructor(operation: string, retryAfterMs: number, status?: number, requestId?: string);
|
|
10
|
+
}
|
|
11
|
+
export declare class CooldownError extends WellSkyError {
|
|
12
|
+
readonly until: string;
|
|
13
|
+
constructor(operation: string, until: number);
|
|
14
|
+
}
|
|
15
|
+
export declare class ValidationError extends WellSkyError {
|
|
16
|
+
readonly fields: readonly string[];
|
|
17
|
+
constructor(operation: string, fields?: readonly string[]);
|
|
18
|
+
}
|
|
19
|
+
export declare class UpstreamError extends WellSkyError {
|
|
20
|
+
constructor(operation: string, status: number, requestId?: string, retryAfterMs?: number);
|
|
21
|
+
}
|
|
22
|
+
export declare class AmbiguousCommitError extends WellSkyError {
|
|
23
|
+
constructor(operation: string);
|
|
24
|
+
}
|
|
25
|
+
export declare class DefinitionDriftError extends WellSkyError {
|
|
26
|
+
readonly fields: readonly string[];
|
|
27
|
+
constructor(fields: readonly string[]);
|
|
28
|
+
}
|
|
29
|
+
export declare class UnknownPicklistValueError extends WellSkyError {
|
|
30
|
+
readonly field: string;
|
|
31
|
+
constructor(field: string);
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,qBAAa,mBAAoB,SAAQ,YAAY;gBACvC,SAAS,EAAE,MAAM;CAC9B;AACD,qBAAa,SAAU,SAAQ,YAAY;gBAC7B,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM;CAC/C;AACD,qBAAa,cAAe,SAAQ,YAAY;gBAClC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,SAAM,EAAE,SAAS,CAAC,EAAE,MAAM;CACtF;AACD,qBAAa,aAAc,SAAQ,YAAY;IAC7C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;gBACX,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;CAC7C;AACD,qBAAa,eAAgB,SAAQ,YAAY;IAC/C,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;gBACvB,SAAS,EAAE,MAAM,EAAE,MAAM,GAAE,SAAS,MAAM,EAAO;CAC9D;AACD,qBAAa,aAAc,SAAQ,YAAY;gBACjC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM;CACzF;AACD,qBAAa,oBAAqB,SAAQ,YAAY;gBACxC,SAAS,EAAE,MAAM;CAC9B;AACD,qBAAa,oBAAqB,SAAQ,YAAY;IACpD,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;gBACvB,MAAM,EAAE,SAAS,MAAM,EAAE;CACtC;AACD,qBAAa,yBAA0B,SAAQ,YAAY;IACzD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;gBACX,KAAK,EAAE,MAAM;CAC1B"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { WellSkyError } from "./runtime.js";
|
|
2
|
+
export class TenantMismatchError extends WellSkyError {
|
|
3
|
+
constructor(operation) { super("tenant_mismatch", operation); this.name = "TenantMismatchError"; }
|
|
4
|
+
}
|
|
5
|
+
export class AuthError extends WellSkyError {
|
|
6
|
+
constructor(operation, status) { super("auth", operation, status === undefined ? {} : { status }); this.name = "AuthError"; }
|
|
7
|
+
}
|
|
8
|
+
export class ThrottledError extends WellSkyError {
|
|
9
|
+
constructor(operation, retryAfterMs, status = 429, requestId) { super("throttled", operation, { status, retryAfterMs, ...(requestId === undefined ? {} : { requestId }) }); this.name = "ThrottledError"; }
|
|
10
|
+
}
|
|
11
|
+
export class CooldownError extends WellSkyError {
|
|
12
|
+
until;
|
|
13
|
+
constructor(operation, until) { super("cooldown", operation); this.name = "CooldownError"; this.until = new Date(until).toISOString(); }
|
|
14
|
+
}
|
|
15
|
+
export class ValidationError extends WellSkyError {
|
|
16
|
+
fields;
|
|
17
|
+
constructor(operation, fields = []) { super("validation", operation); this.name = "ValidationError"; this.fields = [...fields]; }
|
|
18
|
+
}
|
|
19
|
+
export class UpstreamError extends WellSkyError {
|
|
20
|
+
constructor(operation, status, requestId, retryAfterMs) { super("http", operation, { status, ...(requestId === undefined ? {} : { requestId }), ...(retryAfterMs === undefined ? {} : { retryAfterMs }) }); this.name = "UpstreamError"; }
|
|
21
|
+
}
|
|
22
|
+
export class AmbiguousCommitError extends WellSkyError {
|
|
23
|
+
constructor(operation) { super("ambiguous_commit", operation); this.name = "AmbiguousCommitError"; }
|
|
24
|
+
}
|
|
25
|
+
export class DefinitionDriftError extends WellSkyError {
|
|
26
|
+
fields;
|
|
27
|
+
constructor(fields) { super("definition_drift", "assessment metadata"); this.name = "DefinitionDriftError"; this.fields = [...fields]; }
|
|
28
|
+
}
|
|
29
|
+
export class UnknownPicklistValueError extends WellSkyError {
|
|
30
|
+
field;
|
|
31
|
+
constructor(field) { super("unknown_picklist_value", "picklist resolution"); this.name = "UnknownPicklistValueError"; this.field = field; }
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"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","sourcesContent":["import { WellSkyError } from \"./runtime.js\";\n\nexport class TenantMismatchError extends WellSkyError {\n constructor(operation: string) { super(\"tenant_mismatch\", operation); this.name = \"TenantMismatchError\"; }\n}\nexport class AuthError extends WellSkyError {\n constructor(operation: string, status?: number) { super(\"auth\", operation, status === undefined ? {} : { status }); this.name = \"AuthError\"; }\n}\nexport class ThrottledError extends WellSkyError {\n constructor(operation: string, retryAfterMs: number, status = 429, requestId?: string) { super(\"throttled\", operation, { status, retryAfterMs, ...(requestId === undefined ? {} : { requestId }) }); this.name = \"ThrottledError\"; }\n}\nexport class CooldownError extends WellSkyError {\n readonly until: string;\n constructor(operation: string, until: number) { super(\"cooldown\", operation); this.name = \"CooldownError\"; this.until = new Date(until).toISOString(); }\n}\nexport class ValidationError extends WellSkyError {\n readonly fields: readonly string[];\n constructor(operation: string, fields: readonly string[] = []) { super(\"validation\", operation); this.name = \"ValidationError\"; this.fields = [...fields]; }\n}\nexport class UpstreamError extends WellSkyError {\n constructor(operation: string, status: number, requestId?: string, retryAfterMs?: number) { super(\"http\", operation, { status, ...(requestId === undefined ? {} : { requestId }), ...(retryAfterMs === undefined ? {} : { retryAfterMs }) }); this.name = \"UpstreamError\"; }\n}\nexport class AmbiguousCommitError extends WellSkyError {\n constructor(operation: string) { super(\"ambiguous_commit\", operation); this.name = \"AmbiguousCommitError\"; }\n}\nexport class DefinitionDriftError extends WellSkyError {\n readonly fields: readonly string[];\n constructor(fields: readonly string[]) { super(\"definition_drift\", \"assessment metadata\"); this.name = \"DefinitionDriftError\"; this.fields = [...fields]; }\n}\nexport class UnknownPicklistValueError extends WellSkyError {\n readonly field: string;\n constructor(field: string) { super(\"unknown_picklist_value\", \"picklist resolution\"); this.name = \"UnknownPicklistValueError\"; this.field = field; }\n}\n"]}
|