@noodleseed/one 0.46.0 → 0.47.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/dist/commands/auth-ops.d.ts.map +1 -1
- package/dist/commands/auth-ops.js +28 -4
- package/dist/commands/auth-ops.js.map +1 -1
- package/dist/commands/billing-enforcement-ops.d.ts +2 -0
- package/dist/commands/billing-enforcement-ops.d.ts.map +1 -0
- package/dist/commands/billing-enforcement-ops.js +312 -0
- package/dist/commands/billing-enforcement-ops.js.map +1 -0
- package/dist/commands/billing-metering-ops.d.ts +2 -0
- package/dist/commands/billing-metering-ops.d.ts.map +1 -0
- package/dist/commands/billing-metering-ops.js +128 -0
- package/dist/commands/billing-metering-ops.js.map +1 -0
- package/dist/commands/billing-metering-validation-ops.d.ts +2 -0
- package/dist/commands/billing-metering-validation-ops.d.ts.map +1 -0
- package/dist/commands/billing-metering-validation-ops.js +186 -0
- package/dist/commands/billing-metering-validation-ops.js.map +1 -0
- package/dist/commands/billing-ops.d.ts.map +1 -1
- package/dist/commands/billing-ops.js +6 -0
- package/dist/commands/billing-ops.js.map +1 -1
- package/dist/commands/catalog-data-resources.d.ts.map +1 -1
- package/dist/commands/catalog-data-resources.js +14 -3
- package/dist/commands/catalog-data-resources.js.map +1 -1
- package/dist/commands/catalog-render.d.ts.map +1 -1
- package/dist/commands/catalog-render.js +7 -5
- package/dist/commands/catalog-render.js.map +1 -1
- package/dist/commands/deploy-ops.d.ts.map +1 -1
- package/dist/commands/deploy-ops.js +10 -1
- package/dist/commands/deploy-ops.js.map +1 -1
- package/dist/commands/deploy-output.d.ts.map +1 -1
- package/dist/commands/deploy-output.js +4 -0
- package/dist/commands/deploy-output.js.map +1 -1
- package/dist/commands/deploy-version-resolution.d.ts +1 -0
- package/dist/commands/deploy-version-resolution.d.ts.map +1 -1
- package/dist/commands/deploy-version-resolution.js +8 -0
- package/dist/commands/deploy-version-resolution.js.map +1 -1
- package/dist/commands/mcp-apps-chatgpt.d.ts +7 -0
- package/dist/commands/mcp-apps-chatgpt.d.ts.map +1 -0
- package/dist/commands/mcp-apps-chatgpt.js +143 -0
- package/dist/commands/mcp-apps-chatgpt.js.map +1 -0
- package/dist/commands/mcp-apps.d.ts.map +1 -1
- package/dist/commands/mcp-apps.js +2 -114
- package/dist/commands/mcp-apps.js.map +1 -1
- package/dist/deploy-payload-size.d.ts +3 -0
- package/dist/deploy-payload-size.d.ts.map +1 -0
- package/dist/deploy-payload-size.js +29 -0
- package/dist/deploy-payload-size.js.map +1 -0
- package/dist/deploy.d.ts.map +1 -1
- package/dist/deploy.js +16 -8
- package/dist/deploy.js.map +1 -1
- package/dist/sdk-version-skew.d.ts +3 -0
- package/dist/sdk-version-skew.d.ts.map +1 -0
- package/dist/sdk-version-skew.js +34 -0
- package/dist/sdk-version-skew.js.map +1 -0
- package/node_modules/@noodle-borg/agent-kit/dist/generated/example-files.js +2 -2
- package/node_modules/@noodle-borg/agent-kit/dist/generated/example-files.js.map +1 -1
- package/node_modules/@noodle-borg/agent-kit/dist/skill-authoring-refs.js +1 -1
- package/node_modules/@noodle-borg/agent-kit/dist/skill-authoring-refs.js.map +1 -1
- package/node_modules/@noodle-borg/agent-kit/dist/skill-content.js +1 -1
- package/node_modules/@noodle-borg/agent-kit/dist/skill-content.js.map +1 -1
- package/node_modules/@noodle-borg/agent-kit/dist/skill-embedded-assistant-ref.js +2 -2
- package/node_modules/@noodle-borg/agent-kit/dist/skill-embedded-assistant-ref.js.map +1 -1
- package/node_modules/@noodle-borg/agent-kit/package.json +1 -1
- package/node_modules/@noodle-borg/authoring/dist/server.d.ts +5 -0
- package/node_modules/@noodle-borg/authoring/dist/server.d.ts.map +1 -1
- package/node_modules/@noodle-borg/authoring/dist/server.js +1 -0
- package/node_modules/@noodle-borg/authoring/dist/server.js.map +1 -1
- package/node_modules/@noodle-borg/compiler/dist/artifact/types.d.ts +7 -1
- package/node_modules/@noodle-borg/compiler/dist/artifact/types.d.ts.map +1 -1
- package/node_modules/@noodle-borg/compiler/dist/artifact/types.js +4 -1
- package/node_modules/@noodle-borg/compiler/dist/artifact/types.js.map +1 -1
- package/node_modules/@noodle-borg/compiler/dist/compile.d.ts.map +1 -1
- package/node_modules/@noodle-borg/compiler/dist/compile.js +3 -0
- package/node_modules/@noodle-borg/compiler/dist/compile.js.map +1 -1
- package/node_modules/@noodle-borg/compiler/dist/manifest/schema.d.ts +12 -0
- package/node_modules/@noodle-borg/compiler/dist/manifest/schema.d.ts.map +1 -1
- package/node_modules/@noodle-borg/compiler/dist/manifest/schema.js +7 -0
- package/node_modules/@noodle-borg/compiler/dist/manifest/schema.js.map +1 -1
- package/node_modules/@noodle-borg/protocol/dist/sdk-server.js +18 -0
- package/node_modules/@noodle-borg/protocol/dist/sdk-server.js.map +1 -1
- package/node_modules/@noodle-borg/protocol/dist/tool-interaction.d.ts +3 -0
- package/node_modules/@noodle-borg/protocol/dist/tool-interaction.d.ts.map +1 -1
- package/node_modules/@noodle-borg/protocol/dist/tool-interaction.js +12 -3
- package/node_modules/@noodle-borg/protocol/dist/tool-interaction.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/billing/enforcement-profile.d.ts +96 -0
- package/node_modules/@noodle-borg/service/dist/billing/enforcement-profile.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/enforcement-profile.js +198 -0
- package/node_modules/@noodle-borg/service/dist/billing/enforcement-profile.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/integration.d.ts +25 -2
- package/node_modules/@noodle-borg/service/dist/billing/integration.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/billing/integration.js +51 -5
- package/node_modules/@noodle-borg/service/dist/billing/integration.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/billing/meter-capacity.d.ts +77 -0
- package/node_modules/@noodle-borg/service/dist/billing/meter-capacity.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/meter-capacity.js +202 -0
- package/node_modules/@noodle-borg/service/dist/billing/meter-capacity.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/meter-live-validation-contract.d.ts +8 -0
- package/node_modules/@noodle-borg/service/dist/billing/meter-live-validation-contract.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/meter-live-validation-contract.js +93 -0
- package/node_modules/@noodle-borg/service/dist/billing/meter-live-validation-contract.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/meter-live-validation.d.ts +76 -0
- package/node_modules/@noodle-borg/service/dist/billing/meter-live-validation.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/meter-live-validation.js +233 -0
- package/node_modules/@noodle-borg/service/dist/billing/meter-live-validation.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/meter-readiness-health.d.ts +89 -0
- package/node_modules/@noodle-borg/service/dist/billing/meter-readiness-health.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/meter-readiness-health.js +191 -0
- package/node_modules/@noodle-borg/service/dist/billing/meter-readiness-health.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/meter-readiness.d.ts +99 -0
- package/node_modules/@noodle-borg/service/dist/billing/meter-readiness.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/meter-readiness.js +136 -0
- package/node_modules/@noodle-borg/service/dist/billing/meter-readiness.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/meter-runtime-config.d.ts +9 -0
- package/node_modules/@noodle-borg/service/dist/billing/meter-runtime-config.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/meter-runtime-config.js +24 -0
- package/node_modules/@noodle-borg/service/dist/billing/meter-runtime-config.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/meter-validation-epoch.d.ts +75 -0
- package/node_modules/@noodle-borg/service/dist/billing/meter-validation-epoch.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/meter-validation-epoch.js +127 -0
- package/node_modules/@noodle-borg/service/dist/billing/meter-validation-epoch.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-enforcement-profile-schema.d.ts +4 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-enforcement-profile-schema.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-enforcement-profile-schema.js +107 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-enforcement-profile-schema.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-enforcement-profile.d.ts +18 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-enforcement-profile.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-enforcement-profile.js +341 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-enforcement-profile.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-clock.d.ts +3 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-clock.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-clock.js +9 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-clock.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-epoch-fixtures.d.ts +13 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-epoch-fixtures.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-epoch-fixtures.js +102 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-epoch-fixtures.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-epochs.d.ts +41 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-epochs.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-epochs.js +289 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-epochs.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-evidence-retention.d.ts +16 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-evidence-retention.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-evidence-retention.js +126 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-evidence-retention.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-live-validation.d.ts +33 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-live-validation.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-live-validation.js +436 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-live-validation.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-maintenance.d.ts +26 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-maintenance.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-maintenance.js +146 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-maintenance.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-partition.d.ts +8 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-partition.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-partition.js +42 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-partition.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-prepare-preflight.d.ts +8 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-prepare-preflight.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-prepare-preflight.js +44 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-prepare-preflight.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-readiness-live.d.ts +13 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-readiness-live.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-readiness-live.js +189 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-readiness-live.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-readiness.d.ts +18 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-readiness.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-readiness.js +342 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-readiness.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-reconciliation.d.ts +27 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-reconciliation.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-reconciliation.js +304 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-reconciliation.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-retention.d.ts +22 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-retention.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-retention.js +224 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-retention.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-runtime.d.ts +33 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-runtime.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-runtime.js +173 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-runtime.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-scheduler-schema.d.ts +7 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-scheduler-schema.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-scheduler-schema.js +50 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-scheduler-schema.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-scheduler-store.d.ts +34 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-scheduler-store.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-scheduler-store.js +157 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-scheduler-store.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-scheduler.d.ts +56 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-scheduler.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-scheduler.js +264 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-scheduler.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-schema.d.ts +6 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-schema.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-schema.js +414 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-schema.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-validation.d.ts +43 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-validation.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-validation.js +321 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-validation.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-window-lock.d.ts +10 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-window-lock.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-window-lock.js +13 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-window-lock.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-window-schema.d.ts +6 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-window-schema.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-window-schema.js +248 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-window-schema.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-writer-compaction.d.ts +29 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-writer-compaction.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-writer-compaction.js +240 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-writer-compaction.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-writer-health-schema.d.ts +4 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-writer-health-schema.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-writer-health-schema.js +140 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-meter-writer-health-schema.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-migration.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/billing/postgres-migration.js +4 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-migration.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/billing/postgres-schema.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/billing/postgres-schema.js +6 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres-schema.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/billing/postgres.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/billing/postgres.js +3 -0
- package/node_modules/@noodle-borg/service/dist/billing/postgres.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/billing/service-meter-runtime.d.ts +7 -0
- package/node_modules/@noodle-borg/service/dist/billing/service-meter-runtime.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/service-meter-runtime.js +19 -0
- package/node_modules/@noodle-borg/service/dist/billing/service-meter-runtime.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/shadow-meter.d.ts +9 -4
- package/node_modules/@noodle-borg/service/dist/billing/shadow-meter.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/billing/shadow-meter.js +34 -95
- package/node_modules/@noodle-borg/service/dist/billing/shadow-meter.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/billing/usage-identity.d.ts +14 -0
- package/node_modules/@noodle-borg/service/dist/billing/usage-identity.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/usage-identity.js +87 -0
- package/node_modules/@noodle-borg/service/dist/billing/usage-identity.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/usage-observer.d.ts +6 -0
- package/node_modules/@noodle-borg/service/dist/billing/usage-observer.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing/usage-observer.js +26 -0
- package/node_modules/@noodle-borg/service/dist/billing/usage-observer.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing-public.d.ts +16 -0
- package/node_modules/@noodle-borg/service/dist/billing-public.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/billing-public.js +15 -0
- package/node_modules/@noodle-borg/service/dist/billing-public.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/customer-verifier.d.ts +1 -0
- package/node_modules/@noodle-borg/service/dist/customer-verifier.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/customer-verifier.js +15 -0
- package/node_modules/@noodle-borg/service/dist/customer-verifier.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/http-util.d.ts +2 -0
- package/node_modules/@noodle-borg/service/dist/http-util.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/http-util.js +1 -1
- package/node_modules/@noodle-borg/service/dist/http-util.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/index.d.ts +2 -7
- package/node_modules/@noodle-borg/service/dist/index.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/index.js +1 -6
- package/node_modules/@noodle-borg/service/dist/index.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/main.js +3 -0
- package/node_modules/@noodle-borg/service/dist/main.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/options.d.ts +18 -0
- package/node_modules/@noodle-borg/service/dist/options.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/persistence-options.d.ts +4 -0
- package/node_modules/@noodle-borg/service/dist/persistence-options.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/persistence-options.js +22 -0
- package/node_modules/@noodle-borg/service/dist/persistence-options.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/routes/billing-enforcement-cohort.d.ts +17 -0
- package/node_modules/@noodle-borg/service/dist/routes/billing-enforcement-cohort.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/routes/billing-enforcement-cohort.js +145 -0
- package/node_modules/@noodle-borg/service/dist/routes/billing-enforcement-cohort.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/routes/billing-meter-readiness.d.ts +15 -0
- package/node_modules/@noodle-borg/service/dist/routes/billing-meter-readiness.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/routes/billing-meter-readiness.js +78 -0
- package/node_modules/@noodle-borg/service/dist/routes/billing-meter-readiness.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/routes/billing-meter-validation.d.ts +15 -0
- package/node_modules/@noodle-borg/service/dist/routes/billing-meter-validation.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/routes/billing-meter-validation.js +108 -0
- package/node_modules/@noodle-borg/service/dist/routes/billing-meter-validation.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/routes/commercial-dispatch.d.ts +6 -0
- package/node_modules/@noodle-borg/service/dist/routes/commercial-dispatch.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/commercial-dispatch.js +99 -0
- package/node_modules/@noodle-borg/service/dist/routes/commercial-dispatch.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/commercial-service-deps.d.ts +25 -0
- package/node_modules/@noodle-borg/service/dist/routes/commercial-service-deps.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/routes/commercial-service-deps.js +35 -0
- package/node_modules/@noodle-borg/service/dist/routes/commercial-service-deps.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/routes/control-plane.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/control-plane.js +3 -1
- package/node_modules/@noodle-borg/service/dist/routes/control-plane.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/serve-options.d.ts +93 -0
- package/node_modules/@noodle-borg/service/dist/serve-options.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/serve-options.js +2 -0
- package/node_modules/@noodle-borg/service/dist/serve-options.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/serve.d.ts +2 -92
- package/node_modules/@noodle-borg/service/dist/serve.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/serve.js +64 -59
- package/node_modules/@noodle-borg/service/dist/serve.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/service-resource-cleanup.d.ts +22 -0
- package/node_modules/@noodle-borg/service/dist/service-resource-cleanup.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/service-resource-cleanup.js +51 -0
- package/node_modules/@noodle-borg/service/dist/service-resource-cleanup.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/service.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/service.js +10 -21
- package/node_modules/@noodle-borg/service/dist/service.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/cloudsql-pool.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/cloudsql-pool.js +7 -1
- package/node_modules/@noodle-borg/service/dist/store/cloudsql-pool.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/postgres-billing.d.ts +6 -2
- package/node_modules/@noodle-borg/service/dist/store/postgres-billing.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/postgres-billing.js +11 -1
- package/node_modules/@noodle-borg/service/dist/store/postgres-billing.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { validateSlug } from '../store/validate.js';
|
|
3
|
+
import { BILLING_METER_AGGREGATE_RETENTION_MONTHS, BILLING_METER_EXACT_KEY_TOMBSTONE_RETENTION_DAYS, BILLING_METER_RECEIPT_RETENTION_DAYS, BILLING_METER_RETRY_IDENTITY_VERSION, } from './meter-readiness.js';
|
|
4
|
+
import { BILLING_METER_VALIDATION_WRITER_CONTRACT_VERSION } from './meter-validation-epoch.js';
|
|
5
|
+
import { validateBillingAccountId } from './model.js';
|
|
6
|
+
import { readBillingMeterTransactionTime } from './postgres-meter-clock.js';
|
|
7
|
+
import { billingMeterWindowLockKey } from './postgres-meter-window-lock.js';
|
|
8
|
+
import { validateScalarId } from './postgres-records.js';
|
|
9
|
+
import { validateBillingUsageRetryWindowMs } from './usage-store.js';
|
|
10
|
+
import { resolveUtcMonthlyUsageWindow } from './usage-window.js';
|
|
11
|
+
export class BillingMeterValidationIdempotencyConflictError extends Error {
|
|
12
|
+
code = 'billing_meter_validation_idempotency_conflict';
|
|
13
|
+
constructor() {
|
|
14
|
+
super('billing meter validation identity was reused with different semantics');
|
|
15
|
+
this.name = 'BillingMeterValidationIdempotencyConflictError';
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Validation-only transaction for load/reconciliation proof. It is deliberately absent from request
|
|
20
|
+
* dispatch and accepts only a prepared epoch; it does not make or enforce a customer admission decision.
|
|
21
|
+
*/
|
|
22
|
+
export async function recordBillingMeterValidationUsage(pool, input, options) {
|
|
23
|
+
const client = await pool.connect();
|
|
24
|
+
try {
|
|
25
|
+
await client.query('BEGIN');
|
|
26
|
+
const result = await recordBillingMeterValidationUsageTx(client, input, options);
|
|
27
|
+
await client.query('COMMIT');
|
|
28
|
+
return result;
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
try {
|
|
32
|
+
await client.query('ROLLBACK');
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
// Preserve the transaction error; a broken client is discarded by pg when released.
|
|
36
|
+
}
|
|
37
|
+
throw error;
|
|
38
|
+
}
|
|
39
|
+
finally {
|
|
40
|
+
client.release();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/** Reuse the exact receipt/counter transaction from the live writer without accepting an epoch on its API. */
|
|
44
|
+
export function recordBillingMeterValidationUsageTx(client, input, options) {
|
|
45
|
+
const usage = normalizeValidationInput(input);
|
|
46
|
+
const retryWindowMs = validateBillingUsageRetryWindowMs(options.retryWindowMs);
|
|
47
|
+
const expectedKeyGeneration = validateFingerprint('billing meter expected key generation', options.keyGeneration);
|
|
48
|
+
const expectedReleaseSha = validateReleaseSha(options.releaseSha);
|
|
49
|
+
const expectedWriterContractVersion = validateWriterContractVersion(options.writerContractVersion ?? BILLING_METER_VALIDATION_WRITER_CONTRACT_VERSION);
|
|
50
|
+
const writerSessionId = options.writerSessionId === undefined
|
|
51
|
+
? undefined
|
|
52
|
+
: validateScalarId('billing meter writer session id', options.writerSessionId);
|
|
53
|
+
return recordValidationUsageTx(client, usage, retryWindowMs, expectedKeyGeneration, expectedReleaseSha, expectedWriterContractVersion, writerSessionId);
|
|
54
|
+
}
|
|
55
|
+
async function recordValidationUsageTx(client, usage, retryWindowMs, expectedKeyGeneration, expectedReleaseSha, expectedWriterContractVersion, writerSessionId) {
|
|
56
|
+
const recordedAt = await readBillingMeterTransactionTime(client);
|
|
57
|
+
const dedupeKind = usage.highConfidenceKeyHash === undefined ? 'fallback' : 'exact';
|
|
58
|
+
const dedupeValue = usage.highConfidenceKeyHash ?? usage.fallbackFingerprint;
|
|
59
|
+
await client.query('SELECT pg_advisory_xact_lock(hashtextextended($1, 0))', [
|
|
60
|
+
`${usage.epochId}:${dedupeKind}:${dedupeValue}`,
|
|
61
|
+
]);
|
|
62
|
+
const epoch = await client.query(`SELECT state, retry_identity_version, key_generation, release_sha, writer_contract_version
|
|
63
|
+
FROM billing_meter_epochs WHERE id = $1 FOR SHARE`, [usage.epochId]);
|
|
64
|
+
if (epoch.rows[0]?.state !== 'prepared') {
|
|
65
|
+
throw new Error('billing meter validation requires a prepared epoch');
|
|
66
|
+
}
|
|
67
|
+
if (epoch.rows[0].retry_identity_version !== BILLING_METER_RETRY_IDENTITY_VERSION) {
|
|
68
|
+
throw new Error('billing meter validation retry identity version is unsupported');
|
|
69
|
+
}
|
|
70
|
+
if (epoch.rows[0].key_generation !== expectedKeyGeneration) {
|
|
71
|
+
throw new Error('billing meter validation key generation does not match the prepared epoch');
|
|
72
|
+
}
|
|
73
|
+
if (epoch.rows[0].release_sha !== expectedReleaseSha) {
|
|
74
|
+
throw new Error('billing meter validation release SHA does not match the prepared epoch');
|
|
75
|
+
}
|
|
76
|
+
if (epoch.rows[0].writer_contract_version !== expectedWriterContractVersion) {
|
|
77
|
+
throw new Error('billing meter validation writer contract does not match the prepared epoch');
|
|
78
|
+
}
|
|
79
|
+
if (usage.highConfidenceKeyHash !== undefined) {
|
|
80
|
+
const exact = await client.query(`SELECT event_id, classification, semantic_fingerprint
|
|
81
|
+
FROM billing_meter_exact_key_tombstones
|
|
82
|
+
WHERE epoch_id = $1 AND key_hash = decode($2, 'hex')`, [usage.epochId, usage.highConfidenceKeyHash]);
|
|
83
|
+
const prior = exact.rows[0];
|
|
84
|
+
if (prior !== undefined) {
|
|
85
|
+
if (!prior.semantic_fingerprint.equals(Buffer.from(usage.semanticFingerprint, 'hex'))) {
|
|
86
|
+
throw new BillingMeterValidationIdempotencyConflictError();
|
|
87
|
+
}
|
|
88
|
+
return {
|
|
89
|
+
outcome: 'duplicate',
|
|
90
|
+
deduplicatedBy: 'high_confidence_key',
|
|
91
|
+
eventId: prior.event_id,
|
|
92
|
+
classification: prior.classification,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
const retryCutoff = new Date(Date.parse(recordedAt) - retryWindowMs).toISOString();
|
|
98
|
+
const retryCeiling = new Date(Date.parse(recordedAt) + retryWindowMs).toISOString();
|
|
99
|
+
const fallback = await client.query(`SELECT event_id, classification
|
|
100
|
+
FROM billing_meter_usage_events
|
|
101
|
+
WHERE epoch_id = $1
|
|
102
|
+
AND fallback_fingerprint = decode($2, 'hex')
|
|
103
|
+
AND semantic_fingerprint = decode($3, 'hex')
|
|
104
|
+
AND recorded_at >= $4
|
|
105
|
+
AND recorded_at <= $5
|
|
106
|
+
ORDER BY recorded_at DESC, event_id
|
|
107
|
+
LIMIT 1`, [
|
|
108
|
+
usage.epochId,
|
|
109
|
+
usage.fallbackFingerprint,
|
|
110
|
+
usage.semanticFingerprint,
|
|
111
|
+
retryCutoff,
|
|
112
|
+
retryCeiling,
|
|
113
|
+
]);
|
|
114
|
+
const prior = fallback.rows[0];
|
|
115
|
+
if (prior !== undefined) {
|
|
116
|
+
return {
|
|
117
|
+
outcome: 'duplicate',
|
|
118
|
+
deduplicatedBy: 'bounded_fallback',
|
|
119
|
+
eventId: prior.event_id,
|
|
120
|
+
classification: prior.classification,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
const resolution = await client.query(`SELECT link.billing_account_id,
|
|
125
|
+
link.version AS link_version,
|
|
126
|
+
snapshot.id AS snapshot_id,
|
|
127
|
+
snapshot.version AS snapshot_version,
|
|
128
|
+
snapshot.monthly_usage_anchor
|
|
129
|
+
FROM org_billing_links AS link
|
|
130
|
+
JOIN billing_account_active_snapshots AS active
|
|
131
|
+
ON active.billing_account_id = link.billing_account_id
|
|
132
|
+
JOIN billing_entitlement_snapshots AS snapshot
|
|
133
|
+
ON snapshot.billing_account_id = active.billing_account_id
|
|
134
|
+
AND snapshot.id = active.snapshot_id
|
|
135
|
+
WHERE link.org_slug = $1
|
|
136
|
+
AND link.active
|
|
137
|
+
AND snapshot.verification_status = 'verified'
|
|
138
|
+
FOR SHARE OF link, active, snapshot`, [usage.org]);
|
|
139
|
+
const attribution = resolution.rows[0];
|
|
140
|
+
if (attribution === undefined) {
|
|
141
|
+
throw new Error('billing setup is incomplete for organization');
|
|
142
|
+
}
|
|
143
|
+
const window = resolveUtcMonthlyUsageWindow(toIso(attribution.monthly_usage_anchor), recordedAt);
|
|
144
|
+
const resolved = {
|
|
145
|
+
...usage,
|
|
146
|
+
billingAccountId: validateBillingAccountId(attribution.billing_account_id),
|
|
147
|
+
linkVersion: attribution.link_version,
|
|
148
|
+
snapshotId: validateScalarId('billing meter snapshot id', attribution.snapshot_id),
|
|
149
|
+
snapshotVersion: attribution.snapshot_version,
|
|
150
|
+
windowStart: window.start,
|
|
151
|
+
windowEnd: window.end,
|
|
152
|
+
admittedAt: recordedAt,
|
|
153
|
+
recordedAt,
|
|
154
|
+
};
|
|
155
|
+
await client.query('SELECT pg_advisory_xact_lock_shared(hashtextextended($1, 0))', [
|
|
156
|
+
billingMeterWindowLockKey({
|
|
157
|
+
epochId: resolved.epochId,
|
|
158
|
+
windowStart: resolved.windowStart,
|
|
159
|
+
windowEnd: resolved.windowEnd,
|
|
160
|
+
}),
|
|
161
|
+
]);
|
|
162
|
+
const sealed = await client.query(`SELECT EXISTS (
|
|
163
|
+
SELECT 1
|
|
164
|
+
FROM billing_meter_reconciliation_runs
|
|
165
|
+
WHERE epoch_id = $1 AND window_start = $2 AND window_end = $3 AND sealed
|
|
166
|
+
) AS sealed`, [resolved.epochId, resolved.windowStart, resolved.windowEnd]);
|
|
167
|
+
if (sealed.rows[0]?.sealed === true) {
|
|
168
|
+
throw new Error('billing meter validation window is sealed');
|
|
169
|
+
}
|
|
170
|
+
const eventId = `bmve_${randomUUID()}`;
|
|
171
|
+
const eventValues = [
|
|
172
|
+
eventId,
|
|
173
|
+
usage.epochId,
|
|
174
|
+
usage.highConfidenceKeyHash ?? null,
|
|
175
|
+
usage.fallbackFingerprint,
|
|
176
|
+
usage.semanticFingerprint,
|
|
177
|
+
usage.classification,
|
|
178
|
+
resolved.billingAccountId,
|
|
179
|
+
resolved.org,
|
|
180
|
+
resolved.app,
|
|
181
|
+
resolved.environment,
|
|
182
|
+
resolved.deploymentId,
|
|
183
|
+
resolved.linkVersion,
|
|
184
|
+
resolved.snapshotId,
|
|
185
|
+
resolved.snapshotVersion,
|
|
186
|
+
resolved.admittedAt,
|
|
187
|
+
resolved.windowStart,
|
|
188
|
+
resolved.windowEnd,
|
|
189
|
+
resolved.recordedAt,
|
|
190
|
+
];
|
|
191
|
+
await client.query(`INSERT INTO billing_meter_usage_events
|
|
192
|
+
(event_id, epoch_id, mode, high_confidence_key_hash, fallback_fingerprint,
|
|
193
|
+
semantic_fingerprint, classification, billing_account_id, org_slug, app_slug,
|
|
194
|
+
environment, deployment_id, link_version, snapshot_id, snapshot_version, admitted_at,
|
|
195
|
+
window_start, window_end, recorded_at, retention_until${writerSessionId === undefined ? '' : ', writer_session_id'})
|
|
196
|
+
VALUES
|
|
197
|
+
($1, $2, 'validation', decode($3, 'hex'), decode($4, 'hex'), decode($5, 'hex'),
|
|
198
|
+
$6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18,
|
|
199
|
+
$17::timestamptz + interval '${BILLING_METER_RECEIPT_RETENTION_DAYS} days'${writerSessionId === undefined ? '' : ', $19'})`, writerSessionId === undefined ? eventValues : [...eventValues, writerSessionId]);
|
|
200
|
+
if (usage.highConfidenceKeyHash !== undefined) {
|
|
201
|
+
await client.query(`INSERT INTO billing_meter_exact_key_tombstones
|
|
202
|
+
(epoch_id, key_hash, semantic_fingerprint, event_id, classification, window_end,
|
|
203
|
+
created_at, retention_until)
|
|
204
|
+
VALUES
|
|
205
|
+
($1, decode($2, 'hex'), decode($3, 'hex'), $4, $5, $6, $7,
|
|
206
|
+
$6::timestamptz + interval '${BILLING_METER_EXACT_KEY_TOMBSTONE_RETENTION_DAYS} days')`, [
|
|
207
|
+
usage.epochId,
|
|
208
|
+
usage.highConfidenceKeyHash,
|
|
209
|
+
usage.semanticFingerprint,
|
|
210
|
+
eventId,
|
|
211
|
+
usage.classification,
|
|
212
|
+
resolved.windowEnd,
|
|
213
|
+
resolved.recordedAt,
|
|
214
|
+
]);
|
|
215
|
+
}
|
|
216
|
+
const increments = classificationIncrements(usage.classification);
|
|
217
|
+
const account = await upsertValidationCounter(client, {
|
|
218
|
+
table: 'billing_meter_account_windows',
|
|
219
|
+
conflict: 'epoch_id, billing_account_id, window_start',
|
|
220
|
+
columns: ['epoch_id', 'billing_account_id', 'window_start'],
|
|
221
|
+
values: [resolved.epochId, resolved.billingAccountId, resolved.windowStart],
|
|
222
|
+
usage: resolved,
|
|
223
|
+
increments,
|
|
224
|
+
});
|
|
225
|
+
const organization = await upsertValidationCounter(client, {
|
|
226
|
+
table: 'billing_meter_org_windows',
|
|
227
|
+
conflict: 'epoch_id, billing_account_id, org_slug, window_start',
|
|
228
|
+
columns: ['epoch_id', 'billing_account_id', 'org_slug', 'window_start'],
|
|
229
|
+
values: [resolved.epochId, resolved.billingAccountId, resolved.org, resolved.windowStart],
|
|
230
|
+
usage: resolved,
|
|
231
|
+
increments,
|
|
232
|
+
});
|
|
233
|
+
if (!account || !organization)
|
|
234
|
+
throw new Error('billing meter validation window conflict');
|
|
235
|
+
return {
|
|
236
|
+
outcome: 'recorded',
|
|
237
|
+
deduplicatedBy: null,
|
|
238
|
+
eventId,
|
|
239
|
+
classification: usage.classification,
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
async function upsertValidationCounter(client, input) {
|
|
243
|
+
const prefix = input.values.map((_, index) => `$${index + 1}`).join(', ');
|
|
244
|
+
const offset = input.values.length;
|
|
245
|
+
const result = await client.query(`INSERT INTO ${input.table}
|
|
246
|
+
(${input.columns.join(', ')}, window_end, included_calls, overage_calls, denied_calls,
|
|
247
|
+
first_admitted_at, last_admitted_at, updated_at, retention_until)
|
|
248
|
+
VALUES
|
|
249
|
+
(${prefix}, $${offset + 1}, $${offset + 2}, $${offset + 3}, $${offset + 4},
|
|
250
|
+
$${offset + 5}, $${offset + 5}, $${offset + 6},
|
|
251
|
+
$${offset + 1}::timestamptz + interval '${BILLING_METER_AGGREGATE_RETENTION_MONTHS} months')
|
|
252
|
+
ON CONFLICT (${input.conflict}) DO UPDATE SET
|
|
253
|
+
included_calls = ${input.table}.included_calls + EXCLUDED.included_calls,
|
|
254
|
+
overage_calls = ${input.table}.overage_calls + EXCLUDED.overage_calls,
|
|
255
|
+
denied_calls = ${input.table}.denied_calls + EXCLUDED.denied_calls,
|
|
256
|
+
first_admitted_at = LEAST(${input.table}.first_admitted_at, EXCLUDED.first_admitted_at),
|
|
257
|
+
last_admitted_at = GREATEST(${input.table}.last_admitted_at, EXCLUDED.last_admitted_at),
|
|
258
|
+
updated_at = EXCLUDED.updated_at
|
|
259
|
+
WHERE ${input.table}.window_end = EXCLUDED.window_end
|
|
260
|
+
RETURNING 1`, [
|
|
261
|
+
...input.values,
|
|
262
|
+
input.usage.windowEnd,
|
|
263
|
+
...input.increments,
|
|
264
|
+
input.usage.admittedAt,
|
|
265
|
+
input.usage.recordedAt,
|
|
266
|
+
]);
|
|
267
|
+
return result.rowCount === 1;
|
|
268
|
+
}
|
|
269
|
+
function classificationIncrements(classification) {
|
|
270
|
+
if (classification === 'included')
|
|
271
|
+
return [1, 0, 0];
|
|
272
|
+
if (classification === 'overage')
|
|
273
|
+
return [0, 1, 0];
|
|
274
|
+
return [0, 0, 1];
|
|
275
|
+
}
|
|
276
|
+
function normalizeValidationInput(input) {
|
|
277
|
+
if (input.classification !== 'included' &&
|
|
278
|
+
input.classification !== 'overage' &&
|
|
279
|
+
input.classification !== 'denied') {
|
|
280
|
+
throw new Error('billing meter validation classification is invalid');
|
|
281
|
+
}
|
|
282
|
+
return {
|
|
283
|
+
...input,
|
|
284
|
+
epochId: validateScalarId('billing meter epoch id', input.epochId),
|
|
285
|
+
org: validateSlug('org', input.org),
|
|
286
|
+
app: validateSlug('app', input.app),
|
|
287
|
+
environment: validateSlug('env', input.environment),
|
|
288
|
+
deploymentId: validateScalarId('billing meter deployment id', input.deploymentId),
|
|
289
|
+
...(input.highConfidenceKeyHash === undefined
|
|
290
|
+
? {}
|
|
291
|
+
: {
|
|
292
|
+
highConfidenceKeyHash: validateFingerprint('billing meter high-confidence key', input.highConfidenceKeyHash),
|
|
293
|
+
}),
|
|
294
|
+
fallbackFingerprint: validateFingerprint('billing meter fallback fingerprint', input.fallbackFingerprint),
|
|
295
|
+
semanticFingerprint: validateFingerprint('billing meter semantic fingerprint', input.semanticFingerprint),
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
function toIso(value) {
|
|
299
|
+
const date = value instanceof Date ? value : new Date(value);
|
|
300
|
+
if (!Number.isFinite(date.getTime()))
|
|
301
|
+
throw new Error('billing meter timestamp is invalid');
|
|
302
|
+
return date.toISOString();
|
|
303
|
+
}
|
|
304
|
+
function validateFingerprint(name, value) {
|
|
305
|
+
if (!/^[0-9a-f]{64}$/.test(value))
|
|
306
|
+
throw new Error(`${name} must be a SHA-256 digest`);
|
|
307
|
+
return value;
|
|
308
|
+
}
|
|
309
|
+
function validateReleaseSha(value) {
|
|
310
|
+
if (!/^[0-9a-f]{40}$/.test(value)) {
|
|
311
|
+
throw new Error('billing meter release SHA must be a full 40-character commit digest');
|
|
312
|
+
}
|
|
313
|
+
return value;
|
|
314
|
+
}
|
|
315
|
+
function validateWriterContractVersion(value) {
|
|
316
|
+
if (!Number.isSafeInteger(value) || value < 1) {
|
|
317
|
+
throw new Error('billing meter writer contract version must be positive');
|
|
318
|
+
}
|
|
319
|
+
return value;
|
|
320
|
+
}
|
|
321
|
+
//# sourceMappingURL=postgres-meter-validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres-meter-validation.js","sourceRoot":"","sources":["../../src/billing/postgres-meter-validation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare const BILLING_METER_CHANGED_WINDOW_RECONCILIATION_DELAY_MS: number;
|
|
2
|
+
export declare const BILLING_METER_CLEAN_WINDOW_RECONCILIATION_INTERVAL_MS: number;
|
|
3
|
+
export declare const BILLING_METER_FAILED_WINDOW_RECONCILIATION_DELAY_MS: number;
|
|
4
|
+
export declare const BILLING_METER_INTEGRITY_MODULUS = "2305843009213693951";
|
|
5
|
+
export declare function billingMeterWindowLockKey(input: {
|
|
6
|
+
readonly epochId: string;
|
|
7
|
+
readonly windowStart: string;
|
|
8
|
+
readonly windowEnd: string;
|
|
9
|
+
}): string;
|
|
10
|
+
//# sourceMappingURL=postgres-meter-window-lock.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres-meter-window-lock.d.ts","sourceRoot":"","sources":["../../src/billing/postgres-meter-window-lock.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,oDAAoD,QAAkB,CAAC;AACpF,eAAO,MAAM,qDAAqD,QAAsB,CAAC;AACzF,eAAO,MAAM,mDAAmD,QAAkB,CAAC;AACnF,eAAO,MAAM,+BAA+B,wBAAwB,CAAC;AAErE,wBAAgB,yBAAyB,CAAC,KAAK,EAAE;IAC/C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B,GAAG,MAAM,CAOT"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export const BILLING_METER_CHANGED_WINDOW_RECONCILIATION_DELAY_MS = 15 * 60 * 1_000;
|
|
2
|
+
export const BILLING_METER_CLEAN_WINDOW_RECONCILIATION_INTERVAL_MS = 6 * 60 * 60 * 1_000;
|
|
3
|
+
export const BILLING_METER_FAILED_WINDOW_RECONCILIATION_DELAY_MS = 15 * 60 * 1_000;
|
|
4
|
+
export const BILLING_METER_INTEGRITY_MODULUS = '2305843009213693951';
|
|
5
|
+
export function billingMeterWindowLockKey(input) {
|
|
6
|
+
const windowStartMs = Date.parse(input.windowStart);
|
|
7
|
+
const windowEndMs = Date.parse(input.windowEnd);
|
|
8
|
+
if (!Number.isSafeInteger(windowStartMs) || !Number.isSafeInteger(windowEndMs)) {
|
|
9
|
+
throw new Error('billing meter window lock requires valid instants');
|
|
10
|
+
}
|
|
11
|
+
return `billing-meter-window:${input.epochId}:${windowStartMs}:${windowEndMs}`;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=postgres-meter-window-lock.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres-meter-window-lock.js","sourceRoot":"","sources":["../../src/billing/postgres-meter-window-lock.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,oDAAoD,GAAG,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC;AACpF,MAAM,CAAC,MAAM,qDAAqD,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC;AACzF,MAAM,CAAC,MAAM,mDAAmD,GAAG,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC;AACnF,MAAM,CAAC,MAAM,+BAA+B,GAAG,qBAAqB,CAAC;AAErE,MAAM,UAAU,yBAAyB,CAAC,KAIzC;IACC,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IACpD,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAChD,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,WAAW,CAAC,EAAE,CAAC;QAC/E,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;IACvE,CAAC;IACD,OAAO,wBAAwB,KAAK,CAAC,OAAO,IAAI,aAAa,IAAI,WAAW,EAAE,CAAC;AACjF,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Pool } from 'pg';
|
|
2
|
+
/** Create the one-row-per-window checkpoint before the receipt table adds its completeness FK. */
|
|
3
|
+
export declare function ensureBillingMeterWindowRegistrySchema(pool: Pool): Promise<void>;
|
|
4
|
+
/** Attach receipt-side checkpoint maintenance only after the partitioned receipt parent exists. */
|
|
5
|
+
export declare function ensureBillingMeterReceiptIntegritySchema(pool: Pool): Promise<void>;
|
|
6
|
+
//# sourceMappingURL=postgres-meter-window-schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres-meter-window-schema.d.ts","sourceRoot":"","sources":["../../src/billing/postgres-meter-window-schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAI/B,kGAAkG;AAClG,wBAAsB,sCAAsC,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAkDtF;AAED,mGAAmG;AACnG,wBAAsB,wCAAwC,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CA+LxF"}
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
import { BILLING_METER_AGGREGATE_RETENTION_MONTHS } from './meter-readiness.js';
|
|
2
|
+
import { BILLING_METER_INTEGRITY_MODULUS } from './postgres-meter-window-lock.js';
|
|
3
|
+
/** Create the one-row-per-window checkpoint before the receipt table adds its completeness FK. */
|
|
4
|
+
export async function ensureBillingMeterWindowRegistrySchema(pool) {
|
|
5
|
+
await pool.query(`
|
|
6
|
+
CREATE TABLE IF NOT EXISTS billing_meter_windows (
|
|
7
|
+
epoch_id text NOT NULL
|
|
8
|
+
REFERENCES billing_meter_epochs(id) ON DELETE RESTRICT,
|
|
9
|
+
window_start timestamptz NOT NULL,
|
|
10
|
+
window_end timestamptz NOT NULL CHECK (window_end > window_start),
|
|
11
|
+
receipt_included_calls bigint NOT NULL DEFAULT 0 CHECK (receipt_included_calls >= 0),
|
|
12
|
+
receipt_overage_calls bigint NOT NULL DEFAULT 0 CHECK (receipt_overage_calls >= 0),
|
|
13
|
+
receipt_denied_calls bigint NOT NULL DEFAULT 0 CHECK (receipt_denied_calls >= 0),
|
|
14
|
+
writer_observed_calls bigint NOT NULL DEFAULT 0 CHECK (writer_observed_calls >= 0),
|
|
15
|
+
account_integrity_a numeric(19, 0) NOT NULL DEFAULT 0
|
|
16
|
+
CHECK (account_integrity_a >= 0 AND account_integrity_a < ${BILLING_METER_INTEGRITY_MODULUS}),
|
|
17
|
+
account_integrity_b numeric(19, 0) NOT NULL DEFAULT 0
|
|
18
|
+
CHECK (account_integrity_b >= 0 AND account_integrity_b < ${BILLING_METER_INTEGRITY_MODULUS}),
|
|
19
|
+
org_integrity_a numeric(19, 0) NOT NULL DEFAULT 0
|
|
20
|
+
CHECK (org_integrity_a >= 0 AND org_integrity_a < ${BILLING_METER_INTEGRITY_MODULUS}),
|
|
21
|
+
org_integrity_b numeric(19, 0) NOT NULL DEFAULT 0
|
|
22
|
+
CHECK (org_integrity_b >= 0 AND org_integrity_b < ${BILLING_METER_INTEGRITY_MODULUS}),
|
|
23
|
+
first_observed_at timestamptz,
|
|
24
|
+
last_observed_at timestamptz,
|
|
25
|
+
last_writer_observed_at timestamptz,
|
|
26
|
+
sealed_at timestamptz,
|
|
27
|
+
retention_until timestamptz NOT NULL,
|
|
28
|
+
PRIMARY KEY (epoch_id, window_start, window_end),
|
|
29
|
+
CHECK (
|
|
30
|
+
(first_observed_at IS NULL AND last_observed_at IS NULL) OR
|
|
31
|
+
(first_observed_at IS NOT NULL AND last_observed_at IS NOT NULL AND
|
|
32
|
+
last_observed_at >= first_observed_at)
|
|
33
|
+
),
|
|
34
|
+
CHECK (
|
|
35
|
+
retention_until =
|
|
36
|
+
window_end + interval '${BILLING_METER_AGGREGATE_RETENTION_MONTHS} months'
|
|
37
|
+
)
|
|
38
|
+
)
|
|
39
|
+
`);
|
|
40
|
+
await pool.query(`
|
|
41
|
+
CREATE INDEX IF NOT EXISTS billing_meter_windows_unsealed_idx
|
|
42
|
+
ON billing_meter_windows (epoch_id, window_end, first_observed_at)
|
|
43
|
+
WHERE sealed_at IS NULL
|
|
44
|
+
`);
|
|
45
|
+
await pool.query(`
|
|
46
|
+
CREATE INDEX IF NOT EXISTS billing_meter_windows_observation_span_idx
|
|
47
|
+
ON billing_meter_windows (first_observed_at, last_observed_at)
|
|
48
|
+
WHERE first_observed_at IS NOT NULL
|
|
49
|
+
`);
|
|
50
|
+
await pool.query(`
|
|
51
|
+
CREATE INDEX IF NOT EXISTS billing_meter_windows_retention_idx
|
|
52
|
+
ON billing_meter_windows (retention_until)
|
|
53
|
+
`);
|
|
54
|
+
}
|
|
55
|
+
/** Attach receipt-side checkpoint maintenance only after the partitioned receipt parent exists. */
|
|
56
|
+
export async function ensureBillingMeterReceiptIntegritySchema(pool) {
|
|
57
|
+
await pool.query(`
|
|
58
|
+
DO $$
|
|
59
|
+
BEGIN
|
|
60
|
+
IF NOT EXISTS (
|
|
61
|
+
SELECT 1 FROM pg_constraint
|
|
62
|
+
WHERE conrelid = 'billing_meter_usage_events'::regclass
|
|
63
|
+
AND conname = 'billing_meter_usage_events_window_fkey'
|
|
64
|
+
) THEN
|
|
65
|
+
ALTER TABLE billing_meter_usage_events
|
|
66
|
+
ADD CONSTRAINT billing_meter_usage_events_window_fkey
|
|
67
|
+
FOREIGN KEY (epoch_id, window_start, window_end)
|
|
68
|
+
REFERENCES billing_meter_windows(epoch_id, window_start, window_end)
|
|
69
|
+
ON DELETE RESTRICT;
|
|
70
|
+
END IF;
|
|
71
|
+
END
|
|
72
|
+
$$
|
|
73
|
+
`);
|
|
74
|
+
await pool.query(`
|
|
75
|
+
CREATE OR REPLACE FUNCTION billing_meter_integrity_lane(
|
|
76
|
+
integrity_scope text,
|
|
77
|
+
account_id text,
|
|
78
|
+
organization_slug text,
|
|
79
|
+
usage_classification text,
|
|
80
|
+
lane integer
|
|
81
|
+
) RETURNS numeric AS $$
|
|
82
|
+
WITH lane_bytes AS (
|
|
83
|
+
SELECT decode(
|
|
84
|
+
substr(
|
|
85
|
+
md5(
|
|
86
|
+
integrity_scope || ':' || octet_length(account_id)::text || ':' || account_id ||
|
|
87
|
+
':' || octet_length(organization_slug)::text || ':' || organization_slug ||
|
|
88
|
+
':' || usage_classification
|
|
89
|
+
),
|
|
90
|
+
CASE lane WHEN 1 THEN 1 WHEN 2 THEN 17 END,
|
|
91
|
+
16
|
|
92
|
+
),
|
|
93
|
+
'hex'
|
|
94
|
+
) AS value
|
|
95
|
+
WHERE lane IN (1, 2)
|
|
96
|
+
)
|
|
97
|
+
SELECT mod(
|
|
98
|
+
coalesce(
|
|
99
|
+
sum(get_byte(value, ordinal)::numeric * power(256::numeric, 7 - ordinal)),
|
|
100
|
+
0
|
|
101
|
+
),
|
|
102
|
+
${BILLING_METER_INTEGRITY_MODULUS}
|
|
103
|
+
)
|
|
104
|
+
FROM lane_bytes
|
|
105
|
+
CROSS JOIN generate_series(0, 7) AS ordinal
|
|
106
|
+
$$ LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE
|
|
107
|
+
`);
|
|
108
|
+
await pool.query(`
|
|
109
|
+
CREATE OR REPLACE FUNCTION billing_meter_receipt_before_insert()
|
|
110
|
+
RETURNS trigger AS $$
|
|
111
|
+
DECLARE
|
|
112
|
+
window_sealed_at timestamptz;
|
|
113
|
+
BEGIN
|
|
114
|
+
PERFORM pg_advisory_xact_lock_shared(
|
|
115
|
+
hashtextextended(
|
|
116
|
+
'billing-meter-window:' || NEW.epoch_id || ':' ||
|
|
117
|
+
((extract(epoch FROM NEW.window_start) * 1000)::bigint)::text || ':' ||
|
|
118
|
+
((extract(epoch FROM NEW.window_end) * 1000)::bigint)::text,
|
|
119
|
+
0
|
|
120
|
+
)
|
|
121
|
+
);
|
|
122
|
+
INSERT INTO billing_meter_windows
|
|
123
|
+
(epoch_id, window_start, window_end, retention_until)
|
|
124
|
+
VALUES
|
|
125
|
+
(NEW.epoch_id, NEW.window_start, NEW.window_end,
|
|
126
|
+
NEW.window_end + interval '${BILLING_METER_AGGREGATE_RETENTION_MONTHS} months')
|
|
127
|
+
ON CONFLICT (epoch_id, window_start, window_end) DO NOTHING;
|
|
128
|
+
SELECT sealed_at INTO window_sealed_at
|
|
129
|
+
FROM billing_meter_windows
|
|
130
|
+
WHERE epoch_id = NEW.epoch_id
|
|
131
|
+
AND window_start = NEW.window_start
|
|
132
|
+
AND window_end = NEW.window_end;
|
|
133
|
+
IF window_sealed_at IS NOT NULL THEN
|
|
134
|
+
RAISE EXCEPTION 'billing meter validation window is sealed';
|
|
135
|
+
END IF;
|
|
136
|
+
RETURN NEW;
|
|
137
|
+
END
|
|
138
|
+
$$ LANGUAGE plpgsql
|
|
139
|
+
`);
|
|
140
|
+
await pool.query(`
|
|
141
|
+
CREATE OR REPLACE FUNCTION billing_meter_receipt_after_insert()
|
|
142
|
+
RETURNS trigger AS $$
|
|
143
|
+
BEGIN
|
|
144
|
+
UPDATE billing_meter_windows
|
|
145
|
+
SET receipt_included_calls = receipt_included_calls +
|
|
146
|
+
CASE WHEN NEW.classification = 'included' THEN 1 ELSE 0 END,
|
|
147
|
+
receipt_overage_calls = receipt_overage_calls +
|
|
148
|
+
CASE WHEN NEW.classification = 'overage' THEN 1 ELSE 0 END,
|
|
149
|
+
receipt_denied_calls = receipt_denied_calls +
|
|
150
|
+
CASE WHEN NEW.classification = 'denied' THEN 1 ELSE 0 END,
|
|
151
|
+
writer_observed_calls = writer_observed_calls +
|
|
152
|
+
CASE WHEN to_jsonb(NEW)->>'writer_session_id' IS NULL THEN 0 ELSE 1 END,
|
|
153
|
+
account_integrity_a = mod(
|
|
154
|
+
account_integrity_a + billing_meter_integrity_lane(
|
|
155
|
+
'account', NEW.billing_account_id, '', NEW.classification, 1
|
|
156
|
+
),
|
|
157
|
+
${BILLING_METER_INTEGRITY_MODULUS}
|
|
158
|
+
),
|
|
159
|
+
account_integrity_b = mod(
|
|
160
|
+
account_integrity_b + billing_meter_integrity_lane(
|
|
161
|
+
'account', NEW.billing_account_id, '', NEW.classification, 2
|
|
162
|
+
),
|
|
163
|
+
${BILLING_METER_INTEGRITY_MODULUS}
|
|
164
|
+
),
|
|
165
|
+
org_integrity_a = mod(
|
|
166
|
+
org_integrity_a + billing_meter_integrity_lane(
|
|
167
|
+
'organization', NEW.billing_account_id, NEW.org_slug, NEW.classification, 1
|
|
168
|
+
),
|
|
169
|
+
${BILLING_METER_INTEGRITY_MODULUS}
|
|
170
|
+
),
|
|
171
|
+
org_integrity_b = mod(
|
|
172
|
+
org_integrity_b + billing_meter_integrity_lane(
|
|
173
|
+
'organization', NEW.billing_account_id, NEW.org_slug, NEW.classification, 2
|
|
174
|
+
),
|
|
175
|
+
${BILLING_METER_INTEGRITY_MODULUS}
|
|
176
|
+
),
|
|
177
|
+
first_observed_at = least(coalesce(first_observed_at, NEW.recorded_at), NEW.recorded_at),
|
|
178
|
+
last_observed_at = greatest(coalesce(last_observed_at, NEW.recorded_at), NEW.recorded_at),
|
|
179
|
+
last_writer_observed_at = CASE
|
|
180
|
+
WHEN to_jsonb(NEW)->>'writer_session_id' IS NULL THEN last_writer_observed_at
|
|
181
|
+
ELSE greatest(coalesce(last_writer_observed_at, NEW.recorded_at), NEW.recorded_at)
|
|
182
|
+
END
|
|
183
|
+
WHERE epoch_id = NEW.epoch_id
|
|
184
|
+
AND window_start = NEW.window_start
|
|
185
|
+
AND window_end = NEW.window_end
|
|
186
|
+
AND sealed_at IS NULL;
|
|
187
|
+
IF NOT FOUND THEN
|
|
188
|
+
RAISE EXCEPTION 'billing meter validation window is sealed';
|
|
189
|
+
END IF;
|
|
190
|
+
RETURN NULL;
|
|
191
|
+
END
|
|
192
|
+
$$ LANGUAGE plpgsql
|
|
193
|
+
`);
|
|
194
|
+
await pool.query(`
|
|
195
|
+
CREATE OR REPLACE FUNCTION billing_meter_receipt_guard_mutation()
|
|
196
|
+
RETURNS trigger AS $$
|
|
197
|
+
BEGIN
|
|
198
|
+
IF TG_OP = 'UPDATE' THEN
|
|
199
|
+
RAISE EXCEPTION 'billing meter receipts are immutable';
|
|
200
|
+
END IF;
|
|
201
|
+
IF current_setting('noodle.billing_meter_receipt_maintenance', true) = 'on' AND EXISTS (
|
|
202
|
+
SELECT 1 FROM billing_meter_windows
|
|
203
|
+
WHERE epoch_id = OLD.epoch_id
|
|
204
|
+
AND window_start = OLD.window_start
|
|
205
|
+
AND window_end = OLD.window_end
|
|
206
|
+
AND sealed_at IS NOT NULL
|
|
207
|
+
) THEN
|
|
208
|
+
RETURN OLD;
|
|
209
|
+
END IF;
|
|
210
|
+
RAISE EXCEPTION 'billing meter receipt deletion requires sealed maintenance';
|
|
211
|
+
END
|
|
212
|
+
$$ LANGUAGE plpgsql
|
|
213
|
+
`);
|
|
214
|
+
await pool.query(`
|
|
215
|
+
DO $$
|
|
216
|
+
BEGIN
|
|
217
|
+
IF NOT EXISTS (
|
|
218
|
+
SELECT 1 FROM pg_trigger
|
|
219
|
+
WHERE tgrelid = 'billing_meter_usage_events'::regclass
|
|
220
|
+
AND tgname = 'billing_meter_receipt_before_insert_trigger'
|
|
221
|
+
) THEN
|
|
222
|
+
CREATE TRIGGER billing_meter_receipt_before_insert_trigger
|
|
223
|
+
BEFORE INSERT ON billing_meter_usage_events
|
|
224
|
+
FOR EACH ROW EXECUTE FUNCTION billing_meter_receipt_before_insert();
|
|
225
|
+
END IF;
|
|
226
|
+
IF NOT EXISTS (
|
|
227
|
+
SELECT 1 FROM pg_trigger
|
|
228
|
+
WHERE tgrelid = 'billing_meter_usage_events'::regclass
|
|
229
|
+
AND tgname = 'billing_meter_receipt_after_insert_trigger'
|
|
230
|
+
) THEN
|
|
231
|
+
CREATE TRIGGER billing_meter_receipt_after_insert_trigger
|
|
232
|
+
AFTER INSERT ON billing_meter_usage_events
|
|
233
|
+
FOR EACH ROW EXECUTE FUNCTION billing_meter_receipt_after_insert();
|
|
234
|
+
END IF;
|
|
235
|
+
IF NOT EXISTS (
|
|
236
|
+
SELECT 1 FROM pg_trigger
|
|
237
|
+
WHERE tgrelid = 'billing_meter_usage_events'::regclass
|
|
238
|
+
AND tgname = 'billing_meter_receipt_guard_mutation_trigger'
|
|
239
|
+
) THEN
|
|
240
|
+
CREATE TRIGGER billing_meter_receipt_guard_mutation_trigger
|
|
241
|
+
BEFORE UPDATE OR DELETE ON billing_meter_usage_events
|
|
242
|
+
FOR EACH ROW EXECUTE FUNCTION billing_meter_receipt_guard_mutation();
|
|
243
|
+
END IF;
|
|
244
|
+
END
|
|
245
|
+
$$
|
|
246
|
+
`);
|
|
247
|
+
}
|
|
248
|
+
//# sourceMappingURL=postgres-meter-window-schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres-meter-window-schema.js","sourceRoot":"","sources":["../../src/billing/postgres-meter-window-schema.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,wCAAwC,EAAE,MAAM,sBAAsB,CAAC;AAChF,OAAO,EAAE,+BAA+B,EAAE,MAAM,iCAAiC,CAAC;AAElF,kGAAkG;AAClG,MAAM,CAAC,KAAK,UAAU,sCAAsC,CAAC,IAAU;IACrE,MAAM,IAAI,CAAC,KAAK,CAAC;;;;;;;;;;;oEAWiD,+BAA+B;;oEAE/B,+BAA+B;;4DAEvC,+BAA+B;;4DAE/B,+BAA+B;;;;;;;;;;;;;;mCAcxD,wCAAwC;;;GAGxE,CAAC,CAAC;IACH,MAAM,IAAI,CAAC,KAAK,CAAC;;;;GAIhB,CAAC,CAAC;IACH,MAAM,IAAI,CAAC,KAAK,CAAC;;;;GAIhB,CAAC,CAAC;IACH,MAAM,IAAI,CAAC,KAAK,CAAC;;;GAGhB,CAAC,CAAC;AACL,CAAC;AAED,mGAAmG;AACnG,MAAM,CAAC,KAAK,UAAU,wCAAwC,CAAC,IAAU;IACvE,MAAM,IAAI,CAAC,KAAK,CAAC;;;;;;;;;;;;;;;;GAgBhB,CAAC,CAAC;IACH,MAAM,IAAI,CAAC,KAAK,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;UA4BT,+BAA+B;;;;;GAKtC,CAAC,CAAC;IACH,MAAM,IAAI,CAAC,KAAK,CAAC;;;;;;;;;;;;;;;;;;sCAkBmB,wCAAwC;;;;;;;;;;;;;GAa3E,CAAC,CAAC;IACH,MAAM,IAAI,CAAC,KAAK,CAAC;;;;;;;;;;;;;;;;;cAiBL,+BAA+B;;;;;;cAM/B,+BAA+B;;;;;;cAM/B,+BAA+B;;;;;;cAM/B,+BAA+B;;;;;;;;;;;;;;;;;;GAkB1C,CAAC,CAAC;IACH,MAAM,IAAI,CAAC,KAAK,CAAC;;;;;;;;;;;;;;;;;;;GAmBhB,CAAC,CAAC;IACH,MAAM,IAAI,CAAC,KAAK,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgChB,CAAC,CAAC;AACL,CAAC"}
|