create-safest-tools 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +71 -0
- package/bin/create-safest-tools.mjs +12 -0
- package/package.json +34 -0
- package/src/cli.mjs +128 -0
- package/src/config.mjs +151 -0
- package/src/scaffold.mjs +30 -0
- package/template/LICENSE +201 -0
- package/template/README.md +35 -0
- package/template/console/README.md +28 -0
- package/template/console/analytics/AnalyticsWorkspace.tsx +55 -0
- package/template/console/analytics/controller.ts +133 -0
- package/template/console/analytics/events.ts +33 -0
- package/template/console/analytics/store.ts +33 -0
- package/template/console/analytics/types.ts +38 -0
- package/template/console/appeals/AppealWorkspace.tsx +73 -0
- package/template/console/appeals/controller.ts +125 -0
- package/template/console/appeals/events.ts +33 -0
- package/template/console/appeals/store.ts +35 -0
- package/template/console/appeals/types.ts +37 -0
- package/template/console/assistant/AssistantWorkspace.tsx +133 -0
- package/template/console/assistant/types.ts +34 -0
- package/template/console/auth/AccountJourney.tsx +69 -0
- package/template/console/auth/InvitationAcceptance.tsx +145 -0
- package/template/console/auth/OAuthButtons.tsx +78 -0
- package/template/console/auth/OperatorLogin.tsx +110 -0
- package/template/console/auth/PasswordRecovery.tsx +132 -0
- package/template/console/auth/account-route.ts +15 -0
- package/template/console/auth/browser-navigation.ts +7 -0
- package/template/console/auth/events.ts +15 -0
- package/template/console/command/CommandCentre.tsx +119 -0
- package/template/console/command/controller.ts +267 -0
- package/template/console/command/events.ts +19 -0
- package/template/console/command/store.ts +36 -0
- package/template/console/command/types.ts +61 -0
- package/template/console/components/AnalystIdentity.tsx +25 -0
- package/template/console/components/PageHeader.tsx +27 -0
- package/template/console/configuration/ConfigurationDialog.tsx +200 -0
- package/template/console/configuration/ConfigurationWorkspace.tsx +66 -0
- package/template/console/configuration/FormBuilder.tsx +143 -0
- package/template/console/configuration/api.ts +40 -0
- package/template/console/configuration/events.ts +14 -0
- package/template/console/configuration/types.ts +79 -0
- package/template/console/lib/format.ts +49 -0
- package/template/console/lib/http.ts +96 -0
- package/template/console/main.tsx +225 -0
- package/template/console/operations/OperationsWorkspace.tsx +126 -0
- package/template/console/operations/controller.ts +237 -0
- package/template/console/operations/events.ts +37 -0
- package/template/console/operations/store.ts +32 -0
- package/template/console/operations/types.ts +107 -0
- package/template/console/people/PeopleWorkspace.tsx +81 -0
- package/template/console/people/types.ts +25 -0
- package/template/console/profile/ProfileWorkspace.tsx +136 -0
- package/template/console/profile/events.ts +9 -0
- package/template/console/profile/types.ts +6 -0
- package/template/console/quality/QualityWorkspace.tsx +87 -0
- package/template/console/quality/controller.ts +154 -0
- package/template/console/quality/events.ts +34 -0
- package/template/console/quality/store.ts +36 -0
- package/template/console/quality/types.ts +70 -0
- package/template/console/queues/QueueEditor.tsx +173 -0
- package/template/console/queues/QueueWorkspace.tsx +109 -0
- package/template/console/queues/controller.ts +194 -0
- package/template/console/queues/events.ts +34 -0
- package/template/console/queues/store.ts +37 -0
- package/template/console/queues/types.ts +102 -0
- package/template/console/registry/RegistryDialog.tsx +198 -0
- package/template/console/registry/RegistryWorkspace.tsx +108 -0
- package/template/console/registry/events.ts +14 -0
- package/template/console/registry/types.ts +52 -0
- package/template/console/reports/ReportDrawer.tsx +159 -0
- package/template/console/reports/ReportWorkspace.tsx +90 -0
- package/template/console/reports/controller.ts +517 -0
- package/template/console/reports/events.ts +42 -0
- package/template/console/reports/store.ts +39 -0
- package/template/console/reports/types.ts +230 -0
- package/template/console/settings/BrandEditor.tsx +126 -0
- package/template/console/settings/ChannelDialog.tsx +241 -0
- package/template/console/settings/SettingsWorkspace.tsx +155 -0
- package/template/console/settings/events.ts +19 -0
- package/template/console/settings/handoff.ts +22 -0
- package/template/console/settings/types.ts +93 -0
- package/template/console/shell/WorkspaceShell.tsx +160 -0
- package/template/console/shell/controller.ts +182 -0
- package/template/console/shell/events.ts +25 -0
- package/template/console/shell/navigation.ts +61 -0
- package/template/console/shell/store.ts +56 -0
- package/template/console/shell/types.ts +86 -0
- package/template/console/workflows/CreateWorkflowDialog.tsx +87 -0
- package/template/console/workflows/WorkflowCanvas.tsx +42 -0
- package/template/console/workflows/WorkflowDialogs.tsx +6 -0
- package/template/console/workflows/WorkflowStudio.tsx +331 -0
- package/template/console/workflows/WorkflowWorkspace.tsx +82 -0
- package/template/console/workflows/events.ts +17 -0
- package/template/console/workflows/graph.ts +156 -0
- package/template/console/workflows/templates.ts +70 -0
- package/template/console/workflows/types.ts +201 -0
- package/template/gitignore.template +18 -0
- package/template/migrations/0001_reports_foundation.sql +444 -0
- package/template/migrations/0002_human_report_loop.sql +65 -0
- package/template/migrations/0003_delivery_reliability.sql +18 -0
- package/template/migrations/0004_public_intake.sql +14 -0
- package/template/migrations/0005_operations_visibility.sql +24 -0
- package/template/migrations/0006_ai_governance.sql +198 -0
- package/template/migrations/0007_ai_release_gates.sql +6 -0
- package/template/migrations/0008_retention_analytics_exports.sql +52 -0
- package/template/migrations/0009_retention_derived_copies.sql +14 -0
- package/template/migrations/0010_ai_quality_controls.sql +26 -0
- package/template/migrations/0011_analyst_presence.sql +28 -0
- package/template/migrations/0012_queue_policies.sql +87 -0
- package/template/migrations/0013_routing_agents.sql +63 -0
- package/template/migrations/0014_webhook_enrichments.sql +122 -0
- package/template/migrations/0015_queue_owned_ai.sql +55 -0
- package/template/migrations/0016_operator_accounts.sql +67 -0
- package/template/migrations/0017_operator_profiles_and_recovery.sql +33 -0
- package/template/migrations/0018_platform_configuration.sql +382 -0
- package/template/migrations/0019_workflow_authoring_runtime.sql +372 -0
- package/template/migrations/0020_tasks_findings_assistant_budgets.sql +427 -0
- package/template/migrations/0021_abuse_evidence_operations.sql +324 -0
- package/template/migrations/0022_workflow_dispatch_operations.sql +42 -0
- package/template/migrations/0023_component_connection_execution.sql +75 -0
- package/template/migrations/0024_access_runtime_integrity.sql +72 -0
- package/template/migrations/0025_installation_timezone.sql +11 -0
- package/template/migrations/0026_ai_and_egress_execution_controls.sql +49 -0
- package/template/migrations/0027_prompt_and_ai_registry.sql +37 -0
- package/template/migrations/0028_step_attempt_ai_provenance.sql +13 -0
- package/template/migrations/0029_evidence_fetch_transport.sql +5 -0
- package/template/migrations/0030_evidence_dlq_incidents.sql +45 -0
- package/template/migrations/0031_shadow_quality_integrity.sql +7 -0
- package/template/migrations/0032_action_delivery_outbox.sql +55 -0
- package/template/migrations/0033_configuration_and_assistant_drafts.sql +43 -0
- package/template/migrations/0034_installation_integrations.sql +31 -0
- package/template/migrations/0035_workspace_governance.sql +21 -0
- package/template/migrations/0036_published_routing_baseline.sql +15 -0
- package/template/migrations/0037_builtin_phishing_specialist.sql +71 -0
- package/template/migrations/0038_remove_deprecated_enrichment_runtime.sql +228 -0
- package/template/migrations/0039_secure_reporting_channels.sql +45 -0
- package/template/migrations/0040_notification_only_reporting.sql +24 -0
- package/template/migrations/0041_better_auth_credentials.sql +17 -0
- package/template/package.json +47 -0
- package/template/public/_headers +27 -0
- package/template/public/app-icon-192.png +0 -0
- package/template/public/app-icon-512.png +0 -0
- package/template/public/brand-icon.svg +7 -0
- package/template/public/brand-tokens.css +80 -0
- package/template/public/console/auth-shell.js +19340 -0
- package/template/public/customer-brand.js +58 -0
- package/template/public/embed/embed.css +139 -0
- package/template/public/embed/embed.js +408 -0
- package/template/public/embed/index.html +91 -0
- package/template/public/favicon.svg +7 -0
- package/template/public/fonts/Manrope-Variable.ttf +0 -0
- package/template/public/fonts/Newsreader-Italic-Variable.ttf +0 -0
- package/template/public/fonts/Newsreader-Variable.ttf +0 -0
- package/template/public/index.html +123 -0
- package/template/public/logo-primary.svg +7 -0
- package/template/public/logo-reversed.svg +7 -0
- package/template/public/manifest.webmanifest +21 -0
- package/template/public/public-report.js +184 -0
- package/template/public/report/index.html +39 -0
- package/template/public/report/public-report.css +20 -0
- package/template/public/social-card.png +0 -0
- package/template/public/styles.css +1521 -0
- package/template/public/widget.css +80 -0
- package/template/public/widget.js +220 -0
- package/template/reports.config.example.json +38 -0
- package/template/reports.schema.json +89 -0
- package/template/scripts/reports-auth-onboarding.mjs +180 -0
- package/template/scripts/reports-backup.mjs +276 -0
- package/template/scripts/reports-cloudflare-preflight.mjs +152 -0
- package/template/scripts/reports-deploy.mjs +173 -0
- package/template/scripts/reports-plan.mjs +226 -0
- package/template/scripts/reports-restore.mjs +180 -0
- package/template/scripts/reports-secrets.mjs +73 -0
- package/template/scripts/reports-uninstall-plan.mjs +32 -0
- package/template/src/agent-executor.ts +330 -0
- package/template/src/ai-observability.ts +163 -0
- package/template/src/ai-registry-validation.ts +244 -0
- package/template/src/ai-registry.ts +292 -0
- package/template/src/api-cursor.ts +84 -0
- package/template/src/assistant.ts +554 -0
- package/template/src/audit.ts +39 -0
- package/template/src/backup-service.ts +269 -0
- package/template/src/budget-control.ts +127 -0
- package/template/src/component-executor.ts +845 -0
- package/template/src/configuration-registry.ts +550 -0
- package/template/src/connection-egress.ts +430 -0
- package/template/src/connection-oauth.ts +368 -0
- package/template/src/evidence-service.ts +335 -0
- package/template/src/human-tasks.ts +316 -0
- package/template/src/index.ts +4114 -0
- package/template/src/installation-admin.ts +301 -0
- package/template/src/intake-abuse.ts +156 -0
- package/template/src/platform-registry-validation.ts +367 -0
- package/template/src/platform-registry.ts +753 -0
- package/template/src/report-admin.ts +342 -0
- package/template/src/report-ai-quality.ts +390 -0
- package/template/src/report-ai-validation.ts +80 -0
- package/template/src/report-ai.ts +857 -0
- package/template/src/report-auth.ts +292 -0
- package/template/src/report-better-auth.ts +583 -0
- package/template/src/report-context-schema.ts +132 -0
- package/template/src/report-context.ts +126 -0
- package/template/src/report-crypto.ts +142 -0
- package/template/src/report-delivery.ts +579 -0
- package/template/src/report-form-validation.ts +51 -0
- package/template/src/report-governance.ts +510 -0
- package/template/src/report-http.ts +90 -0
- package/template/src/report-operations.ts +685 -0
- package/template/src/report-operator-accounts.ts +810 -0
- package/template/src/report-presence.ts +398 -0
- package/template/src/report-queue-validation.ts +309 -0
- package/template/src/report-queues.ts +478 -0
- package/template/src/report-repository.ts +972 -0
- package/template/src/report-router-agent.ts +328 -0
- package/template/src/report-router-validation.ts +81 -0
- package/template/src/report-routing.ts +178 -0
- package/template/src/report-turnstile.ts +142 -0
- package/template/src/report-types.ts +224 -0
- package/template/src/report-validation.ts +279 -0
- package/template/src/report-workflow-validation.ts +119 -0
- package/template/src/report-workflow.ts +886 -0
- package/template/src/shadow-quality.ts +278 -0
- package/template/src/workflow-actions.ts +782 -0
- package/template/src/workflow-compiler.ts +230 -0
- package/template/src/workflow-dynamic-runtime.ts +613 -0
- package/template/src/workflow-effects.ts +316 -0
- package/template/src/workflow-expressions.ts +191 -0
- package/template/src/workflow-platform-types.ts +121 -0
- package/template/src/workflow-platform-validation.ts +540 -0
- package/template/src/workflow-repository.ts +916 -0
- package/template/src/workflow-runs.ts +686 -0
- package/template/src/workflow-simulator.ts +211 -0
- package/template/src/workspace-branding.ts +128 -0
- package/template/src/workspace-governance.ts +279 -0
- package/template/tsconfig.console.json +23 -0
- package/template/tsconfig.json +22 -0
- package/template/vite.console.config.ts +20 -0
- package/template/worker-configuration.d.ts +65 -0
|
@@ -0,0 +1,444 @@
|
|
|
1
|
+
PRAGMA foreign_keys = ON;
|
|
2
|
+
|
|
3
|
+
CREATE TABLE installations (
|
|
4
|
+
id TEXT PRIMARY KEY,
|
|
5
|
+
display_name TEXT NOT NULL,
|
|
6
|
+
default_locale TEXT NOT NULL DEFAULT 'en',
|
|
7
|
+
anonymous_reporting_enabled INTEGER NOT NULL DEFAULT 0 CHECK (anonymous_reporting_enabled IN (0, 1)),
|
|
8
|
+
created_at TEXT NOT NULL,
|
|
9
|
+
updated_at TEXT NOT NULL
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
CREATE TABLE application_integrations (
|
|
13
|
+
id TEXT PRIMARY KEY,
|
|
14
|
+
installation_id TEXT NOT NULL REFERENCES installations(id),
|
|
15
|
+
name TEXT NOT NULL,
|
|
16
|
+
key_id TEXT NOT NULL UNIQUE,
|
|
17
|
+
allowed_origins_json TEXT NOT NULL DEFAULT '[]',
|
|
18
|
+
enabled INTEGER NOT NULL DEFAULT 1 CHECK (enabled IN (0, 1)),
|
|
19
|
+
created_at TEXT NOT NULL,
|
|
20
|
+
updated_at TEXT NOT NULL
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
CREATE TABLE report_form_versions (
|
|
24
|
+
id TEXT PRIMARY KEY,
|
|
25
|
+
installation_id TEXT NOT NULL REFERENCES installations(id),
|
|
26
|
+
form_key TEXT NOT NULL,
|
|
27
|
+
version INTEGER NOT NULL CHECK (version > 0),
|
|
28
|
+
title TEXT NOT NULL,
|
|
29
|
+
description TEXT NOT NULL DEFAULT '',
|
|
30
|
+
target_types_json TEXT NOT NULL,
|
|
31
|
+
reasons_json TEXT NOT NULL,
|
|
32
|
+
fields_json TEXT NOT NULL,
|
|
33
|
+
consent_notice TEXT NOT NULL,
|
|
34
|
+
published_at TEXT,
|
|
35
|
+
retired_at TEXT,
|
|
36
|
+
created_by TEXT NOT NULL,
|
|
37
|
+
created_at TEXT NOT NULL,
|
|
38
|
+
UNIQUE (installation_id, form_key, version)
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
CREATE TABLE policy_versions (
|
|
42
|
+
id TEXT PRIMARY KEY,
|
|
43
|
+
installation_id TEXT NOT NULL REFERENCES installations(id),
|
|
44
|
+
policy_key TEXT NOT NULL,
|
|
45
|
+
version INTEGER NOT NULL CHECK (version > 0),
|
|
46
|
+
title TEXT NOT NULL,
|
|
47
|
+
rules_json TEXT NOT NULL,
|
|
48
|
+
published_at TEXT,
|
|
49
|
+
created_by TEXT NOT NULL,
|
|
50
|
+
created_at TEXT NOT NULL,
|
|
51
|
+
UNIQUE (installation_id, policy_key, version)
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
CREATE TABLE queue_definitions (
|
|
55
|
+
id TEXT PRIMARY KEY,
|
|
56
|
+
installation_id TEXT NOT NULL REFERENCES installations(id),
|
|
57
|
+
queue_key TEXT NOT NULL,
|
|
58
|
+
name TEXT NOT NULL,
|
|
59
|
+
queue_kind TEXT NOT NULL CHECK (queue_kind IN ('human', 'ai', 'appeal', 'operations')),
|
|
60
|
+
enabled INTEGER NOT NULL DEFAULT 1 CHECK (enabled IN (0, 1)),
|
|
61
|
+
created_at TEXT NOT NULL,
|
|
62
|
+
updated_at TEXT NOT NULL,
|
|
63
|
+
UNIQUE (installation_id, queue_key)
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
CREATE TABLE queue_versions (
|
|
67
|
+
id TEXT PRIMARY KEY,
|
|
68
|
+
queue_id TEXT NOT NULL REFERENCES queue_definitions(id),
|
|
69
|
+
version INTEGER NOT NULL CHECK (version > 0),
|
|
70
|
+
mode TEXT NOT NULL CHECK (mode IN ('off', 'shadow', 'assist', 'autonomous_low_priority')),
|
|
71
|
+
priority INTEGER NOT NULL DEFAULT 50 CHECK (priority BETWEEN 0 AND 100),
|
|
72
|
+
response_sla_minutes INTEGER,
|
|
73
|
+
resolution_sla_minutes INTEGER,
|
|
74
|
+
claim_ttl_minutes INTEGER NOT NULL DEFAULT 15 CHECK (claim_ttl_minutes BETWEEN 1 AND 1440),
|
|
75
|
+
fallback_queue_id TEXT REFERENCES queue_definitions(id),
|
|
76
|
+
configuration_json TEXT NOT NULL DEFAULT '{}',
|
|
77
|
+
published_at TEXT,
|
|
78
|
+
created_by TEXT NOT NULL,
|
|
79
|
+
created_at TEXT NOT NULL,
|
|
80
|
+
UNIQUE (queue_id, version)
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
CREATE TABLE routing_rule_versions (
|
|
84
|
+
id TEXT PRIMARY KEY,
|
|
85
|
+
installation_id TEXT NOT NULL REFERENCES installations(id),
|
|
86
|
+
version INTEGER NOT NULL CHECK (version > 0),
|
|
87
|
+
rules_json TEXT NOT NULL,
|
|
88
|
+
fixture_results_json TEXT NOT NULL,
|
|
89
|
+
published_at TEXT,
|
|
90
|
+
created_by TEXT NOT NULL,
|
|
91
|
+
created_at TEXT NOT NULL,
|
|
92
|
+
UNIQUE (installation_id, version)
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
CREATE TABLE reports (
|
|
96
|
+
id TEXT PRIMARY KEY,
|
|
97
|
+
public_reference TEXT NOT NULL UNIQUE,
|
|
98
|
+
installation_id TEXT NOT NULL REFERENCES installations(id),
|
|
99
|
+
integration_id TEXT NOT NULL REFERENCES application_integrations(id),
|
|
100
|
+
idempotency_key TEXT NOT NULL,
|
|
101
|
+
source TEXT NOT NULL CHECK (source IN ('signed_widget', 'public_page', 'server_api')),
|
|
102
|
+
form_version_id TEXT REFERENCES report_form_versions(id),
|
|
103
|
+
policy_version_id TEXT REFERENCES policy_versions(id),
|
|
104
|
+
routing_rule_version_id TEXT REFERENCES routing_rule_versions(id),
|
|
105
|
+
queue_id TEXT REFERENCES queue_definitions(id),
|
|
106
|
+
state TEXT NOT NULL CHECK (state IN (
|
|
107
|
+
'received', 'human_review', 'ai_review', 'awaiting_reporter', 'resolved_by_human',
|
|
108
|
+
'resolved_by_ai', 'human_review_requested', 'appealed', 'closed'
|
|
109
|
+
)),
|
|
110
|
+
priority INTEGER NOT NULL DEFAULT 50 CHECK (priority BETWEEN 0 AND 100),
|
|
111
|
+
reason_code TEXT NOT NULL,
|
|
112
|
+
locale TEXT NOT NULL,
|
|
113
|
+
consent_notice TEXT NOT NULL,
|
|
114
|
+
consented_at TEXT NOT NULL,
|
|
115
|
+
submitted_at TEXT NOT NULL,
|
|
116
|
+
received_at TEXT NOT NULL,
|
|
117
|
+
updated_at TEXT NOT NULL,
|
|
118
|
+
due_at TEXT,
|
|
119
|
+
resolved_at TEXT,
|
|
120
|
+
routing_status TEXT NOT NULL DEFAULT 'pending' CHECK (routing_status IN ('pending', 'enqueued', 'processing', 'complete', 'failed')),
|
|
121
|
+
routing_attempts INTEGER NOT NULL DEFAULT 0 CHECK (routing_attempts >= 0),
|
|
122
|
+
routing_error_code TEXT,
|
|
123
|
+
UNIQUE (integration_id, idempotency_key)
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
CREATE INDEX reports_queue_state_priority_idx
|
|
127
|
+
ON reports(queue_id, state, priority DESC, received_at ASC, id ASC);
|
|
128
|
+
CREATE INDEX reports_routing_status_idx
|
|
129
|
+
ON reports(routing_status, received_at ASC, id ASC);
|
|
130
|
+
CREATE INDEX reports_target_time_idx
|
|
131
|
+
ON reports(installation_id, received_at DESC, id DESC);
|
|
132
|
+
|
|
133
|
+
CREATE TABLE report_participants (
|
|
134
|
+
id TEXT PRIMARY KEY,
|
|
135
|
+
report_id TEXT NOT NULL REFERENCES reports(id) ON DELETE CASCADE,
|
|
136
|
+
audience TEXT NOT NULL CHECK (audience IN ('reporter', 'affected_user')),
|
|
137
|
+
reference TEXT,
|
|
138
|
+
contact_mode TEXT NOT NULL CHECK (contact_mode IN ('portal', 'customer_notification', 'none')),
|
|
139
|
+
contact_ciphertext TEXT,
|
|
140
|
+
created_at TEXT NOT NULL,
|
|
141
|
+
UNIQUE (report_id, audience)
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
CREATE TABLE report_targets (
|
|
145
|
+
id TEXT PRIMARY KEY,
|
|
146
|
+
report_id TEXT NOT NULL REFERENCES reports(id) ON DELETE CASCADE,
|
|
147
|
+
target_type TEXT NOT NULL,
|
|
148
|
+
target_reference TEXT NOT NULL,
|
|
149
|
+
owner_reference TEXT,
|
|
150
|
+
customer_url TEXT,
|
|
151
|
+
signed_facts_json TEXT NOT NULL DEFAULT '{}',
|
|
152
|
+
created_at TEXT NOT NULL,
|
|
153
|
+
UNIQUE (report_id, target_type, target_reference)
|
|
154
|
+
);
|
|
155
|
+
|
|
156
|
+
CREATE INDEX report_targets_reference_idx
|
|
157
|
+
ON report_targets(target_type, target_reference, report_id);
|
|
158
|
+
|
|
159
|
+
CREATE TABLE report_answers (
|
|
160
|
+
report_id TEXT NOT NULL REFERENCES reports(id) ON DELETE CASCADE,
|
|
161
|
+
field_key TEXT NOT NULL,
|
|
162
|
+
value_json TEXT NOT NULL,
|
|
163
|
+
created_at TEXT NOT NULL,
|
|
164
|
+
PRIMARY KEY (report_id, field_key)
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
CREATE TABLE evidence_references (
|
|
168
|
+
id TEXT PRIMARY KEY,
|
|
169
|
+
report_id TEXT NOT NULL REFERENCES reports(id) ON DELETE CASCADE,
|
|
170
|
+
evidence_kind TEXT NOT NULL CHECK (evidence_kind IN ('allegation', 'signed_fact', 'customer_reference', 'fetched_record', 'snapshot')),
|
|
171
|
+
reference TEXT NOT NULL,
|
|
172
|
+
availability TEXT NOT NULL DEFAULT 'available' CHECK (availability IN ('available', 'unavailable', 'deleted', 'changed')),
|
|
173
|
+
retention_class TEXT NOT NULL DEFAULT 'reference',
|
|
174
|
+
created_at TEXT NOT NULL,
|
|
175
|
+
UNIQUE (report_id, evidence_kind, reference)
|
|
176
|
+
);
|
|
177
|
+
|
|
178
|
+
CREATE TABLE report_state_history (
|
|
179
|
+
id TEXT PRIMARY KEY,
|
|
180
|
+
report_id TEXT NOT NULL REFERENCES reports(id) ON DELETE CASCADE,
|
|
181
|
+
background_job_id TEXT UNIQUE REFERENCES background_jobs(id),
|
|
182
|
+
from_state TEXT,
|
|
183
|
+
to_state TEXT NOT NULL,
|
|
184
|
+
reason_code TEXT NOT NULL,
|
|
185
|
+
actor_type TEXT NOT NULL,
|
|
186
|
+
actor_id TEXT NOT NULL,
|
|
187
|
+
created_at TEXT NOT NULL
|
|
188
|
+
);
|
|
189
|
+
|
|
190
|
+
CREATE INDEX report_state_history_report_idx
|
|
191
|
+
ON report_state_history(report_id, created_at ASC, id ASC);
|
|
192
|
+
|
|
193
|
+
CREATE TABLE portal_sessions (
|
|
194
|
+
id TEXT PRIMARY KEY,
|
|
195
|
+
report_id TEXT NOT NULL REFERENCES reports(id) ON DELETE CASCADE,
|
|
196
|
+
audience TEXT NOT NULL CHECK (audience IN ('reporter', 'affected_user')),
|
|
197
|
+
token_hash TEXT NOT NULL UNIQUE,
|
|
198
|
+
expires_at TEXT NOT NULL,
|
|
199
|
+
revoked_at TEXT,
|
|
200
|
+
created_at TEXT NOT NULL,
|
|
201
|
+
last_used_at TEXT
|
|
202
|
+
);
|
|
203
|
+
|
|
204
|
+
CREATE INDEX portal_sessions_report_idx ON portal_sessions(report_id, audience, expires_at);
|
|
205
|
+
|
|
206
|
+
CREATE TABLE context_token_uses (
|
|
207
|
+
jti TEXT PRIMARY KEY,
|
|
208
|
+
integration_id TEXT NOT NULL REFERENCES application_integrations(id),
|
|
209
|
+
report_id TEXT NOT NULL UNIQUE REFERENCES reports(id) ON DELETE CASCADE,
|
|
210
|
+
used_at TEXT NOT NULL
|
|
211
|
+
);
|
|
212
|
+
|
|
213
|
+
CREATE TABLE case_messages (
|
|
214
|
+
id TEXT PRIMARY KEY,
|
|
215
|
+
report_id TEXT NOT NULL REFERENCES reports(id) ON DELETE CASCADE,
|
|
216
|
+
audience TEXT NOT NULL CHECK (audience IN ('internal', 'reporter', 'affected_user')),
|
|
217
|
+
direction TEXT NOT NULL CHECK (direction IN ('inbound', 'outbound', 'internal')),
|
|
218
|
+
sender_type TEXT NOT NULL CHECK (sender_type IN ('reporter', 'affected_user', 'human', 'ai', 'system')),
|
|
219
|
+
sender_id TEXT NOT NULL,
|
|
220
|
+
body TEXT NOT NULL,
|
|
221
|
+
template_version_id TEXT,
|
|
222
|
+
automated INTEGER NOT NULL DEFAULT 0 CHECK (automated IN (0, 1)),
|
|
223
|
+
delivery_state TEXT NOT NULL DEFAULT 'not_required' CHECK (delivery_state IN ('not_required', 'queued', 'delivered', 'failed', 'suppressed')),
|
|
224
|
+
created_at TEXT NOT NULL
|
|
225
|
+
);
|
|
226
|
+
|
|
227
|
+
CREATE INDEX case_messages_report_audience_idx
|
|
228
|
+
ON case_messages(report_id, audience, created_at ASC, id ASC);
|
|
229
|
+
|
|
230
|
+
CREATE TABLE review_claims (
|
|
231
|
+
report_id TEXT PRIMARY KEY REFERENCES reports(id) ON DELETE CASCADE,
|
|
232
|
+
reviewer_id TEXT NOT NULL,
|
|
233
|
+
claimed_at TEXT NOT NULL,
|
|
234
|
+
expires_at TEXT NOT NULL,
|
|
235
|
+
version INTEGER NOT NULL DEFAULT 1 CHECK (version > 0)
|
|
236
|
+
);
|
|
237
|
+
|
|
238
|
+
CREATE TABLE decisions (
|
|
239
|
+
id TEXT PRIMARY KEY,
|
|
240
|
+
report_id TEXT NOT NULL REFERENCES reports(id),
|
|
241
|
+
decision_code TEXT NOT NULL,
|
|
242
|
+
policy_version_id TEXT NOT NULL REFERENCES policy_versions(id),
|
|
243
|
+
policy_code TEXT NOT NULL,
|
|
244
|
+
rationale TEXT NOT NULL,
|
|
245
|
+
evidence_references_json TEXT NOT NULL,
|
|
246
|
+
maker_type TEXT NOT NULL CHECK (maker_type IN ('human', 'ai')),
|
|
247
|
+
maker_id TEXT NOT NULL,
|
|
248
|
+
queue_version_id TEXT REFERENCES queue_versions(id),
|
|
249
|
+
ai_run_id TEXT,
|
|
250
|
+
proposed_action_code TEXT,
|
|
251
|
+
supersedes_decision_id TEXT REFERENCES decisions(id),
|
|
252
|
+
created_at TEXT NOT NULL
|
|
253
|
+
);
|
|
254
|
+
|
|
255
|
+
CREATE INDEX decisions_report_idx ON decisions(report_id, created_at DESC, id DESC);
|
|
256
|
+
|
|
257
|
+
CREATE TABLE notices (
|
|
258
|
+
id TEXT PRIMARY KEY,
|
|
259
|
+
report_id TEXT NOT NULL REFERENCES reports(id),
|
|
260
|
+
decision_id TEXT REFERENCES decisions(id),
|
|
261
|
+
audience TEXT NOT NULL CHECK (audience IN ('reporter', 'affected_user')),
|
|
262
|
+
template_version_id TEXT NOT NULL,
|
|
263
|
+
rendered_body TEXT NOT NULL,
|
|
264
|
+
delivery_state TEXT NOT NULL CHECK (delivery_state IN ('queued', 'delivered', 'failed', 'suppressed')),
|
|
265
|
+
created_at TEXT NOT NULL,
|
|
266
|
+
updated_at TEXT NOT NULL
|
|
267
|
+
);
|
|
268
|
+
|
|
269
|
+
CREATE TABLE action_outbox (
|
|
270
|
+
id TEXT PRIMARY KEY,
|
|
271
|
+
report_id TEXT NOT NULL REFERENCES reports(id),
|
|
272
|
+
decision_id TEXT NOT NULL REFERENCES decisions(id),
|
|
273
|
+
idempotency_key TEXT NOT NULL UNIQUE,
|
|
274
|
+
action_code TEXT NOT NULL,
|
|
275
|
+
target_reference TEXT NOT NULL,
|
|
276
|
+
payload_json TEXT NOT NULL,
|
|
277
|
+
status TEXT NOT NULL CHECK (status IN ('pending', 'delivering', 'accepted', 'rejected', 'already_applied', 'failed')),
|
|
278
|
+
attempt_count INTEGER NOT NULL DEFAULT 0 CHECK (attempt_count >= 0),
|
|
279
|
+
next_attempt_at TEXT NOT NULL,
|
|
280
|
+
last_error_code TEXT,
|
|
281
|
+
created_at TEXT NOT NULL,
|
|
282
|
+
updated_at TEXT NOT NULL
|
|
283
|
+
);
|
|
284
|
+
|
|
285
|
+
CREATE INDEX action_outbox_due_idx ON action_outbox(status, next_attempt_at, id);
|
|
286
|
+
|
|
287
|
+
CREATE TABLE action_attempts (
|
|
288
|
+
id TEXT PRIMARY KEY,
|
|
289
|
+
action_id TEXT NOT NULL REFERENCES action_outbox(id) ON DELETE CASCADE,
|
|
290
|
+
attempt_number INTEGER NOT NULL CHECK (attempt_number > 0),
|
|
291
|
+
response_class TEXT NOT NULL,
|
|
292
|
+
response_status INTEGER,
|
|
293
|
+
error_code TEXT,
|
|
294
|
+
started_at TEXT NOT NULL,
|
|
295
|
+
finished_at TEXT NOT NULL,
|
|
296
|
+
UNIQUE (action_id, attempt_number)
|
|
297
|
+
);
|
|
298
|
+
|
|
299
|
+
CREATE TABLE notification_outbox (
|
|
300
|
+
id TEXT PRIMARY KEY,
|
|
301
|
+
notice_id TEXT NOT NULL REFERENCES notices(id),
|
|
302
|
+
idempotency_key TEXT NOT NULL UNIQUE,
|
|
303
|
+
channel TEXT NOT NULL CHECK (channel IN ('customer_webhook', 'email')),
|
|
304
|
+
payload_json TEXT NOT NULL,
|
|
305
|
+
status TEXT NOT NULL CHECK (status IN ('pending', 'delivering', 'delivered', 'failed', 'suppressed')),
|
|
306
|
+
attempt_count INTEGER NOT NULL DEFAULT 0 CHECK (attempt_count >= 0),
|
|
307
|
+
next_attempt_at TEXT NOT NULL,
|
|
308
|
+
last_error_code TEXT,
|
|
309
|
+
created_at TEXT NOT NULL,
|
|
310
|
+
updated_at TEXT NOT NULL
|
|
311
|
+
);
|
|
312
|
+
|
|
313
|
+
CREATE INDEX notification_outbox_due_idx ON notification_outbox(status, next_attempt_at, id);
|
|
314
|
+
|
|
315
|
+
CREATE TABLE notification_attempts (
|
|
316
|
+
id TEXT PRIMARY KEY,
|
|
317
|
+
notification_id TEXT NOT NULL REFERENCES notification_outbox(id) ON DELETE CASCADE,
|
|
318
|
+
attempt_number INTEGER NOT NULL CHECK (attempt_number > 0),
|
|
319
|
+
response_class TEXT NOT NULL,
|
|
320
|
+
response_status INTEGER,
|
|
321
|
+
error_code TEXT,
|
|
322
|
+
started_at TEXT NOT NULL,
|
|
323
|
+
finished_at TEXT NOT NULL,
|
|
324
|
+
UNIQUE (notification_id, attempt_number)
|
|
325
|
+
);
|
|
326
|
+
|
|
327
|
+
CREATE TABLE appeals (
|
|
328
|
+
id TEXT PRIMARY KEY,
|
|
329
|
+
report_id TEXT NOT NULL REFERENCES reports(id),
|
|
330
|
+
decision_id TEXT NOT NULL REFERENCES decisions(id),
|
|
331
|
+
appellant_audience TEXT NOT NULL CHECK (appellant_audience IN ('reporter', 'affected_user')),
|
|
332
|
+
reason TEXT NOT NULL,
|
|
333
|
+
state TEXT NOT NULL CHECK (state IN ('submitted', 'human_review', 'upheld', 'modified', 'reversed')),
|
|
334
|
+
queue_id TEXT NOT NULL REFERENCES queue_definitions(id),
|
|
335
|
+
submitted_at TEXT NOT NULL,
|
|
336
|
+
resolved_at TEXT,
|
|
337
|
+
UNIQUE (decision_id, appellant_audience)
|
|
338
|
+
);
|
|
339
|
+
|
|
340
|
+
CREATE INDEX appeals_queue_state_idx ON appeals(queue_id, state, submitted_at ASC, id ASC);
|
|
341
|
+
|
|
342
|
+
CREATE TABLE appeal_decisions (
|
|
343
|
+
id TEXT PRIMARY KEY,
|
|
344
|
+
appeal_id TEXT NOT NULL UNIQUE REFERENCES appeals(id),
|
|
345
|
+
outcome TEXT NOT NULL CHECK (outcome IN ('upheld', 'modified', 'reversed')),
|
|
346
|
+
rationale TEXT NOT NULL,
|
|
347
|
+
reviewer_id TEXT NOT NULL,
|
|
348
|
+
corrective_action_id TEXT REFERENCES action_outbox(id),
|
|
349
|
+
created_at TEXT NOT NULL
|
|
350
|
+
);
|
|
351
|
+
|
|
352
|
+
CREATE TABLE background_jobs (
|
|
353
|
+
id TEXT PRIMARY KEY,
|
|
354
|
+
report_id TEXT REFERENCES reports(id),
|
|
355
|
+
job_type TEXT NOT NULL CHECK (job_type IN ('route_report', 'deliver_action', 'deliver_notification', 'resume_ai', 'retention')),
|
|
356
|
+
idempotency_key TEXT NOT NULL UNIQUE,
|
|
357
|
+
state TEXT NOT NULL CHECK (state IN ('pending', 'enqueued', 'processing', 'complete', 'failed', 'dead_letter')),
|
|
358
|
+
payload_json TEXT NOT NULL,
|
|
359
|
+
attempt_count INTEGER NOT NULL DEFAULT 0 CHECK (attempt_count >= 0),
|
|
360
|
+
available_at TEXT NOT NULL,
|
|
361
|
+
last_error_code TEXT,
|
|
362
|
+
created_at TEXT NOT NULL,
|
|
363
|
+
updated_at TEXT NOT NULL
|
|
364
|
+
);
|
|
365
|
+
|
|
366
|
+
CREATE INDEX background_jobs_reconcile_idx ON background_jobs(state, available_at, id);
|
|
367
|
+
|
|
368
|
+
CREATE TABLE audit_entries (
|
|
369
|
+
sequence INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
370
|
+
id TEXT NOT NULL UNIQUE,
|
|
371
|
+
action TEXT NOT NULL,
|
|
372
|
+
actor_type TEXT NOT NULL,
|
|
373
|
+
actor_id TEXT NOT NULL,
|
|
374
|
+
target_type TEXT NOT NULL,
|
|
375
|
+
target_id TEXT NOT NULL,
|
|
376
|
+
details_json TEXT NOT NULL,
|
|
377
|
+
previous_hash TEXT NOT NULL UNIQUE,
|
|
378
|
+
entry_hash TEXT NOT NULL UNIQUE,
|
|
379
|
+
created_at TEXT NOT NULL
|
|
380
|
+
);
|
|
381
|
+
|
|
382
|
+
CREATE INDEX audit_entries_target_idx
|
|
383
|
+
ON audit_entries(target_type, target_id, sequence DESC);
|
|
384
|
+
|
|
385
|
+
CREATE TABLE daily_aggregates (
|
|
386
|
+
aggregate_date TEXT NOT NULL,
|
|
387
|
+
metric_key TEXT NOT NULL,
|
|
388
|
+
dimension_key TEXT NOT NULL,
|
|
389
|
+
dimension_value TEXT NOT NULL,
|
|
390
|
+
value INTEGER NOT NULL DEFAULT 0,
|
|
391
|
+
updated_at TEXT NOT NULL,
|
|
392
|
+
PRIMARY KEY (aggregate_date, metric_key, dimension_key, dimension_value)
|
|
393
|
+
);
|
|
394
|
+
|
|
395
|
+
INSERT INTO installations (
|
|
396
|
+
id, display_name, default_locale, anonymous_reporting_enabled, created_at, updated_at
|
|
397
|
+
) VALUES (
|
|
398
|
+
'default', 'Safest Resolve', 'en', 0, strftime('%Y-%m-%dT%H:%M:%fZ', 'now'), strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
|
|
399
|
+
);
|
|
400
|
+
|
|
401
|
+
INSERT INTO application_integrations (
|
|
402
|
+
id, installation_id, name, key_id, allowed_origins_json, enabled, created_at, updated_at
|
|
403
|
+
) VALUES (
|
|
404
|
+
'default', 'default', 'Default integration', 'default', '["http://localhost:8787","http://localhost:8788"]', 1,
|
|
405
|
+
strftime('%Y-%m-%dT%H:%M:%fZ', 'now'), strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
|
|
406
|
+
);
|
|
407
|
+
|
|
408
|
+
INSERT INTO report_form_versions (
|
|
409
|
+
id, installation_id, form_key, version, title, description, target_types_json, reasons_json,
|
|
410
|
+
fields_json, consent_notice, published_at, created_by, created_at
|
|
411
|
+
) VALUES (
|
|
412
|
+
'general-v1', 'default', 'general', 1, 'Report a safety concern',
|
|
413
|
+
'Tell the service owner about abuse or a safety concern.',
|
|
414
|
+
'["message","profile","listing","account","file","transaction","service"]',
|
|
415
|
+
'[{"code":"harassment","label":"Harassment"},{"code":"spam","label":"Spam or scam"},{"code":"threat","label":"Threat or immediate danger"},{"code":"other","label":"Something else"}]',
|
|
416
|
+
'[{"key":"details","label":"What happened?","type":"long_text","required":true,"max_length":4000}]',
|
|
417
|
+
'Your report will be shared with authorized safety reviewers and handled according to the service privacy policy.',
|
|
418
|
+
strftime('%Y-%m-%dT%H:%M:%fZ', 'now'), 'system', strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
|
|
419
|
+
);
|
|
420
|
+
|
|
421
|
+
INSERT INTO policy_versions (
|
|
422
|
+
id, installation_id, policy_key, version, title, rules_json, published_at, created_by, created_at
|
|
423
|
+
) VALUES (
|
|
424
|
+
'general-policy-v1', 'default', 'general', 1, 'General safety policy',
|
|
425
|
+
'[{"code":"GENERAL-1","title":"Customer review required"}]',
|
|
426
|
+
strftime('%Y-%m-%dT%H:%M:%fZ', 'now'), 'system', strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
|
|
427
|
+
);
|
|
428
|
+
|
|
429
|
+
INSERT INTO queue_definitions (id, installation_id, queue_key, name, queue_kind, created_at, updated_at) VALUES
|
|
430
|
+
('urgent-human', 'default', 'urgent-human', 'Urgent human', 'human', strftime('%Y-%m-%dT%H:%M:%fZ', 'now'), strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
|
|
431
|
+
('standard-human', 'default', 'standard-human', 'Standard human', 'human', strftime('%Y-%m-%dT%H:%M:%fZ', 'now'), strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
|
|
432
|
+
('low-priority-ai', 'default', 'low-priority-ai', 'Low-priority AI', 'ai', strftime('%Y-%m-%dT%H:%M:%fZ', 'now'), strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
|
|
433
|
+
('appeals', 'default', 'appeals', 'Appeals', 'appeal', strftime('%Y-%m-%dT%H:%M:%fZ', 'now'), strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
|
|
434
|
+
('operations', 'default', 'operations', 'Operations', 'operations', strftime('%Y-%m-%dT%H:%M:%fZ', 'now'), strftime('%Y-%m-%dT%H:%M:%fZ', 'now'));
|
|
435
|
+
|
|
436
|
+
INSERT INTO queue_versions (
|
|
437
|
+
id, queue_id, version, mode, priority, response_sla_minutes, resolution_sla_minutes,
|
|
438
|
+
claim_ttl_minutes, fallback_queue_id, configuration_json, published_at, created_by, created_at
|
|
439
|
+
) VALUES
|
|
440
|
+
('urgent-human-v1', 'urgent-human', 1, 'off', 100, 15, 240, 15, NULL, '{}', strftime('%Y-%m-%dT%H:%M:%fZ', 'now'), 'system', strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
|
|
441
|
+
('standard-human-v1', 'standard-human', 1, 'off', 50, 1440, 10080, 15, NULL, '{}', strftime('%Y-%m-%dT%H:%M:%fZ', 'now'), 'system', strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
|
|
442
|
+
('low-priority-ai-v1', 'low-priority-ai', 1, 'shadow', 20, 1440, 10080, 15, 'standard-human', '{"allowed_outcomes":[],"protected_categories":[],"daily_volume_budget":0}', strftime('%Y-%m-%dT%H:%M:%fZ', 'now'), 'system', strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
|
|
443
|
+
('appeals-v1', 'appeals', 1, 'off', 60, 1440, 10080, 30, NULL, '{}', strftime('%Y-%m-%dT%H:%M:%fZ', 'now'), 'system', strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
|
|
444
|
+
('operations-v1', 'operations', 1, 'off', 80, 60, 1440, 30, NULL, '{}', strftime('%Y-%m-%dT%H:%M:%fZ', 'now'), 'system', strftime('%Y-%m-%dT%H:%M:%fZ', 'now'));
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
PRAGMA foreign_keys = ON;
|
|
2
|
+
|
|
3
|
+
ALTER TABLE case_messages ADD COLUMN idempotency_key TEXT;
|
|
4
|
+
CREATE UNIQUE INDEX case_messages_idempotency_idx ON case_messages(report_id, idempotency_key) WHERE idempotency_key IS NOT NULL;
|
|
5
|
+
|
|
6
|
+
ALTER TABLE decisions ADD COLUMN idempotency_key TEXT;
|
|
7
|
+
CREATE UNIQUE INDEX decisions_idempotency_idx ON decisions(report_id, idempotency_key) WHERE idempotency_key IS NOT NULL;
|
|
8
|
+
|
|
9
|
+
ALTER TABLE notices ADD COLUMN idempotency_key TEXT;
|
|
10
|
+
CREATE UNIQUE INDEX notices_idempotency_idx ON notices(report_id, audience, idempotency_key) WHERE idempotency_key IS NOT NULL;
|
|
11
|
+
|
|
12
|
+
ALTER TABLE appeals ADD COLUMN idempotency_key TEXT;
|
|
13
|
+
CREATE UNIQUE INDEX appeals_idempotency_idx ON appeals(report_id, idempotency_key) WHERE idempotency_key IS NOT NULL;
|
|
14
|
+
|
|
15
|
+
CREATE TABLE message_template_versions (
|
|
16
|
+
id TEXT PRIMARY KEY,
|
|
17
|
+
installation_id TEXT NOT NULL REFERENCES installations(id),
|
|
18
|
+
template_key TEXT NOT NULL,
|
|
19
|
+
version INTEGER NOT NULL CHECK (version > 0),
|
|
20
|
+
audience TEXT NOT NULL CHECK (audience IN ('reporter', 'affected_user')),
|
|
21
|
+
purpose TEXT NOT NULL CHECK (purpose IN ('follow_up', 'outcome', 'affected_user_notice', 'appeal_outcome')),
|
|
22
|
+
locale TEXT NOT NULL,
|
|
23
|
+
body_template TEXT NOT NULL,
|
|
24
|
+
published_at TEXT,
|
|
25
|
+
created_by TEXT NOT NULL,
|
|
26
|
+
created_at TEXT NOT NULL,
|
|
27
|
+
UNIQUE (installation_id, template_key, version, locale)
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
CREATE TABLE appeal_claims (
|
|
31
|
+
appeal_id TEXT PRIMARY KEY REFERENCES appeals(id) ON DELETE CASCADE,
|
|
32
|
+
reviewer_id TEXT NOT NULL,
|
|
33
|
+
claimed_at TEXT NOT NULL,
|
|
34
|
+
expires_at TEXT NOT NULL,
|
|
35
|
+
version INTEGER NOT NULL DEFAULT 1 CHECK (version > 0)
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
CREATE TABLE audit_events (
|
|
39
|
+
id TEXT PRIMARY KEY,
|
|
40
|
+
idempotency_key TEXT NOT NULL UNIQUE,
|
|
41
|
+
action TEXT NOT NULL,
|
|
42
|
+
actor_type TEXT NOT NULL,
|
|
43
|
+
actor_id TEXT NOT NULL,
|
|
44
|
+
target_type TEXT NOT NULL,
|
|
45
|
+
target_id TEXT NOT NULL,
|
|
46
|
+
details_json TEXT NOT NULL,
|
|
47
|
+
created_at TEXT NOT NULL,
|
|
48
|
+
chained_at TEXT,
|
|
49
|
+
chain_error_code TEXT
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
CREATE INDEX audit_events_pending_idx ON audit_events(chained_at, created_at, id);
|
|
53
|
+
|
|
54
|
+
INSERT INTO message_template_versions (
|
|
55
|
+
id, installation_id, template_key, version, audience, purpose, locale,
|
|
56
|
+
body_template, published_at, created_by, created_at
|
|
57
|
+
) VALUES
|
|
58
|
+
('reporter-follow-up-v1', 'default', 'reporter-follow-up', 1, 'reporter', 'follow_up', 'en',
|
|
59
|
+
'{{message}}', strftime('%Y-%m-%dT%H:%M:%fZ', 'now'), 'system', strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
|
|
60
|
+
('reporter-outcome-v1', 'default', 'reporter-outcome', 1, 'reporter', 'outcome', 'en',
|
|
61
|
+
'{{message}}', strftime('%Y-%m-%dT%H:%M:%fZ', 'now'), 'system', strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
|
|
62
|
+
('affected-user-notice-v1', 'default', 'affected-user-notice', 1, 'affected_user', 'affected_user_notice', 'en',
|
|
63
|
+
'{{message}}', strftime('%Y-%m-%dT%H:%M:%fZ', 'now'), 'system', strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
|
|
64
|
+
('appeal-outcome-v1', 'default', 'appeal-outcome', 1, 'affected_user', 'appeal_outcome', 'en',
|
|
65
|
+
'{{message}}', strftime('%Y-%m-%dT%H:%M:%fZ', 'now'), 'system', strftime('%Y-%m-%dT%H:%M:%fZ', 'now'));
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
PRAGMA foreign_keys = ON;
|
|
2
|
+
|
|
3
|
+
ALTER TABLE notices ADD COLUMN message_id TEXT REFERENCES case_messages(id);
|
|
4
|
+
|
|
5
|
+
ALTER TABLE appeal_decisions ADD COLUMN idempotency_key TEXT;
|
|
6
|
+
CREATE UNIQUE INDEX appeal_decisions_idempotency_idx
|
|
7
|
+
ON appeal_decisions(appeal_id, idempotency_key) WHERE idempotency_key IS NOT NULL;
|
|
8
|
+
|
|
9
|
+
ALTER TABLE action_outbox ADD COLUMN lease_expires_at TEXT;
|
|
10
|
+
ALTER TABLE action_outbox ADD COLUMN terminal INTEGER NOT NULL DEFAULT 0 CHECK (terminal IN (0, 1));
|
|
11
|
+
|
|
12
|
+
ALTER TABLE notification_outbox ADD COLUMN lease_expires_at TEXT;
|
|
13
|
+
ALTER TABLE notification_outbox ADD COLUMN terminal INTEGER NOT NULL DEFAULT 0 CHECK (terminal IN (0, 1));
|
|
14
|
+
|
|
15
|
+
CREATE INDEX action_outbox_reconcile_idx
|
|
16
|
+
ON action_outbox(terminal, status, next_attempt_at, lease_expires_at, id);
|
|
17
|
+
CREATE INDEX notification_outbox_reconcile_idx
|
|
18
|
+
ON notification_outbox(terminal, status, next_attempt_at, lease_expires_at, id);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
PRAGMA foreign_keys = ON;
|
|
2
|
+
|
|
3
|
+
CREATE TABLE intake_rate_limits (
|
|
4
|
+
bucket_key TEXT NOT NULL,
|
|
5
|
+
window_start TEXT NOT NULL,
|
|
6
|
+
request_count INTEGER NOT NULL DEFAULT 0 CHECK (request_count >= 0),
|
|
7
|
+
updated_at TEXT NOT NULL,
|
|
8
|
+
PRIMARY KEY (bucket_key, window_start)
|
|
9
|
+
);
|
|
10
|
+
|
|
11
|
+
CREATE INDEX intake_rate_limits_expiry_idx ON intake_rate_limits(window_start, updated_at);
|
|
12
|
+
|
|
13
|
+
UPDATE installations SET anonymous_reporting_enabled = 1, updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
|
|
14
|
+
WHERE id = 'default';
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
PRAGMA foreign_keys = ON;
|
|
2
|
+
|
|
3
|
+
CREATE TABLE dead_letter_items (
|
|
4
|
+
id TEXT PRIMARY KEY,
|
|
5
|
+
fingerprint TEXT NOT NULL UNIQUE,
|
|
6
|
+
source_queue TEXT NOT NULL,
|
|
7
|
+
source_message_id TEXT NOT NULL,
|
|
8
|
+
job_type TEXT NOT NULL CHECK (job_type IN ('route_report', 'deliver_action', 'deliver_notification', 'invalid')),
|
|
9
|
+
job_id TEXT,
|
|
10
|
+
report_id TEXT REFERENCES reports(id),
|
|
11
|
+
outbox_id TEXT,
|
|
12
|
+
state TEXT NOT NULL DEFAULT 'open' CHECK (state IN ('open', 'acknowledged', 'resolved')),
|
|
13
|
+
error_code TEXT NOT NULL,
|
|
14
|
+
occurrence_count INTEGER NOT NULL DEFAULT 1 CHECK (occurrence_count > 0),
|
|
15
|
+
details_json TEXT NOT NULL DEFAULT '{}',
|
|
16
|
+
first_seen_at TEXT NOT NULL,
|
|
17
|
+
last_seen_at TEXT NOT NULL,
|
|
18
|
+
resolved_at TEXT
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
CREATE INDEX dead_letter_items_state_idx
|
|
22
|
+
ON dead_letter_items(state, last_seen_at DESC, id DESC);
|
|
23
|
+
CREATE INDEX dead_letter_items_report_idx
|
|
24
|
+
ON dead_letter_items(report_id, last_seen_at DESC, id DESC);
|