@crowdsource.you/core 1.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/README.md +571 -0
- package/dist/cases.d.ts +66 -0
- package/dist/cases.d.ts.map +1 -0
- package/dist/cases.js +79 -0
- package/dist/cases.js.map +1 -0
- package/dist/client.d.ts +90 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +125 -0
- package/dist/client.js.map +1 -0
- package/dist/communityNotes.d.ts +49 -0
- package/dist/communityNotes.d.ts.map +1 -0
- package/dist/communityNotes.js +104 -0
- package/dist/communityNotes.js.map +1 -0
- package/dist/credential.d.ts +58 -0
- package/dist/credential.d.ts.map +1 -0
- package/dist/credential.js +71 -0
- package/dist/credential.js.map +1 -0
- package/dist/defaults.d.ts +61 -0
- package/dist/defaults.d.ts.map +1 -0
- package/dist/defaults.js +82 -0
- package/dist/defaults.js.map +1 -0
- package/dist/digest.d.ts +44 -0
- package/dist/digest.d.ts.map +1 -0
- package/dist/digest.js +79 -0
- package/dist/digest.js.map +1 -0
- package/dist/envelope.d.ts +143 -0
- package/dist/envelope.d.ts.map +1 -0
- package/dist/envelope.js +258 -0
- package/dist/envelope.js.map +1 -0
- package/dist/errors.d.ts +90 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +151 -0
- package/dist/errors.js.map +1 -0
- package/dist/esm/cases.js +74 -0
- package/dist/esm/cases.js.map +1 -0
- package/dist/esm/client.js +121 -0
- package/dist/esm/client.js.map +1 -0
- package/dist/esm/communityNotes.js +100 -0
- package/dist/esm/communityNotes.js.map +1 -0
- package/dist/esm/credential.js +67 -0
- package/dist/esm/credential.js.map +1 -0
- package/dist/esm/defaults.js +77 -0
- package/dist/esm/defaults.js.map +1 -0
- package/dist/esm/digest.js +74 -0
- package/dist/esm/digest.js.map +1 -0
- package/dist/esm/envelope.js +252 -0
- package/dist/esm/envelope.js.map +1 -0
- package/dist/esm/errors.js +140 -0
- package/dist/esm/errors.js.map +1 -0
- package/dist/esm/express/index.js +29 -0
- package/dist/esm/express/index.js.map +1 -0
- package/dist/esm/express/middleware.js +293 -0
- package/dist/esm/express/middleware.js.map +1 -0
- package/dist/esm/express/store.js +69 -0
- package/dist/esm/express/store.js.map +1 -0
- package/dist/esm/express/verify.js +133 -0
- package/dist/esm/express/verify.js.map +1 -0
- package/dist/esm/index.js +57 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/outbox/client.js +43 -0
- package/dist/esm/outbox/client.js.map +1 -0
- package/dist/esm/outbox/decision.js +153 -0
- package/dist/esm/outbox/decision.js.map +1 -0
- package/dist/esm/outbox/delivery.js +129 -0
- package/dist/esm/outbox/delivery.js.map +1 -0
- package/dist/esm/outbox/enforcement/executor.js +219 -0
- package/dist/esm/outbox/enforcement/executor.js.map +1 -0
- package/dist/esm/outbox/enforcement/planner.js +326 -0
- package/dist/esm/outbox/enforcement/planner.js.map +1 -0
- package/dist/esm/outbox/evidence.js +173 -0
- package/dist/esm/outbox/evidence.js.map +1 -0
- package/dist/esm/outbox/inbound.js +87 -0
- package/dist/esm/outbox/inbound.js.map +1 -0
- package/dist/esm/outbox/index.js +71 -0
- package/dist/esm/outbox/index.js.map +1 -0
- package/dist/esm/outbox/intake.js +140 -0
- package/dist/esm/outbox/intake.js.map +1 -0
- package/dist/esm/outbox/integration.js +116 -0
- package/dist/esm/outbox/integration.js.map +1 -0
- package/dist/esm/outbox/outbox/dispatcher.js +114 -0
- package/dist/esm/outbox/outbox/dispatcher.js.map +1 -0
- package/dist/esm/outbox/outbox/service.js +271 -0
- package/dist/esm/outbox/outbox/service.js.map +1 -0
- package/dist/esm/outbox/postgres/index.js +41 -0
- package/dist/esm/outbox/postgres/index.js.map +1 -0
- package/dist/esm/outbox/postgres/registries.js +155 -0
- package/dist/esm/outbox/postgres/registries.js.map +1 -0
- package/dist/esm/outbox/postgres/reportColumns.js +191 -0
- package/dist/esm/outbox/postgres/reportColumns.js.map +1 -0
- package/dist/esm/outbox/postgres/store/enforcement.js +158 -0
- package/dist/esm/outbox/postgres/store/enforcement.js.map +1 -0
- package/dist/esm/outbox/postgres/store/events.js +101 -0
- package/dist/esm/outbox/postgres/store/events.js.map +1 -0
- package/dist/esm/outbox/postgres/store/index.js +59 -0
- package/dist/esm/outbox/postgres/store/index.js.map +1 -0
- package/dist/esm/outbox/postgres/store/outbox.js +207 -0
- package/dist/esm/outbox/postgres/store/outbox.js.map +1 -0
- package/dist/esm/outbox/postgres/store/reports.js +231 -0
- package/dist/esm/outbox/postgres/store/reports.js.map +1 -0
- package/dist/esm/outbox/postgres/store/transaction.js +29 -0
- package/dist/esm/outbox/postgres/store/transaction.js.map +1 -0
- package/dist/esm/outbox/postgres/tables.js +270 -0
- package/dist/esm/outbox/postgres/tables.js.map +1 -0
- package/dist/esm/outbox/reconciliation.js +157 -0
- package/dist/esm/outbox/reconciliation.js.map +1 -0
- package/dist/esm/outbox/reportStatus.js +22 -0
- package/dist/esm/outbox/reportStatus.js.map +1 -0
- package/dist/esm/outbox/retention.js +33 -0
- package/dist/esm/outbox/retention.js.map +1 -0
- package/dist/esm/outbox/store/types.js +30 -0
- package/dist/esm/outbox/store/types.js.map +1 -0
- package/dist/esm/outbox/types.js +23 -0
- package/dist/esm/outbox/types.js.map +1 -0
- package/dist/esm/outbox/webhook.js +145 -0
- package/dist/esm/outbox/webhook.js.map +1 -0
- package/dist/esm/package.json +1 -0
- package/dist/esm/reports.js +74 -0
- package/dist/esm/reports.js.map +1 -0
- package/dist/esm/testing/fixtures.js +132 -0
- package/dist/esm/testing/fixtures.js.map +1 -0
- package/dist/esm/testing/index.js +33 -0
- package/dist/esm/testing/index.js.map +1 -0
- package/dist/esm/testing/sandbox.js +337 -0
- package/dist/esm/testing/sandbox.js.map +1 -0
- package/dist/esm/testing/webhook-simulator.js +93 -0
- package/dist/esm/testing/webhook-simulator.js.map +1 -0
- package/dist/esm/transport.js +177 -0
- package/dist/esm/transport.js.map +1 -0
- package/dist/esm/webhookEndpoints.js +139 -0
- package/dist/esm/webhookEndpoints.js.map +1 -0
- package/dist/express/index.d.ts +32 -0
- package/dist/express/index.d.ts.map +1 -0
- package/dist/express/index.js +40 -0
- package/dist/express/index.js.map +1 -0
- package/dist/express/middleware.d.ts +97 -0
- package/dist/express/middleware.d.ts.map +1 -0
- package/dist/express/middleware.js +298 -0
- package/dist/express/middleware.js.map +1 -0
- package/dist/express/store.d.ts +45 -0
- package/dist/express/store.d.ts.map +1 -0
- package/dist/express/store.js +72 -0
- package/dist/express/store.js.map +1 -0
- package/dist/express/verify.d.ts +86 -0
- package/dist/express/verify.d.ts.map +1 -0
- package/dist/express/verify.js +138 -0
- package/dist/express/verify.js.map +1 -0
- package/dist/index.d.ts +67 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +89 -0
- package/dist/index.js.map +1 -0
- package/dist/outbox/client.d.ts +35 -0
- package/dist/outbox/client.d.ts.map +1 -0
- package/dist/outbox/client.js +46 -0
- package/dist/outbox/client.js.map +1 -0
- package/dist/outbox/decision.d.ts +36 -0
- package/dist/outbox/decision.d.ts.map +1 -0
- package/dist/outbox/decision.js +159 -0
- package/dist/outbox/decision.js.map +1 -0
- package/dist/outbox/delivery.d.ts +50 -0
- package/dist/outbox/delivery.d.ts.map +1 -0
- package/dist/outbox/delivery.js +135 -0
- package/dist/outbox/delivery.js.map +1 -0
- package/dist/outbox/enforcement/executor.d.ts +26 -0
- package/dist/outbox/enforcement/executor.d.ts.map +1 -0
- package/dist/outbox/enforcement/executor.js +222 -0
- package/dist/outbox/enforcement/executor.js.map +1 -0
- package/dist/outbox/enforcement/planner.d.ts +50 -0
- package/dist/outbox/enforcement/planner.d.ts.map +1 -0
- package/dist/outbox/enforcement/planner.js +333 -0
- package/dist/outbox/enforcement/planner.js.map +1 -0
- package/dist/outbox/evidence.d.ts +114 -0
- package/dist/outbox/evidence.d.ts.map +1 -0
- package/dist/outbox/evidence.js +181 -0
- package/dist/outbox/evidence.js.map +1 -0
- package/dist/outbox/inbound.d.ts +78 -0
- package/dist/outbox/inbound.d.ts.map +1 -0
- package/dist/outbox/inbound.js +91 -0
- package/dist/outbox/inbound.js.map +1 -0
- package/dist/outbox/index.d.ts +79 -0
- package/dist/outbox/index.d.ts.map +1 -0
- package/dist/outbox/index.js +98 -0
- package/dist/outbox/index.js.map +1 -0
- package/dist/outbox/intake.d.ts +62 -0
- package/dist/outbox/intake.d.ts.map +1 -0
- package/dist/outbox/intake.js +145 -0
- package/dist/outbox/intake.js.map +1 -0
- package/dist/outbox/integration.d.ts +62 -0
- package/dist/outbox/integration.d.ts.map +1 -0
- package/dist/outbox/integration.js +119 -0
- package/dist/outbox/integration.js.map +1 -0
- package/dist/outbox/outbox/dispatcher.d.ts +26 -0
- package/dist/outbox/outbox/dispatcher.d.ts.map +1 -0
- package/dist/outbox/outbox/dispatcher.js +119 -0
- package/dist/outbox/outbox/dispatcher.js.map +1 -0
- package/dist/outbox/outbox/service.d.ts +124 -0
- package/dist/outbox/outbox/service.d.ts.map +1 -0
- package/dist/outbox/outbox/service.js +279 -0
- package/dist/outbox/outbox/service.js.map +1 -0
- package/dist/outbox/postgres/index.d.ts +44 -0
- package/dist/outbox/postgres/index.d.ts.map +1 -0
- package/dist/outbox/postgres/index.js +51 -0
- package/dist/outbox/postgres/index.js.map +1 -0
- package/dist/outbox/postgres/registries.d.ts +69 -0
- package/dist/outbox/postgres/registries.d.ts.map +1 -0
- package/dist/outbox/postgres/registries.js +159 -0
- package/dist/outbox/postgres/registries.js.map +1 -0
- package/dist/outbox/postgres/reportColumns.d.ts +154 -0
- package/dist/outbox/postgres/reportColumns.d.ts.map +1 -0
- package/dist/outbox/postgres/reportColumns.js +195 -0
- package/dist/outbox/postgres/reportColumns.js.map +1 -0
- package/dist/outbox/postgres/store/enforcement.d.ts +33 -0
- package/dist/outbox/postgres/store/enforcement.d.ts.map +1 -0
- package/dist/outbox/postgres/store/enforcement.js +161 -0
- package/dist/outbox/postgres/store/enforcement.js.map +1 -0
- package/dist/outbox/postgres/store/events.d.ts +46 -0
- package/dist/outbox/postgres/store/events.d.ts.map +1 -0
- package/dist/outbox/postgres/store/events.js +104 -0
- package/dist/outbox/postgres/store/events.js.map +1 -0
- package/dist/outbox/postgres/store/index.d.ts +27 -0
- package/dist/outbox/postgres/store/index.d.ts.map +1 -0
- package/dist/outbox/postgres/store/index.js +62 -0
- package/dist/outbox/postgres/store/index.js.map +1 -0
- package/dist/outbox/postgres/store/outbox.d.ts +8 -0
- package/dist/outbox/postgres/store/outbox.d.ts.map +1 -0
- package/dist/outbox/postgres/store/outbox.js +210 -0
- package/dist/outbox/postgres/store/outbox.js.map +1 -0
- package/dist/outbox/postgres/store/reports.d.ts +69 -0
- package/dist/outbox/postgres/store/reports.d.ts.map +1 -0
- package/dist/outbox/postgres/store/reports.js +234 -0
- package/dist/outbox/postgres/store/reports.js.map +1 -0
- package/dist/outbox/postgres/store/transaction.d.ts +49 -0
- package/dist/outbox/postgres/store/transaction.d.ts.map +1 -0
- package/dist/outbox/postgres/store/transaction.js +32 -0
- package/dist/outbox/postgres/store/transaction.js.map +1 -0
- package/dist/outbox/postgres/tables.d.ts +737 -0
- package/dist/outbox/postgres/tables.d.ts.map +1 -0
- package/dist/outbox/postgres/tables.js +273 -0
- package/dist/outbox/postgres/tables.js.map +1 -0
- package/dist/outbox/reconciliation.d.ts +49 -0
- package/dist/outbox/reconciliation.d.ts.map +1 -0
- package/dist/outbox/reconciliation.js +162 -0
- package/dist/outbox/reconciliation.js.map +1 -0
- package/dist/outbox/reportStatus.d.ts +12 -0
- package/dist/outbox/reportStatus.d.ts.map +1 -0
- package/dist/outbox/reportStatus.js +25 -0
- package/dist/outbox/reportStatus.js.map +1 -0
- package/dist/outbox/retention.d.ts +33 -0
- package/dist/outbox/retention.d.ts.map +1 -0
- package/dist/outbox/retention.js +36 -0
- package/dist/outbox/retention.js.map +1 -0
- package/dist/outbox/store/types.d.ts +466 -0
- package/dist/outbox/store/types.d.ts.map +1 -0
- package/dist/outbox/store/types.js +31 -0
- package/dist/outbox/store/types.js.map +1 -0
- package/dist/outbox/types.d.ts +660 -0
- package/dist/outbox/types.d.ts.map +1 -0
- package/dist/outbox/types.js +24 -0
- package/dist/outbox/types.js.map +1 -0
- package/dist/outbox/webhook.d.ts +15 -0
- package/dist/outbox/webhook.d.ts.map +1 -0
- package/dist/outbox/webhook.js +148 -0
- package/dist/outbox/webhook.js.map +1 -0
- package/dist/reports.d.ts +73 -0
- package/dist/reports.d.ts.map +1 -0
- package/dist/reports.js +78 -0
- package/dist/reports.js.map +1 -0
- package/dist/testing/fixtures.d.ts +62 -0
- package/dist/testing/fixtures.d.ts.map +1 -0
- package/dist/testing/fixtures.js +137 -0
- package/dist/testing/fixtures.js.map +1 -0
- package/dist/testing/index.d.ts +36 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +43 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/sandbox.d.ts +109 -0
- package/dist/testing/sandbox.d.ts.map +1 -0
- package/dist/testing/sandbox.js +342 -0
- package/dist/testing/sandbox.js.map +1 -0
- package/dist/testing/webhook-simulator.d.ts +78 -0
- package/dist/testing/webhook-simulator.d.ts.map +1 -0
- package/dist/testing/webhook-simulator.js +98 -0
- package/dist/testing/webhook-simulator.js.map +1 -0
- package/dist/transport.d.ts +59 -0
- package/dist/transport.d.ts.map +1 -0
- package/dist/transport.js +181 -0
- package/dist/transport.js.map +1 -0
- package/dist/webhookEndpoints.d.ts +147 -0
- package/dist/webhookEndpoints.d.ts.map +1 -0
- package/dist/webhookEndpoints.js +143 -0
- package/dist/webhookEndpoints.js.map +1 -0
- package/package.json +127 -0
- package/src/cases.ts +119 -0
- package/src/client.ts +202 -0
- package/src/communityNotes.ts +194 -0
- package/src/credential.ts +100 -0
- package/src/defaults.ts +87 -0
- package/src/digest.ts +91 -0
- package/src/envelope.ts +432 -0
- package/src/errors.ts +165 -0
- package/src/express/index.ts +43 -0
- package/src/express/middleware.ts +387 -0
- package/src/express/store.ts +85 -0
- package/src/express/verify.ts +166 -0
- package/src/index.ts +107 -0
- package/src/outbox/client.ts +75 -0
- package/src/outbox/decision.ts +209 -0
- package/src/outbox/delivery.ts +163 -0
- package/src/outbox/enforcement/executor.ts +288 -0
- package/src/outbox/enforcement/planner.ts +377 -0
- package/src/outbox/evidence.ts +231 -0
- package/src/outbox/inbound.ts +140 -0
- package/src/outbox/index.ts +160 -0
- package/src/outbox/intake.ts +175 -0
- package/src/outbox/integration.ts +205 -0
- package/src/outbox/outbox/dispatcher.ts +131 -0
- package/src/outbox/outbox/service.ts +444 -0
- package/src/outbox/postgres/index.ts +59 -0
- package/src/outbox/postgres/registries.ts +177 -0
- package/src/outbox/postgres/reportColumns.ts +281 -0
- package/src/outbox/postgres/store/enforcement.ts +186 -0
- package/src/outbox/postgres/store/events.ts +112 -0
- package/src/outbox/postgres/store/index.ts +72 -0
- package/src/outbox/postgres/store/outbox.ts +273 -0
- package/src/outbox/postgres/store/reports.ts +349 -0
- package/src/outbox/postgres/store/transaction.ts +64 -0
- package/src/outbox/postgres/tables.ts +339 -0
- package/src/outbox/reconciliation.ts +199 -0
- package/src/outbox/reportStatus.ts +24 -0
- package/src/outbox/retention.ts +34 -0
- package/src/outbox/store/types.ts +528 -0
- package/src/outbox/types.ts +753 -0
- package/src/outbox/webhook.ts +165 -0
- package/src/reports.ts +138 -0
- package/src/testing/fixtures.ts +183 -0
- package/src/testing/index.ts +57 -0
- package/src/testing/sandbox.ts +469 -0
- package/src/testing/webhook-simulator.ts +166 -0
- package/src/transport.ts +250 -0
- package/src/webhookEndpoints.ts +256 -0
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.postgresReportStore = postgresReportStore;
|
|
4
|
+
const drizzle_orm_1 = require("drizzle-orm");
|
|
5
|
+
const OPTIONAL_REPORT_FIELDS = [
|
|
6
|
+
'details',
|
|
7
|
+
'localStatusReason',
|
|
8
|
+
'crowdSourceReportId',
|
|
9
|
+
'crowdSourceCaseId',
|
|
10
|
+
'crowdSourceMerged',
|
|
11
|
+
'contentSnapshotHash',
|
|
12
|
+
'submittedAt',
|
|
13
|
+
'lastDeliveryError',
|
|
14
|
+
'decisionId',
|
|
15
|
+
'decisionRevision',
|
|
16
|
+
'decisionOutcome',
|
|
17
|
+
'decisionStatus',
|
|
18
|
+
'decidedAt',
|
|
19
|
+
'enforcedAction',
|
|
20
|
+
'enforcedAt',
|
|
21
|
+
];
|
|
22
|
+
/** Drop the package's own optional fields when the column is NULL. */
|
|
23
|
+
function absentWhereNull(row) {
|
|
24
|
+
const normalised = { ...row };
|
|
25
|
+
for (const field of OPTIONAL_REPORT_FIELDS) {
|
|
26
|
+
if (normalised[field] === null)
|
|
27
|
+
delete normalised[field];
|
|
28
|
+
}
|
|
29
|
+
return normalised;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* The row, as the port declares it.
|
|
33
|
+
*
|
|
34
|
+
* An unchecked declaration, not a conversion — the same escape the Mongoose store
|
|
35
|
+
* takes with `.lean<TReport>()`, and for the same reason: a driver cannot know an
|
|
36
|
+
* adopter's row type, and `ModerationReportTable` deliberately erases column types
|
|
37
|
+
* so that any adopter's table is accepted.
|
|
38
|
+
*
|
|
39
|
+
* What bounds it is that both halves are checked elsewhere. Column PRESENCE is a
|
|
40
|
+
* compile error, gated by `scripts/test-report-table-type.mjs`. Column VALUES are
|
|
41
|
+
* asserted by round-trips against a real database in
|
|
42
|
+
* `postgresReportStore.test.ts`. What remains unchecked is a column declared with
|
|
43
|
+
* the wrong TYPE, which the migration and the schema test cover instead.
|
|
44
|
+
*/
|
|
45
|
+
function asReport(row) {
|
|
46
|
+
return absentWhereNull(row);
|
|
47
|
+
}
|
|
48
|
+
function postgresReportStore(input) {
|
|
49
|
+
const { db } = input;
|
|
50
|
+
const reports = input.reportTable;
|
|
51
|
+
/**
|
|
52
|
+
* `count(*)::int`, and the cast is load-bearing.
|
|
53
|
+
*
|
|
54
|
+
* `count(*)` is `bigint`, which postgres.js hands back as a STRING to avoid
|
|
55
|
+
* losing precision — so `sql<number>` without the cast is an assertion that
|
|
56
|
+
* quietly lies, and the caller's `number` is `'3'`. The `::int` makes the
|
|
57
|
+
* database do the conversion.
|
|
58
|
+
*/
|
|
59
|
+
const total = (0, drizzle_orm_1.sql) `count(*)::int`;
|
|
60
|
+
return {
|
|
61
|
+
async findDuplicate({ reporter, reportedId, reportedType }, tx) {
|
|
62
|
+
const rows = await tx
|
|
63
|
+
.select()
|
|
64
|
+
.from(reports)
|
|
65
|
+
.where((0, drizzle_orm_1.and)((0, drizzle_orm_1.eq)(reports.reporter, reporter), (0, drizzle_orm_1.eq)(reports.reportedId, reportedId), (0, drizzle_orm_1.eq)(reports.reportedType, reportedType)))
|
|
66
|
+
.limit(1);
|
|
67
|
+
const [row] = rows;
|
|
68
|
+
return row === undefined ? null : asReport(row);
|
|
69
|
+
},
|
|
70
|
+
async insert(report, tx) {
|
|
71
|
+
const rows = await tx
|
|
72
|
+
.insert(reports)
|
|
73
|
+
.values({
|
|
74
|
+
/**
|
|
75
|
+
* The application's own columns FIRST, so a field this package owns can
|
|
76
|
+
* never be overwritten by one it knows nothing about. A report whose
|
|
77
|
+
* `localStatus` came from `extra` would be queued with nothing to
|
|
78
|
+
* deliver it, or received with a delivery event that tries anyway.
|
|
79
|
+
*
|
|
80
|
+
* A key that is not a column raises here — Postgres has no silent
|
|
81
|
+
* discard. Mongoose strict mode drops an undeclared path with no throw
|
|
82
|
+
* and no warning, which is why the Mongo half needs a standing test
|
|
83
|
+
* that every DTO field resolves to a schema path.
|
|
84
|
+
*/
|
|
85
|
+
...report.extra,
|
|
86
|
+
reportedType: report.reportedType,
|
|
87
|
+
reportedId: report.reportedId,
|
|
88
|
+
reporter: report.reporter,
|
|
89
|
+
categories: [...report.categories],
|
|
90
|
+
...(report.details === undefined ? {} : { details: report.details }),
|
|
91
|
+
localStatus: report.localStatus,
|
|
92
|
+
...(report.localStatusReason === undefined
|
|
93
|
+
? {}
|
|
94
|
+
: { localStatusReason: report.localStatusReason }),
|
|
95
|
+
})
|
|
96
|
+
.returning();
|
|
97
|
+
const [row] = rows;
|
|
98
|
+
if (row === undefined) {
|
|
99
|
+
throw new Error('The moderation report insert returned no row.');
|
|
100
|
+
}
|
|
101
|
+
return asReport(row);
|
|
102
|
+
},
|
|
103
|
+
async findById(reportId) {
|
|
104
|
+
const rows = await db.select().from(reports).where((0, drizzle_orm_1.eq)(reports.id, reportId)).limit(1);
|
|
105
|
+
const [row] = rows;
|
|
106
|
+
return row === undefined ? null : asReport(row);
|
|
107
|
+
},
|
|
108
|
+
async findByCaseId(caseId) {
|
|
109
|
+
const rows = await db
|
|
110
|
+
.select({
|
|
111
|
+
id: reports.id,
|
|
112
|
+
reportedType: reports.reportedType,
|
|
113
|
+
reportedId: reports.reportedId,
|
|
114
|
+
})
|
|
115
|
+
.from(reports)
|
|
116
|
+
.where((0, drizzle_orm_1.eq)(reports.crowdSourceCaseId, caseId));
|
|
117
|
+
return rows.map((row) => ({
|
|
118
|
+
id: String(row.id),
|
|
119
|
+
reportedType: String(row.reportedType),
|
|
120
|
+
reportedId: String(row.reportedId),
|
|
121
|
+
}));
|
|
122
|
+
},
|
|
123
|
+
async applyDecision(reportId, update, maxRevision) {
|
|
124
|
+
const rows = await db
|
|
125
|
+
.update(reports)
|
|
126
|
+
.set(decisionSet(update))
|
|
127
|
+
.where((0, drizzle_orm_1.and)((0, drizzle_orm_1.eq)(reports.id, reportId),
|
|
128
|
+
/**
|
|
129
|
+
* The revision guard, in the WHERE clause. It is the DATABASE that
|
|
130
|
+
* refuses a stale write rather than a read-then-write in this
|
|
131
|
+
* process: deliveries overlap — CrowdSource retries for 24 hours, and
|
|
132
|
+
* a correction can arrive while the decision it supersedes is still
|
|
133
|
+
* being applied — and an older revision landing last would otherwise
|
|
134
|
+
* overwrite the current answer.
|
|
135
|
+
*
|
|
136
|
+
* `IS NULL` is the port of Mongo's `$exists: false`, because a report
|
|
137
|
+
* with no decision yet stores NULL rather than omitting the column.
|
|
138
|
+
* `<=` rather than `<` is deliberate: a redelivery of the SAME
|
|
139
|
+
* revision rewrites, which is harmless and keeps a partially-applied
|
|
140
|
+
* decision converging.
|
|
141
|
+
*/
|
|
142
|
+
(0, drizzle_orm_1.or)((0, drizzle_orm_1.isNull)(reports.decisionRevision), (0, drizzle_orm_1.lte)(reports.decisionRevision, maxRevision))))
|
|
143
|
+
.returning({ id: reports.id });
|
|
144
|
+
return rows.length === 1;
|
|
145
|
+
},
|
|
146
|
+
async markSubmitted(reportId, submission) {
|
|
147
|
+
await db
|
|
148
|
+
.update(reports)
|
|
149
|
+
.set({
|
|
150
|
+
localStatus: 'submitted',
|
|
151
|
+
crowdSourceReportId: submission.crowdSourceReportId,
|
|
152
|
+
crowdSourceCaseId: submission.crowdSourceCaseId,
|
|
153
|
+
crowdSourceMerged: submission.crowdSourceMerged,
|
|
154
|
+
contentSnapshotHash: submission.contentSnapshotHash,
|
|
155
|
+
submittedAt: submission.submittedAt,
|
|
156
|
+
// A report that has landed carries no failure and no reason it was
|
|
157
|
+
// going nowhere. `null` CLEARS in drizzle; `undefined` would leave the
|
|
158
|
+
// stale value in place, which is the port of Mongo's `$unset`.
|
|
159
|
+
lastDeliveryError: null,
|
|
160
|
+
localStatusReason: null,
|
|
161
|
+
})
|
|
162
|
+
.where((0, drizzle_orm_1.eq)(reports.id, reportId));
|
|
163
|
+
},
|
|
164
|
+
async markDeliveryFailed(reportId, lastDeliveryError) {
|
|
165
|
+
await db
|
|
166
|
+
.update(reports)
|
|
167
|
+
.set({ localStatus: 'delivery_failed', lastDeliveryError })
|
|
168
|
+
.where((0, drizzle_orm_1.eq)(reports.id, reportId));
|
|
169
|
+
},
|
|
170
|
+
async close(reportId, localStatusReason) {
|
|
171
|
+
await db
|
|
172
|
+
.update(reports)
|
|
173
|
+
.set({ localStatus: 'closed', localStatusReason })
|
|
174
|
+
.where((0, drizzle_orm_1.eq)(reports.id, reportId));
|
|
175
|
+
},
|
|
176
|
+
async findPendingOldestFirst(limit) {
|
|
177
|
+
/**
|
|
178
|
+
* `queued` and `delivery_failed` only. `received` is excluded deliberately
|
|
179
|
+
* and the omission is the safety property, not an oversight: those reports
|
|
180
|
+
* have no subject provider, so an event re-derived for one would fail on
|
|
181
|
+
* its first attempt and dead-letter.
|
|
182
|
+
*
|
|
183
|
+
* Oldest first, and ASC needs no explicit NULLS placement: both drizzle and
|
|
184
|
+
* Postgres default ascending to NULLS LAST, so this matches the
|
|
185
|
+
* `(local_status, created_at)` index. A DESCENDING order would need the
|
|
186
|
+
* placement spelled out — see the enforcement store's reversal lookup for
|
|
187
|
+
* what that costs when it is not.
|
|
188
|
+
*/
|
|
189
|
+
const rows = await db
|
|
190
|
+
.select({ id: reports.id })
|
|
191
|
+
.from(reports)
|
|
192
|
+
.where((0, drizzle_orm_1.inArray)(reports.localStatus, ['queued', 'delivery_failed']))
|
|
193
|
+
.orderBy((0, drizzle_orm_1.asc)(reports.createdAt))
|
|
194
|
+
.limit(limit);
|
|
195
|
+
return rows.map((row) => String(row.id));
|
|
196
|
+
},
|
|
197
|
+
async countAwaitingDecision(submittedBefore) {
|
|
198
|
+
const rows = await db
|
|
199
|
+
.select({ total })
|
|
200
|
+
.from(reports)
|
|
201
|
+
.where((0, drizzle_orm_1.and)((0, drizzle_orm_1.eq)(reports.localStatus, 'submitted'), (0, drizzle_orm_1.lt)(reports.submittedAt, submittedBefore)));
|
|
202
|
+
return rows[0]?.total ?? 0;
|
|
203
|
+
},
|
|
204
|
+
async countLocalOnly() {
|
|
205
|
+
const rows = await db
|
|
206
|
+
.select({ total })
|
|
207
|
+
.from(reports)
|
|
208
|
+
.where((0, drizzle_orm_1.eq)(reports.localStatus, 'received'));
|
|
209
|
+
return rows[0]?.total ?? 0;
|
|
210
|
+
},
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* The `$set` a decision writes, as one object.
|
|
215
|
+
*
|
|
216
|
+
* `extra` FIRST, for the same reason it is first on insert: it is the adopter's
|
|
217
|
+
* legacy verdict field, and this package's own fields must win.
|
|
218
|
+
*/
|
|
219
|
+
function decisionSet(update) {
|
|
220
|
+
return {
|
|
221
|
+
...update.extra,
|
|
222
|
+
localStatus: update.localStatus,
|
|
223
|
+
decisionId: update.decisionId,
|
|
224
|
+
decisionRevision: update.decisionRevision,
|
|
225
|
+
decisionOutcome: update.decisionOutcome,
|
|
226
|
+
decisionStatus: update.decisionStatus,
|
|
227
|
+
decidedAt: update.decidedAt,
|
|
228
|
+
...(update.enforcedAction === undefined
|
|
229
|
+
? {}
|
|
230
|
+
: { enforcedAction: update.enforcedAction }),
|
|
231
|
+
...(update.enforcedAt === undefined ? {} : { enforcedAt: update.enforcedAt }),
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
//# sourceMappingURL=reports.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reports.js","sourceRoot":"","sources":["../../../../src/outbox/postgres/store/reports.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { TablesRelationalConfig } from 'drizzle-orm';
|
|
2
|
+
import type { PgDatabase, PgQueryResultHKT } from 'drizzle-orm/pg-core';
|
|
3
|
+
import type { ModerationTransactionRunner } from '../../store/types.js';
|
|
4
|
+
/**
|
|
5
|
+
* The drizzle handle this package's Postgres stores talk to.
|
|
6
|
+
*
|
|
7
|
+
* Deliberately the BASE `PgDatabase` rather than a `PostgresJsDatabase`: the
|
|
8
|
+
* stores must accept both the pool handle an adopter builds and the `tx` handed
|
|
9
|
+
* to a `db.transaction` callback, and those are different types. Written this
|
|
10
|
+
* way, one signature serves both and no store needs to know which it holds.
|
|
11
|
+
*
|
|
12
|
+
* ## The generic that has to be `Record<string, unknown>`, and the error you get
|
|
13
|
+
*
|
|
14
|
+
* `TablesRelationalConfig` and `Record<string, unknown>` are the only spellings
|
|
15
|
+
* that accept both. The narrow one a reader reaches for first —
|
|
16
|
+
* `Record<string, never>` for the schema — accepts NEITHER (`TS2345`, the schema
|
|
17
|
+
* generic is invariant).
|
|
18
|
+
*
|
|
19
|
+
* The consequence lands on the ADOPTER, so it is worth stating: a handle built
|
|
20
|
+
* with NO schema (`drizzle(client)`, or `PostgresJsDatabase<Record<string, never>>`)
|
|
21
|
+
* is not assignable either, and the compiler explains it as
|
|
22
|
+
* `Seems like the schema generic is missing - did you forget to add it to your DB
|
|
23
|
+
* type?` — an error about `query`, on a store call that never touches the
|
|
24
|
+
* relational query builder. Pass your schema to `drizzle()` (or use
|
|
25
|
+
* `createDatabase({ databaseUrl, schema })` from `@oxy.so/db`) and it resolves.
|
|
26
|
+
* Both directions are verified in this package's own type-check.
|
|
27
|
+
*/
|
|
28
|
+
export type ModerationPgHandle = PgDatabase<PgQueryResultHKT, Record<string, unknown>, TablesRelationalConfig>;
|
|
29
|
+
/**
|
|
30
|
+
* The transaction runner, in Postgres.
|
|
31
|
+
*
|
|
32
|
+
* READ COMMITTED, explicitly, and not `repeatable read`. Neither multi-statement
|
|
33
|
+
* transaction this package runs — a report insert plus an outbox upsert, an event
|
|
34
|
+
* update plus an outbox upsert — reads-then-decides in a way snapshot isolation
|
|
35
|
+
* protects, so `repeatable read` would import `40001` serialization failures and
|
|
36
|
+
* a retry loop for no benefit.
|
|
37
|
+
*
|
|
38
|
+
* What it deliberately does NOT promise: intake's duplicate-check-then-insert is
|
|
39
|
+
* not serialized at READ COMMITTED, and the "one report per reporter per object"
|
|
40
|
+
* unique index is explicitly the application's responsibility.
|
|
41
|
+
*
|
|
42
|
+
* The failure this runner exists to make impossible is subtler than Mongo's. A
|
|
43
|
+
* store call given `db` instead of `tx` inside the callback runs on a DIFFERENT
|
|
44
|
+
* pooled connection and commits on its own — no error, no warning, and the
|
|
45
|
+
* atomicity the outbox exists for is simply gone. `postgresOutboxStore.enqueue`
|
|
46
|
+
* refuses a handle that is not a transaction for exactly that reason.
|
|
47
|
+
*/
|
|
48
|
+
export declare function postgresTransactionRunner(db: ModerationPgHandle): ModerationTransactionRunner<ModerationPgHandle>;
|
|
49
|
+
//# sourceMappingURL=transaction.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transaction.d.ts","sourceRoot":"","sources":["../../../../src/outbox/postgres/store/transaction.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACxE,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,sBAAsB,CAAC;AAExE;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,MAAM,kBAAkB,GAAG,UAAU,CACzC,gBAAgB,EAChB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACvB,sBAAsB,CACvB,CAAC;AAEF;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,yBAAyB,CACvC,EAAE,EAAE,kBAAkB,GACrB,2BAA2B,CAAC,kBAAkB,CAAC,CAQjD"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.postgresTransactionRunner = postgresTransactionRunner;
|
|
4
|
+
/**
|
|
5
|
+
* The transaction runner, in Postgres.
|
|
6
|
+
*
|
|
7
|
+
* READ COMMITTED, explicitly, and not `repeatable read`. Neither multi-statement
|
|
8
|
+
* transaction this package runs — a report insert plus an outbox upsert, an event
|
|
9
|
+
* update plus an outbox upsert — reads-then-decides in a way snapshot isolation
|
|
10
|
+
* protects, so `repeatable read` would import `40001` serialization failures and
|
|
11
|
+
* a retry loop for no benefit.
|
|
12
|
+
*
|
|
13
|
+
* What it deliberately does NOT promise: intake's duplicate-check-then-insert is
|
|
14
|
+
* not serialized at READ COMMITTED, and the "one report per reporter per object"
|
|
15
|
+
* unique index is explicitly the application's responsibility.
|
|
16
|
+
*
|
|
17
|
+
* The failure this runner exists to make impossible is subtler than Mongo's. A
|
|
18
|
+
* store call given `db` instead of `tx` inside the callback runs on a DIFFERENT
|
|
19
|
+
* pooled connection and commits on its own — no error, no warning, and the
|
|
20
|
+
* atomicity the outbox exists for is simply gone. `postgresOutboxStore.enqueue`
|
|
21
|
+
* refuses a handle that is not a transaction for exactly that reason.
|
|
22
|
+
*/
|
|
23
|
+
function postgresTransactionRunner(db) {
|
|
24
|
+
return {
|
|
25
|
+
async run(operation) {
|
|
26
|
+
return await db.transaction(async (tx) => await operation(tx), {
|
|
27
|
+
isolationLevel: 'read committed',
|
|
28
|
+
});
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=transaction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transaction.js","sourceRoot":"","sources":["../../../../src/outbox/postgres/store/transaction.ts"],"names":[],"mappings":";;AAqDA,8DAUC;AA7BD;;;;;;;;;;;;;;;;;;GAkBG;AACH,SAAgB,yBAAyB,CACvC,EAAsB;IAEtB,OAAO;QACL,KAAK,CAAC,GAAG,CAAI,SAAiD;YAC5D,OAAO,MAAM,EAAE,CAAC,WAAW,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE,CAAC,MAAM,SAAS,CAAC,EAAE,CAAC,EAAE;gBAC7D,cAAc,EAAE,gBAAgB;aACjC,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC"}
|