@ttt-productions/ttt-core 0.78.23 → 0.78.25
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/constants/app-mode.d.ts +1 -0
- package/dist/constants/app-mode.d.ts.map +1 -1
- package/dist/constants/app-mode.js +11 -0
- package/dist/constants/app-mode.js.map +1 -1
- package/dist/constants/business-user.d.ts +1 -1
- package/dist/constants/business-user.js +1 -1
- package/dist/constants/business-user.js.map +1 -1
- package/dist/constants/release-flags.d.ts +2 -2
- package/dist/constants/release-flags.d.ts.map +1 -1
- package/dist/constants/release-flags.js +2 -2
- package/dist/constants/release-flags.js.map +1 -1
- package/dist/doc-schemas/chat-sync.d.ts.map +1 -1
- package/dist/doc-schemas/chat-sync.js +3 -2
- package/dist/doc-schemas/chat-sync.js.map +1 -1
- package/dist/doc-schemas/commissions.d.ts +14 -11
- package/dist/doc-schemas/commissions.d.ts.map +1 -1
- package/dist/doc-schemas/commissions.js +14 -4
- package/dist/doc-schemas/commissions.js.map +1 -1
- package/dist/doc-schemas/media-activation-jobs.d.ts.map +1 -1
- package/dist/doc-schemas/media-activation-jobs.js +4 -3
- package/dist/doc-schemas/media-activation-jobs.js.map +1 -1
- package/dist/doc-schemas/media-assets.d.ts +2 -2
- package/dist/doc-schemas/media-assets.d.ts.map +1 -1
- package/dist/doc-schemas/media-assets.js +5 -4
- package/dist/doc-schemas/media-assets.js.map +1 -1
- package/dist/doc-schemas/messaging.d.ts.map +1 -1
- package/dist/doc-schemas/messaging.js +3 -2
- package/dist/doc-schemas/messaging.js.map +1 -1
- package/dist/doc-schemas/ncii/allegations.js +3 -3
- package/dist/doc-schemas/ncii/allegations.js.map +1 -1
- package/dist/doc-schemas/ncii/cases.d.ts.map +1 -1
- package/dist/doc-schemas/ncii/cases.js +4 -3
- package/dist/doc-schemas/ncii/cases.js.map +1 -1
- package/dist/doc-schemas/ncii/config.d.ts.map +1 -1
- package/dist/doc-schemas/ncii/config.js +4 -3
- package/dist/doc-schemas/ncii/config.js.map +1 -1
- package/dist/doc-schemas/ncii/holds.js +3 -3
- package/dist/doc-schemas/ncii/holds.js.map +1 -1
- package/dist/doc-schemas/ncii/removal.js +3 -3
- package/dist/doc-schemas/ncii/removal.js.map +1 -1
- package/dist/doc-schemas/ncii/requests.d.ts.map +1 -1
- package/dist/doc-schemas/ncii/requests.js +4 -3
- package/dist/doc-schemas/ncii/requests.js.map +1 -1
- package/dist/doc-schemas/notification-ledger.d.ts.map +1 -1
- package/dist/doc-schemas/notification-ledger.js +3 -1
- package/dist/doc-schemas/notification-ledger.js.map +1 -1
- package/dist/doc-schemas/payments.d.ts.map +1 -1
- package/dist/doc-schemas/payments.js +2 -1
- package/dist/doc-schemas/payments.js.map +1 -1
- package/dist/doc-schemas/registry.d.ts +108 -35
- package/dist/doc-schemas/registry.d.ts.map +1 -1
- package/dist/doc-schemas/registry.js +4 -0
- package/dist/doc-schemas/registry.js.map +1 -1
- package/dist/doc-schemas/safety/age.d.ts.map +1 -1
- package/dist/doc-schemas/safety/age.js +4 -3
- package/dist/doc-schemas/safety/age.js.map +1 -1
- package/dist/doc-schemas/safety/case-aliases.d.ts.map +1 -1
- package/dist/doc-schemas/safety/case-aliases.js +5 -4
- package/dist/doc-schemas/safety/case-aliases.js.map +1 -1
- package/dist/doc-schemas/safety/case.d.ts.map +1 -1
- package/dist/doc-schemas/safety/case.js +4 -3
- package/dist/doc-schemas/safety/case.js.map +1 -1
- package/dist/doc-schemas/safety/evidence.js +3 -3
- package/dist/doc-schemas/safety/evidence.js.map +1 -1
- package/dist/doc-schemas/safety/foundation.d.ts.map +1 -1
- package/dist/doc-schemas/safety/foundation.js +5 -3
- package/dist/doc-schemas/safety/foundation.js.map +1 -1
- package/dist/doc-schemas/safety/holds.d.ts.map +1 -1
- package/dist/doc-schemas/safety/holds.js +4 -3
- package/dist/doc-schemas/safety/holds.js.map +1 -1
- package/dist/doc-schemas/safety/monitors.d.ts.map +1 -1
- package/dist/doc-schemas/safety/monitors.js +5 -3
- package/dist/doc-schemas/safety/monitors.js.map +1 -1
- package/dist/doc-schemas/safety/provenance.js +3 -3
- package/dist/doc-schemas/safety/provenance.js.map +1 -1
- package/dist/doc-schemas/safety/report.d.ts.map +1 -1
- package/dist/doc-schemas/safety/report.js +4 -3
- package/dist/doc-schemas/safety/report.js.map +1 -1
- package/dist/doc-schemas/safety/sagas.js +3 -3
- package/dist/doc-schemas/safety/sagas.js.map +1 -1
- package/dist/doc-schemas/social.d.ts +130 -0
- package/dist/doc-schemas/social.d.ts.map +1 -1
- package/dist/doc-schemas/social.js +91 -2
- package/dist/doc-schemas/social.js.map +1 -1
- package/dist/doc-schemas/square-announcement-jobs.d.ts +306 -14
- package/dist/doc-schemas/square-announcement-jobs.d.ts.map +1 -1
- package/dist/doc-schemas/square-announcement-jobs.js +15 -2
- package/dist/doc-schemas/square-announcement-jobs.js.map +1 -1
- package/dist/doc-schemas/user.js +3 -3
- package/dist/doc-schemas/user.js.map +1 -1
- package/dist/doc-schemas/work-project.js +2 -2
- package/dist/doc-schemas/work-project.js.map +1 -1
- package/dist/ids/chat-ids.d.ts +3 -2
- package/dist/ids/chat-ids.d.ts.map +1 -1
- package/dist/ids/chat-ids.js +3 -2
- package/dist/ids/chat-ids.js.map +1 -1
- package/dist/media/domain-events-admin.d.ts +0 -7
- package/dist/media/domain-events-admin.d.ts.map +1 -1
- package/dist/media/domain-events-admin.js +0 -11
- package/dist/media/domain-events-admin.js.map +1 -1
- package/dist/media/domain-events.d.ts +0 -6
- package/dist/media/domain-events.d.ts.map +1 -1
- package/dist/media/domain-events.js +1 -2
- package/dist/media/domain-events.js.map +1 -1
- package/dist/media/hall-library-target-fields.js +1 -1
- package/dist/media/hall-library-target-fields.js.map +1 -1
- package/dist/media/pending-media.d.ts +0 -54
- package/dist/media/pending-media.d.ts.map +1 -1
- package/dist/media/photodna-coverage.d.ts.map +1 -1
- package/dist/media/photodna-coverage.js +5 -3
- package/dist/media/photodna-coverage.js.map +1 -1
- package/dist/paths/related-ids.js +1 -1
- package/dist/paths/related-ids.js.map +1 -1
- package/dist/safety/ncii-intake-derivations.d.ts.map +1 -1
- package/dist/safety/ncii-intake-derivations.js +4 -2
- package/dist/safety/ncii-intake-derivations.js.map +1 -1
- package/dist/safety/resource-keys.d.ts.map +1 -1
- package/dist/safety/resource-keys.js +2 -1
- package/dist/safety/resource-keys.js.map +1 -1
- package/dist/schemas/chat.js +3 -3
- package/dist/schemas/chat.js.map +1 -1
- package/dist/schemas/ncii.js +1 -1
- package/dist/schemas/ncii.js.map +1 -1
- package/dist/schemas/notification.d.ts +8 -8
- package/dist/schemas/notification.d.ts.map +1 -1
- package/dist/schemas/notification.js +17 -11
- package/dist/schemas/notification.js.map +1 -1
- package/dist/types/social.d.ts +1 -45
- package/dist/types/social.d.ts.map +1 -1
- package/dist/types/social.js.map +1 -1
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"removal.js","sourceRoot":"","sources":["../../../src/doc-schemas/ncii/removal.ts"],"names":[],"mappings":"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","sourcesContent":["// Trust & Safety — NCII per-request removal deadline + durable removal saga\n// (Appendix A §A11 [H4]).\n//\n// The removal job is REQUEST-scoped, not case-scoped: the deadline monitor lives\n// at `safetySlaMonitors/{requestId}__nciiRemovalDeadline` and a monitor can never\n// be resolved by finishing a DIFFERENT linked request. The case-level\n// `nciiRemovalDeadlineAt` MAY mirror the minimum active deadline but is NOT the\n// source of truth.\n//\n// COMPLETION PREDICATE [H4]: completion is derived ONLY from verified target rows\n// + approved legal outcomes — a request is `completed` ONLY when the reported\n// target AND every known identical copy reaches `verificationState='verifiedGone'`\n// OR carries an approved `NciiTerminalException`. A partial technical failure is\n// the HONEST outcome `unableToComplete` (technical) or\n// `completedWithApprovedException` (counsel-approved) — NEVER ordinary `completed`.\n// A worker crash resumes idempotently (replay is idempotent by `targetKeyHash` +\n// the job's deterministic `jobId`); a `leftover`/`failed` target re-drives from\n// its last unverified sub-state.\n//\n// Every shape here is transcribed verbatim from docs/code_changes_needed/\n// trust-and-safety/IMPLEMENTATION_PLAN.md Appendix A §A11 [H4] — no invented\n// values, no placeholders.\n//\n// SHARED enums + the locator come from ../safety/foundation.js (the single source\n// for every cross-cluster enum); they are NEVER redefined here. This cluster\n// IMPORTS NciiTargetSurfaceSchema, NciiTargetOutcomeSchema, and TargetLocatorV1Schema.\n//\n// Collection note: this cluster introduces NEW Firestore collections (+ one child\n// subcollection under `nciiRemovalJobs`); wiring collections.ts / path-builders.ts\n// / registry.ts is deferred to the app leg (the orchestrator binds the schemas +\n// path builders there); the deterministic doc-id shapes are documented on each\n// schema below.\n\nimport { z } from 'zod';\nimport {\n NciiTargetSurfaceSchema,\n NciiTargetOutcomeSchema,\n TargetLocatorV1Schema,\n} from '../safety/foundation.js';\n\n// ===========================================================================\n// §A11 [H4] — phase / status vocabularies for the removal saga\n// ===========================================================================\n\n/** The removal saga phase progression. `denyServing` precedes\n * `removeOrTombstone`; `verifyRemoval` precedes `complete`. */\nexport const NciiRemovalPhaseSchema = z.enum([\n 'resolveTargets',\n 'discoverKnownCopies',\n 'denyServing',\n 'removeOrTombstone',\n 'writeHashBlocks',\n 'verifyRemoval',\n 'complete',\n]);\nexport type NciiRemovalPhase = z.infer<typeof NciiRemovalPhaseSchema>;\n\n/** Top-level durable run status of the removal job. */\nexport const NciiRemovalStatusSchema = z.enum([\n 'pending',\n 'running',\n 'retryableFailure',\n 'deadLetter',\n 'completed',\n]);\nexport type NciiRemovalStatus = z.infer<typeof NciiRemovalStatusSchema>;\n\n// ===========================================================================\n// §A11 [H4] — NciiDiscoveryCursorV1 (typed resumable discovery cursor — never an\n// untyped blob). Embedded on NciiRemovalJobV1.cursor.\n// ===========================================================================\n\n/** Typed resumable discovery cursor. `phase` mirrors the job phase enum;\n * `lastSurface` is the cross-cluster NciiTargetSurface. */\nexport const NciiDiscoveryCursorV1Schema = z.object({\n phase: NciiRemovalPhaseSchema,\n lastSurface: NciiTargetSurfaceSchema,\n lastCursorToken: z.string().min(1).optional(),\n}).strict();\nexport type NciiDiscoveryCursorV1 = z.infer<typeof NciiDiscoveryCursorV1Schema>;\n\n// ===========================================================================\n// §A11 [H4] — nciiRemovalJobs/{jobId}\n// Deterministic `jobId = sha256('ncii-removal-v1:' + requestId + ':' + caseId +\n// ':' + generation)` (racing workers create the SAME job — idempotent).\n// ===========================================================================\n\n/** `nciiRemovalJobs/{jobId}` — REQUEST-scoped durable removal saga. Doc id\n * `jobId` is deterministic:\n * `sha256('ncii-removal-v1:' + requestId + ':' + caseId + ':' + generation)`\n * (racing workers create the same job). */\nexport const NciiRemovalJobV1Schema = z.object({\n schemaVersion: z.literal(1),\n // = sha256('ncii-removal-v1:' + requestId + ':' + caseId + ':' + generation)\n jobId: z.string().min(1),\n caseId: z.string().min(1),\n requestId: z.string().min(1),\n generation: z.number(),\n phase: NciiRemovalPhaseSchema,\n status: NciiRemovalStatusSchema,\n // typed resumable discovery cursor — never an untyped blob\n cursor: NciiDiscoveryCursorV1Schema.optional(),\n leaseOwner: z.string().min(1).optional(),\n leaseExpiresAt: z.number().optional(),\n attemptCount: z.number(),\n nextAttemptAt: z.number().optional(),\n lastErrorCode: z.string().optional(),\n createdAt: z.number(),\n updatedAt: z.number(),\n completedAt: z.number().optional(),\n deadLetterAt: z.number().optional(),\n}).strict();\nexport type NciiRemovalJobV1 = z.infer<typeof NciiRemovalJobV1Schema>;\n\n// ===========================================================================\n// §A11 [H4] — nciiRemovalJobs/{jobId}/targets/{targetKeyHash}\n// Per-target child row. `targetKeyHash` is the deterministic id derived from the\n// canonical locator. Per-target transitions are independent sub-state machines.\n// ===========================================================================\n\n/** Serving-deny sub-state. */\nexport const NciiTargetServingDenyStateSchema = z.enum(['pending', 'denied', 'failed']);\nexport type NciiTargetServingDenyState = z.infer<typeof NciiTargetServingDenyStateSchema>;\n\n/** Removal sub-state. */\nexport const NciiTargetRemovalStateSchema = z.enum(['pending', 'removed', 'tombstoned', 'failed']);\nexport type NciiTargetRemovalState = z.infer<typeof NciiTargetRemovalStateSchema>;\n\n/** Verification sub-state. */\nexport const NciiTargetVerificationStateSchema = z.enum(['pending', 'verifiedGone', 'leftover']);\nexport type NciiTargetVerificationState = z.infer<typeof NciiTargetVerificationStateSchema>;\n\n/** `nciiRemovalJobs/{jobId}/targets/{targetKeyHash}` — per-target removal row.\n * Doc id `targetKeyHash` is the deterministic id from the canonical locator.\n * Per-target transitions: `servingDeny (pending→denied | failed)`;\n * `removal (pending→removed | tombstoned | failed)`;\n * `verification (pending→verifiedGone | leftover)`. */\nexport const NciiRemovalTargetV1Schema = z.object({\n // deterministic id from the canonical locator\n targetKeyHash: z.string().min(1),\n locator: TargetLocatorV1Schema,\n surface: NciiTargetSurfaceSchema,\n expectedGeneration: z.number().optional(),\n servingDenyState: NciiTargetServingDenyStateSchema,\n removalState: NciiTargetRemovalStateSchema,\n verificationState: NciiTargetVerificationStateSchema,\n outcome: NciiTargetOutcomeSchema,\n attemptCount: z.number(),\n leaseOwner: z.string().min(1).optional(),\n leaseExpiresAt: z.number().optional(),\n lastErrorCode: z.string().optional(),\n updatedAt: z.number(),\n}).strict();\nexport type NciiRemovalTargetV1 = z.infer<typeof NciiRemovalTargetV1Schema>;\n"]}
|
|
1
|
+
{"version":3,"file":"removal.js","sourceRoot":"","sources":["../../../src/doc-schemas/ncii/removal.ts"],"names":[],"mappings":"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","sourcesContent":["// Trust & Safety — NCII per-request removal deadline + durable removal saga\n// (Appendix A §A11 [H4]).\n//\n// The removal job is REQUEST-scoped, not case-scoped: the deadline monitor lives\n// at `safetySlaMonitors/{requestId}__nciiRemovalDeadline` and a monitor can never\n// be resolved by finishing a DIFFERENT linked request. The case-level\n// `nciiRemovalDeadlineAt` MAY mirror the minimum active deadline but is NOT the\n// source of truth.\n//\n// COMPLETION PREDICATE [H4]: completion is derived ONLY from verified target rows\n// + approved legal outcomes — a request is `completed` ONLY when the reported\n// target AND every known identical copy reaches `verificationState='verifiedGone'`\n// OR carries an approved `NciiTerminalException`. A partial technical failure is\n// the HONEST outcome `unableToComplete` (technical) or\n// `completedWithApprovedException` (counsel-approved) — NEVER ordinary `completed`.\n// A worker crash resumes idempotently (replay is idempotent by `targetKeyHash` +\n// the job's deterministic `jobId`); a `leftover`/`failed` target re-drives from\n// its last unverified sub-state.\n//\n// Every shape here is transcribed verbatim from the frozen Trust & Safety spec\n// (Appendix A §A11 [H4]) — no invented values, no placeholders; the durable design\n// owner is ttt-prod docs/design/nonconsensual-intimate-imagery-and-take-it-down.md.\n//\n// SHARED enums + the locator come from ../safety/foundation.js (the single source\n// for every cross-cluster enum); they are NEVER redefined here. This cluster\n// IMPORTS NciiTargetSurfaceSchema, NciiTargetOutcomeSchema, and TargetLocatorV1Schema.\n//\n// Collection note: this cluster introduces NEW Firestore collections (+ one child\n// subcollection under `nciiRemovalJobs`); wiring collections.ts / path-builders.ts\n// / registry.ts is deferred to the app leg (the orchestrator binds the schemas +\n// path builders there); the deterministic doc-id shapes are documented on each\n// schema below.\n\nimport { z } from 'zod';\nimport {\n NciiTargetSurfaceSchema,\n NciiTargetOutcomeSchema,\n TargetLocatorV1Schema,\n} from '../safety/foundation.js';\n\n// ===========================================================================\n// §A11 [H4] — phase / status vocabularies for the removal saga\n// ===========================================================================\n\n/** The removal saga phase progression. `denyServing` precedes\n * `removeOrTombstone`; `verifyRemoval` precedes `complete`. */\nexport const NciiRemovalPhaseSchema = z.enum([\n 'resolveTargets',\n 'discoverKnownCopies',\n 'denyServing',\n 'removeOrTombstone',\n 'writeHashBlocks',\n 'verifyRemoval',\n 'complete',\n]);\nexport type NciiRemovalPhase = z.infer<typeof NciiRemovalPhaseSchema>;\n\n/** Top-level durable run status of the removal job. */\nexport const NciiRemovalStatusSchema = z.enum([\n 'pending',\n 'running',\n 'retryableFailure',\n 'deadLetter',\n 'completed',\n]);\nexport type NciiRemovalStatus = z.infer<typeof NciiRemovalStatusSchema>;\n\n// ===========================================================================\n// §A11 [H4] — NciiDiscoveryCursorV1 (typed resumable discovery cursor — never an\n// untyped blob). Embedded on NciiRemovalJobV1.cursor.\n// ===========================================================================\n\n/** Typed resumable discovery cursor. `phase` mirrors the job phase enum;\n * `lastSurface` is the cross-cluster NciiTargetSurface. */\nexport const NciiDiscoveryCursorV1Schema = z.object({\n phase: NciiRemovalPhaseSchema,\n lastSurface: NciiTargetSurfaceSchema,\n lastCursorToken: z.string().min(1).optional(),\n}).strict();\nexport type NciiDiscoveryCursorV1 = z.infer<typeof NciiDiscoveryCursorV1Schema>;\n\n// ===========================================================================\n// §A11 [H4] — nciiRemovalJobs/{jobId}\n// Deterministic `jobId = sha256('ncii-removal-v1:' + requestId + ':' + caseId +\n// ':' + generation)` (racing workers create the SAME job — idempotent).\n// ===========================================================================\n\n/** `nciiRemovalJobs/{jobId}` — REQUEST-scoped durable removal saga. Doc id\n * `jobId` is deterministic:\n * `sha256('ncii-removal-v1:' + requestId + ':' + caseId + ':' + generation)`\n * (racing workers create the same job). */\nexport const NciiRemovalJobV1Schema = z.object({\n schemaVersion: z.literal(1),\n // = sha256('ncii-removal-v1:' + requestId + ':' + caseId + ':' + generation)\n jobId: z.string().min(1),\n caseId: z.string().min(1),\n requestId: z.string().min(1),\n generation: z.number(),\n phase: NciiRemovalPhaseSchema,\n status: NciiRemovalStatusSchema,\n // typed resumable discovery cursor — never an untyped blob\n cursor: NciiDiscoveryCursorV1Schema.optional(),\n leaseOwner: z.string().min(1).optional(),\n leaseExpiresAt: z.number().optional(),\n attemptCount: z.number(),\n nextAttemptAt: z.number().optional(),\n lastErrorCode: z.string().optional(),\n createdAt: z.number(),\n updatedAt: z.number(),\n completedAt: z.number().optional(),\n deadLetterAt: z.number().optional(),\n}).strict();\nexport type NciiRemovalJobV1 = z.infer<typeof NciiRemovalJobV1Schema>;\n\n// ===========================================================================\n// §A11 [H4] — nciiRemovalJobs/{jobId}/targets/{targetKeyHash}\n// Per-target child row. `targetKeyHash` is the deterministic id derived from the\n// canonical locator. Per-target transitions are independent sub-state machines.\n// ===========================================================================\n\n/** Serving-deny sub-state. */\nexport const NciiTargetServingDenyStateSchema = z.enum(['pending', 'denied', 'failed']);\nexport type NciiTargetServingDenyState = z.infer<typeof NciiTargetServingDenyStateSchema>;\n\n/** Removal sub-state. */\nexport const NciiTargetRemovalStateSchema = z.enum(['pending', 'removed', 'tombstoned', 'failed']);\nexport type NciiTargetRemovalState = z.infer<typeof NciiTargetRemovalStateSchema>;\n\n/** Verification sub-state. */\nexport const NciiTargetVerificationStateSchema = z.enum(['pending', 'verifiedGone', 'leftover']);\nexport type NciiTargetVerificationState = z.infer<typeof NciiTargetVerificationStateSchema>;\n\n/** `nciiRemovalJobs/{jobId}/targets/{targetKeyHash}` — per-target removal row.\n * Doc id `targetKeyHash` is the deterministic id from the canonical locator.\n * Per-target transitions: `servingDeny (pending→denied | failed)`;\n * `removal (pending→removed | tombstoned | failed)`;\n * `verification (pending→verifiedGone | leftover)`. */\nexport const NciiRemovalTargetV1Schema = z.object({\n // deterministic id from the canonical locator\n targetKeyHash: z.string().min(1),\n locator: TargetLocatorV1Schema,\n surface: NciiTargetSurfaceSchema,\n expectedGeneration: z.number().optional(),\n servingDenyState: NciiTargetServingDenyStateSchema,\n removalState: NciiTargetRemovalStateSchema,\n verificationState: NciiTargetVerificationStateSchema,\n outcome: NciiTargetOutcomeSchema,\n attemptCount: z.number(),\n leaseOwner: z.string().min(1).optional(),\n leaseExpiresAt: z.number().optional(),\n lastErrorCode: z.string().optional(),\n updatedAt: z.number(),\n}).strict();\nexport type NciiRemovalTargetV1 = z.infer<typeof NciiRemovalTargetV1Schema>;\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"requests.d.ts","sourceRoot":"","sources":["../../../src/doc-schemas/ncii/requests.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"requests.d.ts","sourceRoot":"","sources":["../../../src/doc-schemas/ncii/requests.ts"],"names":[],"mappings":"AAsCA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAaL,KAAK,mBAAmB,EACxB,KAAK,uBAAuB,EAC7B,MAAM,yBAAyB,CAAC;AASjC,eAAO,MAAM,6BAA6B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAuB/B,CAAC;AACZ,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC;AAQpF,sEAAsE;AACtE,eAAO,MAAM,+BAA+B;;;EAA0C,CAAC;AACvF,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,+BAA+B,CAAC,CAAC;AAExF,oFAAoF;AACpF,eAAO,MAAM,qCAAqC;;;;;;;kBAIvC,CAAC;AACZ,MAAM,MAAM,+BAA+B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qCAAqC,CAAC,CAAC;AAEpG;;;;;;iFAMiF;AACjF,eAAO,MAAM,8BAA8B;;;;;;EAMzC,CAAC;AACH,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,8BAA8B,CAAC,CAAC;AAEtF;;8EAE8E;AAC9E,eAAO,MAAM,+BAA+B;;;;;;;;;;;kBAKjC,CAAC;AACZ,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,+BAA+B,CAAC,CAAC;AAExF;;;;;iBAKiB;AACjB,eAAO,MAAM,0CAA0C;;;;;;;;;;;;;;;;;kBAM5C,CAAC;AACZ,MAAM,MAAM,oCAAoC,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0CAA0C,CAAC,CAAC;AAE9G;;kBAEkB;AAClB,eAAO,MAAM,kCAAkC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAmBpC,CAAC;AACZ,MAAM,MAAM,4BAA4B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kCAAkC,CAAC,CAAC;AAQ9F,gCAAgC;AAChC,eAAO,MAAM,mCAAmC;;;;EAA8C,CAAC;AAC/F,MAAM,MAAM,6BAA6B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mCAAmC,CAAC,CAAC;AAEhG;oFACoF;AACpF,eAAO,MAAM,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAY9B,CAAC;AACZ,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAC;AASlF;sBACsB;AACtB,eAAO,MAAM,sCAAsC;;;;EAAiD,CAAC;AACrG,MAAM,MAAM,gCAAgC,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sCAAsC,CAAC,CAAC;AAEtG;;gCAEgC;AAChC,eAAO,MAAM,kCAAkC;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAYpC,CAAC;AACZ,MAAM,MAAM,4BAA4B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kCAAkC,CAAC,CAAC;AAQ9F;sEACsE;AACtE,eAAO,MAAM,+BAA+B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAUjC,CAAC;AACZ,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,+BAA+B,CAAC,CAAC;AAiBxF;;;;4DAI4D;AAC5D,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;kBAe5B,CAAC;AACZ,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAY9E,sEAAsE;AACtE,eAAO,MAAM,gCAAgC;;;;;;;;EAQ3C,CAAC;AACH,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gCAAgC,CAAC,CAAC;AAE1F;4EAC4E;AAC5E,eAAO,MAAM,qCAAqC;;;;;;;;;;;;;;;;;;;;kBAavC,CAAC;AACZ,MAAM,MAAM,+BAA+B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qCAAqC,CAAC,CAAC;AASpG,qFAAqF;AACrF,eAAO,MAAM,oCAAoC,sIAOE,CAAC;AAEpD;;;yEAGyE;AACzE,eAAO,MAAM,8CAA8C,kLAIR,CAAC;AAEpD;wDACwD;AACxD,eAAO,MAAM,0BAA0B,2CAGY,CAAC;AAEpD;;;;;;wFAMwF;AACxF,wBAAgB,kBAAkB,CAChC,aAAa,EAAE,uBAAuB,GACrC,SAAS,mBAAmB,EAAE,CAIhC;AAED;;;;;;;;;+DAS+D;AAC/D,wBAAgB,mBAAmB,CAAC,KAAK,EAAE;IACzC,aAAa,EAAE,uBAAuB,CAAC;IACvC,kBAAkB,EAAE,SAAS,mBAAmB,EAAE,CAAC;CACpD,GAAG;IAAE,MAAM,EAAE,YAAY,GAAG,UAAU,CAAC;IAAC,iBAAiB,EAAE,mBAAmB,EAAE,CAAA;CAAE,CAelF;AAYD;2DAC2D;AAC3D,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,aAAa,EAAE,uBAAuB,CAAC;IAChD,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,mBAAmB,CAAC,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/E,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAC1C,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC;mFAC+E;IAC/E,QAAQ,CAAC,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAC1C;yEACqE;IACrE,QAAQ,CAAC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IACvC,+EAA+E;IAC/E,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;CAC9B;AAMD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,eAAe,GAAG,mBAAmB,EAAE,CAqBhF;AAED,wFAAwF;AACxF,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,MAAM,EAAE,YAAY,GAAG,UAAU,CAAC;IAC3C,QAAQ,CAAC,kBAAkB,EAAE,mBAAmB,EAAE,CAAC;IACnD,QAAQ,CAAC,iBAAiB,EAAE,mBAAmB,EAAE,CAAC;CACnD;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,eAAe,GAAG,uBAAuB,CAOlF"}
|
|
@@ -16,9 +16,10 @@
|
|
|
16
16
|
// intake `idempotencyKey` (like `nciiAuthorityEvidence/`), so no `statusProjection`
|
|
17
17
|
// collection-group lookup remains.
|
|
18
18
|
//
|
|
19
|
-
// Every shape here is transcribed verbatim from
|
|
20
|
-
//
|
|
21
|
-
//
|
|
19
|
+
// Every shape here is transcribed verbatim from the frozen Trust & Safety spec
|
|
20
|
+
// (Appendix A §A11 (2) + [C-02] + [F7] + [F10]) — no invented values, no
|
|
21
|
+
// placeholders; the durable design owner is ttt-prod
|
|
22
|
+
// docs/design/nonconsensual-intimate-imagery-and-take-it-down.md.
|
|
22
23
|
//
|
|
23
24
|
// SHARED enums + locator types come from ../safety/foundation.js (the single
|
|
24
25
|
// source for every cross-cluster enum); they are NEVER redefined here. This
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"requests.js","sourceRoot":"","sources":["../../../src/doc-schemas/ncii/requests.ts"],"names":[],"mappings":"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","sourcesContent":["// Trust & Safety — NCII statutory TAKE IT DOWN requests (Appendix A §A11, concept\n// (2)) — the SPLIT model: a PII-free root + a restricted requester-PII subdoc +\n// immutable submissions/validityDecisions + operator actions + isolated public\n// evidence uploads.\n//\n// Only a COMPLETE + VALID request can arm the 48h clock. The public no-login form\n// CANNOT submit a \"valid request\" without the required fields; validation\n// failures use the enumerated TakeItDownInvalidReasonCode. The root holds NO\n// requester PII / narrative / signature / authority — those live in the restricted\n// `/private/requester` subdoc.\n//\n// The public post-submission tracking tail (status page / status route / supplement\n// route / status token / public status projection) was removed (DJ 2026-07-02, feature\n// never wanted): the public flow is submit-only, so the status-token fields and the\n// `TakeItDownPublicStatusV1` projection no longer exist. Evidence folders re-key on the\n// intake `idempotencyKey` (like `nciiAuthorityEvidence/`), so no `statusProjection`\n// collection-group lookup remains.\n//\n// Every shape here is transcribed verbatim from docs/code_changes_needed/\n// trust-and-safety/IMPLEMENTATION_PLAN.md Appendix A §A11 (2) + [C-02] + [F7] +\n// [F10] — no invented values, no placeholders.\n//\n// SHARED enums + locator types come from ../safety/foundation.js (the single\n// source for every cross-cluster enum); they are NEVER redefined here. This\n// cluster IMPORTS TakeItDownRequesterRoleSchema, TargetLocatorSummaryV1Schema,\n// TakeItDownCompletenessStatusSchema, TakeItDownValidityStatusSchema,\n// TakeItDownInvalidReasonCodeSchema, TakeItDownPublicStatusSchema,\n// NciiRemovalCompletionOutcomeSchema, NciiActionTypeSchema, NciiActionResultSchema,\n// TakeItDownFieldCodeSchema, and SafetyReviewerCapabilitySchema.\n//\n// Collection note: this cluster introduces a NEW Firestore collection plus several\n// subcollections (private/requester, submissions, validityDecisions, actions,\n// evidence). Wiring collections.ts / path-builders.ts / registry.ts is deferred to\n// the app leg (the orchestrator binds the schemas + path builders there); the doc-id\n// shapes (including the deterministic intake requestId [H-07]) are documented on each\n// schema below.\n\nimport { z } from 'zod';\nimport { MAX_NCII_ACTION_SUMMARY_LENGTH } from '../../constants/business.js';\nimport {\n TakeItDownRequesterRoleSchema,\n TargetLocatorV1Schema,\n TargetLocatorSummaryV1Schema,\n TakeItDownCompletenessStatusSchema,\n TakeItDownValidityStatusSchema,\n TakeItDownInvalidReasonCodeSchema,\n TakeItDownPublicStatusSchema,\n NciiRemovalCompletionOutcomeSchema,\n NciiActionTypeSchema,\n NciiActionResultSchema,\n TakeItDownFieldCodeSchema,\n SafetyReviewerCapabilitySchema,\n type TakeItDownFieldCode,\n type TakeItDownRequesterRole,\n} from '../safety/foundation.js';\n\n// ===========================================================================\n// §A11 (2) [H1] — ROOT takeItDownRequests/{requestId} = TakeItDownRequestRootV1\n// (NO requester PII / narrative / signature / authority). [H-07] the intake\n// `requestId` is the deterministic sha256('takeItDownRequest:v1:' +\n// idempotencyKey + ':' + normalizedTargetKey) so retries resolve to one doc.\n// ===========================================================================\n\nexport const TakeItDownRequestRootV1Schema = z.object({\n schemaVersion: z.literal(1),\n requestId: z.string().min(1),\n caseId: z.string().min(1).optional(),\n requesterRole: TakeItDownRequesterRoleSchema,\n // privacy-safe summary ONLY — never the narrative\n targetLocatorSummary: TargetLocatorSummaryV1Schema,\n receivedAt: z.number(),\n completenessStatus: TakeItDownCompletenessStatusSchema, // 'incomplete' | 'complete'\n validityStatus: TakeItDownValidityStatusSchema, // 'pending' | 'valid' | 'invalid' | 'unableToLocate'\n invalidReasonCode: TakeItDownInvalidReasonCodeSchema.optional(),\n completenessDeterminedAt: z.number().optional(),\n validityDeterminedAt: z.number().optional(),\n completedBySubmissionId: z.string().min(1).optional(), // which immutable submission completed the request\n validRequestReceivedAt: z.number().optional(), // [F3] EARLIEST complete+valid receipt — pins the clock\n removalDeadlineAt: z.number().optional(), // = validRequestReceivedAt + 48h (non-authoritative projection; [H4])\n publicStatus: TakeItDownPublicStatusSchema,\n requestClosedAt: z.number().optional(), // when the request reached a terminal disposition\n removalCompletionAt: z.number().optional(), // [M-01] set when removal verified-completes\n finalClosedAt: z.number().optional(), // [H-08] = requestClosedAt (no appeal window); arms for EVERY terminal disposition. The request's retention clocks (PII / evidence / status-token) count from here.\n removalCompletionOutcome: NciiRemovalCompletionOutcomeSchema.optional(), // [H4] honest derived completion — NEVER 'completed' for a partial technical failure\n createdAt: z.number(),\n updatedAt: z.number(),\n}).strict();\nexport type TakeItDownRequestRootV1 = z.infer<typeof TakeItDownRequestRootV1Schema>;\n\n// ===========================================================================\n// §A11 (2) [H1] / [F7] — RESTRICTED takeItDownRequests/{requestId}/private/requester\n// = TakeItDownRequesterPrivateV1 (nciiRequestReviewer / nciiEvidenceReviewer only).\n// Holds signature, full contact, narrative, certifications.\n// ===========================================================================\n\n/** electronicSignature.signatureMethod — typed vs drawn signature. */\nexport const TakeItDownSignatureMethodSchema = z.enum(['typedName', 'drawnSignature']);\nexport type TakeItDownSignatureMethod = z.infer<typeof TakeItDownSignatureMethodSchema>;\n\n/** The statutory electronic signature block (embedded on the restricted subdoc). */\nexport const TakeItDownElectronicSignatureV1Schema = z.object({\n signedName: z.string(),\n signedAt: z.number(),\n signatureMethod: TakeItDownSignatureMethodSchema,\n}).strict();\nexport type TakeItDownElectronicSignatureV1 = z.infer<typeof TakeItDownElectronicSignatureV1Schema>;\n\n/** [H-02] Server-owned scan status for the optional authority-proof photo.\n * Written by `onNciiEvidenceUploaded` when the authority-evidence prefix is\n * matched. `pending` until the scan resolves; `clean` = safe for operator\n * review; `matched` = PhotoDNA hit (converges to child-safety path); `rejected`\n * = spoof/magic-byte rejection; `unavailable` = scan could not produce a\n * verdict (fail-closed until resolved). Absence of the photo leaves the status\n * absent — operators must not be shown/allowed to act on proof until `clean`. */\nexport const AuthorityProofScanStatusSchema = z.enum([\n 'pending',\n 'clean',\n 'matched',\n 'rejected',\n 'unavailable',\n]);\nexport type AuthorityProofScanStatus = z.infer<typeof AuthorityProofScanStatusSchema>;\n\n/** [H-02] Server-owned authority-proof scan state. Embedded on the authorized-\n * representative block; written by the `onNciiEvidenceUploaded` trigger (never\n * by the client). Present only when an authority-proof photo was uploaded. */\nexport const AuthorityProofScanStateV1Schema = z.object({\n scanStatus: AuthorityProofScanStatusSchema,\n objectGeneration: z.string().min(1),\n objectHash: z.string().min(1),\n scannedAt: z.number().optional(),\n}).strict();\nexport type AuthorityProofScanStateV1 = z.infer<typeof AuthorityProofScanStateV1Schema>;\n\n/** The authorized-representative block — present only for an\n * `authorizedRepresentative` requester.\n * [H-03] `authorityCertification` is a required good-faith attestation of\n * authority; `authorityEvidenceRef` + `authorityProofScan` are OPTIONAL\n * (presence is supporting material; absence never blocks completeness or the\n * 48h clock). */\nexport const TakeItDownAuthorizedRepresentativeV1Schema = z.object({\n representedPersonName: z.string(),\n authorityBasis: z.string(),\n authorityCertification: z.boolean(),\n authorityEvidenceRef: z.string().min(1).optional(),\n authorityProofScan: AuthorityProofScanStateV1Schema.optional(),\n}).strict();\nexport type TakeItDownAuthorizedRepresentativeV1 = z.infer<typeof TakeItDownAuthorizedRepresentativeV1Schema>;\n\n/** `takeItDownRequests/{requestId}/private/requester` = TakeItDownRequesterPrivateV1.\n * RESTRICTED — nciiRequestReviewer / nciiEvidenceReviewer only. Fixed doc id\n * `requester`. */\nexport const TakeItDownRequesterPrivateV1Schema = z.object({\n schemaVersion: z.literal(1),\n requesterName: z.string(),\n contactEmail: z.string(),\n contactPhone: z.string().optional(),\n electronicSignature: TakeItDownElectronicSignatureV1Schema,\n authorizedRepresentative: TakeItDownAuthorizedRepresentativeV1Schema.optional(),\n nonconsentStatement: z.string(), // the statutory non-consent statement\n supportingFacts: z.string(),\n goodFaithCertification: z.boolean(),\n accuracyCertification: z.boolean().optional(), // NOT a hard validity gate by default — counsel decides\n // The EXACT validated locator the requester submitted (restricted; operator-only — never on the\n // PII-free root, which keeps only TargetLocatorSummaryV1). For the public no-login url-only intake\n // this is the raw `{ kind:'url', url }` so the operator can FIND the on-platform content and\n // mark + link it as NCII evidence (the public intake never auto-resolves a TTT target — C-03\n // anti-abuse). Optional so a not-yet-backfilled request still validates; intake always writes it.\n targetLocator: TargetLocatorV1Schema.optional(),\n createdAt: z.number(),\n updatedAt: z.number(),\n}).strict();\nexport type TakeItDownRequesterPrivateV1 = z.infer<typeof TakeItDownRequesterPrivateV1Schema>;\n\n// ===========================================================================\n// §A11 (2) [H1] — IMMUTABLE takeItDownRequests/{requestId}/submissions/{submissionId}\n// = TakeItDownSubmissionV1 (append-only; the earliest complete receipt is\n// reconstructed from these, never from the mutable root).\n// ===========================================================================\n\n/** Who created a submission. */\nexport const TakeItDownSubmissionCreatedBySchema = z.enum(['requester', 'operator', 'system']);\nexport type TakeItDownSubmissionCreatedBy = z.infer<typeof TakeItDownSubmissionCreatedBySchema>;\n\n/** `takeItDownRequests/{requestId}/submissions/{submissionId}` = TakeItDownSubmissionV1\n * — IMMUTABLE append-only. Doc id `submissionId` is a deterministic/assigned id. */\nexport const TakeItDownSubmissionV1Schema = z.object({\n schemaVersion: z.literal(1),\n submissionId: z.string().min(1),\n sequence: z.number(), // monotonic per request — append order\n receivedAt: z.number(), // the immutable statutory receipt time of THIS submission\n suppliedFieldCodes: z.array(TakeItDownFieldCodeSchema).max(16),\n evidenceIds: z.array(z.string().min(1)).max(16),\n cumulativeRequestSnapshotHash: z.string(), // hash of the cumulative request state as of this submission\n cumulativeCompleteness: TakeItDownCompletenessStatusSchema, // 'incomplete' | 'complete'\n firstCompletedRequest: z.boolean(), // true on the submission whose cumulative state FIRST became complete\n supersedesSubmissionId: z.string().min(1).optional(),\n createdBy: TakeItDownSubmissionCreatedBySchema,\n}).strict();\nexport type TakeItDownSubmissionV1 = z.infer<typeof TakeItDownSubmissionV1Schema>;\n\n// ===========================================================================\n// §A11 (2) [H2] — IMMUTABLE takeItDownRequests/{requestId}/validityDecisions/{decisionId}\n// = TakeItDownValidityDecisionV1 (append-only; the authoritative validity ruling —\n// the root `validityStatus` is its projection). `incomplete` is NEVER a validity\n// result.\n// ===========================================================================\n\n/** The validity-decision result. `incomplete` is a COMPLETENESS state, NEVER a\n * validity result. */\nexport const TakeItDownValidityDecisionResultSchema = z.enum(['valid', 'invalid', 'unableToLocate']);\nexport type TakeItDownValidityDecisionResult = z.infer<typeof TakeItDownValidityDecisionResultSchema>;\n\n/** `takeItDownRequests/{requestId}/validityDecisions/{decisionId}` =\n * TakeItDownValidityDecisionV1 — IMMUTABLE append-only. Doc id `decisionId` is a\n * deterministic/assigned id. */\nexport const TakeItDownValidityDecisionV1Schema = z.object({\n schemaVersion: z.literal(1),\n decisionId: z.string().min(1),\n requestId: z.string().min(1),\n result: TakeItDownValidityDecisionResultSchema,\n basisSubmissionIds: z.array(z.string().min(1)).max(16), // the submissions the decision relied on\n validFromSubmissionId: z.string().min(1).optional(), // the EARLIEST submission whose cumulative snapshot satisfies the valid decision\n validRequestReceivedAt: z.number().optional(), // = that submission's immutable receivedAt (the binding statutory time)\n reasonCode: TakeItDownInvalidReasonCodeSchema.optional(),\n rationaleRef: z.string(), // pointer to a restricted rationale row\n decidedByUid: z.string().min(1),\n decidedAt: z.number(),\n}).strict();\nexport type TakeItDownValidityDecisionV1 = z.infer<typeof TakeItDownValidityDecisionV1Schema>;\n\n// ===========================================================================\n// §A11 (2) [L1] — takeItDownRequests/{requestId}/actions/{actionId} = the request\n// action row (CLOSED enums + a detailRef to a RESTRICTED row, never an inline\n// rationale blob).\n// ===========================================================================\n\n/** `takeItDownRequests/{requestId}/actions/{actionId}` — the [L1] closed-enum +\n * detailRef row. Doc id `actionId` is a deterministic/assigned id. */\nexport const TakeItDownRequestActionV1Schema = z.object({\n schemaVersion: z.literal(1),\n actionId: z.string().min(1),\n at: z.number(),\n actorId: z.string().min(1),\n capability: SafetyReviewerCapabilitySchema, // = the §[M4] matrix capability used\n actionType: NciiActionTypeSchema,\n result: NciiActionResultSchema,\n summary: z.string().max(MAX_NCII_ACTION_SUMMARY_LENGTH), // BOUNDED, non-sensitive\n detailRef: z.string().min(1), // pointer to a RESTRICTED detail row holding any sensitive rationale\n}).strict();\nexport type TakeItDownRequestActionV1 = z.infer<typeof TakeItDownRequestActionV1Schema>;\n\n// ===========================================================================\n// §A11 (2) [F10] — takeItDownRequests/{requestId}/evidence/{evidenceId} = the\n// public-evidence-upload record (account-less + in-app evidence lands in an\n// ISOLATED admin-only Firebase Storage bucket, never R2, never served, no durable\n// URL). Evidence reuses the `ncii-evidence` fileOrigin spec and the ONE shared\n// PhotoDNA scan (image → PhotoDNA; video → frame-extraction → PhotoDNA per frame),\n// byte-exact / no transcode (`preserveOriginal`). It does NOT use the auth-gated\n// `startUpload` path — a not-logged-in victim can't call it — so the browser writes\n// the file DIRECTLY to the isolated bucket (App-Check + create-only + image/video +\n// size-cap storage rules; path keyed by the opaque `requestReference`) and a Storage\n// onFinalize trigger runs that same scan. This record exists ONLY after a CLEAN\n// scan; a validated match opens a child-safety case and the bytes are held there\n// instead (no evidence record, never shown).\n// ===========================================================================\n\n/** `takeItDownRequests/{requestId}/evidence/{evidenceId}` — the [F10] public\n * evidence-upload record. Doc id `evidenceId` is a deterministic/assigned id.\n * INVARIANT: this record NEVER sets `originatingUploaderUid` — enforcement / NCMEC\n * attribution targets the ORIGINAL content's originatingUploaderUid (perpetrator)\n * via MediaOriginLineageV1 (a correlation, not a merge). */\nexport const TakeItDownEvidenceV1Schema = z.object({\n schemaVersion: z.literal(1),\n evidenceId: z.string().min(1),\n requestId: z.string().min(1),\n uploadContext: z.literal('takeItDownEvidence'), // LITERAL tag — never an ordinary content origin\n submitterUid: z.string().min(1).optional(), // the submitter is NEVER auto-actioned for evidence they submit\n bucket: z.string().min(1),\n key: z.string().min(1),\n generation: z.string().min(1),\n contentType: z.string().min(1),\n sizeBytes: z.number(),\n sha256: z.string().min(1),\n md5: z.string().min(1),\n capturedAt: z.number(),\n createdAt: z.number(),\n}).strict();\nexport type TakeItDownEvidenceV1 = z.infer<typeof TakeItDownEvidenceV1Schema>;\n\n// ===========================================================================\n// [H-01] nciiRetainedEvidenceInventory/{inventoryId} = NciiRetainedEvidenceInventoryV1\n// — a durable, OPERATOR-VISIBLE inventory row for an NCII-evidence object that the\n// onNciiEvidenceUploaded scan RETAINED but did NOT record as evidence (orphan /\n// oversized / spoof / malformed / archive-polyglot). The bytes are preserved (NO\n// auto-delete EVER — disposal stays verified-LE-only); this row makes the retained\n// object visible + accountable in the admin console instead of living only in a log\n// line. METADATA only — never bytes, never a served URL.\n// ===========================================================================\n\n/** Why an evidence object was retained without an evidence record. */\nexport const NciiRetainedEvidenceReasonSchema = z.enum([\n 'orphan', // requestReference matched no real request\n 'fileTooLarge', // over maxEvidenceFileBytes\n 'imageTooLarge', // over the decode pixel / dimension budget\n 'archiveOrPolyglot', // archive/polyglot signature\n 'malformedPath', // not a 3-segment nciiEvidence/{ref}/{file} key\n 'scanRejected', // PhotoDNA scan rejected it as a spoof (magic bytes / kind)\n 'capOverflow', // past the per-request count or total-bytes cap — retained but not recorded as evidence\n]);\nexport type NciiRetainedEvidenceReason = z.infer<typeof NciiRetainedEvidenceReasonSchema>;\n\n/** `nciiRetainedEvidenceInventory/{inventoryId}` — the [H-01] retained-object row.\n * Doc id is deterministic on bucket+key+generation (idempotent re-fire). */\nexport const NciiRetainedEvidenceInventoryV1Schema = z.object({\n schemaVersion: z.literal(1),\n inventoryId: z.string().min(1),\n reason: NciiRetainedEvidenceReasonSchema,\n bucket: z.string().min(1),\n key: z.string().min(1),\n generation: z.string().min(1),\n /** The path segment (an orphan reference matches no request). */\n requestReference: z.string().min(1).optional(),\n contentType: z.string().min(1).optional(),\n sizeBytes: z.number().optional(),\n detectedAt: z.number(),\n createdAt: z.number(),\n}).strict();\nexport type NciiRetainedEvidenceInventoryV1 = z.infer<typeof NciiRetainedEvidenceInventoryV1Schema>;\n\n// ===========================================================================\n// §A11 [C-02] — conditional completeness predicate (`computeCompleteness`).\n// requiredFieldCodes(requesterRole) + a contact one-of. These are EMBEDDED /\n// NON-DOC shapes (not Firestore documents): the counsel-ratified required set + a\n// documented predicate. Completeness is NOT \"every TakeItDownFieldCode arrived\".\n// ===========================================================================\n\n/** [C-02] Required field codes for a `depictedPerson` request (counsel-ratified). */\nexport const REQUIRED_FIELD_CODES_DEPICTED_PERSON = [\n 'requesterName',\n 'requesterRole',\n 'electronicSignature',\n 'targetLocator',\n 'nonconsentStatement',\n 'goodFaithCertification',\n] as const satisfies readonly TakeItDownFieldCode[];\n\n/** [C-02 / H-03] Required field codes for an `authorizedRepresentative` request =\n * depicted-person set ∪ { authorityBasis, authorityCertification }.\n * `authorityEvidence` (the optional documentary photo) is NOT required;\n * absence or pending scan never blocks completeness or the 48h clock. */\nexport const REQUIRED_FIELD_CODES_AUTHORIZED_REPRESENTATIVE = [\n ...REQUIRED_FIELD_CODES_DEPICTED_PERSON,\n 'authorityBasis',\n 'authorityCertification',\n] as const satisfies readonly TakeItDownFieldCode[];\n\n/** [C-02] The contact one-of: at least ONE of these must be present (neither is\n * individually required; either alone satisfies it). */\nexport const CONTACT_ONE_OF_FIELD_CODES = [\n 'contactEmail',\n 'contactPhone',\n] as const satisfies readonly TakeItDownFieldCode[];\n\n/** [C-02 / H-03] `requiredFieldCodes(requesterRole)` — the required set.\n * `supportingFacts` is collected but is NOT a completeness gate; `contactEmail` /\n * `contactPhone` are governed by the contact one-of (see CONTACT_ONE_OF_FIELD_CODES),\n * never individually required. `authorityEvidence` (the optional documentary photo)\n * is NOT required; absence or a pending/unavailable scan never blocks completeness\n * or the 48h clock. The implementer uses EXACTLY this set and never hard-requires\n * `contactPhone` or the authorizedRepresentative block on a depicted-person request. */\nexport function requiredFieldCodes(\n requesterRole: TakeItDownRequesterRole,\n): readonly TakeItDownFieldCode[] {\n return requesterRole === 'authorizedRepresentative'\n ? REQUIRED_FIELD_CODES_AUTHORIZED_REPRESENTATIVE\n : REQUIRED_FIELD_CODES_DEPICTED_PERSON;\n}\n\n/** [C-02 / H-02 / H-03] `computeCompleteness` — returns `complete` iff every code in\n * `requiredFieldCodes(requesterRole)` is supplied AND the contact one-of holds;\n * otherwise `incomplete` with the missing codes surfaced (those become\n * `TakeItDownPublicStatusV1.missingFieldCodes`). The missing-set lists the role's\n * unmet required codes, plus a `contactEmail`/`contactPhone` representative for an\n * unmet contact one-of (the implementer/UI decides which contact code to surface;\n * here we surface `contactEmail` as the canonical missing-contact marker).\n * [H-02] The optional authority-proof photo's presence, absence, or pending scan\n * (`authorityProofScan.scanStatus`) is NEVER a gate — completeness is purely the\n * written statutory elements + the authority certification. */\nexport function computeCompleteness(input: {\n requesterRole: TakeItDownRequesterRole;\n suppliedFieldCodes: readonly TakeItDownFieldCode[];\n}): { status: 'incomplete' | 'complete'; missingFieldCodes: TakeItDownFieldCode[] } {\n const supplied = new Set(input.suppliedFieldCodes);\n const missingFieldCodes: TakeItDownFieldCode[] = [];\n\n for (const code of requiredFieldCodes(input.requesterRole)) {\n if (!supplied.has(code)) missingFieldCodes.push(code);\n }\n\n const contactSatisfied = CONTACT_ONE_OF_FIELD_CODES.some((code) => supplied.has(code));\n if (!contactSatisfied) missingFieldCodes.push('contactEmail');\n\n return {\n status: missingFieldCodes.length === 0 ? 'complete' : 'incomplete',\n missingFieldCodes,\n };\n}\n\n// ===========================================================================\n// §A11 [C-02 / H-03] — intake field-code derivation + completeness (SINGLE-SOURCED).\n// `NciiIntakeFacts`, `suppliedFieldCodes`, and `deriveCompleteness` are pure and sit\n// beside `computeCompleteness` so BOTH the public route graph (src/) and the functions\n// graph (functions/src/) import the ONE implementation — the two \"byte-identical\"\n// intakeShared mirrors that had already drifted ([H-03] authorityCertification existed\n// on only one side) are eliminated. These are EMBEDDED / NON-DOC shapes (not Firestore\n// documents).\n// ===========================================================================\n\n/** The decoded intake payload the field-code extractor inspects. The route/callable\n * maps the raw body onto this AFTER zod-validating it. */\nexport interface NciiIntakeFacts {\n readonly requesterRole: TakeItDownRequesterRole;\n readonly requesterName?: string;\n readonly contactEmail?: string;\n readonly contactPhone?: string;\n readonly electronicSignature?: { signedName: string; signatureMethod: string };\n readonly nonconsentStatement?: string;\n readonly supportingFacts?: string;\n readonly goodFaithCertification?: boolean;\n readonly authorityBasis?: string;\n /** [H-03] The required good-faith authority certification. Arms completeness alongside\n * authorityBasis; the optional documentary photo never gates completeness. */\n readonly authorityCertification?: boolean;\n /** [H-03] Optional documentary authority-proof photo ref. Present/absent never blocks\n * completeness or the 48h clock; it is supporting material only. */\n readonly authorityEvidenceRef?: string;\n /** Present only for a resolvable/recorded locator (TTT-hosted or external). */\n readonly hasLocator: boolean;\n}\n\nfunction nonEmpty(s: string | undefined): boolean {\n return typeof s === 'string' && s.trim().length > 0;\n}\n\n/**\n * Derive the set of supplied `TakeItDownFieldCode`s from the decoded facts. This is\n * the bridge between the raw form fields and the enumerated codes the\n * `computeCompleteness` predicate consumes — completeness is NEVER \"every field code\n * arrived\", it is exactly the counsel-ratified required set (handled by\n * `computeCompleteness`) over THIS supplied set.\n */\nexport function suppliedFieldCodes(facts: NciiIntakeFacts): TakeItDownFieldCode[] {\n const codes: TakeItDownFieldCode[] = [];\n if (nonEmpty(facts.requesterName)) codes.push('requesterName');\n if (nonEmpty(facts.contactEmail)) codes.push('contactEmail');\n if (nonEmpty(facts.contactPhone)) codes.push('contactPhone');\n // requesterRole is always present (it is required to even shape the request).\n codes.push('requesterRole');\n if (facts.electronicSignature && nonEmpty(facts.electronicSignature.signedName)) {\n codes.push('electronicSignature');\n }\n if (facts.hasLocator) codes.push('targetLocator');\n if (nonEmpty(facts.nonconsentStatement)) codes.push('nonconsentStatement');\n if (nonEmpty(facts.supportingFacts)) codes.push('supportingFacts');\n if (facts.goodFaithCertification === true) codes.push('goodFaithCertification');\n if (nonEmpty(facts.authorityBasis)) codes.push('authorityBasis');\n // [H-03] authorityCertification is the required authority attestation that arms completeness.\n if (facts.authorityCertification === true) codes.push('authorityCertification');\n // [H-03] authorityEvidence (documentary photo) is OPTIONAL — recorded when present but\n // never a completeness gate; absence never blocks the 48h clock.\n if (nonEmpty(facts.authorityEvidenceRef)) codes.push('authorityEvidence');\n return codes;\n}\n\n/** The full completeness determination: status + the supplied set + the missing set. */\nexport interface NciiCompletenessOutcome {\n readonly status: 'incomplete' | 'complete';\n readonly suppliedFieldCodes: TakeItDownFieldCode[];\n readonly missingFieldCodes: TakeItDownFieldCode[];\n}\n\n/**\n * Compute completeness from the decoded facts using the shared `computeCompleteness`\n * predicate ([C-02]). One call so every intake (public route + logged-in callable +\n * any functions-graph recompute) uses an identical determination.\n */\nexport function deriveCompleteness(facts: NciiIntakeFacts): NciiCompletenessOutcome {\n const supplied = suppliedFieldCodes(facts);\n const { status, missingFieldCodes } = computeCompleteness({\n requesterRole: facts.requesterRole,\n suppliedFieldCodes: supplied,\n });\n return { status, suppliedFieldCodes: supplied, missingFieldCodes };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"requests.js","sourceRoot":"","sources":["../../../src/doc-schemas/ncii/requests.ts"],"names":[],"mappings":"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","sourcesContent":["// Trust & Safety — NCII statutory TAKE IT DOWN requests (Appendix A §A11, concept\n// (2)) — the SPLIT model: a PII-free root + a restricted requester-PII subdoc +\n// immutable submissions/validityDecisions + operator actions + isolated public\n// evidence uploads.\n//\n// Only a COMPLETE + VALID request can arm the 48h clock. The public no-login form\n// CANNOT submit a \"valid request\" without the required fields; validation\n// failures use the enumerated TakeItDownInvalidReasonCode. The root holds NO\n// requester PII / narrative / signature / authority — those live in the restricted\n// `/private/requester` subdoc.\n//\n// The public post-submission tracking tail (status page / status route / supplement\n// route / status token / public status projection) was removed (DJ 2026-07-02, feature\n// never wanted): the public flow is submit-only, so the status-token fields and the\n// `TakeItDownPublicStatusV1` projection no longer exist. Evidence folders re-key on the\n// intake `idempotencyKey` (like `nciiAuthorityEvidence/`), so no `statusProjection`\n// collection-group lookup remains.\n//\n// Every shape here is transcribed verbatim from the frozen Trust & Safety spec\n// (Appendix A §A11 (2) + [C-02] + [F7] + [F10]) — no invented values, no\n// placeholders; the durable design owner is ttt-prod\n// docs/design/nonconsensual-intimate-imagery-and-take-it-down.md.\n//\n// SHARED enums + locator types come from ../safety/foundation.js (the single\n// source for every cross-cluster enum); they are NEVER redefined here. This\n// cluster IMPORTS TakeItDownRequesterRoleSchema, TargetLocatorSummaryV1Schema,\n// TakeItDownCompletenessStatusSchema, TakeItDownValidityStatusSchema,\n// TakeItDownInvalidReasonCodeSchema, TakeItDownPublicStatusSchema,\n// NciiRemovalCompletionOutcomeSchema, NciiActionTypeSchema, NciiActionResultSchema,\n// TakeItDownFieldCodeSchema, and SafetyReviewerCapabilitySchema.\n//\n// Collection note: this cluster introduces a NEW Firestore collection plus several\n// subcollections (private/requester, submissions, validityDecisions, actions,\n// evidence). Wiring collections.ts / path-builders.ts / registry.ts is deferred to\n// the app leg (the orchestrator binds the schemas + path builders there); the doc-id\n// shapes (including the deterministic intake requestId [H-07]) are documented on each\n// schema below.\n\nimport { z } from 'zod';\nimport { MAX_NCII_ACTION_SUMMARY_LENGTH } from '../../constants/business.js';\nimport {\n TakeItDownRequesterRoleSchema,\n TargetLocatorV1Schema,\n TargetLocatorSummaryV1Schema,\n TakeItDownCompletenessStatusSchema,\n TakeItDownValidityStatusSchema,\n TakeItDownInvalidReasonCodeSchema,\n TakeItDownPublicStatusSchema,\n NciiRemovalCompletionOutcomeSchema,\n NciiActionTypeSchema,\n NciiActionResultSchema,\n TakeItDownFieldCodeSchema,\n SafetyReviewerCapabilitySchema,\n type TakeItDownFieldCode,\n type TakeItDownRequesterRole,\n} from '../safety/foundation.js';\n\n// ===========================================================================\n// §A11 (2) [H1] — ROOT takeItDownRequests/{requestId} = TakeItDownRequestRootV1\n// (NO requester PII / narrative / signature / authority). [H-07] the intake\n// `requestId` is the deterministic sha256('takeItDownRequest:v1:' +\n// idempotencyKey + ':' + normalizedTargetKey) so retries resolve to one doc.\n// ===========================================================================\n\nexport const TakeItDownRequestRootV1Schema = z.object({\n schemaVersion: z.literal(1),\n requestId: z.string().min(1),\n caseId: z.string().min(1).optional(),\n requesterRole: TakeItDownRequesterRoleSchema,\n // privacy-safe summary ONLY — never the narrative\n targetLocatorSummary: TargetLocatorSummaryV1Schema,\n receivedAt: z.number(),\n completenessStatus: TakeItDownCompletenessStatusSchema, // 'incomplete' | 'complete'\n validityStatus: TakeItDownValidityStatusSchema, // 'pending' | 'valid' | 'invalid' | 'unableToLocate'\n invalidReasonCode: TakeItDownInvalidReasonCodeSchema.optional(),\n completenessDeterminedAt: z.number().optional(),\n validityDeterminedAt: z.number().optional(),\n completedBySubmissionId: z.string().min(1).optional(), // which immutable submission completed the request\n validRequestReceivedAt: z.number().optional(), // [F3] EARLIEST complete+valid receipt — pins the clock\n removalDeadlineAt: z.number().optional(), // = validRequestReceivedAt + 48h (non-authoritative projection; [H4])\n publicStatus: TakeItDownPublicStatusSchema,\n requestClosedAt: z.number().optional(), // when the request reached a terminal disposition\n removalCompletionAt: z.number().optional(), // [M-01] set when removal verified-completes\n finalClosedAt: z.number().optional(), // [H-08] = requestClosedAt (no appeal window); arms for EVERY terminal disposition. The request's retention clocks (PII / evidence / status-token) count from here.\n removalCompletionOutcome: NciiRemovalCompletionOutcomeSchema.optional(), // [H4] honest derived completion — NEVER 'completed' for a partial technical failure\n createdAt: z.number(),\n updatedAt: z.number(),\n}).strict();\nexport type TakeItDownRequestRootV1 = z.infer<typeof TakeItDownRequestRootV1Schema>;\n\n// ===========================================================================\n// §A11 (2) [H1] / [F7] — RESTRICTED takeItDownRequests/{requestId}/private/requester\n// = TakeItDownRequesterPrivateV1 (nciiRequestReviewer / nciiEvidenceReviewer only).\n// Holds signature, full contact, narrative, certifications.\n// ===========================================================================\n\n/** electronicSignature.signatureMethod — typed vs drawn signature. */\nexport const TakeItDownSignatureMethodSchema = z.enum(['typedName', 'drawnSignature']);\nexport type TakeItDownSignatureMethod = z.infer<typeof TakeItDownSignatureMethodSchema>;\n\n/** The statutory electronic signature block (embedded on the restricted subdoc). */\nexport const TakeItDownElectronicSignatureV1Schema = z.object({\n signedName: z.string(),\n signedAt: z.number(),\n signatureMethod: TakeItDownSignatureMethodSchema,\n}).strict();\nexport type TakeItDownElectronicSignatureV1 = z.infer<typeof TakeItDownElectronicSignatureV1Schema>;\n\n/** [H-02] Server-owned scan status for the optional authority-proof photo.\n * Written by `onNciiEvidenceUploaded` when the authority-evidence prefix is\n * matched. `pending` until the scan resolves; `clean` = safe for operator\n * review; `matched` = PhotoDNA hit (converges to child-safety path); `rejected`\n * = spoof/magic-byte rejection; `unavailable` = scan could not produce a\n * verdict (fail-closed until resolved). Absence of the photo leaves the status\n * absent — operators must not be shown/allowed to act on proof until `clean`. */\nexport const AuthorityProofScanStatusSchema = z.enum([\n 'pending',\n 'clean',\n 'matched',\n 'rejected',\n 'unavailable',\n]);\nexport type AuthorityProofScanStatus = z.infer<typeof AuthorityProofScanStatusSchema>;\n\n/** [H-02] Server-owned authority-proof scan state. Embedded on the authorized-\n * representative block; written by the `onNciiEvidenceUploaded` trigger (never\n * by the client). Present only when an authority-proof photo was uploaded. */\nexport const AuthorityProofScanStateV1Schema = z.object({\n scanStatus: AuthorityProofScanStatusSchema,\n objectGeneration: z.string().min(1),\n objectHash: z.string().min(1),\n scannedAt: z.number().optional(),\n}).strict();\nexport type AuthorityProofScanStateV1 = z.infer<typeof AuthorityProofScanStateV1Schema>;\n\n/** The authorized-representative block — present only for an\n * `authorizedRepresentative` requester.\n * [H-03] `authorityCertification` is a required good-faith attestation of\n * authority; `authorityEvidenceRef` + `authorityProofScan` are OPTIONAL\n * (presence is supporting material; absence never blocks completeness or the\n * 48h clock). */\nexport const TakeItDownAuthorizedRepresentativeV1Schema = z.object({\n representedPersonName: z.string(),\n authorityBasis: z.string(),\n authorityCertification: z.boolean(),\n authorityEvidenceRef: z.string().min(1).optional(),\n authorityProofScan: AuthorityProofScanStateV1Schema.optional(),\n}).strict();\nexport type TakeItDownAuthorizedRepresentativeV1 = z.infer<typeof TakeItDownAuthorizedRepresentativeV1Schema>;\n\n/** `takeItDownRequests/{requestId}/private/requester` = TakeItDownRequesterPrivateV1.\n * RESTRICTED — nciiRequestReviewer / nciiEvidenceReviewer only. Fixed doc id\n * `requester`. */\nexport const TakeItDownRequesterPrivateV1Schema = z.object({\n schemaVersion: z.literal(1),\n requesterName: z.string(),\n contactEmail: z.string(),\n contactPhone: z.string().optional(),\n electronicSignature: TakeItDownElectronicSignatureV1Schema,\n authorizedRepresentative: TakeItDownAuthorizedRepresentativeV1Schema.optional(),\n nonconsentStatement: z.string(), // the statutory non-consent statement\n supportingFacts: z.string(),\n goodFaithCertification: z.boolean(),\n accuracyCertification: z.boolean().optional(), // NOT a hard validity gate by default — counsel decides\n // The EXACT validated locator the requester submitted (restricted; operator-only — never on the\n // PII-free root, which keeps only TargetLocatorSummaryV1). For the public no-login url-only intake\n // this is the raw `{ kind:'url', url }` so the operator can FIND the on-platform content and\n // mark + link it as NCII evidence (the public intake never auto-resolves a TTT target — C-03\n // anti-abuse). Optional so a not-yet-backfilled request still validates; intake always writes it.\n targetLocator: TargetLocatorV1Schema.optional(),\n createdAt: z.number(),\n updatedAt: z.number(),\n}).strict();\nexport type TakeItDownRequesterPrivateV1 = z.infer<typeof TakeItDownRequesterPrivateV1Schema>;\n\n// ===========================================================================\n// §A11 (2) [H1] — IMMUTABLE takeItDownRequests/{requestId}/submissions/{submissionId}\n// = TakeItDownSubmissionV1 (append-only; the earliest complete receipt is\n// reconstructed from these, never from the mutable root).\n// ===========================================================================\n\n/** Who created a submission. */\nexport const TakeItDownSubmissionCreatedBySchema = z.enum(['requester', 'operator', 'system']);\nexport type TakeItDownSubmissionCreatedBy = z.infer<typeof TakeItDownSubmissionCreatedBySchema>;\n\n/** `takeItDownRequests/{requestId}/submissions/{submissionId}` = TakeItDownSubmissionV1\n * — IMMUTABLE append-only. Doc id `submissionId` is a deterministic/assigned id. */\nexport const TakeItDownSubmissionV1Schema = z.object({\n schemaVersion: z.literal(1),\n submissionId: z.string().min(1),\n sequence: z.number(), // monotonic per request — append order\n receivedAt: z.number(), // the immutable statutory receipt time of THIS submission\n suppliedFieldCodes: z.array(TakeItDownFieldCodeSchema).max(16),\n evidenceIds: z.array(z.string().min(1)).max(16),\n cumulativeRequestSnapshotHash: z.string(), // hash of the cumulative request state as of this submission\n cumulativeCompleteness: TakeItDownCompletenessStatusSchema, // 'incomplete' | 'complete'\n firstCompletedRequest: z.boolean(), // true on the submission whose cumulative state FIRST became complete\n supersedesSubmissionId: z.string().min(1).optional(),\n createdBy: TakeItDownSubmissionCreatedBySchema,\n}).strict();\nexport type TakeItDownSubmissionV1 = z.infer<typeof TakeItDownSubmissionV1Schema>;\n\n// ===========================================================================\n// §A11 (2) [H2] — IMMUTABLE takeItDownRequests/{requestId}/validityDecisions/{decisionId}\n// = TakeItDownValidityDecisionV1 (append-only; the authoritative validity ruling —\n// the root `validityStatus` is its projection). `incomplete` is NEVER a validity\n// result.\n// ===========================================================================\n\n/** The validity-decision result. `incomplete` is a COMPLETENESS state, NEVER a\n * validity result. */\nexport const TakeItDownValidityDecisionResultSchema = z.enum(['valid', 'invalid', 'unableToLocate']);\nexport type TakeItDownValidityDecisionResult = z.infer<typeof TakeItDownValidityDecisionResultSchema>;\n\n/** `takeItDownRequests/{requestId}/validityDecisions/{decisionId}` =\n * TakeItDownValidityDecisionV1 — IMMUTABLE append-only. Doc id `decisionId` is a\n * deterministic/assigned id. */\nexport const TakeItDownValidityDecisionV1Schema = z.object({\n schemaVersion: z.literal(1),\n decisionId: z.string().min(1),\n requestId: z.string().min(1),\n result: TakeItDownValidityDecisionResultSchema,\n basisSubmissionIds: z.array(z.string().min(1)).max(16), // the submissions the decision relied on\n validFromSubmissionId: z.string().min(1).optional(), // the EARLIEST submission whose cumulative snapshot satisfies the valid decision\n validRequestReceivedAt: z.number().optional(), // = that submission's immutable receivedAt (the binding statutory time)\n reasonCode: TakeItDownInvalidReasonCodeSchema.optional(),\n rationaleRef: z.string(), // pointer to a restricted rationale row\n decidedByUid: z.string().min(1),\n decidedAt: z.number(),\n}).strict();\nexport type TakeItDownValidityDecisionV1 = z.infer<typeof TakeItDownValidityDecisionV1Schema>;\n\n// ===========================================================================\n// §A11 (2) [L1] — takeItDownRequests/{requestId}/actions/{actionId} = the request\n// action row (CLOSED enums + a detailRef to a RESTRICTED row, never an inline\n// rationale blob).\n// ===========================================================================\n\n/** `takeItDownRequests/{requestId}/actions/{actionId}` — the [L1] closed-enum +\n * detailRef row. Doc id `actionId` is a deterministic/assigned id. */\nexport const TakeItDownRequestActionV1Schema = z.object({\n schemaVersion: z.literal(1),\n actionId: z.string().min(1),\n at: z.number(),\n actorId: z.string().min(1),\n capability: SafetyReviewerCapabilitySchema, // = the §[M4] matrix capability used\n actionType: NciiActionTypeSchema,\n result: NciiActionResultSchema,\n summary: z.string().max(MAX_NCII_ACTION_SUMMARY_LENGTH), // BOUNDED, non-sensitive\n detailRef: z.string().min(1), // pointer to a RESTRICTED detail row holding any sensitive rationale\n}).strict();\nexport type TakeItDownRequestActionV1 = z.infer<typeof TakeItDownRequestActionV1Schema>;\n\n// ===========================================================================\n// §A11 (2) [F10] — takeItDownRequests/{requestId}/evidence/{evidenceId} = the\n// public-evidence-upload record (account-less + in-app evidence lands in an\n// ISOLATED admin-only Firebase Storage bucket, never R2, never served, no durable\n// URL). Evidence reuses the `ncii-evidence` fileOrigin spec and the ONE shared\n// PhotoDNA scan (image → PhotoDNA; video → frame-extraction → PhotoDNA per frame),\n// byte-exact / no transcode (`preserveOriginal`). It does NOT use the auth-gated\n// `startUpload` path — a not-logged-in victim can't call it — so the browser writes\n// the file DIRECTLY to the isolated bucket (App-Check + create-only + image/video +\n// size-cap storage rules; path keyed by the opaque `requestReference`) and a Storage\n// onFinalize trigger runs that same scan. This record exists ONLY after a CLEAN\n// scan; a validated match opens a child-safety case and the bytes are held there\n// instead (no evidence record, never shown).\n// ===========================================================================\n\n/** `takeItDownRequests/{requestId}/evidence/{evidenceId}` — the [F10] public\n * evidence-upload record. Doc id `evidenceId` is a deterministic/assigned id.\n * INVARIANT: this record NEVER sets `originatingUploaderUid` — enforcement / NCMEC\n * attribution targets the ORIGINAL content's originatingUploaderUid (perpetrator)\n * via MediaOriginLineageV1 (a correlation, not a merge). */\nexport const TakeItDownEvidenceV1Schema = z.object({\n schemaVersion: z.literal(1),\n evidenceId: z.string().min(1),\n requestId: z.string().min(1),\n uploadContext: z.literal('takeItDownEvidence'), // LITERAL tag — never an ordinary content origin\n submitterUid: z.string().min(1).optional(), // the submitter is NEVER auto-actioned for evidence they submit\n bucket: z.string().min(1),\n key: z.string().min(1),\n generation: z.string().min(1),\n contentType: z.string().min(1),\n sizeBytes: z.number(),\n sha256: z.string().min(1),\n md5: z.string().min(1),\n capturedAt: z.number(),\n createdAt: z.number(),\n}).strict();\nexport type TakeItDownEvidenceV1 = z.infer<typeof TakeItDownEvidenceV1Schema>;\n\n// ===========================================================================\n// [H-01] nciiRetainedEvidenceInventory/{inventoryId} = NciiRetainedEvidenceInventoryV1\n// — a durable, OPERATOR-VISIBLE inventory row for an NCII-evidence object that the\n// onNciiEvidenceUploaded scan RETAINED but did NOT record as evidence (orphan /\n// oversized / spoof / malformed / archive-polyglot). The bytes are preserved (NO\n// auto-delete EVER — disposal stays verified-LE-only); this row makes the retained\n// object visible + accountable in the admin console instead of living only in a log\n// line. METADATA only — never bytes, never a served URL.\n// ===========================================================================\n\n/** Why an evidence object was retained without an evidence record. */\nexport const NciiRetainedEvidenceReasonSchema = z.enum([\n 'orphan', // requestReference matched no real request\n 'fileTooLarge', // over maxEvidenceFileBytes\n 'imageTooLarge', // over the decode pixel / dimension budget\n 'archiveOrPolyglot', // archive/polyglot signature\n 'malformedPath', // not a 3-segment nciiEvidence/{ref}/{file} key\n 'scanRejected', // PhotoDNA scan rejected it as a spoof (magic bytes / kind)\n 'capOverflow', // past the per-request count or total-bytes cap — retained but not recorded as evidence\n]);\nexport type NciiRetainedEvidenceReason = z.infer<typeof NciiRetainedEvidenceReasonSchema>;\n\n/** `nciiRetainedEvidenceInventory/{inventoryId}` — the [H-01] retained-object row.\n * Doc id is deterministic on bucket+key+generation (idempotent re-fire). */\nexport const NciiRetainedEvidenceInventoryV1Schema = z.object({\n schemaVersion: z.literal(1),\n inventoryId: z.string().min(1),\n reason: NciiRetainedEvidenceReasonSchema,\n bucket: z.string().min(1),\n key: z.string().min(1),\n generation: z.string().min(1),\n /** The path segment (an orphan reference matches no request). */\n requestReference: z.string().min(1).optional(),\n contentType: z.string().min(1).optional(),\n sizeBytes: z.number().optional(),\n detectedAt: z.number(),\n createdAt: z.number(),\n}).strict();\nexport type NciiRetainedEvidenceInventoryV1 = z.infer<typeof NciiRetainedEvidenceInventoryV1Schema>;\n\n// ===========================================================================\n// §A11 [C-02] — conditional completeness predicate (`computeCompleteness`).\n// requiredFieldCodes(requesterRole) + a contact one-of. These are EMBEDDED /\n// NON-DOC shapes (not Firestore documents): the counsel-ratified required set + a\n// documented predicate. Completeness is NOT \"every TakeItDownFieldCode arrived\".\n// ===========================================================================\n\n/** [C-02] Required field codes for a `depictedPerson` request (counsel-ratified). */\nexport const REQUIRED_FIELD_CODES_DEPICTED_PERSON = [\n 'requesterName',\n 'requesterRole',\n 'electronicSignature',\n 'targetLocator',\n 'nonconsentStatement',\n 'goodFaithCertification',\n] as const satisfies readonly TakeItDownFieldCode[];\n\n/** [C-02 / H-03] Required field codes for an `authorizedRepresentative` request =\n * depicted-person set ∪ { authorityBasis, authorityCertification }.\n * `authorityEvidence` (the optional documentary photo) is NOT required;\n * absence or pending scan never blocks completeness or the 48h clock. */\nexport const REQUIRED_FIELD_CODES_AUTHORIZED_REPRESENTATIVE = [\n ...REQUIRED_FIELD_CODES_DEPICTED_PERSON,\n 'authorityBasis',\n 'authorityCertification',\n] as const satisfies readonly TakeItDownFieldCode[];\n\n/** [C-02] The contact one-of: at least ONE of these must be present (neither is\n * individually required; either alone satisfies it). */\nexport const CONTACT_ONE_OF_FIELD_CODES = [\n 'contactEmail',\n 'contactPhone',\n] as const satisfies readonly TakeItDownFieldCode[];\n\n/** [C-02 / H-03] `requiredFieldCodes(requesterRole)` — the required set.\n * `supportingFacts` is collected but is NOT a completeness gate; `contactEmail` /\n * `contactPhone` are governed by the contact one-of (see CONTACT_ONE_OF_FIELD_CODES),\n * never individually required. `authorityEvidence` (the optional documentary photo)\n * is NOT required; absence or a pending/unavailable scan never blocks completeness\n * or the 48h clock. The implementer uses EXACTLY this set and never hard-requires\n * `contactPhone` or the authorizedRepresentative block on a depicted-person request. */\nexport function requiredFieldCodes(\n requesterRole: TakeItDownRequesterRole,\n): readonly TakeItDownFieldCode[] {\n return requesterRole === 'authorizedRepresentative'\n ? REQUIRED_FIELD_CODES_AUTHORIZED_REPRESENTATIVE\n : REQUIRED_FIELD_CODES_DEPICTED_PERSON;\n}\n\n/** [C-02 / H-02 / H-03] `computeCompleteness` — returns `complete` iff every code in\n * `requiredFieldCodes(requesterRole)` is supplied AND the contact one-of holds;\n * otherwise `incomplete` with the missing codes surfaced (those become\n * `TakeItDownPublicStatusV1.missingFieldCodes`). The missing-set lists the role's\n * unmet required codes, plus a `contactEmail`/`contactPhone` representative for an\n * unmet contact one-of (the implementer/UI decides which contact code to surface;\n * here we surface `contactEmail` as the canonical missing-contact marker).\n * [H-02] The optional authority-proof photo's presence, absence, or pending scan\n * (`authorityProofScan.scanStatus`) is NEVER a gate — completeness is purely the\n * written statutory elements + the authority certification. */\nexport function computeCompleteness(input: {\n requesterRole: TakeItDownRequesterRole;\n suppliedFieldCodes: readonly TakeItDownFieldCode[];\n}): { status: 'incomplete' | 'complete'; missingFieldCodes: TakeItDownFieldCode[] } {\n const supplied = new Set(input.suppliedFieldCodes);\n const missingFieldCodes: TakeItDownFieldCode[] = [];\n\n for (const code of requiredFieldCodes(input.requesterRole)) {\n if (!supplied.has(code)) missingFieldCodes.push(code);\n }\n\n const contactSatisfied = CONTACT_ONE_OF_FIELD_CODES.some((code) => supplied.has(code));\n if (!contactSatisfied) missingFieldCodes.push('contactEmail');\n\n return {\n status: missingFieldCodes.length === 0 ? 'complete' : 'incomplete',\n missingFieldCodes,\n };\n}\n\n// ===========================================================================\n// §A11 [C-02 / H-03] — intake field-code derivation + completeness (SINGLE-SOURCED).\n// `NciiIntakeFacts`, `suppliedFieldCodes`, and `deriveCompleteness` are pure and sit\n// beside `computeCompleteness` so BOTH the public route graph (src/) and the functions\n// graph (functions/src/) import the ONE implementation — the two \"byte-identical\"\n// intakeShared mirrors that had already drifted ([H-03] authorityCertification existed\n// on only one side) are eliminated. These are EMBEDDED / NON-DOC shapes (not Firestore\n// documents).\n// ===========================================================================\n\n/** The decoded intake payload the field-code extractor inspects. The route/callable\n * maps the raw body onto this AFTER zod-validating it. */\nexport interface NciiIntakeFacts {\n readonly requesterRole: TakeItDownRequesterRole;\n readonly requesterName?: string;\n readonly contactEmail?: string;\n readonly contactPhone?: string;\n readonly electronicSignature?: { signedName: string; signatureMethod: string };\n readonly nonconsentStatement?: string;\n readonly supportingFacts?: string;\n readonly goodFaithCertification?: boolean;\n readonly authorityBasis?: string;\n /** [H-03] The required good-faith authority certification. Arms completeness alongside\n * authorityBasis; the optional documentary photo never gates completeness. */\n readonly authorityCertification?: boolean;\n /** [H-03] Optional documentary authority-proof photo ref. Present/absent never blocks\n * completeness or the 48h clock; it is supporting material only. */\n readonly authorityEvidenceRef?: string;\n /** Present only for a resolvable/recorded locator (TTT-hosted or external). */\n readonly hasLocator: boolean;\n}\n\nfunction nonEmpty(s: string | undefined): boolean {\n return typeof s === 'string' && s.trim().length > 0;\n}\n\n/**\n * Derive the set of supplied `TakeItDownFieldCode`s from the decoded facts. This is\n * the bridge between the raw form fields and the enumerated codes the\n * `computeCompleteness` predicate consumes — completeness is NEVER \"every field code\n * arrived\", it is exactly the counsel-ratified required set (handled by\n * `computeCompleteness`) over THIS supplied set.\n */\nexport function suppliedFieldCodes(facts: NciiIntakeFacts): TakeItDownFieldCode[] {\n const codes: TakeItDownFieldCode[] = [];\n if (nonEmpty(facts.requesterName)) codes.push('requesterName');\n if (nonEmpty(facts.contactEmail)) codes.push('contactEmail');\n if (nonEmpty(facts.contactPhone)) codes.push('contactPhone');\n // requesterRole is always present (it is required to even shape the request).\n codes.push('requesterRole');\n if (facts.electronicSignature && nonEmpty(facts.electronicSignature.signedName)) {\n codes.push('electronicSignature');\n }\n if (facts.hasLocator) codes.push('targetLocator');\n if (nonEmpty(facts.nonconsentStatement)) codes.push('nonconsentStatement');\n if (nonEmpty(facts.supportingFacts)) codes.push('supportingFacts');\n if (facts.goodFaithCertification === true) codes.push('goodFaithCertification');\n if (nonEmpty(facts.authorityBasis)) codes.push('authorityBasis');\n // [H-03] authorityCertification is the required authority attestation that arms completeness.\n if (facts.authorityCertification === true) codes.push('authorityCertification');\n // [H-03] authorityEvidence (documentary photo) is OPTIONAL — recorded when present but\n // never a completeness gate; absence never blocks the 48h clock.\n if (nonEmpty(facts.authorityEvidenceRef)) codes.push('authorityEvidence');\n return codes;\n}\n\n/** The full completeness determination: status + the supplied set + the missing set. */\nexport interface NciiCompletenessOutcome {\n readonly status: 'incomplete' | 'complete';\n readonly suppliedFieldCodes: TakeItDownFieldCode[];\n readonly missingFieldCodes: TakeItDownFieldCode[];\n}\n\n/**\n * Compute completeness from the decoded facts using the shared `computeCompleteness`\n * predicate ([C-02]). One call so every intake (public route + logged-in callable +\n * any functions-graph recompute) uses an identical determination.\n */\nexport function deriveCompleteness(facts: NciiIntakeFacts): NciiCompletenessOutcome {\n const supplied = suppliedFieldCodes(facts);\n const { status, missingFieldCodes } = computeCompleteness({\n requesterRole: facts.requesterRole,\n suppliedFieldCodes: supplied,\n });\n return { status, suppliedFieldCodes: supplied, missingFieldCodes };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notification-ledger.d.ts","sourceRoot":"","sources":["../../src/doc-schemas/notification-ledger.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"notification-ledger.d.ts","sourceRoot":"","sources":["../../src/doc-schemas/notification-ledger.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB;;+CAE+C;AAC/C,eAAO,MAAM,iCAAiC;;;;iBAI5C,CAAC;AAKH,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAkBrC,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAI9E,eAAO,MAAM,6BAA6B;;;;iBAIxC,CAAC;AAEH,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAmBtC,CAAC;AACH,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
// Notification redesign ledger Firestore schemas (chat-edge-rebuild P1).
|
|
2
|
-
//
|
|
2
|
+
// The notification-ledger field lists are FROZEN here — this file is their single
|
|
3
|
+
// source; the durable design owner is ttt-prod docs/design/notification-system.md.
|
|
4
|
+
// Admin-SDK-only.
|
|
3
5
|
// `expireAt` is the only Firestore `Timestamp` field (native TTL); every other
|
|
4
6
|
// time field is epoch-ms `number`.
|
|
5
7
|
import { z } from 'zod';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notification-ledger.js","sourceRoot":"","sources":["../../src/doc-schemas/notification-ledger.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,
|
|
1
|
+
{"version":3,"file":"notification-ledger.js","sourceRoot":"","sources":["../../src/doc-schemas/notification-ledger.ts"],"names":[],"mappings":"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","sourcesContent":["// Notification redesign ledger Firestore schemas (chat-edge-rebuild P1).\n// The notification-ledger field lists are FROZEN here — this file is their single\n// source; the durable design owner is ttt-prod docs/design/notification-system.md.\n// Admin-SDK-only.\n// `expireAt` is the only Firestore `Timestamp` field (native TTL); every other\n// time field is epoch-ms `number`.\n\nimport { z } from 'zod';\n\n/** Native-TTL Timestamp (set only at the resolved-success terminal). */\nconst expireAtField = z.unknown().optional();\n\n/** The materialization payload carried on every delivery row.\n * `actorId` is `null` for system / no-actor occurrences (the engine writes null and\n * never injects it into `latestActorIds`). */\nexport const NotificationDeliveryPayloadSchema = z.object({\n actorId: z.string().nullable(),\n metadata: z.record(z.string(), z.unknown()),\n occurrenceAt: z.number(),\n});\n\n// ── notificationDeliveries/{deliveryId} ─────────────────────────────────────\n// BOTH the recipient ledger AND the occurrence ledger. Shared-admin rows set\n// recipientUid=null (the deliveryId hash uses the literal 'shared').\nexport const NotificationDeliverySchema = z.object({\n deliveryId: z.string(),\n state: z.enum(['queued', 'materialized', 'deadLetter']),\n notificationType: z.string(),\n eventId: z.string(),\n recipientUid: z.string().nullable(),\n aggregationKey: z.string(),\n strategy: z.enum(['increment', 'staticRelight']),\n payload: NotificationDeliveryPayloadSchema,\n payloadVersion: z.number(),\n materializationClass: z.enum(['directQueued', 'realtimeFallback', 'fanoutOrphan', 'retry']),\n createdAt: z.number(),\n attemptCount: z.number(),\n nextAttemptAt: z.number(),\n lastError: z.string().nullable(),\n materializedAt: z.number().nullable(),\n deadLetteredAt: z.number().nullable(),\n expireAt: expireAtField,\n});\nexport type NotificationDelivery = z.infer<typeof NotificationDeliverySchema>;\n\n// ── notificationFanoutJobs/{jobId} ──────────────────────────────────────────\n// jobId = `${eventId}:${notificationType}`. No `running` state (no leases).\nexport const NotificationFanoutPhaseSchema = z.object({\n selector: z.record(z.string(), z.unknown()),\n cursor: z.unknown().nullable(),\n done: z.boolean(),\n});\n\nexport const NotificationFanoutJobSchema = z.object({\n jobId: z.string(),\n schemaVersion: z.number(),\n notificationType: z.string(),\n eventId: z.string(),\n priority: z.union([z.literal(0), z.literal(1), z.literal(2)]),\n payload: z.record(z.string(), z.unknown()),\n phases: z.array(NotificationFanoutPhaseSchema),\n phaseIndex: z.number(),\n revision: z.number(),\n status: z.enum(['pending', 'complete', 'deadLetter']),\n attemptCount: z.number(),\n nextAttemptAt: z.number(),\n lastError: z.string().nullable(),\n createdAt: z.number(),\n updatedAt: z.number(),\n completedAt: z.number().nullable(),\n deadLetteredAt: z.number().nullable(),\n expireAt: expireAtField,\n});\nexport type NotificationFanoutJob = z.infer<typeof NotificationFanoutJobSchema>;\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"payments.d.ts","sourceRoot":"","sources":["../../src/doc-schemas/payments.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"payments.d.ts","sourceRoot":"","sources":["../../src/doc-schemas/payments.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;iBAiB9B,CAAC;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAOhE,eAAO,MAAM,8BAA8B;;;;;;;;;;iBAUzC,CAAC;AACH,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,8BAA8B,CAAC,CAAC;AAQtF,eAAO,MAAM,4BAA4B;;;;;;iBAMvC,CAAC;AACH,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAC;AAMlF,eAAO,MAAM,0BAA0B;;;;;iBAKrC,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAM9E,eAAO,MAAM,8BAA8B;;;;;;;;;iBASzC,CAAC;AACH,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,8BAA8B,CAAC,CAAC;AAMtF,eAAO,MAAM,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;iBAsBzC,CAAC;AACH,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,8BAA8B,CAAC,CAAC;AAMtF,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;iBAWpC,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC"}
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
// server-only companions: provider refs (Stripe IDs), the idempotency sentinel, the
|
|
3
3
|
// independent integrity trail, and the paid-event quarantine queue. Types inferred via
|
|
4
4
|
// z.infer. Money data lives here, never in social.ts.
|
|
5
|
-
// See docs/design/donation-payment-system.md
|
|
5
|
+
// See ttt-prod docs/design/donation-payment-system.md (the design owner for the
|
|
6
|
+
// pledge/Stripe flow).
|
|
6
7
|
import { z } from 'zod';
|
|
7
8
|
// pledgePayments/{pledgePaymentId} — public-safe canonical money record. One doc per completed
|
|
8
9
|
// pledge; never deleted/archived. No Stripe IDs, no supporter message. Auth-readable; server-only
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"payments.js","sourceRoot":"","sources":["../../src/doc-schemas/payments.ts"],"names":[],"mappings":"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","sourcesContent":["// Payment / pledge Firestore document SCHEMAS — the public-safe pledge ledger and its\n// server-only companions: provider refs (Stripe IDs), the idempotency sentinel, the\n// independent integrity trail, and the paid-event quarantine queue. Types inferred via\n// z.infer. Money data lives here, never in social.ts.\n// See docs/design/donation-payment-system.md and docs/PHASE_6_STRIPE.md.\n\nimport { z } from 'zod';\n\n// pledgePayments/{pledgePaymentId} — public-safe canonical money record. One doc per completed\n// pledge; never deleted/archived. No Stripe IDs, no supporter message. Auth-readable; server-only\n// writes. netAmount = max(0, amount - refundedAmount - disputeLostAmount) is the sum() target.\n// At launch refundedAmount/disputeLostAmount are 0 so netAmount === amount.\n// (functions/src/payments/runProcessStripePledgeEvent.ts)\nexport const PledgePaymentSchema = z.object({\n pledgePaymentId: z.string(),\n userId: z.string(),\n amount: z.number(), // gross cents charged (Stripe-confirmed amount_total)\n refundedAmount: z.number(), // cumulative refunded cents; LAUNCH default 0\n disputeLostAmount: z.number(), // cents withdrawn on a lost dispute; LAUNCH default 0\n netAmount: z.number(), // max(0, amount - refundedAmount - disputeLostAmount); sum() target\n currency: z.string(), // \"usd\"\n paymentInstrument: z.literal('card'),\n status: z.literal('completed'),\n refundState: z.enum(['none', 'partial', 'full']), // LAUNCH always 'none'\n disputeState: z.enum(['none', 'underReview', 'won', 'lost']), // LAUNCH always 'none'\n // Server timestamp (ms) of the checkout's 18+/public-disclosure attestation, stamped at session\n // creation and carried through Stripe metadata. A paid session missing it is quarantined.\n ageAttestedAt: z.number(),\n createdAt: z.number(),\n updatedAt: z.number(),\n});\nexport type PledgePayment = z.infer<typeof PledgePaymentSchema>;\n\n// pledgePaymentProviderRefs/{pledgePaymentId} — server-only Stripe references for reconciliation\n// and (post-launch) refund/dispute lookup. Rule is permanently `if false` (Admin SDK only) so no\n// Stripe IDs ever sit on an auth-readable doc. One doc per pledge (singular). refundIds/disputeId\n// are refund-ready, defaulted ([] / null) at launch — zero migration when handlers ship.\n// (functions/src/payments/runProcessStripePledgeEvent.ts)\nexport const PledgePaymentProviderRefSchema = z.object({\n pledgePaymentId: z.string(),\n userId: z.string(),\n stripeSessionId: z.string(),\n paymentIntentId: z.string(),\n latestChargeId: z.string().nullable(), // resolved when known; null at launch if not fetched\n refundIds: z.array(z.string()), // post-launch; LAUNCH default []\n disputeId: z.string().nullable(), // post-launch; LAUNCH default null\n createdAt: z.number(),\n updatedAt: z.number(),\n});\nexport type PledgePaymentProviderRef = z.infer<typeof PledgePaymentProviderRefSchema>;\n\n// pledgePaymentTotals/summary — the stored running-totals singleton behind every \"total raised\"\n// surface. Incremented via FieldValue.increment INSIDE the Stripe webhook's pledge-record\n// transaction (same commit as the pledgePayments doc — the two can never drift on a completed\n// pledge); refund/dispute paths decrement when those handlers ship. Auth-readable, server-only\n// writes. An idempotent recompute script rebuilds/verifies it from pledgePayments for drift\n// repair. Shape mirrors the PledgePaymentTotals view-model + updatedAt.\nexport const PledgePaymentTotalsDocSchema = z.object({\n netRaised: z.number(),\n grossRaised: z.number(),\n totalRefunded: z.number(),\n pledgeCount: z.number(),\n updatedAt: z.number(),\n});\nexport type PledgePaymentTotalsDoc = z.infer<typeof PledgePaymentTotalsDocSchema>;\n\n// processedStripeEvents/{stripeEventId} — idempotency sentinel, one doc per processed Stripe\n// event.id, kept forever. Checked + written in the same transaction as the side effect so a\n// redelivered event (completion, expiry, failure, or quarantine) produces no duplicate.\n// pledgePaymentId is set only when the event created a pledge. (runProcessStripePledgeEvent.ts)\nexport const ProcessedStripeEventSchema = z.object({\n eventId: z.string(),\n eventType: z.string(),\n processedAt: z.number(),\n pledgePaymentId: z.string().nullable(),\n});\nexport type ProcessedStripeEvent = z.infer<typeof ProcessedStripeEventSchema>;\n\n// pledgePaymentLedgerEvents/{ledgerId} — independent integrity record from the onPledgePaymentWritten\n// trigger (mirrors stakeShareAuditEvents). before/after are raw doc snapshots (null on create/delete)\n// kept as permissive bags so a malformed/anomalous write is still captured forensically.\n// (functions/src/audit/runPledgePaymentLedgerAudit.ts)\nexport const PledgePaymentLedgerEventSchema = z.object({\n ledgerId: z.string(),\n pledgePaymentId: z.string(),\n subtype: z.string(), // e.g. 'created' | 'anomaly'\n reason: z.string(),\n before: z.record(z.string(), z.unknown()).nullable(),\n after: z.record(z.string(), z.unknown()).nullable(),\n source: z.literal('firestore-trigger'),\n createdAt: z.number(),\n});\nexport type PledgePaymentLedgerEvent = z.infer<typeof PledgePaymentLedgerEventSchema>;\n\n// paymentWebhookQuarantine/{stripeEventId} — admin-readable repair queue for paid-but-malformed\n// events (e.g. missing metadata) that must NOT make Stripe retry. Redaction rule: never store raw\n// payloads, card/billing data, customer email, addresses, or receipt URLs — IDs + a short redacted\n// rawSafeSummary only. (functions/src/payments/runProcessStripePledgeEvent.ts)\nexport const PaymentWebhookQuarantineSchema = z.object({\n eventId: z.string(),\n eventType: z.string(),\n livemode: z.boolean(),\n reason: z.string(),\n recoverable: z.boolean(),\n stripeObjectIds: z.object({\n sessionId: z.string().optional(),\n paymentIntentId: z.string().optional(),\n chargeId: z.string().optional(),\n }),\n pledgePaymentId: z.string().optional(),\n userId: z.string().optional(),\n amount: z.number().optional(),\n currency: z.string().optional(),\n rawSafeSummary: z.string(),\n status: z.enum(['open', 'resolved', 'ignored']),\n adminTaskId: z.string().optional(),\n createdAt: z.number(),\n resolvedAt: z.number().optional(),\n resolvedBy: z.string().optional(),\n resolutionNote: z.string().optional(),\n});\nexport type PaymentWebhookQuarantine = z.infer<typeof PaymentWebhookQuarantineSchema>;\n\n// pledgeRefundRequests/{requestId} — user-initiated pledge refund request (post-launch handler).\n// Lifecycle: requested → (admin approves) initiated → completed, or requested → (admin) denied.\n// NO Stripe ids on this doc — the refund id lands on pledgePaymentProviderRefs.refundIds. Server-only\n// writes. Timestamps are epoch-millis numbers (this repo never uses Firestore Timestamps).\nexport const PledgeRefundRequestSchema = z.object({\n pledgePaymentId: z.string(),\n userId: z.string(),\n amount: z.number(),\n status: z.enum(['requested', 'initiated', 'denied', 'completed']),\n reason: z.string().optional(), // the requester's stated reason\n denialReason: z.string().optional(), // set when an admin denies\n resolvedBy: z.string().optional(), // admin uid who approved/denied\n requestedAt: z.number(),\n resolvedAt: z.number().optional(),\n completedAt: z.number().optional(),\n});\nexport type PledgeRefundRequest = z.infer<typeof PledgeRefundRequestSchema>;\n"]}
|
|
1
|
+
{"version":3,"file":"payments.js","sourceRoot":"","sources":["../../src/doc-schemas/payments.ts"],"names":[],"mappings":"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","sourcesContent":["// Payment / pledge Firestore document SCHEMAS — the public-safe pledge ledger and its\n// server-only companions: provider refs (Stripe IDs), the idempotency sentinel, the\n// independent integrity trail, and the paid-event quarantine queue. Types inferred via\n// z.infer. Money data lives here, never in social.ts.\n// See ttt-prod docs/design/donation-payment-system.md (the design owner for the\n// pledge/Stripe flow).\n\nimport { z } from 'zod';\n\n// pledgePayments/{pledgePaymentId} — public-safe canonical money record. One doc per completed\n// pledge; never deleted/archived. No Stripe IDs, no supporter message. Auth-readable; server-only\n// writes. netAmount = max(0, amount - refundedAmount - disputeLostAmount) is the sum() target.\n// At launch refundedAmount/disputeLostAmount are 0 so netAmount === amount.\n// (functions/src/payments/runProcessStripePledgeEvent.ts)\nexport const PledgePaymentSchema = z.object({\n pledgePaymentId: z.string(),\n userId: z.string(),\n amount: z.number(), // gross cents charged (Stripe-confirmed amount_total)\n refundedAmount: z.number(), // cumulative refunded cents; LAUNCH default 0\n disputeLostAmount: z.number(), // cents withdrawn on a lost dispute; LAUNCH default 0\n netAmount: z.number(), // max(0, amount - refundedAmount - disputeLostAmount); sum() target\n currency: z.string(), // \"usd\"\n paymentInstrument: z.literal('card'),\n status: z.literal('completed'),\n refundState: z.enum(['none', 'partial', 'full']), // LAUNCH always 'none'\n disputeState: z.enum(['none', 'underReview', 'won', 'lost']), // LAUNCH always 'none'\n // Server timestamp (ms) of the checkout's 18+/public-disclosure attestation, stamped at session\n // creation and carried through Stripe metadata. A paid session missing it is quarantined.\n ageAttestedAt: z.number(),\n createdAt: z.number(),\n updatedAt: z.number(),\n});\nexport type PledgePayment = z.infer<typeof PledgePaymentSchema>;\n\n// pledgePaymentProviderRefs/{pledgePaymentId} — server-only Stripe references for reconciliation\n// and (post-launch) refund/dispute lookup. Rule is permanently `if false` (Admin SDK only) so no\n// Stripe IDs ever sit on an auth-readable doc. One doc per pledge (singular). refundIds/disputeId\n// are refund-ready, defaulted ([] / null) at launch — zero migration when handlers ship.\n// (functions/src/payments/runProcessStripePledgeEvent.ts)\nexport const PledgePaymentProviderRefSchema = z.object({\n pledgePaymentId: z.string(),\n userId: z.string(),\n stripeSessionId: z.string(),\n paymentIntentId: z.string(),\n latestChargeId: z.string().nullable(), // resolved when known; null at launch if not fetched\n refundIds: z.array(z.string()), // post-launch; LAUNCH default []\n disputeId: z.string().nullable(), // post-launch; LAUNCH default null\n createdAt: z.number(),\n updatedAt: z.number(),\n});\nexport type PledgePaymentProviderRef = z.infer<typeof PledgePaymentProviderRefSchema>;\n\n// pledgePaymentTotals/summary — the stored running-totals singleton behind every \"total raised\"\n// surface. Incremented via FieldValue.increment INSIDE the Stripe webhook's pledge-record\n// transaction (same commit as the pledgePayments doc — the two can never drift on a completed\n// pledge); refund/dispute paths decrement when those handlers ship. Auth-readable, server-only\n// writes. An idempotent recompute script rebuilds/verifies it from pledgePayments for drift\n// repair. Shape mirrors the PledgePaymentTotals view-model + updatedAt.\nexport const PledgePaymentTotalsDocSchema = z.object({\n netRaised: z.number(),\n grossRaised: z.number(),\n totalRefunded: z.number(),\n pledgeCount: z.number(),\n updatedAt: z.number(),\n});\nexport type PledgePaymentTotalsDoc = z.infer<typeof PledgePaymentTotalsDocSchema>;\n\n// processedStripeEvents/{stripeEventId} — idempotency sentinel, one doc per processed Stripe\n// event.id, kept forever. Checked + written in the same transaction as the side effect so a\n// redelivered event (completion, expiry, failure, or quarantine) produces no duplicate.\n// pledgePaymentId is set only when the event created a pledge. (runProcessStripePledgeEvent.ts)\nexport const ProcessedStripeEventSchema = z.object({\n eventId: z.string(),\n eventType: z.string(),\n processedAt: z.number(),\n pledgePaymentId: z.string().nullable(),\n});\nexport type ProcessedStripeEvent = z.infer<typeof ProcessedStripeEventSchema>;\n\n// pledgePaymentLedgerEvents/{ledgerId} — independent integrity record from the onPledgePaymentWritten\n// trigger (mirrors stakeShareAuditEvents). before/after are raw doc snapshots (null on create/delete)\n// kept as permissive bags so a malformed/anomalous write is still captured forensically.\n// (functions/src/audit/runPledgePaymentLedgerAudit.ts)\nexport const PledgePaymentLedgerEventSchema = z.object({\n ledgerId: z.string(),\n pledgePaymentId: z.string(),\n subtype: z.string(), // e.g. 'created' | 'anomaly'\n reason: z.string(),\n before: z.record(z.string(), z.unknown()).nullable(),\n after: z.record(z.string(), z.unknown()).nullable(),\n source: z.literal('firestore-trigger'),\n createdAt: z.number(),\n});\nexport type PledgePaymentLedgerEvent = z.infer<typeof PledgePaymentLedgerEventSchema>;\n\n// paymentWebhookQuarantine/{stripeEventId} — admin-readable repair queue for paid-but-malformed\n// events (e.g. missing metadata) that must NOT make Stripe retry. Redaction rule: never store raw\n// payloads, card/billing data, customer email, addresses, or receipt URLs — IDs + a short redacted\n// rawSafeSummary only. (functions/src/payments/runProcessStripePledgeEvent.ts)\nexport const PaymentWebhookQuarantineSchema = z.object({\n eventId: z.string(),\n eventType: z.string(),\n livemode: z.boolean(),\n reason: z.string(),\n recoverable: z.boolean(),\n stripeObjectIds: z.object({\n sessionId: z.string().optional(),\n paymentIntentId: z.string().optional(),\n chargeId: z.string().optional(),\n }),\n pledgePaymentId: z.string().optional(),\n userId: z.string().optional(),\n amount: z.number().optional(),\n currency: z.string().optional(),\n rawSafeSummary: z.string(),\n status: z.enum(['open', 'resolved', 'ignored']),\n adminTaskId: z.string().optional(),\n createdAt: z.number(),\n resolvedAt: z.number().optional(),\n resolvedBy: z.string().optional(),\n resolutionNote: z.string().optional(),\n});\nexport type PaymentWebhookQuarantine = z.infer<typeof PaymentWebhookQuarantineSchema>;\n\n// pledgeRefundRequests/{requestId} — user-initiated pledge refund request (post-launch handler).\n// Lifecycle: requested → (admin approves) initiated → completed, or requested → (admin) denied.\n// NO Stripe ids on this doc — the refund id lands on pledgePaymentProviderRefs.refundIds. Server-only\n// writes. Timestamps are epoch-millis numbers (this repo never uses Firestore Timestamps).\nexport const PledgeRefundRequestSchema = z.object({\n pledgePaymentId: z.string(),\n userId: z.string(),\n amount: z.number(),\n status: z.enum(['requested', 'initiated', 'denied', 'completed']),\n reason: z.string().optional(), // the requester's stated reason\n denialReason: z.string().optional(), // set when an admin denies\n resolvedBy: z.string().optional(), // admin uid who approved/denied\n requestedAt: z.number(),\n resolvedAt: z.number().optional(),\n completedAt: z.number().optional(),\n});\nexport type PledgeRefundRequest = z.infer<typeof PledgeRefundRequestSchema>;\n"]}
|