@noodleseed/one 0.45.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/saas-scaffold-template.js +1 -1
- package/dist/saas-scaffold-template.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/dist/widget-scaffold-template.d.ts.map +1 -1
- package/dist/widget-scaffold-template.js +4 -2
- package/dist/widget-scaffold-template.js.map +1 -1
- package/node_modules/@noodle-borg/agent-kit/dist/generated/example-files.js +3 -3
- 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.d.ts.map +1 -1
- package/node_modules/@noodle-borg/agent-kit/dist/skill-embedded-assistant-ref.js +6 -4
- 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/assistant.d.ts +9 -0
- package/node_modules/@noodle-borg/authoring/dist/assistant.d.ts.map +1 -1
- package/node_modules/@noodle-borg/authoring/dist/assistant.js.map +1 -1
- package/node_modules/@noodle-borg/authoring/dist/server.d.ts +7 -0
- package/node_modules/@noodle-borg/authoring/dist/server.d.ts.map +1 -1
- package/node_modules/@noodle-borg/authoring/dist/server.js +2 -0
- package/node_modules/@noodle-borg/authoring/dist/server.js.map +1 -1
- package/node_modules/@noodle-borg/compiler/dist/artifact/types.d.ts +10 -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 +6 -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 +4 -0
- package/node_modules/@noodle-borg/compiler/dist/compile.js.map +1 -1
- package/node_modules/@noodle-borg/compiler/dist/manifest/schema.d.ts +52 -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 +17 -0
- package/node_modules/@noodle-borg/compiler/dist/manifest/schema.js.map +1 -1
- package/node_modules/@noodle-borg/protocol/dist/mapping.d.ts.map +1 -1
- package/node_modules/@noodle-borg/protocol/dist/mapping.js +1 -0
- package/node_modules/@noodle-borg/protocol/dist/mapping.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/assistant-interactive.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/assistant-interactive.js +7 -3
- package/node_modules/@noodle-borg/service/dist/assistant-interactive.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/assistant-presentation.d.ts +11 -0
- package/node_modules/@noodle-borg/service/dist/assistant-presentation.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/assistant-presentation.js +67 -3
- package/node_modules/@noodle-borg/service/dist/assistant-presentation.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/assistant-interaction-stream.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/assistant-interaction-stream.js +2 -1
- package/node_modules/@noodle-borg/service/dist/routes/assistant-interaction-stream.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/assistant-interactions.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/assistant-interactions.js +6 -2
- package/node_modules/@noodle-borg/service/dist/routes/assistant-interactions.js.map +1 -1
- 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/node_modules/@noodle-borg/wire-contracts/dist/assistant.d.ts +3 -0
- package/node_modules/@noodle-borg/wire-contracts/dist/assistant.d.ts.map +1 -1
- package/node_modules/@noodle-borg/wire-contracts/dist/assistant.js +3 -0
- package/node_modules/@noodle-borg/wire-contracts/dist/assistant.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
import { createHash, randomUUID } from 'node:crypto';
|
|
2
|
+
import { insertAuditEvent } from '@noodle-borg/module-audit';
|
|
3
|
+
import { BILLING_ENFORCEMENT_COHORT_KIND, BillingEnforcementCohortConflictError, BillingEnforcementCohortSealResponseSchema, BillingEnforcementCohortStatusResponseSchema, billingEnforcementCohortRequestFingerprint, billingEnforcementCohortSuccessAudit, normalizeBillingEnforcementServiceUrl, parseBillingEnforcementCohortSealRequest, } from './enforcement-profile.js';
|
|
4
|
+
import { normalizeBillingEmail, validateBillingAccountId } from './model.js';
|
|
5
|
+
import { readBillingMeterTransactionTime } from './postgres-meter-clock.js';
|
|
6
|
+
import { validateScalarId } from './postgres-records.js';
|
|
7
|
+
export const BILLING_ENFORCEMENT_COHORT_LIFECYCLE_LOCK_KEY = 'billing-enforcement-cohort-seal:legacy-internal-v1';
|
|
8
|
+
export async function getEnforcementCohortStatusRow(pool) {
|
|
9
|
+
const client = await pool.connect();
|
|
10
|
+
try {
|
|
11
|
+
await client.query('BEGIN ISOLATION LEVEL REPEATABLE READ READ ONLY');
|
|
12
|
+
const response = await readEnforcementCohortStatus(client);
|
|
13
|
+
await client.query('COMMIT');
|
|
14
|
+
return response;
|
|
15
|
+
}
|
|
16
|
+
catch (error) {
|
|
17
|
+
await rollbackQuietly(client);
|
|
18
|
+
throw error;
|
|
19
|
+
}
|
|
20
|
+
finally {
|
|
21
|
+
client.release();
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export function getActiveBillingAccountEnforcementProfileRow(pool, billingAccountId) {
|
|
25
|
+
return getActiveBillingAccountEnforcementProfileQuery(pool, validateBillingAccountId(billingAccountId));
|
|
26
|
+
}
|
|
27
|
+
export async function sealEnforcementCohortRow(pool, input) {
|
|
28
|
+
const request = parseBillingEnforcementCohortSealRequest(input.request);
|
|
29
|
+
const actor = normalizeActor(input.actor);
|
|
30
|
+
const service = normalizeBillingEnforcementServiceUrl(input.service);
|
|
31
|
+
const fingerprint = billingEnforcementCohortRequestFingerprint({
|
|
32
|
+
action: 'seal',
|
|
33
|
+
request,
|
|
34
|
+
actor,
|
|
35
|
+
service,
|
|
36
|
+
});
|
|
37
|
+
const idempotencyHash = hashIdempotencyKey(request.idempotencyKey);
|
|
38
|
+
const client = await pool.connect();
|
|
39
|
+
try {
|
|
40
|
+
await client.query('BEGIN ISOLATION LEVEL READ COMMITTED');
|
|
41
|
+
await lockLifecycle(client);
|
|
42
|
+
const replay = await findOperation(client, idempotencyHash);
|
|
43
|
+
if (replay !== undefined) {
|
|
44
|
+
const response = replayOperation(replay, fingerprint);
|
|
45
|
+
const replayedAt = await readBillingMeterTransactionTime(client);
|
|
46
|
+
await insertAuditEvent(client, billingEnforcementCohortSuccessAudit(response, actor), {
|
|
47
|
+
now: () => new Date(replayedAt),
|
|
48
|
+
});
|
|
49
|
+
await client.query('COMMIT');
|
|
50
|
+
return response;
|
|
51
|
+
}
|
|
52
|
+
const existing = await findSeal(client);
|
|
53
|
+
if (existing !== undefined) {
|
|
54
|
+
throw new BillingEnforcementCohortConflictError('enforcement_cohort_already_sealed', 'the legacy internal enforcement cohort was already sealed under a different key');
|
|
55
|
+
}
|
|
56
|
+
// The order matches normal workspace provisioning (organization, account, billing tuple). A writer
|
|
57
|
+
// already holding an insert lock finishes first and is included; later writers wait and observe the seal.
|
|
58
|
+
await client.query(`
|
|
59
|
+
LOCK TABLE orgs, billing_accounts, billing_entitlement_snapshots,
|
|
60
|
+
billing_account_active_snapshots, org_billing_links
|
|
61
|
+
IN SHARE ROW EXCLUSIVE MODE
|
|
62
|
+
`);
|
|
63
|
+
const attributionBlockerCount = await countAttributionBlockers(client);
|
|
64
|
+
if (attributionBlockerCount !== 0) {
|
|
65
|
+
throw new BillingEnforcementCohortConflictError('billing_attribution_incomplete', 'every managed organization must have verified billing attribution before sealing');
|
|
66
|
+
}
|
|
67
|
+
const sealedAt = await readBillingMeterTransactionTime(client);
|
|
68
|
+
const sealId = `becs_${randomUUID()}`;
|
|
69
|
+
await client.query(`INSERT INTO billing_enforcement_cohort_seals
|
|
70
|
+
(id, singleton, schema_version, cohort_kind, state, legacy_account_profile,
|
|
71
|
+
post_seal_account_profile, sealed_at, sealed_by_subject, sealed_by_email,
|
|
72
|
+
service_origin, reason)
|
|
73
|
+
VALUES ($1, true, 1, $2, 'sealed', 'legacy_internal_exempt', 'enforced',
|
|
74
|
+
$3, $4, $5, $6, $7)`, [
|
|
75
|
+
sealId,
|
|
76
|
+
BILLING_ENFORCEMENT_COHORT_KIND,
|
|
77
|
+
sealedAt,
|
|
78
|
+
actor.subject,
|
|
79
|
+
actor.email,
|
|
80
|
+
service,
|
|
81
|
+
request.reason,
|
|
82
|
+
]);
|
|
83
|
+
const profiles = await client.query(`INSERT INTO billing_account_enforcement_profiles
|
|
84
|
+
(billing_account_id, version, schema_version, mode, cohort_kind, cohort_seal_id,
|
|
85
|
+
source, effective_from, created_at)
|
|
86
|
+
SELECT id, 1, 1, 'legacy_internal_exempt', $2, $1,
|
|
87
|
+
'legacy_cohort_seal', $3, $3
|
|
88
|
+
FROM billing_accounts
|
|
89
|
+
ORDER BY id`, [sealId, BILLING_ENFORCEMENT_COHORT_KIND, sealedAt]);
|
|
90
|
+
await client.query(`INSERT INTO billing_account_active_enforcement_profiles
|
|
91
|
+
(billing_account_id, profile_version)
|
|
92
|
+
SELECT billing_account_id, version
|
|
93
|
+
FROM billing_account_enforcement_profiles
|
|
94
|
+
WHERE cohort_seal_id = $1`, [sealId]);
|
|
95
|
+
const status = await readEnforcementCohortStatus(client);
|
|
96
|
+
if (status.state !== 'sealed' ||
|
|
97
|
+
status.sealId !== sealId ||
|
|
98
|
+
status.billingAccountCount !== profiles.rowCount ||
|
|
99
|
+
status.unprofiledAccountCount !== 0 ||
|
|
100
|
+
status.enforcedAccountCount !== 0) {
|
|
101
|
+
throw new BillingEnforcementCohortConflictError('enforcement_profile_state_conflict', 'the legacy internal cohort could not be classified completely');
|
|
102
|
+
}
|
|
103
|
+
const response = BillingEnforcementCohortSealResponseSchema.parse({
|
|
104
|
+
...status,
|
|
105
|
+
replayed: false,
|
|
106
|
+
activationState: 'not_active',
|
|
107
|
+
});
|
|
108
|
+
await insertOperation(client, {
|
|
109
|
+
response,
|
|
110
|
+
idempotencyHash,
|
|
111
|
+
fingerprint,
|
|
112
|
+
actor,
|
|
113
|
+
service,
|
|
114
|
+
reason: request.reason,
|
|
115
|
+
createdAt: sealedAt,
|
|
116
|
+
});
|
|
117
|
+
await insertAuditEvent(client, billingEnforcementCohortSuccessAudit(response, actor), {
|
|
118
|
+
now: () => new Date(sealedAt),
|
|
119
|
+
});
|
|
120
|
+
await client.query('COMMIT');
|
|
121
|
+
return response;
|
|
122
|
+
}
|
|
123
|
+
catch (error) {
|
|
124
|
+
await rollbackQuietly(client);
|
|
125
|
+
throw translateTransactionError(error);
|
|
126
|
+
}
|
|
127
|
+
finally {
|
|
128
|
+
client.release();
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Application-side defense in depth after account insertion. The database trigger normally creates the
|
|
133
|
+
* profile first; the active-profile lookup keeps this helper idempotent with that trigger-created state.
|
|
134
|
+
*/
|
|
135
|
+
export async function ensurePostSealBillingAccountEnforcementProfileTx(client, billingAccountId) {
|
|
136
|
+
const accountId = validateBillingAccountId(billingAccountId);
|
|
137
|
+
const seal = await findSeal(client);
|
|
138
|
+
if (seal === undefined)
|
|
139
|
+
return undefined;
|
|
140
|
+
const existing = await getActiveBillingAccountEnforcementProfileQuery(client, accountId);
|
|
141
|
+
if (existing !== undefined)
|
|
142
|
+
return existing;
|
|
143
|
+
const effectiveFrom = await readBillingMeterTransactionTime(client);
|
|
144
|
+
const { rows } = await client.query(`INSERT INTO billing_account_enforcement_profiles
|
|
145
|
+
(billing_account_id, version, schema_version, mode, cohort_kind, cohort_seal_id,
|
|
146
|
+
source, effective_from, created_at)
|
|
147
|
+
VALUES ($1, 1, 1, 'enforced', $2, $3, 'post_seal_account', $4, $4)
|
|
148
|
+
RETURNING *`, [accountId, BILLING_ENFORCEMENT_COHORT_KIND, seal.id, effectiveFrom]);
|
|
149
|
+
await client.query(`INSERT INTO billing_account_active_enforcement_profiles
|
|
150
|
+
(billing_account_id, profile_version)
|
|
151
|
+
VALUES ($1, 1)`, [accountId]);
|
|
152
|
+
return profileRowToRecord(rows[0]);
|
|
153
|
+
}
|
|
154
|
+
export async function requireBillingAccountEnforcementProfileIfSealedTx(client, billingAccountId) {
|
|
155
|
+
if ((await findSeal(client)) === undefined)
|
|
156
|
+
return;
|
|
157
|
+
if ((await getActiveBillingAccountEnforcementProfileQuery(client, billingAccountId)) === undefined) {
|
|
158
|
+
throw new Error('default billing account is incomplete');
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
async function readEnforcementCohortStatus(queryable) {
|
|
162
|
+
const seal = await findSeal(queryable);
|
|
163
|
+
const counts = await queryable.query(`
|
|
164
|
+
SELECT
|
|
165
|
+
count(account.id)::text AS billing_account_count,
|
|
166
|
+
count(profile.billing_account_id)::text AS profiled_account_count,
|
|
167
|
+
count(*) FILTER (WHERE profile.mode = 'legacy_internal_exempt')::text
|
|
168
|
+
AS legacy_internal_exempt_account_count,
|
|
169
|
+
count(*) FILTER (WHERE profile.mode = 'enforced')::text AS enforced_account_count,
|
|
170
|
+
count(*) FILTER (WHERE profile.billing_account_id IS NULL)::text AS unprofiled_account_count
|
|
171
|
+
FROM billing_accounts AS account
|
|
172
|
+
LEFT JOIN billing_account_active_enforcement_profiles AS active
|
|
173
|
+
ON active.billing_account_id = account.id
|
|
174
|
+
LEFT JOIN billing_account_enforcement_profiles AS profile
|
|
175
|
+
ON profile.billing_account_id = active.billing_account_id
|
|
176
|
+
AND profile.version = active.profile_version
|
|
177
|
+
`);
|
|
178
|
+
const attributionBlockerCount = await countAttributionBlockers(queryable);
|
|
179
|
+
const row = counts.rows[0];
|
|
180
|
+
return BillingEnforcementCohortStatusResponseSchema.parse({
|
|
181
|
+
schemaVersion: 1,
|
|
182
|
+
cohortKind: BILLING_ENFORCEMENT_COHORT_KIND,
|
|
183
|
+
state: seal === undefined ? 'unsealed' : 'sealed',
|
|
184
|
+
sealId: seal?.id ?? null,
|
|
185
|
+
sealedAt: seal === undefined ? null : toIso(seal.sealed_at),
|
|
186
|
+
legacyAccountProfile: 'legacy_internal_exempt',
|
|
187
|
+
postSealAccountProfile: 'enforced',
|
|
188
|
+
billingAccountCount: parseCount(row?.billing_account_count),
|
|
189
|
+
profiledAccountCount: parseCount(row?.profiled_account_count),
|
|
190
|
+
legacyInternalExemptAccountCount: parseCount(row?.legacy_internal_exempt_account_count),
|
|
191
|
+
enforcedAccountCount: parseCount(row?.enforced_account_count),
|
|
192
|
+
unprofiledAccountCount: parseCount(row?.unprofiled_account_count),
|
|
193
|
+
billingAttributionComplete: attributionBlockerCount === 0,
|
|
194
|
+
attributionBlockerCount,
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
async function countAttributionBlockers(queryable) {
|
|
198
|
+
const { rows } = await queryable.query(`
|
|
199
|
+
SELECT count(*)::text AS incomplete
|
|
200
|
+
FROM (
|
|
201
|
+
-- Blocker units are distinct entities: each unlinked managed organization and each incomplete
|
|
202
|
+
-- account used by at least one active non-local organization link contributes exactly once.
|
|
203
|
+
-- Unlinked draft/snapshotless accounts are valid and do not block the cohort seal.
|
|
204
|
+
SELECT 'organization' AS blocker_kind, org.slug AS blocker_id
|
|
205
|
+
FROM orgs AS org
|
|
206
|
+
WHERE org.slug <> 'local'
|
|
207
|
+
AND NOT EXISTS (
|
|
208
|
+
SELECT 1
|
|
209
|
+
FROM org_billing_links AS link
|
|
210
|
+
WHERE link.org_slug = org.slug AND link.active
|
|
211
|
+
)
|
|
212
|
+
UNION ALL
|
|
213
|
+
SELECT DISTINCT 'billing_account' AS blocker_kind, link.billing_account_id AS blocker_id
|
|
214
|
+
FROM org_billing_links AS link
|
|
215
|
+
JOIN orgs AS org ON org.slug = link.org_slug
|
|
216
|
+
WHERE org.slug <> 'local'
|
|
217
|
+
AND link.active
|
|
218
|
+
AND NOT EXISTS (
|
|
219
|
+
SELECT 1
|
|
220
|
+
FROM billing_account_active_snapshots AS active
|
|
221
|
+
JOIN billing_entitlement_snapshots AS snapshot
|
|
222
|
+
ON snapshot.billing_account_id = active.billing_account_id
|
|
223
|
+
AND snapshot.id = active.snapshot_id
|
|
224
|
+
WHERE active.billing_account_id = link.billing_account_id
|
|
225
|
+
AND snapshot.verification_status = 'verified'
|
|
226
|
+
)
|
|
227
|
+
) AS blockers
|
|
228
|
+
`);
|
|
229
|
+
return parseCount(rows[0]?.incomplete);
|
|
230
|
+
}
|
|
231
|
+
async function findSeal(queryable) {
|
|
232
|
+
const { rows } = await queryable.query(`SELECT id, cohort_kind, state, legacy_account_profile,
|
|
233
|
+
post_seal_account_profile, sealed_at
|
|
234
|
+
FROM billing_enforcement_cohort_seals
|
|
235
|
+
WHERE singleton = true`);
|
|
236
|
+
return rows[0];
|
|
237
|
+
}
|
|
238
|
+
async function getActiveBillingAccountEnforcementProfileQuery(queryable, billingAccountId) {
|
|
239
|
+
const { rows } = await queryable.query(`SELECT profile.*
|
|
240
|
+
FROM billing_account_active_enforcement_profiles AS active
|
|
241
|
+
JOIN billing_account_enforcement_profiles AS profile
|
|
242
|
+
ON profile.billing_account_id = active.billing_account_id
|
|
243
|
+
AND profile.version = active.profile_version
|
|
244
|
+
WHERE active.billing_account_id = $1`, [validateBillingAccountId(billingAccountId)]);
|
|
245
|
+
return rows[0] === undefined ? undefined : profileRowToRecord(rows[0]);
|
|
246
|
+
}
|
|
247
|
+
function profileRowToRecord(row) {
|
|
248
|
+
if (row.schema_version !== 1 ||
|
|
249
|
+
row.cohort_kind !== BILLING_ENFORCEMENT_COHORT_KIND ||
|
|
250
|
+
!((row.mode === 'legacy_internal_exempt' && row.source === 'legacy_cohort_seal') ||
|
|
251
|
+
(row.mode === 'enforced' && row.source === 'post_seal_account'))) {
|
|
252
|
+
throw new Error('billing enforcement profile is invalid');
|
|
253
|
+
}
|
|
254
|
+
return {
|
|
255
|
+
schemaVersion: 1,
|
|
256
|
+
billingAccountId: validateBillingAccountId(row.billing_account_id),
|
|
257
|
+
version: row.version,
|
|
258
|
+
mode: row.mode,
|
|
259
|
+
cohortKind: row.cohort_kind,
|
|
260
|
+
cohortSealId: validateScalarId('billing enforcement cohort seal id', row.cohort_seal_id),
|
|
261
|
+
source: row.source,
|
|
262
|
+
effectiveFrom: toIso(row.effective_from),
|
|
263
|
+
createdAt: toIso(row.created_at),
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
function normalizeActor(actor) {
|
|
267
|
+
return {
|
|
268
|
+
...actor,
|
|
269
|
+
subject: validateScalarId('billing enforcement actor subject', actor.subject),
|
|
270
|
+
email: normalizeBillingEmail(actor.email),
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
function hashIdempotencyKey(value) {
|
|
274
|
+
return createHash('sha256').update(value).digest('hex');
|
|
275
|
+
}
|
|
276
|
+
function lockLifecycle(client) {
|
|
277
|
+
return client.query('SELECT pg_advisory_xact_lock(hashtextextended($1, 0))', [
|
|
278
|
+
BILLING_ENFORCEMENT_COHORT_LIFECYCLE_LOCK_KEY,
|
|
279
|
+
]);
|
|
280
|
+
}
|
|
281
|
+
async function findOperation(client, idempotencyHash) {
|
|
282
|
+
const { rows } = await client.query(`SELECT action, request_fingerprint, result
|
|
283
|
+
FROM billing_enforcement_cohort_operations
|
|
284
|
+
WHERE idempotency_key_hash = $1`, [idempotencyHash]);
|
|
285
|
+
return rows[0];
|
|
286
|
+
}
|
|
287
|
+
function replayOperation(row, fingerprint) {
|
|
288
|
+
if (row.action !== 'seal' || row.request_fingerprint !== fingerprint) {
|
|
289
|
+
throw new BillingEnforcementCohortConflictError('idempotency_key_conflict', 'idempotency key was already used by a different request or actor');
|
|
290
|
+
}
|
|
291
|
+
const response = BillingEnforcementCohortSealResponseSchema.parse(row.result);
|
|
292
|
+
return { ...response, replayed: true };
|
|
293
|
+
}
|
|
294
|
+
async function insertOperation(client, input) {
|
|
295
|
+
await client.query(`INSERT INTO billing_enforcement_cohort_operations
|
|
296
|
+
(operation_id, action, idempotency_key_hash, request_fingerprint, cohort_seal_id,
|
|
297
|
+
result, actor_subject, actor_email, service_origin, reason, created_at)
|
|
298
|
+
VALUES ($1, 'seal', $2, $3, $4, $5::jsonb, $6, $7, $8, $9, $10)`, [
|
|
299
|
+
`beco_${randomUUID()}`,
|
|
300
|
+
input.idempotencyHash,
|
|
301
|
+
input.fingerprint,
|
|
302
|
+
input.response.sealId,
|
|
303
|
+
JSON.stringify(input.response),
|
|
304
|
+
input.actor.subject,
|
|
305
|
+
input.actor.email,
|
|
306
|
+
input.service,
|
|
307
|
+
input.reason,
|
|
308
|
+
input.createdAt,
|
|
309
|
+
]);
|
|
310
|
+
}
|
|
311
|
+
function parseCount(value) {
|
|
312
|
+
const parsed = Number(value ?? '0');
|
|
313
|
+
if (!Number.isSafeInteger(parsed) || parsed < 0) {
|
|
314
|
+
throw new Error('billing enforcement aggregate count is invalid');
|
|
315
|
+
}
|
|
316
|
+
return parsed;
|
|
317
|
+
}
|
|
318
|
+
function translateTransactionError(error) {
|
|
319
|
+
const code = typeof error === 'object' && error !== null && 'code' in error
|
|
320
|
+
? String(error.code)
|
|
321
|
+
: undefined;
|
|
322
|
+
if (code === '40001' || code === '40P01') {
|
|
323
|
+
return new BillingEnforcementCohortConflictError('serialization_conflict', 'billing enforcement cohort state changed concurrently; retry the exact request');
|
|
324
|
+
}
|
|
325
|
+
return error;
|
|
326
|
+
}
|
|
327
|
+
function toIso(value) {
|
|
328
|
+
const date = value instanceof Date ? value : new Date(value);
|
|
329
|
+
if (!Number.isFinite(date.getTime()))
|
|
330
|
+
throw new Error('billing enforcement timestamp is invalid');
|
|
331
|
+
return date.toISOString();
|
|
332
|
+
}
|
|
333
|
+
async function rollbackQuietly(client) {
|
|
334
|
+
try {
|
|
335
|
+
await client.query('ROLLBACK');
|
|
336
|
+
}
|
|
337
|
+
catch {
|
|
338
|
+
// Preserve the original transaction failure.
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
//# sourceMappingURL=postgres-enforcement-profile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres-enforcement-profile.js","sourceRoot":"","sources":["../../src/billing/postgres-enforcement-profile.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres-meter-clock.d.ts","sourceRoot":"","sources":["../../src/billing/postgres-meter-clock.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAG3C,wBAAsB,+BAA+B,CAAC,MAAM,EAAE,IAAI,GAAG,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAUhG"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { normalizeBillingUsageInstant } from './usage-window.js';
|
|
2
|
+
export async function readBillingMeterTransactionTime(client) {
|
|
3
|
+
const result = await client.query('SELECT billing_meter_transaction_time() AS transaction_time');
|
|
4
|
+
const value = result.rows[0]?.transaction_time;
|
|
5
|
+
if (value === undefined)
|
|
6
|
+
throw new Error('billing meter database clock returned no result');
|
|
7
|
+
return normalizeBillingUsageInstant('billing meter database transaction time', value instanceof Date ? value.toISOString() : value);
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=postgres-meter-clock.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres-meter-clock.js","sourceRoot":"","sources":["../../src/billing/postgres-meter-clock.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,4BAA4B,EAAE,MAAM,mBAAmB,CAAC;AAEjE,MAAM,CAAC,KAAK,UAAU,+BAA+B,CAAC,MAAyB;IAC7E,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,KAAK,CAC/B,6DAA6D,CAC9D,CAAC;IACF,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,gBAAgB,CAAC;IAC/C,IAAI,KAAK,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IAC5F,OAAO,4BAA4B,CACjC,yCAAyC,EACzC,KAAK,YAAY,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,KAAK,CACpD,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Pool } from 'pg';
|
|
2
|
+
/** Internal fixture setup only; production lifecycle mutations use the audited epoch store. */
|
|
3
|
+
export declare function prepareBillingMeterValidationEpoch(pool: Pool, input: {
|
|
4
|
+
readonly epochId: string;
|
|
5
|
+
readonly keyGeneration: string;
|
|
6
|
+
readonly releaseSha: string;
|
|
7
|
+
readonly retryIdentityVersion: number;
|
|
8
|
+
readonly writerContractVersion?: number;
|
|
9
|
+
}): Promise<void>;
|
|
10
|
+
export declare function retireBillingMeterValidationEpoch(pool: Pool, input: {
|
|
11
|
+
readonly epochId: string;
|
|
12
|
+
}): Promise<void>;
|
|
13
|
+
//# sourceMappingURL=postgres-meter-epoch-fixtures.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres-meter-epoch-fixtures.d.ts","sourceRoot":"","sources":["../../src/billing/postgres-meter-epoch-fixtures.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAc,MAAM,IAAI,CAAC;AAK3C,+FAA+F;AAC/F,wBAAsB,kCAAkC,CACtD,IAAI,EAAE,IAAI,EACV,KAAK,EAAE;IACL,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,qBAAqB,CAAC,EAAE,MAAM,CAAC;CACzC,GACA,OAAO,CAAC,IAAI,CAAC,CAsDf;AAED,wBAAsB,iCAAiC,CACrD,IAAI,EAAE,IAAI,EACV,KAAK,EAAE;IAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAClC,OAAO,CAAC,IAAI,CAAC,CA6Bf"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { BILLING_METER_VALIDATION_WRITER_CONTRACT_VERSION } from './meter-validation-epoch.js';
|
|
2
|
+
import { readBillingMeterTransactionTime } from './postgres-meter-clock.js';
|
|
3
|
+
import { validateScalarId } from './postgres-records.js';
|
|
4
|
+
/** Internal fixture setup only; production lifecycle mutations use the audited epoch store. */
|
|
5
|
+
export async function prepareBillingMeterValidationEpoch(pool, input) {
|
|
6
|
+
const epochId = validateScalarId('billing meter epoch id', input.epochId);
|
|
7
|
+
const generation = validateGeneration(input.keyGeneration);
|
|
8
|
+
const releaseSha = validateReleaseSha(input.releaseSha);
|
|
9
|
+
const writerContractVersion = validatePositiveVersion('billing meter writer contract version', input.writerContractVersion ?? BILLING_METER_VALIDATION_WRITER_CONTRACT_VERSION);
|
|
10
|
+
if (!Number.isSafeInteger(input.retryIdentityVersion) || input.retryIdentityVersion < 1) {
|
|
11
|
+
throw new Error('billing meter retry identity version must be positive');
|
|
12
|
+
}
|
|
13
|
+
const client = await pool.connect();
|
|
14
|
+
try {
|
|
15
|
+
await client.query('BEGIN');
|
|
16
|
+
const preparedAt = await readBillingMeterTransactionTime(client);
|
|
17
|
+
const existing = await client.query('SELECT * FROM billing_meter_epochs WHERE id = $1 FOR UPDATE', [epochId]);
|
|
18
|
+
const row = existing.rows[0];
|
|
19
|
+
if (row === undefined) {
|
|
20
|
+
await client.query(`INSERT INTO billing_meter_epochs
|
|
21
|
+
(id, schema_version, state, key_generation, release_sha, retry_identity_version,
|
|
22
|
+
writer_contract_version, prepared_at)
|
|
23
|
+
VALUES ($1, 1, 'prepared', $2, $3, $4, $5, $6)`, [
|
|
24
|
+
epochId,
|
|
25
|
+
generation,
|
|
26
|
+
releaseSha,
|
|
27
|
+
input.retryIdentityVersion,
|
|
28
|
+
writerContractVersion,
|
|
29
|
+
preparedAt,
|
|
30
|
+
]);
|
|
31
|
+
}
|
|
32
|
+
else if (row.state !== 'prepared' ||
|
|
33
|
+
row.key_generation !== generation ||
|
|
34
|
+
row.release_sha !== releaseSha ||
|
|
35
|
+
row.retry_identity_version !== input.retryIdentityVersion ||
|
|
36
|
+
row.writer_contract_version !== writerContractVersion) {
|
|
37
|
+
throw new Error('billing meter validation epoch already exists with different semantics');
|
|
38
|
+
}
|
|
39
|
+
await client.query('COMMIT');
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
await rollbackQuietly(client);
|
|
43
|
+
throw error;
|
|
44
|
+
}
|
|
45
|
+
finally {
|
|
46
|
+
client.release();
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
export async function retireBillingMeterValidationEpoch(pool, input) {
|
|
50
|
+
const epochId = validateScalarId('billing meter epoch id', input.epochId);
|
|
51
|
+
const client = await pool.connect();
|
|
52
|
+
try {
|
|
53
|
+
await client.query('BEGIN');
|
|
54
|
+
const retiredAt = await readBillingMeterTransactionTime(client);
|
|
55
|
+
const existing = await client.query('SELECT state FROM billing_meter_epochs WHERE id = $1 FOR UPDATE', [epochId]);
|
|
56
|
+
const state = existing.rows[0]?.state;
|
|
57
|
+
if (state === undefined)
|
|
58
|
+
throw new Error('billing meter validation epoch does not exist');
|
|
59
|
+
if (state === 'prepared') {
|
|
60
|
+
await client.query(`UPDATE billing_meter_epochs
|
|
61
|
+
SET state = 'retired', retired_at = $2
|
|
62
|
+
WHERE id = $1`, [epochId, retiredAt]);
|
|
63
|
+
}
|
|
64
|
+
else if (state !== 'retired') {
|
|
65
|
+
throw new Error('billing meter validation epoch cannot be retired from its current state');
|
|
66
|
+
}
|
|
67
|
+
await client.query('COMMIT');
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
await rollbackQuietly(client);
|
|
71
|
+
throw error;
|
|
72
|
+
}
|
|
73
|
+
finally {
|
|
74
|
+
client.release();
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function validateGeneration(value) {
|
|
78
|
+
if (!/^[0-9a-f]{64}$/.test(value)) {
|
|
79
|
+
throw new Error('billing meter key generation must be a SHA-256 digest');
|
|
80
|
+
}
|
|
81
|
+
return value;
|
|
82
|
+
}
|
|
83
|
+
function validateReleaseSha(value) {
|
|
84
|
+
if (!/^[0-9a-f]{40}$/.test(value)) {
|
|
85
|
+
throw new Error('billing meter release SHA must be a full 40-character commit digest');
|
|
86
|
+
}
|
|
87
|
+
return value;
|
|
88
|
+
}
|
|
89
|
+
function validatePositiveVersion(name, value) {
|
|
90
|
+
if (!Number.isSafeInteger(value) || value < 1)
|
|
91
|
+
throw new Error(`${name} must be positive`);
|
|
92
|
+
return value;
|
|
93
|
+
}
|
|
94
|
+
async function rollbackQuietly(client) {
|
|
95
|
+
try {
|
|
96
|
+
await client.query('ROLLBACK');
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
// Preserve the original transaction failure.
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=postgres-meter-epoch-fixtures.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres-meter-epoch-fixtures.js","sourceRoot":"","sources":["../../src/billing/postgres-meter-epoch-fixtures.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { Pool, PoolClient } from 'pg';
|
|
2
|
+
import type { ControlPlaneIdentity } from '../auth/deploy-gate.js';
|
|
3
|
+
import { type BillingMeterValidationEpochPrepareRequest, type BillingMeterValidationEpochResult, type BillingMeterValidationEpochRetireRequest, type BillingMeterValidationEpochStore } from './meter-validation-epoch.js';
|
|
4
|
+
export declare const BILLING_METER_VALIDATION_EPOCH_LIFECYCLE_LOCK_KEY = "billing-meter-validation-epoch-lifecycle:v1";
|
|
5
|
+
export interface BillingMeterValidationEpochPrepareBindings {
|
|
6
|
+
readonly keyGeneration: string;
|
|
7
|
+
readonly releaseSha: string;
|
|
8
|
+
readonly retryIdentityVersion: number;
|
|
9
|
+
readonly writerContractVersion: number;
|
|
10
|
+
}
|
|
11
|
+
export type BillingMeterValidationEpochPreparePreflight = (input: {
|
|
12
|
+
readonly client: PoolClient;
|
|
13
|
+
readonly epochId: string;
|
|
14
|
+
readonly bindings: BillingMeterValidationEpochPrepareBindings;
|
|
15
|
+
}) => Promise<boolean>;
|
|
16
|
+
export interface PostgresBillingMeterValidationEpochStoreOptions {
|
|
17
|
+
readonly billingUsageHmacKey?: string;
|
|
18
|
+
readonly releaseSha?: string;
|
|
19
|
+
readonly retryIdentityVersion?: number;
|
|
20
|
+
readonly writerContractVersion?: number;
|
|
21
|
+
/** Required for prepare; retirement and exact replay remain available while health is degraded. */
|
|
22
|
+
readonly preparePreflight?: BillingMeterValidationEpochPreparePreflight;
|
|
23
|
+
readonly id?: () => string;
|
|
24
|
+
}
|
|
25
|
+
/** Durable, validation-only lifecycle. It never creates an active meter epoch. */
|
|
26
|
+
export declare class PostgresBillingMeterValidationEpochStore implements BillingMeterValidationEpochStore {
|
|
27
|
+
#private;
|
|
28
|
+
readonly successAuditMode: "transactional";
|
|
29
|
+
constructor(pool: Pool, options: PostgresBillingMeterValidationEpochStoreOptions);
|
|
30
|
+
prepareValidationEpoch(input: {
|
|
31
|
+
readonly request: BillingMeterValidationEpochPrepareRequest;
|
|
32
|
+
readonly actor: ControlPlaneIdentity;
|
|
33
|
+
readonly service: string;
|
|
34
|
+
}): Promise<BillingMeterValidationEpochResult>;
|
|
35
|
+
retireValidationEpoch(input: {
|
|
36
|
+
readonly request: BillingMeterValidationEpochRetireRequest;
|
|
37
|
+
readonly actor: ControlPlaneIdentity;
|
|
38
|
+
readonly service: string;
|
|
39
|
+
}): Promise<BillingMeterValidationEpochResult>;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=postgres-meter-epochs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres-meter-epochs.d.ts","sourceRoot":"","sources":["../../src/billing/postgres-meter-epochs.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAC3C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAKnE,OAAO,EAGL,KAAK,yCAAyC,EAC9C,KAAK,iCAAiC,EAEtC,KAAK,wCAAwC,EAC7C,KAAK,gCAAgC,EAMtC,MAAM,6BAA6B,CAAC;AAKrC,eAAO,MAAM,iDAAiD,gDACf,CAAC;AAEhD,MAAM,WAAW,0CAA0C;IACzD,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,qBAAqB,EAAE,MAAM,CAAC;CACxC;AAED,MAAM,MAAM,2CAA2C,GAAG,CAAC,KAAK,EAAE;IAChE,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,0CAA0C,CAAC;CAC/D,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAEvB,MAAM,WAAW,+CAA+C;IAC9D,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IACvC,QAAQ,CAAC,qBAAqB,CAAC,EAAE,MAAM,CAAC;IACxC,mGAAmG;IACnG,QAAQ,CAAC,gBAAgB,CAAC,EAAE,2CAA2C,CAAC;IACxE,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,MAAM,CAAC;CAC5B;AAmBD,kFAAkF;AAClF,qBAAa,wCAAyC,YAAW,gCAAgC;;IAC/F,QAAQ,CAAC,gBAAgB,EAAG,eAAe,CAAU;gBAIzC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,+CAA+C;IAKhF,sBAAsB,CAAC,KAAK,EAAE;QAC5B,QAAQ,CAAC,OAAO,EAAE,yCAAyC,CAAC;QAC5D,QAAQ,CAAC,KAAK,EAAE,oBAAoB,CAAC;QACrC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;KAC1B,GAAG,OAAO,CAAC,iCAAiC,CAAC;IAS9C,qBAAqB,CAAC,KAAK,EAAE;QAC3B,QAAQ,CAAC,OAAO,EAAE,wCAAwC,CAAC;QAC3D,QAAQ,CAAC,KAAK,EAAE,oBAAoB,CAAC;QACrC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;KAC1B,GAAG,OAAO,CAAC,iCAAiC,CAAC;CAuP/C"}
|