@adcp/sdk 16.0.0-beta.3 → 16.0.0-beta.4
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/lib/auth/oauth/diagnose.js +3 -11
- package/dist/lib/auth/oauth/diagnose.mjs +4 -12
- package/dist/lib/auth/oauth/diagnostics.d.mts +2 -1
- package/dist/lib/auth/oauth/diagnostics.d.ts +2 -1
- package/dist/lib/auth/oauth/diagnostics.js +8 -10
- package/dist/lib/auth/oauth/diagnostics.mjs +7 -10
- package/dist/lib/index.d.mts +1 -1
- package/dist/lib/index.d.ts +1 -1
- package/dist/lib/index.js +2 -0
- package/dist/lib/index.mjs +7 -1
- package/dist/lib/reporting/consumer-runtime.js +2 -1
- package/dist/lib/reporting/consumer-runtime.mjs +2 -1
- package/dist/lib/reporting/ledger/handler.js +50 -11
- package/dist/lib/reporting/ledger/handler.mjs +50 -12
- package/dist/lib/reporting/ledger/index.d.mts +17 -14
- package/dist/lib/reporting/ledger/index.d.ts +17 -14
- package/dist/lib/reporting/ledger/index.js +32 -20
- package/dist/lib/reporting/ledger/index.mjs +21 -10
- package/dist/lib/reporting/ledger/offering-validation.d.mts +9 -0
- package/dist/lib/reporting/ledger/offering-validation.d.ts +9 -0
- package/dist/lib/reporting/{gcs/bucket-policy.js → ledger/offering-validation.js} +9 -8
- package/dist/lib/reporting/ledger/offering-validation.mjs +8 -0
- package/dist/lib/reporting/ledger/receipts.d.mts +48 -0
- package/dist/lib/reporting/ledger/receipts.d.ts +48 -0
- package/dist/lib/reporting/ledger/receipts.js +186 -0
- package/dist/lib/reporting/ledger/receipts.mjs +161 -0
- package/dist/lib/reporting/ledger/status-ingest.js +3 -3
- package/dist/lib/reporting/ledger/status-ingest.mjs +4 -5
- package/dist/lib/reporting/ledger/types.d.mts +43 -0
- package/dist/lib/reporting/ledger/types.d.ts +43 -0
- package/dist/lib/reporting/ledger/types.js +31 -2
- package/dist/lib/reporting/ledger/types.mjs +26 -1
- package/dist/lib/reporting/pagination.d.mts +6 -0
- package/dist/lib/reporting/pagination.d.ts +6 -0
- package/dist/lib/reporting/{gcs/errors.js → pagination.js} +12 -17
- package/dist/lib/reporting/pagination.mjs +12 -0
- package/dist/lib/reporting/reconciliation.d.mts +1 -0
- package/dist/lib/reporting/reconciliation.d.ts +1 -0
- package/dist/lib/reporting/reconciliation.js +3 -2
- package/dist/lib/reporting/reconciliation.mjs +3 -2
- package/dist/lib/reporting/service/index.d.mts +79 -153
- package/dist/lib/reporting/service/index.d.ts +79 -153
- package/dist/lib/reporting/service/index.js +34 -491
- package/dist/lib/reporting/service/index.mjs +36 -510
- package/dist/lib/reporting/service/scheduler-support.d.mts +43 -0
- package/dist/lib/reporting/service/scheduler-support.d.ts +43 -0
- package/dist/lib/reporting/service/scheduler-support.js +125 -0
- package/dist/lib/reporting/service/scheduler-support.mjs +96 -0
- package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
- package/dist/lib/signing/canonicalize.d.mts +4 -0
- package/dist/lib/signing/canonicalize.d.ts +4 -0
- package/dist/lib/signing/canonicalize.js +14 -8
- package/dist/lib/signing/canonicalize.mjs +14 -8
- package/dist/lib/signing/content-digest.d.mts +8 -0
- package/dist/lib/signing/content-digest.d.ts +8 -0
- package/dist/lib/signing/content-digest.js +11 -5
- package/dist/lib/signing/content-digest.mjs +10 -5
- package/dist/lib/signing/signer.js +9 -6
- package/dist/lib/signing/signer.mjs +10 -7
- package/dist/lib/signing/web-bot-auth.js +103 -37
- package/dist/lib/signing/web-bot-auth.mjs +108 -37
- package/dist/lib/testing/storyboard/junit.js +16 -3
- package/dist/lib/testing/storyboard/junit.mjs +16 -3
- package/dist/lib/testing/storyboard/request-signing/builder.js +10 -9
- package/dist/lib/testing/storyboard/request-signing/builder.mjs +10 -9
- package/dist/lib/testing/storyboard/runner.js +94 -25
- package/dist/lib/testing/storyboard/runner.mjs +94 -25
- package/dist/lib/testing/storyboard/types.d.mts +6 -0
- package/dist/lib/testing/storyboard/types.d.ts +6 -0
- package/dist/lib/testing/storyboard/validations.d.mts +1 -1
- package/dist/lib/testing/storyboard/validations.d.ts +1 -1
- package/dist/lib/version.d.mts +3 -3
- package/dist/lib/version.d.ts +3 -3
- package/dist/lib/version.js +3 -3
- package/dist/lib/version.mjs +3 -3
- package/docs/TYPE-SUMMARY.md +23 -5
- package/docs/guides/REPORTING-GCS-FENCE.md +3 -3
- package/docs/guides/REPORTING-GCS-MANAGED.md +4 -4
- package/docs/guides/REPORTING-LEDGER-CUTOVER.md +7 -7
- package/docs/guides/REPORTING-LEDGER.md +107 -51
- package/docs/guides/REPORTING-OPERATIONS.md +66 -5
- package/docs/guides/REPORTING-STABILITY.md +36 -32
- package/docs/llms.txt +4 -3
- package/docs/migration-14.x-rc-worksheet.md +4 -7
- package/docs/migration-reporting-storage-package.md +186 -0
- package/examples/README.md +1 -1
- package/package.json +13 -78
- package/dist/lib/reporting/azure/index.d.mts +0 -31
- package/dist/lib/reporting/azure/index.d.ts +0 -31
- package/dist/lib/reporting/azure/index.js +0 -266
- package/dist/lib/reporting/azure/index.mjs +0 -249
- package/dist/lib/reporting/bigquery/index.d.mts +0 -246
- package/dist/lib/reporting/bigquery/index.d.ts +0 -246
- package/dist/lib/reporting/bigquery/index.js +0 -633
- package/dist/lib/reporting/bigquery/index.mjs +0 -594
- package/dist/lib/reporting/gcs/adapter.d.mts +0 -38
- package/dist/lib/reporting/gcs/adapter.d.ts +0 -38
- package/dist/lib/reporting/gcs/adapter.js +0 -342
- package/dist/lib/reporting/gcs/adapter.mjs +0 -325
- package/dist/lib/reporting/gcs/bucket-policy.d.mts +0 -3
- package/dist/lib/reporting/gcs/bucket-policy.d.ts +0 -3
- package/dist/lib/reporting/gcs/bucket-policy.mjs +0 -7
- package/dist/lib/reporting/gcs/errors.d.mts +0 -11
- package/dist/lib/reporting/gcs/errors.d.ts +0 -11
- package/dist/lib/reporting/gcs/errors.mjs +0 -16
- package/dist/lib/reporting/gcs/fence.d.mts +0 -41
- package/dist/lib/reporting/gcs/fence.d.ts +0 -41
- package/dist/lib/reporting/gcs/fence.js +0 -250
- package/dist/lib/reporting/gcs/fence.mjs +0 -230
- package/dist/lib/reporting/gcs/index.d.mts +0 -18
- package/dist/lib/reporting/gcs/index.d.ts +0 -18
- package/dist/lib/reporting/gcs/index.js +0 -44
- package/dist/lib/reporting/gcs/index.mjs +0 -14
- package/dist/lib/reporting/gcs/io.d.mts +0 -7
- package/dist/lib/reporting/gcs/io.d.ts +0 -7
- package/dist/lib/reporting/gcs/io.js +0 -95
- package/dist/lib/reporting/gcs/io.mjs +0 -69
- package/dist/lib/reporting/gcs/reader.d.mts +0 -67
- package/dist/lib/reporting/gcs/reader.d.ts +0 -67
- package/dist/lib/reporting/gcs/reader.js +0 -193
- package/dist/lib/reporting/gcs/reader.mjs +0 -169
- package/dist/lib/reporting/gcs/row-provider.d.mts +0 -39
- package/dist/lib/reporting/gcs/row-provider.d.ts +0 -39
- package/dist/lib/reporting/gcs/row-provider.js +0 -225
- package/dist/lib/reporting/gcs/row-provider.mjs +0 -208
- package/dist/lib/reporting/gcs/validation.d.mts +0 -5
- package/dist/lib/reporting/gcs/validation.d.ts +0 -5
- package/dist/lib/reporting/gcs/validation.js +0 -49
- package/dist/lib/reporting/gcs/validation.mjs +0 -25
- package/dist/lib/reporting/ledger/change-feed.d.mts +0 -69
- package/dist/lib/reporting/ledger/change-feed.d.ts +0 -69
- package/dist/lib/reporting/ledger/change-feed.js +0 -107
- package/dist/lib/reporting/ledger/change-feed.mjs +0 -80
- package/dist/lib/reporting/ledger/managed-postgres.d.mts +0 -293
- package/dist/lib/reporting/ledger/managed-postgres.d.ts +0 -293
- package/dist/lib/reporting/ledger/managed-postgres.js +0 -2346
- package/dist/lib/reporting/ledger/managed-postgres.mjs +0 -2332
- package/dist/lib/reporting/ledger/managed-router.d.mts +0 -148
- package/dist/lib/reporting/ledger/managed-router.d.ts +0 -148
- package/dist/lib/reporting/ledger/managed-router.js +0 -280
- package/dist/lib/reporting/ledger/managed-router.mjs +0 -258
- package/dist/lib/reporting/ledger/managed.d.mts +0 -535
- package/dist/lib/reporting/ledger/managed.d.ts +0 -535
- package/dist/lib/reporting/ledger/managed.js +0 -761
- package/dist/lib/reporting/ledger/managed.mjs +0 -729
- package/dist/lib/reporting/ledger/notification-activity.d.mts +0 -332
- package/dist/lib/reporting/ledger/notification-activity.d.ts +0 -332
- package/dist/lib/reporting/ledger/notification-activity.js +0 -1366
- package/dist/lib/reporting/ledger/notification-activity.mjs +0 -1337
- package/dist/lib/reporting/ledger/object-writes.d.mts +0 -128
- package/dist/lib/reporting/ledger/object-writes.d.ts +0 -128
- package/dist/lib/reporting/ledger/object-writes.js +0 -147
- package/dist/lib/reporting/ledger/object-writes.mjs +0 -114
- package/dist/lib/reporting/ledger/postgres.d.mts +0 -689
- package/dist/lib/reporting/ledger/postgres.d.ts +0 -689
- package/dist/lib/reporting/ledger/postgres.js +0 -4462
- package/dist/lib/reporting/ledger/postgres.mjs +0 -4462
- package/dist/lib/reporting/ledger/row-storage-migration.d.mts +0 -59
- package/dist/lib/reporting/ledger/row-storage-migration.d.ts +0 -59
- package/dist/lib/reporting/ledger/row-storage-migration.js +0 -365
- package/dist/lib/reporting/ledger/row-storage-migration.mjs +0 -339
- package/dist/lib/reporting/ledger/row-storage-object.d.mts +0 -203
- package/dist/lib/reporting/ledger/row-storage-object.d.ts +0 -203
- package/dist/lib/reporting/ledger/row-storage-object.js +0 -379
- package/dist/lib/reporting/ledger/row-storage-object.mjs +0 -335
- package/dist/lib/reporting/ledger/row-storage-provider-io.d.mts +0 -44
- package/dist/lib/reporting/ledger/row-storage-provider-io.d.ts +0 -44
- package/dist/lib/reporting/ledger/row-storage-provider-io.js +0 -142
- package/dist/lib/reporting/ledger/row-storage-provider-io.mjs +0 -111
- package/dist/lib/reporting/ledger/row-storage.d.mts +0 -316
- package/dist/lib/reporting/ledger/row-storage.d.ts +0 -316
- package/dist/lib/reporting/ledger/row-storage.js +0 -812
- package/dist/lib/reporting/ledger/row-storage.mjs +0 -802
- package/dist/lib/reporting/s3/index.d.mts +0 -34
- package/dist/lib/reporting/s3/index.d.ts +0 -34
- package/dist/lib/reporting/s3/index.js +0 -347
- package/dist/lib/reporting/s3/index.mjs +0 -340
- package/dist/lib/reporting/service/maintenance.d.mts +0 -148
- package/dist/lib/reporting/service/maintenance.d.ts +0 -148
- package/dist/lib/reporting/service/maintenance.js +0 -185
- package/dist/lib/reporting/service/maintenance.mjs +0 -159
- package/examples/reliable-reporting-service/README.md +0 -169
package/dist/lib/version.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* AdCP SDK library version
|
|
3
3
|
*/
|
|
4
|
-
export declare const LIBRARY_VERSION = "16.0.0-beta.
|
|
4
|
+
export declare const LIBRARY_VERSION = "16.0.0-beta.4";
|
|
5
5
|
/**
|
|
6
6
|
* AdCP specification version this library is built for
|
|
7
7
|
*/
|
|
@@ -33,10 +33,10 @@ export type AdcpVersion = (typeof COMPATIBLE_ADCP_VERSIONS)[number];
|
|
|
33
33
|
* Full version information
|
|
34
34
|
*/
|
|
35
35
|
export declare const VERSION_INFO: {
|
|
36
|
-
readonly library: "16.0.0-beta.
|
|
36
|
+
readonly library: "16.0.0-beta.4";
|
|
37
37
|
readonly adcp: "3.2.4";
|
|
38
38
|
readonly compatibleVersions: readonly ["v2.5", "v2.6", "v3", "3.0.0", "3.0", "3.0.1", "3.0.2", "3.0.3", "3.0.4", "3.0.5", "3.0.6", "3.0.7", "3.0.8", "3.0.9", "3.0.10", "3.0.11", "3.0.12", "3.0.13", "3.0.14", "3.0.15", "3.0.16", "3.0.17", "3.0.18", "3.0.19", "3.0.20", "3.0.21", "3.0.22", "3.0.23", "3.0.24", "3.0.25", "3.1.0", "3.1", "3.1.1", "3.1.2", "3.1.3", "3.1.4", "3.1.5", "3.1.6", "3.1.7", "3.1.8", "3.1.9", "3.1.10", "3.1.11", "3.1.12", "3.1.13", "3.1.14", "3.1.15", "3.1.16", "3.1.17", "3.1.18", "3.1.19", "3.1.20", "3.1.21", "3.1.22", "3.1.23", "3.1.24", "3.2.1", "3.2", "3.2.2", "3.2.3", "3.2.4"];
|
|
39
|
-
readonly generatedAt: "2026-10-
|
|
39
|
+
readonly generatedAt: "2026-10-16T14:15:27.258Z";
|
|
40
40
|
};
|
|
41
41
|
/**
|
|
42
42
|
* Get the AdCP specification version this library is built for
|
package/dist/lib/version.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* AdCP SDK library version
|
|
3
3
|
*/
|
|
4
|
-
export declare const LIBRARY_VERSION = "16.0.0-beta.
|
|
4
|
+
export declare const LIBRARY_VERSION = "16.0.0-beta.4";
|
|
5
5
|
/**
|
|
6
6
|
* AdCP specification version this library is built for
|
|
7
7
|
*/
|
|
@@ -33,10 +33,10 @@ export type AdcpVersion = (typeof COMPATIBLE_ADCP_VERSIONS)[number];
|
|
|
33
33
|
* Full version information
|
|
34
34
|
*/
|
|
35
35
|
export declare const VERSION_INFO: {
|
|
36
|
-
readonly library: "16.0.0-beta.
|
|
36
|
+
readonly library: "16.0.0-beta.4";
|
|
37
37
|
readonly adcp: "3.2.4";
|
|
38
38
|
readonly compatibleVersions: readonly ["v2.5", "v2.6", "v3", "3.0.0", "3.0", "3.0.1", "3.0.2", "3.0.3", "3.0.4", "3.0.5", "3.0.6", "3.0.7", "3.0.8", "3.0.9", "3.0.10", "3.0.11", "3.0.12", "3.0.13", "3.0.14", "3.0.15", "3.0.16", "3.0.17", "3.0.18", "3.0.19", "3.0.20", "3.0.21", "3.0.22", "3.0.23", "3.0.24", "3.0.25", "3.1.0", "3.1", "3.1.1", "3.1.2", "3.1.3", "3.1.4", "3.1.5", "3.1.6", "3.1.7", "3.1.8", "3.1.9", "3.1.10", "3.1.11", "3.1.12", "3.1.13", "3.1.14", "3.1.15", "3.1.16", "3.1.17", "3.1.18", "3.1.19", "3.1.20", "3.1.21", "3.1.22", "3.1.23", "3.1.24", "3.2.1", "3.2", "3.2.2", "3.2.3", "3.2.4"];
|
|
39
|
-
readonly generatedAt: "2026-10-
|
|
39
|
+
readonly generatedAt: "2026-10-16T14:15:27.258Z";
|
|
40
40
|
};
|
|
41
41
|
/**
|
|
42
42
|
* Get the AdCP specification version this library is built for
|
package/dist/lib/version.js
CHANGED
|
@@ -31,7 +31,7 @@ __export(version_exports, {
|
|
|
31
31
|
toReleasePrecisionVersion: () => toReleasePrecisionVersion
|
|
32
32
|
});
|
|
33
33
|
module.exports = __toCommonJS(version_exports);
|
|
34
|
-
const LIBRARY_VERSION = "16.0.0-beta.
|
|
34
|
+
const LIBRARY_VERSION = "16.0.0-beta.4";
|
|
35
35
|
const ADCP_VERSION = "3.2.4";
|
|
36
36
|
const ADCP_MAJOR_VERSION = 3;
|
|
37
37
|
const COMPATIBLE_ADCP_VERSIONS = [
|
|
@@ -98,10 +98,10 @@ const COMPATIBLE_ADCP_VERSIONS = [
|
|
|
98
98
|
"3.2.4"
|
|
99
99
|
];
|
|
100
100
|
const VERSION_INFO = {
|
|
101
|
-
library: "16.0.0-beta.
|
|
101
|
+
library: "16.0.0-beta.4",
|
|
102
102
|
adcp: "3.2.4",
|
|
103
103
|
compatibleVersions: COMPATIBLE_ADCP_VERSIONS,
|
|
104
|
-
generatedAt: "2026-10-
|
|
104
|
+
generatedAt: "2026-10-16T14:15:27.258Z"
|
|
105
105
|
};
|
|
106
106
|
function getAdcpVersion() {
|
|
107
107
|
return ADCP_VERSION;
|
package/dist/lib/version.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const LIBRARY_VERSION = "16.0.0-beta.
|
|
1
|
+
const LIBRARY_VERSION = "16.0.0-beta.4";
|
|
2
2
|
const ADCP_VERSION = "3.2.4";
|
|
3
3
|
const ADCP_MAJOR_VERSION = 3;
|
|
4
4
|
const COMPATIBLE_ADCP_VERSIONS = [
|
|
@@ -65,10 +65,10 @@ const COMPATIBLE_ADCP_VERSIONS = [
|
|
|
65
65
|
"3.2.4"
|
|
66
66
|
];
|
|
67
67
|
const VERSION_INFO = {
|
|
68
|
-
library: "16.0.0-beta.
|
|
68
|
+
library: "16.0.0-beta.4",
|
|
69
69
|
adcp: "3.2.4",
|
|
70
70
|
compatibleVersions: COMPATIBLE_ADCP_VERSIONS,
|
|
71
|
-
generatedAt: "2026-10-
|
|
71
|
+
generatedAt: "2026-10-16T14:15:27.258Z"
|
|
72
72
|
};
|
|
73
73
|
function getAdcpVersion() {
|
|
74
74
|
return ADCP_VERSION;
|
package/docs/TYPE-SUMMARY.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# AdCP Type Summary
|
|
2
2
|
|
|
3
|
-
> Generated at: 2026-10-
|
|
4
|
-
> @adcp/sdk v16.0.0-beta.
|
|
3
|
+
> Generated at: 2026-10-16
|
|
4
|
+
> @adcp/sdk v16.0.0-beta.4
|
|
5
5
|
|
|
6
6
|
Curated reference of the types that matter for using the AdCP client. For full generated types see `src/lib/types/tools.generated.ts` and `src/lib/types/core.generated.ts`.
|
|
7
7
|
|
|
@@ -2900,9 +2900,23 @@ interface InlineReportingAvailabilityEvidenceV1 {
|
|
|
2900
2900
|
|
|
2901
2901
|
## Seller Reporting Ledger
|
|
2902
2902
|
|
|
2903
|
-
|
|
2903
|
+
The ledger interface, handlers and producer import from `@adcp/sdk/reporting/ledger`. The PostgreSQL store, its migrations, row storage and maintenance import from `@adcp/reporting-storage`, managed delivery from `@adcp/reporting-storage/managed` and notification activity from `@adcp/reporting-storage/notifications` (install `@adcp/reporting-storage` next to `@adcp/sdk`; it is pre-1.0 and every export is experimental). `createPostgresPersistentNotificationRuntime` is a server symbol and imports from `@adcp/sdk/server`.
|
|
2904
2904
|
|
|
2905
2905
|
```typescript
|
|
2906
|
+
import { Pool } from 'pg';
|
|
2907
|
+
import { createPostgresPersistentNotificationRuntime } from '@adcp/sdk/server';
|
|
2908
|
+
import {
|
|
2909
|
+
createReportingDeliveryHandler,
|
|
2910
|
+
createReportingProducer,
|
|
2911
|
+
createReportingStatusHandler,
|
|
2912
|
+
createSyncReportingStatusHandler,
|
|
2913
|
+
} from '@adcp/sdk/reporting/ledger';
|
|
2914
|
+
import { PostgresReportingLedgerStore, REPORTING_LEDGER_MIGRATION } from '@adcp/reporting-storage';
|
|
2915
|
+
import {
|
|
2916
|
+
createPostgresReportingNotificationActivityRuntime,
|
|
2917
|
+
createPostgresReportingNotificationAttemptCheckpoint,
|
|
2918
|
+
} from '@adcp/reporting-storage/notifications';
|
|
2919
|
+
|
|
2906
2920
|
// Build the notification path first: the store must be constructed with the
|
|
2907
2921
|
// activity port, or lifecycle transitions record no activity and notify nobody.
|
|
2908
2922
|
const attemptCheckpoint = createPostgresReportingNotificationAttemptCheckpoint({
|
|
@@ -2965,6 +2979,9 @@ The store freezes configuration lineage and period-end denominators, retains imm
|
|
|
2965
2979
|
Import from `@adcp/sdk/reporting/service`. This is the adapter-first lifecycle owner over the source and ledger primitives; it does not introduce another store or transport.
|
|
2966
2980
|
|
|
2967
2981
|
```typescript
|
|
2982
|
+
import { createReliableReportingService } from '@adcp/sdk/reporting/service';
|
|
2983
|
+
import { PostgresReportingLedgerStore, reportingLedgerMaintenance } from '@adcp/reporting-storage';
|
|
2984
|
+
|
|
2968
2985
|
interface ReliableReportingAdapterV1 {
|
|
2969
2986
|
readonly sourceOffering: ReportingSourceOfferingV1;
|
|
2970
2987
|
readonly deliveryOffering: ReportingDeliveryOffering;
|
|
@@ -2987,9 +3004,10 @@ const reporting = createReliableReportingService({
|
|
|
2987
3004
|
resolveCurrency: account => currency,
|
|
2988
3005
|
resolveCoverage: account => ({ constituents }), // authorized media-buy/package denominator
|
|
2989
3006
|
resolveConsumerId, // optional; controls consumer-status handler/capability
|
|
3007
|
+
maintenance: reportingLedgerMaintenance({ retention: { enabled: true } }), // optional factory from @adcp/reporting-storage
|
|
2990
3008
|
});
|
|
2991
3009
|
|
|
2992
|
-
|
|
3010
|
+
for (const sql of reporting.setup.migrations) await pool.query(sql);
|
|
2993
3011
|
const installedPlatform = reporting.install(platform);
|
|
2994
3012
|
await reporting.installConfiguration(configuration, { account: ctx.account });
|
|
2995
3013
|
await reporting.runCycle({ accountId }); // tenant-partitioned
|
|
@@ -2999,7 +3017,7 @@ await reporting.stop();
|
|
|
2999
3017
|
|
|
3000
3018
|
Account identity comes only from the framework-resolved context. Trusted host callbacks derive adapter routing, credential-free `sourceScope`, source timezone, currency, and the authorized constituent denominator. A declaration cannot supply `account`, `sourceScope`, `sourceTimezone`, `contract`, `currency`, `constituents`, or `mediaBuyIds`; `mediaBuyIds` is derived from `resolveCoverage`, so a buyer cannot name another buyer's media buys on a shared upstream network. Currency is frozen into configuration and obligation lineage. Capabilities are Core-only and derived from installed adapters and handlers; managed delivery, reconciled billing, receipts, webhook activity, and notifications are not advertised. Installation requires `platform.accounts.upsert`, which owns the advertised `sync_accounts` configuration path.
|
|
3001
3019
|
|
|
3002
|
-
For complete seller production assembly, use async `createPostgresReliableReportingProductionService` from `@adcp/
|
|
3020
|
+
For complete seller production assembly, use async `createPostgresReliableReportingProductionService` from `@adcp/reporting-storage/service`. It owns the PostgreSQL Core/Managed stores, receipts, all three reporting notifications, webhook activity, migrations, probes, recovery, and capability publication. Supply `activity.tenantScopeForAccount`; Reconciled Billing offerings also require a trusted `obligatedConsumers` roster. Its scheduler and `recoverOnce` require explicit `deploymentWide: true` because recovery scans the whole namespace. See `docs/guides/REPORTING-LEDGER.md` and `docs/guides/REPORTING-OPERATIONS.md`.
|
|
3003
3021
|
|
|
3004
3022
|
Buyer production processes use `createPostgresReportingConsumerRuntimeV1` with `createReliableReportingConsumerV1` from the package root. Verify webhook signatures before passing authenticated hints, preserve seller/principal scope, and configure `evaluateAdjustment` to authorize integrity-valid post-official corrections; the default defers them. See `docs/guides/REPORTING-RECONCILIATION.md`.
|
|
3005
3023
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# Durable GCS reporting write fence
|
|
2
2
|
|
|
3
|
-
`@adcp/
|
|
3
|
+
`@adcp/reporting-storage/gcs` provides a provider write-fence primitive backed by the existing PostgreSQL destination authority. It is a building block for a managed delivery adapter; it does not advertise Managed Delivery or Reconciled Billing capabilities or implement `ReportingManagedDeliveryAdapterV1`.
|
|
4
4
|
|
|
5
|
-
Install the optional official Google client with `npm install @google-cloud/storage@^7.22.0` for Node 20 or Node 22+. Google client `^8.2.0` is also supported on Node 22+. This peer is required when compiling or using the GCS subpath, including its public types; other
|
|
5
|
+
Install the optional official Google client with `npm install @google-cloud/storage@^7.22.0` for Node 20 or Node 22+. Google client `^8.2.0` is also supported on Node 22+. This peer is required when compiling or using the GCS subpath, including its public types; other subpaths remain independent. Apply `REPORTING_LEDGER_MIGRATION`, `REPORTING_MANAGED_DELIVERY_MIGRATION`, then the additive `REPORTING_OBJECT_WRITE_MIGRATION` from `@adcp/reporting-storage` (and `@adcp/reporting-storage/managed` for the managed-delivery one) in the same isolated tenant schema. Apply the final migration to a fresh object-write schema if experimenting with earlier, unpublished versions of these tables: `CREATE TABLE IF NOT EXISTS` does not upgrade incompatible prerelease tables.
|
|
6
6
|
|
|
7
7
|
```typescript
|
|
8
8
|
import { Storage } from '@google-cloud/storage';
|
|
9
|
-
import { createGcsReportingObjectFenceV1 } from '@adcp/
|
|
9
|
+
import { createGcsReportingObjectFenceV1 } from '@adcp/reporting-storage/gcs';
|
|
10
10
|
|
|
11
11
|
const fence = createGcsReportingObjectFenceV1({
|
|
12
12
|
storage: new Storage({ retryOptions: { totalTimeout: 60, maxRetries: 3 } }), // Host-owned ADC; retry timeout is in seconds.
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
# Managed reporting delivery on GCS
|
|
2
2
|
|
|
3
|
-
`@adcp/
|
|
3
|
+
`@adcp/reporting-storage/gcs` supplies a complete `ReportingManagedDeliveryAdapterV1` for private GCS file transfer. It supports `manifest_checksums` and `canonical_digest` by uploading deterministic JSONL and manifest bytes, then inspecting actual provider bytes and digest-pinned private contracts. The managed runtime owns materialization settlement, cleanup leases, retries and capability publication. Verification is attributed to the producer; independent buyer qualification is a separate gate.
|
|
4
4
|
|
|
5
5
|
Install the optional official `@google-cloud/storage` peer. Use 7.22.x on Node 20.19 or later; Storage 8.2.x requires Node 22 or later. The default SDK import does not load Google Storage. Supply a host-owned official Storage client using ADC, workload identity or short-lived impersonation. Never persist credentials in reporting descriptors, contract URIs, `ctx_metadata`, inventory or error envelopes.
|
|
6
6
|
|
|
7
|
-
Apply `REPORTING_LEDGER_MIGRATION`, the applicable Core writer-fence migration, `REPORTING_MANAGED_DELIVERY_MIGRATION`, `REPORTING_OBJECT_WRITE_MIGRATION`, then `REPORTING_OBJECT_WRITE_AUTHORITY_MIGRATION` from `@adcp/
|
|
7
|
+
Apply `REPORTING_LEDGER_MIGRATION`, the applicable Core writer-fence migration, `REPORTING_MANAGED_DELIVERY_MIGRATION`, `REPORTING_OBJECT_WRITE_MIGRATION`, then `REPORTING_OBJECT_WRITE_AUTHORITY_MIGRATION` from `@adcp/reporting-storage` (`REPORTING_MANAGED_DELIVERY_MIGRATION` is on `@adcp/reporting-storage/managed`). The last migration requires PostgreSQL 13 or later and creates one persistent installation UUID per isolated schema. Reapplying it preserves the UUID. Keep that row in backups and restores. **Never run delivery or cleanup from an independently writable clone of live authorization, inventory or materialization tables.** Such a clone would still address the original objects. Start a fresh isolated schema with a distinct deployment namespace and installation UUID, provision new destination grants, and import only the needed immutable Core facts. A restored replica of the same authority keeps its identity. Do not replace an identity while old write plans still exist. The adapter combines the UUID with your stable deployment namespace to avoid collisions between isolated schemas sharing a bucket.
|
|
8
8
|
|
|
9
9
|
Core and managed stores must share the exact same PostgreSQL pool, and Core must enable `managedDelivery: true`. The factory probes both stores and the provider policy before returning an adapter. Hosts supply pool acquisition/connect timeouts; transactions started with a signal additionally limit lock and statement waits. Readiness is bounded by the operation deadline, at most 60 seconds.
|
|
10
10
|
|
|
11
11
|
```typescript
|
|
12
12
|
import { Storage } from '@google-cloud/storage';
|
|
13
|
-
import { createGcsReportingManagedDeliveryAdapterV1 } from '@adcp/
|
|
14
|
-
import { createReportingManagedDeliveryRuntime } from '@adcp/
|
|
13
|
+
import { createGcsReportingManagedDeliveryAdapterV1 } from '@adcp/reporting-storage/gcs';
|
|
14
|
+
import { createReportingManagedDeliveryRuntime } from '@adcp/reporting-storage/managed';
|
|
15
15
|
|
|
16
16
|
const adapter = await createGcsReportingManagedDeliveryAdapterV1({
|
|
17
17
|
storage: new Storage(), // ADC/workload identity; no keys in reporting state
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
This guide is for a seller that already runs its own Reliable Reporting ledger
|
|
4
4
|
(tables for configuration generations, obligations and revisions, row files in
|
|
5
5
|
object storage and a warehouse, status issues and transitions) and wants
|
|
6
|
-
`@adcp/sdk` to own the ledger from now on. Read the
|
|
6
|
+
`@adcp/sdk` and `@adcp/reporting-storage` to own the ledger from now on. Read the
|
|
7
7
|
[ledger guide](REPORTING-LEDGER.md) first for the SDK side, and the
|
|
8
8
|
[operations runbook](REPORTING-OPERATIONS.md) for production practice.
|
|
9
9
|
|
|
@@ -28,7 +28,7 @@ You have two ways to run the SDK's service on top of what you have.
|
|
|
28
28
|
| Change feed | `changeFeed: true`: `changesAfter`, current-revision reads, consumer cursors | You implement it, or go without host reads and the warehouse sink |
|
|
29
29
|
| Retention | `maintenance.retention`: period-aligned retirement honouring the change-feed hold | You implement `retireExpiredPeriods` and tombstones, or never retire |
|
|
30
30
|
| Maintenance | `maintenance`: snapshot sweep, abandoned-upload sweep, feed pruning | You write all of it |
|
|
31
|
-
| Warehouse | `@adcp/
|
|
31
|
+
| Warehouse | `@adcp/reporting-storage/bigquery` sink | Not available: it reads the SDK store |
|
|
32
32
|
| Correctness | Lease fencing, gap-free status checkpoints, immutable generations and the revision binding are enforced in one tested place | Every one of those guarantees is yours to prove |
|
|
33
33
|
| Existing data | Starts empty; old tables stay behind a read-only hook | Old data served natively |
|
|
34
34
|
|
|
@@ -52,8 +52,8 @@ advertise Managed Delivery or Reconciled Billing today, read
|
|
|
52
52
|
```ts
|
|
53
53
|
import { Pool } from 'pg';
|
|
54
54
|
import { Storage } from '@google-cloud/storage';
|
|
55
|
-
import { PostgresReportingLedgerStore } from '@adcp/
|
|
56
|
-
import { createGcsReportingRowObjectProviderV1 } from '@adcp/
|
|
55
|
+
import { PostgresReportingLedgerStore, reportingLedgerMaintenance } from '@adcp/reporting-storage';
|
|
56
|
+
import { createGcsReportingRowObjectProviderV1 } from '@adcp/reporting-storage/gcs';
|
|
57
57
|
import { createReliableReportingService } from '@adcp/sdk/reporting/service';
|
|
58
58
|
|
|
59
59
|
// Apply once, in order, with your migration owner (PostgreSQL 13+):
|
|
@@ -86,10 +86,10 @@ const reporting = createReliableReportingService({
|
|
|
86
86
|
statusRetentionDays: 90, // the commitment advertised to buyers; retention uses it
|
|
87
87
|
// ...adapters, contact, resolveSource, resolveCurrency, resolveCoverage
|
|
88
88
|
legacyRevisionReader, // see "The legacy fallback hook"
|
|
89
|
-
maintenance: {
|
|
89
|
+
maintenance: reportingLedgerMaintenance({
|
|
90
90
|
retention: { enabled: true, recordRetentionDays: 120, limit: 100 },
|
|
91
91
|
changeFeed: { changeRetentionDays: 30, maxFeedHoldDays: 7 },
|
|
92
|
-
},
|
|
92
|
+
}),
|
|
93
93
|
});
|
|
94
94
|
```
|
|
95
95
|
|
|
@@ -118,7 +118,7 @@ state. The bytes live in your bucket.
|
|
|
118
118
|
|
|
119
119
|
### Keeping your BigQuery tables fed
|
|
120
120
|
|
|
121
|
-
`@adcp/
|
|
121
|
+
`@adcp/reporting-storage/bigquery` follows the change feed and loads every
|
|
122
122
|
committed revision's verified rows into BigQuery tables you name
|
|
123
123
|
([sink details](REPORTING-LEDGER.md#bigquery-warehouse-sink)). The warehouse
|
|
124
124
|
copy is derived and never served.
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
# Seller Reporting Ledger
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Reliable Reporting Core turns a conforming reporting source into durable seller-side reporting. It is separate from the buyer-side `reconcileReporting` API.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Two packages make it up. `@adcp/sdk` holds the protocol layer: the `ReportingLedgerStore` interface, the protocol handlers, the producer, `createReliableReportingService` and row encoding (`@adcp/sdk/reporting/ledger`, `@adcp/sdk/reporting/service`). [`@adcp/reporting-storage`](https://github.com/adcontextprotocol/adcp-client/blob/main/packages/reporting-storage/README.md) holds the storage behind it: the PostgreSQL ledger store and migrations, row storage and its GCS, S3 and Azure providers, managed delivery, notification activity, the BigQuery sink and the production composition. Install both (`npm install @adcp/sdk@beta @adcp/reporting-storage@beta pg` while SDK 16 is in beta). Moving from the pre-split `@adcp/sdk/reporting/*` imports? See [Reliable Reporting storage moved to `@adcp/reporting-storage`](../migration-reporting-storage-package.md).
|
|
6
|
+
|
|
7
|
+
> **Stability:** `@adcp/reporting-storage` is pre-1.0 and every export of it is experimental: breaking changes ship in its minor releases. Pin it with `~`. The store, transaction, lease and row-read interfaces in `@adcp/sdk/reporting/ledger` that it implements are `@experimental` too. See the [Reliable Reporting stability policy](REPORTING-STABILITY.md).
|
|
6
8
|
|
|
7
9
|
## Recommended: install the lifecycle service
|
|
8
10
|
|
|
@@ -13,7 +15,7 @@ producer, handlers, and decisioning-platform account resolver.
|
|
|
13
15
|
|
|
14
16
|
```ts
|
|
15
17
|
import { Pool } from 'pg';
|
|
16
|
-
import { PostgresReportingLedgerStore } from '@adcp/
|
|
18
|
+
import { PostgresReportingLedgerStore } from '@adcp/reporting-storage';
|
|
17
19
|
import { createReliableReportingService } from '@adcp/sdk/reporting/service';
|
|
18
20
|
import { createAdcpServerFromPlatform } from '@adcp/sdk/server';
|
|
19
21
|
|
|
@@ -53,7 +55,7 @@ const reporting = createReliableReportingService({
|
|
|
53
55
|
},
|
|
54
56
|
});
|
|
55
57
|
|
|
56
|
-
|
|
58
|
+
for (const sql of reporting.setup.migrations) await pool.query(sql);
|
|
57
59
|
const installedPlatform = reporting.install(platform);
|
|
58
60
|
const server = createAdcpServerFromPlatform(installedPlatform, serverOptions);
|
|
59
61
|
|
|
@@ -86,7 +88,7 @@ still use an `accountIds` roster. Production setup requires
|
|
|
86
88
|
`activity.tenantScopeForAccount`; when an offering uses `consumer_receipt`, it
|
|
87
89
|
also requires a trusted `obligatedConsumers` callback so lifecycle health can
|
|
88
90
|
become reconciled only after every obligated consumer has accepted.
|
|
89
|
-
See the [integrated seller example](
|
|
91
|
+
See the [integrated seller example](https://github.com/adcontextprotocol/adcp-client/blob/main/packages/reporting-storage/examples/reliable-reporting-service/README.md#integrated-seller-production-service)
|
|
90
92
|
for the full option shape.
|
|
91
93
|
|
|
92
94
|
Install a buyer declaration after the account and its media-buy scope have
|
|
@@ -135,6 +137,8 @@ import {
|
|
|
135
137
|
PostgresReportingLedgerStore,
|
|
136
138
|
REPORTING_LEDGER_MIGRATION,
|
|
137
139
|
sweepExpiredReportingLedgerState,
|
|
140
|
+
} from '@adcp/reporting-storage';
|
|
141
|
+
import {
|
|
138
142
|
createReportingDeliveryHandler,
|
|
139
143
|
createReportingProducer,
|
|
140
144
|
createReportingStatusHandler,
|
|
@@ -162,7 +166,7 @@ const getMediaBuyDelivery = createReportingDeliveryHandler(store);
|
|
|
162
166
|
await sweepExpiredReportingLedgerState(pool);
|
|
163
167
|
```
|
|
164
168
|
|
|
165
|
-
Pass `getReportingStatus` and `getMediaBuyDelivery` directly to the matching `createAdcpServer` slots. The delivery helper serves only exact `reporting_revision_id` reads and returns the row payload bound by the ledger revision. Advertise `media_buy.reporting_delivery` in `experimental_features` together with a `media_buy.reporting_delivery` capability whose Reliable Reporting version is `1.0` only after both handlers are wired. Configure account resolution on the server: both handlers require the framework-resolved, caller-scoped account identity and never trust a request-body identity as an authorization boundary. If two callers can name the same upstream account, the resolver must issue distinct internal account IDs for their ledger namespaces. Install immutable delivery-configuration generations through `producer.installConfiguration`, call `planObligations()` after period close, and run `runWorker()` from a durable scheduler. Multiple workers are safe: PostgreSQL claims use `SKIP LOCKED`, expiring leases, and fencing generations.
|
|
169
|
+
Pass `getReportingStatus` and `getMediaBuyDelivery` directly to the matching `createAdcpServer` slots. The delivery helper serves only exact `reporting_revision_id` reads and returns the row payload bound by the ledger revision. Both handlers take `pagination.max_results` as AdCP defines it, from `core/pagination-request.json`: an integer from 1 to 100, 50 when omitted. Any other value (and a `pagination` that is not an object or a `cursor` that is not a string) is refused with `VALIDATION_ERROR` (`field: 'pagination.max_results'`, `'pagination'` or `'pagination.cursor'`) before the ledger is read, so the same request behaves the same on every seller; page with `pagination.cursor`. The buyer-side walkers ask for the schema maximum, 100. Advertise `media_buy.reporting_delivery` in `experimental_features` together with a `media_buy.reporting_delivery` capability whose Reliable Reporting version is `1.0` only after both handlers are wired. Configure account resolution on the server: both handlers require the framework-resolved, caller-scoped account identity and never trust a request-body identity as an authorization boundary. If two callers can name the same upstream account, the resolver must issue distinct internal account IDs for their ledger namespaces. Install immutable delivery-configuration generations through `producer.installConfiguration`, call `planObligations()` after period close, and run `runWorker()` from a durable scheduler. Multiple workers are safe: PostgreSQL claims use `SKIP LOCKED`, expiring leases, and fencing generations.
|
|
166
170
|
|
|
167
171
|
The planner supports fixed millisecond schedules and an explicit source-calendar
|
|
168
172
|
day schedule. For the latter, set the existing schedule identity fields to
|
|
@@ -291,7 +295,7 @@ rows as verified canonical JSONL chunks (the shared SDK persistence layout,
|
|
|
291
295
|
adcontextprotocol/adcp#7996):
|
|
292
296
|
|
|
293
297
|
```ts
|
|
294
|
-
import { REPORTING_ROW_STORAGE_MIGRATION } from '@adcp/
|
|
298
|
+
import { REPORTING_ROW_STORAGE_MIGRATION } from '@adcp/reporting-storage';
|
|
295
299
|
|
|
296
300
|
await pool.query(REPORTING_ROW_STORAGE_MIGRATION); // after REPORTING_LEDGER_MIGRATION; PostgreSQL 13+
|
|
297
301
|
const store = new PostgresReportingLedgerStore(pool, {
|
|
@@ -364,7 +368,7 @@ point reads or writes at a destination the host did not configure.
|
|
|
364
368
|
import {
|
|
365
369
|
PostgresReportingLedgerStore,
|
|
366
370
|
createFilesystemReportingRowObjectProviderV1,
|
|
367
|
-
} from '@adcp/
|
|
371
|
+
} from '@adcp/reporting-storage';
|
|
368
372
|
|
|
369
373
|
const store = new PostgresReportingLedgerStore(pool, {
|
|
370
374
|
acknowledgeIsolatedDatabase: true,
|
|
@@ -462,6 +466,14 @@ await store.readyRowStorage();
|
|
|
462
466
|
version at the recorded size is the same bytes) instead of downloading it
|
|
463
467
|
while holding the account and object locks. A provider without `stat` falls
|
|
464
468
|
back to reading the whole object there. All bundled providers implement it.
|
|
469
|
+
Also implement the optional `list({ prefix, pageToken, pageSize })`, which
|
|
470
|
+
returns `{ objects: [{ objectRef, nativeVersionRef, sizeBytes, createdAt }],
|
|
471
|
+
nextPageToken? }`: every stored version under the prefix once, in a stable
|
|
472
|
+
order (on a versioned store, noncurrent versions too, never delete markers),
|
|
473
|
+
with the version exactly as `putIfAbsent` recorded it and the time it was
|
|
474
|
+
written. The orphan collector needs it; a binding whose provider has no `list`
|
|
475
|
+
is reported as unsupported there. The conformance suite checks it (`list`) when
|
|
476
|
+
present. All bundled providers implement it.
|
|
465
477
|
|
|
466
478
|
#### Cloud providers
|
|
467
479
|
|
|
@@ -472,12 +484,12 @@ reference fails `UNSAFE_BINDING`. Provider errors surface only as stable
|
|
|
472
484
|
`ReportingRowStoreError` codes. Row buckets are separate from Managed Delivery
|
|
473
485
|
buckets.
|
|
474
486
|
|
|
475
|
-
**Google Cloud Storage** (`@adcp/
|
|
487
|
+
**Google Cloud Storage** (`@adcp/reporting-storage/gcs`, optional peer
|
|
476
488
|
`@google-cloud/storage`):
|
|
477
489
|
|
|
478
490
|
```ts
|
|
479
491
|
import { Storage } from '@google-cloud/storage';
|
|
480
|
-
import { createGcsReportingRowObjectProviderV1 } from '@adcp/
|
|
492
|
+
import { createGcsReportingRowObjectProviderV1 } from '@adcp/reporting-storage/gcs';
|
|
481
493
|
|
|
482
494
|
const gcs = createGcsReportingRowObjectProviderV1({
|
|
483
495
|
storage: new Storage(), // keyless credentials (workload identity / ADC)
|
|
@@ -500,12 +512,12 @@ const gcs = createGcsReportingRowObjectProviderV1({
|
|
|
500
512
|
- The client needs `storage.buckets.get` for the probe plus object create, get
|
|
501
513
|
and delete on the bucket.
|
|
502
514
|
|
|
503
|
-
**Amazon S3 and S3-compatible stores** (`@adcp/
|
|
515
|
+
**Amazon S3 and S3-compatible stores** (`@adcp/reporting-storage/s3`, optional peer
|
|
504
516
|
`@aws-sdk/client-s3`):
|
|
505
517
|
|
|
506
518
|
```ts
|
|
507
519
|
import { S3Client } from '@aws-sdk/client-s3';
|
|
508
|
-
import { createS3ReportingRowObjectProviderV1 } from '@adcp/
|
|
520
|
+
import { createS3ReportingRowObjectProviderV1 } from '@adcp/reporting-storage/s3';
|
|
509
521
|
|
|
510
522
|
const s3 = createS3ReportingRowObjectProviderV1({
|
|
511
523
|
client: new S3Client({ region: 'us-east-1' }), // default credential chain
|
|
@@ -542,13 +554,13 @@ const s3 = createS3ReportingRowObjectProviderV1({
|
|
|
542
554
|
`s3:GetBucketPolicyStatus` is optional. For stores without flexible
|
|
543
555
|
checksums, construct the client with `requestChecksumCalculation: 'WHEN_REQUIRED'`.
|
|
544
556
|
|
|
545
|
-
**Azure Blob Storage** (`@adcp/
|
|
557
|
+
**Azure Blob Storage** (`@adcp/reporting-storage/azure`, optional peer
|
|
546
558
|
`@azure/storage-blob`):
|
|
547
559
|
|
|
548
560
|
```ts
|
|
549
561
|
import { DefaultAzureCredential } from '@azure/identity';
|
|
550
562
|
import { BlobServiceClient } from '@azure/storage-blob';
|
|
551
|
-
import { createAzureBlobReportingRowObjectProviderV1 } from '@adcp/
|
|
563
|
+
import { createAzureBlobReportingRowObjectProviderV1 } from '@adcp/reporting-storage/azure';
|
|
552
564
|
|
|
553
565
|
const azure = createAzureBlobReportingRowObjectProviderV1({
|
|
554
566
|
client: new BlobServiceClient('https://acmerows.blob.core.windows.net', new DefaultAzureCredential()),
|
|
@@ -677,7 +689,7 @@ an unknown ID. A revision in (a) to (d) whose content cannot be served is
|
|
|
677
689
|
// Core-only service
|
|
678
690
|
createReliableReportingService({
|
|
679
691
|
// ...
|
|
680
|
-
maintenance: { compaction: { enabled: true, limit: 100 } },
|
|
692
|
+
maintenance: reportingLedgerMaintenance({ compaction: { enabled: true, limit: 100 } }),
|
|
681
693
|
});
|
|
682
694
|
|
|
683
695
|
// Production service
|
|
@@ -751,7 +763,8 @@ and `compactSupersededSnapshots` re-check before compacting.
|
|
|
751
763
|
|
|
752
764
|
You do not need the production service (managed delivery, notifications and
|
|
753
765
|
activity) to keep a ledger tidy. Build the store with the options you want and
|
|
754
|
-
give `createReliableReportingService` a `maintenance` option
|
|
766
|
+
give `createReliableReportingService` a `maintenance` option built by
|
|
767
|
+
`reportingLedgerMaintenance` from `@adcp/reporting-storage`. The production
|
|
755
768
|
service does the same work automatically; the two share one implementation, so
|
|
756
769
|
partial-failure reporting, the `maxFeedHoldDays` that retention honours, per-task
|
|
757
770
|
limits and abort handling are identical.
|
|
@@ -762,7 +775,8 @@ import {
|
|
|
762
775
|
REPORTING_LEDGER_MIGRATION,
|
|
763
776
|
REPORTING_ROW_STORAGE_MIGRATION,
|
|
764
777
|
REPORTING_LEDGER_CHANGES_MIGRATION,
|
|
765
|
-
|
|
778
|
+
reportingLedgerMaintenance,
|
|
779
|
+
} from '@adcp/reporting-storage';
|
|
766
780
|
import { createReliableReportingService } from '@adcp/sdk/reporting/service';
|
|
767
781
|
|
|
768
782
|
// Apply the three migrations, then:
|
|
@@ -777,11 +791,11 @@ const reporting = createReliableReportingService({
|
|
|
777
791
|
store,
|
|
778
792
|
statusRetentionDays: 90, // the commitment advertised to buyers; retention uses it
|
|
779
793
|
// ...adapters, contact, resolveSource, resolveCurrency, resolveCoverage
|
|
780
|
-
maintenance: {
|
|
794
|
+
maintenance: reportingLedgerMaintenance({
|
|
781
795
|
intervalMilliseconds: 300_000, // default: at most one pass per 5 minutes
|
|
782
796
|
retention: { enabled: true, recordRetentionDays: 120, limit: 100 },
|
|
783
797
|
changeFeed: { changeRetentionDays: 30, maxFeedHoldDays: 7 },
|
|
784
|
-
},
|
|
798
|
+
}),
|
|
785
799
|
});
|
|
786
800
|
|
|
787
801
|
reporting.start({ intervalMilliseconds: 60_000, deploymentWide: true, onError });
|
|
@@ -813,12 +827,18 @@ Tasks, in order:
|
|
|
813
827
|
| `change-feed pruning` | when `maintenance.changeFeed` is set | `pruneChanges` with `changeRetentionDays` and `maxFeedHoldDays`. |
|
|
814
828
|
| `retention` | when `maintenance.retention.enabled` is `true` | `retireExpiredPeriods` with the service's `statusRetentionDays` and the feed's `maxFeedHoldDays`. |
|
|
815
829
|
| `snapshot compaction` | when `maintenance.compaction.enabled` is `true` | `compactSupersededSnapshots` with the service's `statusRetentionDays` and `automatedRecoveryWindowSeconds` (see [Compacting superseded snapshots](#compacting-superseded-snapshots-opt-in)). |
|
|
830
|
+
| `orphan object collection` | when `maintenance.orphanCollection.enabled` is `true` | `collectOrphanedRowObjects`: lists each object binding under `{prefix}/{namespace_key}/` and deletes old objects nothing names. Opt-in, rate-limited and resumable; see [Orphaned object collection](REPORTING-OPERATIONS.md#adopting-row-storage-retention-and-the-change-feed). |
|
|
816
831
|
|
|
817
832
|
Notes:
|
|
818
833
|
|
|
819
|
-
- `maintenance`
|
|
834
|
+
- The service's `maintenance` option takes a factory, not an options object:
|
|
835
|
+
the SDK does not know what maintenance a store needs, so it calls the factory
|
|
836
|
+
once at construction with the store and the retention and recovery-window
|
|
837
|
+
commitments it advertises. `reportingLedgerMaintenance(options)` is the
|
|
838
|
+
PostgreSQL one. It requires a `PostgresReportingLedgerStore` (or a store with the
|
|
820
839
|
same `retireExpiredPeriods`, `pruneChanges` and `sweepRowWriteIntents`
|
|
821
|
-
methods
|
|
840
|
+
methods, plus `collectOrphanedRowObjects` when `orphanCollection` is set) and
|
|
841
|
+
fails at construction otherwise. `maintenance.changeFeed` also
|
|
822
842
|
requires `changeFeed: true` on the store, since pruning is otherwise a silent
|
|
823
843
|
no-op.
|
|
824
844
|
- Retention takes `statusRetentionDays` from the service, so it can never retire
|
|
@@ -838,7 +858,7 @@ In-process consumers such as pacing, alerts and warehouse loaders read from the
|
|
|
838
858
|
ledger, never from a warehouse copy.
|
|
839
859
|
|
|
840
860
|
```ts
|
|
841
|
-
import { REPORTING_LEDGER_CHANGES_MIGRATION } from '@adcp/
|
|
861
|
+
import { REPORTING_LEDGER_CHANGES_MIGRATION } from '@adcp/reporting-storage';
|
|
842
862
|
|
|
843
863
|
await pool.query(REPORTING_LEDGER_CHANGES_MIGRATION); // PostgreSQL 13+
|
|
844
864
|
const store = new PostgresReportingLedgerStore(pool, { acknowledgeIsolatedDatabase: true, changeFeed: true });
|
|
@@ -860,30 +880,60 @@ await store.saveFeedConsumerCursor('pacing', page.cursor); // holds back pruning
|
|
|
860
880
|
highest-numbered snapshot. An official revision is terminal, so this is always
|
|
861
881
|
one index lookup.
|
|
862
882
|
- `changesAfter` lists committed obligation, revision, adjustment and retirement
|
|
863
|
-
changes.
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
it
|
|
874
|
-
|
|
883
|
+
changes. Every feed, account-scoped or deployment-wide (omit `account_id`),
|
|
884
|
+
orders by `(xid, seq)` and returns only changes whose transaction precedes
|
|
885
|
+
every transaction still in flight (`xid` below the reading snapshot's
|
|
886
|
+
`xmin`), so a slow commit is never skipped. The order does not depend on the
|
|
887
|
+
account lock, on the order a writer drew `seq` in, or on which lock key a
|
|
888
|
+
writer took: a change with a lower `seq` and a higher `xid` that commits late
|
|
889
|
+
is simply returned on a later page, after the cursor. The cost is that any
|
|
890
|
+
older open transaction on the cluster, including an idle one in another
|
|
891
|
+
database, holds every feed back until it ends; keep transactions short. An
|
|
892
|
+
empty page therefore means either caught up or held back, so poll again rather
|
|
893
|
+
than treating it as the end of the feed. The account scan is served by the
|
|
894
|
+
`(account_id, xid, seq)` index that `REPORTING_LEDGER_CHANGES_MIGRATION`
|
|
895
|
+
creates.
|
|
875
896
|
- **A ledger database has exactly one writer SDK.** The store writes each change
|
|
876
|
-
row under the account advisory lock
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
`
|
|
885
|
-
|
|
886
|
-
|
|
897
|
+
row under the account advisory lock. The feed no longer needs that lock for
|
|
898
|
+
its order, but a second SDK is still unsupported: it can write rows the first
|
|
899
|
+
SDK's lifecycle, retention and idempotency logic does not know about. Give
|
|
900
|
+
another SDK (for example a Python deployment) its own database. `pruneChanges`
|
|
901
|
+
only deletes changes older than `changeRetentionDays`, far longer than any
|
|
902
|
+
transaction should stay open, and consumer holds compare against cursors the
|
|
903
|
+
feed itself returned, so neither adds an ordering assumption.
|
|
904
|
+
- **Upgrading from account cursors that carry only `seq`.** Account feeds used
|
|
905
|
+
to order by `seq` and cut each page before the first in-flight change. An old
|
|
906
|
+
account cursor is `{ seq }` with no `xid`. `changesAfter` accepts it and maps
|
|
907
|
+
it to the position `(xid, seq)` where `xid` is the smaller of the oldest `xid`
|
|
908
|
+
among the account's changes after that `seq` and the reading snapshot's `xmin`.
|
|
909
|
+
Every change after the old `seq` has an `xid` at or above both (a change that
|
|
910
|
+
has not committed yet belongs to a transaction at or above `xmin`), so nothing
|
|
911
|
+
is skipped. The cost is that changes the consumer already read can be returned
|
|
912
|
+
again: those with a lower `seq` and a higher `xid`, and, when a long
|
|
913
|
+
transaction was open at that moment, every change committed since it began.
|
|
914
|
+
Treat redelivery as normal, as for any at-least-once consumer. The returned cursor is in the new
|
|
915
|
+
format, even on an empty page. A legacy cursor fails with `CURSOR_EXPIRED` if
|
|
916
|
+
any change with a higher `seq` was pruned (`adcp_reporting_change_account_horizon.pruned_through_seq`
|
|
917
|
+
still records the highest pruned `seq` for this check). A consumer row saved
|
|
918
|
+
before the upgrade has a NULL `cursor_xid` and holds retention by `seq` until
|
|
919
|
+
the consumer saves its next cursor; `saveFeedConsumerCursor` given a legacy
|
|
920
|
+
cursor maps it the same way. Re-apply `REPORTING_LEDGER_CHANGES_MIGRATION`
|
|
921
|
+
before starting the new binary: it adds the account horizon's `xid` columns,
|
|
922
|
+
replaces the consumer table's check constraint, and creates the new index. On
|
|
923
|
+
a large changes table, create the index first with `CREATE INDEX CONCURRENTLY
|
|
924
|
+
IF NOT EXISTS adcp_reporting_changes_account_xid ON adcp_reporting_changes
|
|
925
|
+
(account_id, xid, seq)`, because a plain `CREATE INDEX` blocks appends while it
|
|
926
|
+
builds; the migration then skips it. The older
|
|
927
|
+
`adcp_reporting_changes_account (account_id, seq)` index is left in place and
|
|
928
|
+
serves the legacy-cursor mapping; drop it once no legacy cursor remains.
|
|
929
|
+
- **Do not run the old and new SDK's change-feed maintenance together.** An older
|
|
930
|
+
host's `pruneChanges`, `retireExpiredPeriods` and compaction hold an account
|
|
931
|
+
consumer's changes by `seq` alone and record only `pruned_through_seq`, so
|
|
932
|
+
against a consumer that holds new-format cursors they can prune a change the
|
|
933
|
+
consumer has not read and never advance the horizon the new reader checks.
|
|
934
|
+
Stop the older hosts' maintenance (or the hosts) before the new binary reads
|
|
935
|
+
the feed. Rolling back is not supported once a consumer has saved a new-format
|
|
936
|
+
account cursor: the older SDK rejects it, so reset those consumers.
|
|
887
937
|
- `pruneChanges` deletes changes older than `changeRetentionDays` (default 30)
|
|
888
938
|
that every consumer updated within `maxFeedHoldDays` (default 7) has passed.
|
|
889
939
|
An older cursor throws `ReportingChangeCursorExpiredError`; resynchronize from
|
|
@@ -918,7 +968,7 @@ await store.saveFeedConsumerCursor('pacing', page.cursor); // holds back pruning
|
|
|
918
968
|
|
|
919
969
|
### BigQuery warehouse sink
|
|
920
970
|
|
|
921
|
-
`@adcp/
|
|
971
|
+
`@adcp/reporting-storage/bigquery` loads committed revisions into your own BigQuery
|
|
922
972
|
tables for analysts. The warehouse copy is derived and non-authoritative. It
|
|
923
973
|
is never read for serving or verification, so its table names, columns,
|
|
924
974
|
partitioning and retention are yours.
|
|
@@ -928,7 +978,7 @@ import { BigQuery } from '@google-cloud/bigquery';
|
|
|
928
978
|
import {
|
|
929
979
|
REPORTING_WAREHOUSE_SINK_MIGRATION,
|
|
930
980
|
createBigQueryReportingWarehouseSinkV1,
|
|
931
|
-
} from '@adcp/
|
|
981
|
+
} from '@adcp/reporting-storage/bigquery';
|
|
932
982
|
|
|
933
983
|
await pool.query(REPORTING_WAREHOUSE_SINK_MIGRATION); // after REPORTING_LEDGER_CHANGES_MIGRATION
|
|
934
984
|
const bigquery = new BigQuery({ projectId: 'analytics-prod' }); // ADC / workload identity
|
|
@@ -1109,9 +1159,13 @@ Core remains the default and has no destination, external-resource, or receipt d
|
|
|
1109
1159
|
```ts
|
|
1110
1160
|
import {
|
|
1111
1161
|
PostgresReportingLedgerStore,
|
|
1162
|
+
} from '@adcp/reporting-storage';
|
|
1163
|
+
import {
|
|
1112
1164
|
PostgresReportingManagedDeliveryStore,
|
|
1113
1165
|
REPORTING_MANAGED_DELIVERY_MIGRATION,
|
|
1114
1166
|
createReportingManagedDeliveryRuntime,
|
|
1167
|
+
} from '@adcp/reporting-storage/managed';
|
|
1168
|
+
import {
|
|
1115
1169
|
reportingManagedDeliveryBindingV1,
|
|
1116
1170
|
} from '@adcp/sdk/reporting/ledger';
|
|
1117
1171
|
|
|
@@ -1182,7 +1236,7 @@ A seller often delivers one feed through several transports: one buyer takes fil
|
|
|
1182
1236
|
import {
|
|
1183
1237
|
createReportingManagedDeliveryAdapterRouterV1,
|
|
1184
1238
|
createReportingManagedDeliveryRuntime,
|
|
1185
|
-
} from '@adcp/
|
|
1239
|
+
} from '@adcp/reporting-storage/managed';
|
|
1186
1240
|
|
|
1187
1241
|
const adapter = createReportingManagedDeliveryAdapterRouterV1({
|
|
1188
1242
|
routes: [
|
|
@@ -1262,12 +1316,14 @@ only for health changes:
|
|
|
1262
1316
|
```ts
|
|
1263
1317
|
import { createPostgresPersistentNotificationRuntime } from '@adcp/sdk/server';
|
|
1264
1318
|
import {
|
|
1265
|
-
createPostgresReportingNotificationActivityRuntime,
|
|
1266
|
-
createPostgresReportingNotificationAttemptCheckpoint,
|
|
1267
1319
|
PostgresReportingLedgerStore,
|
|
1268
1320
|
REPORTING_LEDGER_FINALITY_WRITER_FENCE_MIGRATION,
|
|
1269
1321
|
REPORTING_LEDGER_MIGRATION,
|
|
1270
|
-
} from '@adcp/
|
|
1322
|
+
} from '@adcp/reporting-storage';
|
|
1323
|
+
import {
|
|
1324
|
+
createPostgresReportingNotificationActivityRuntime,
|
|
1325
|
+
createPostgresReportingNotificationAttemptCheckpoint,
|
|
1326
|
+
} from '@adcp/reporting-storage/notifications';
|
|
1271
1327
|
|
|
1272
1328
|
// Build the durable pre-POST checkpoint first. The notification runtime needs
|
|
1273
1329
|
// it, and the activity runtime verifies it targets the same durable store —
|