rcf-lite 0.21.0 → 0.22.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/CHANGELOG.md +16 -0
- package/blueprints/application-account-settings/CHANGELOG.md +12 -0
- package/blueprints/application-account-settings/README.md +114 -0
- package/blueprints/application-account-settings/blueprint.json +234 -0
- package/blueprints/application-account-settings/contributions/adrs/adr-2601-application-account-settings-capability-vocabulary.json +20 -0
- package/blueprints/application-account-settings/contributions/adrs/adr-2602-application-account-settings-security-surface-shape.json +20 -0
- package/blueprints/application-account-settings/contributions/adrs/adr-2603-application-account-settings-theme-persistence.json +20 -0
- package/blueprints/application-account-settings/contributions/adrs/adr-2604-application-account-settings-reauth-window.json +20 -0
- package/blueprints/application-account-settings/contributions/requirements/application-account-settings-req-001.json +18 -0
- package/blueprints/application-account-settings/contributions/requirements/application-account-settings-req-002.json +18 -0
- package/blueprints/application-account-settings/contributions/requirements/application-account-settings-req-003.json +18 -0
- package/blueprints/application-account-settings/contributions/requirements/application-account-settings-req-004.json +18 -0
- package/blueprints/application-account-settings/contributions/requirements/application-account-settings-req-005.json +18 -0
- package/blueprints/application-account-settings/contributions/requirements/application-account-settings-req-006.json +18 -0
- package/blueprints/application-account-settings/contributions/tacs/tac-2601-application-account-settings-shell.json +41 -0
- package/blueprints/application-account-settings/contributions/tacs/tac-2602-application-account-settings-capability-discovery.json +28 -0
- package/blueprints/application-account-settings/contributions/tacs/tac-2603-application-account-settings-hosted-ui-bridge.json +35 -0
- package/blueprints/application-account-settings/contributions/tacs/tac-2604-application-account-settings-session-store.json +40 -0
- package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25101.json +34 -0
- package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25102.json +27 -0
- package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25103.json +27 -0
- package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25104.json +27 -0
- package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25105.json +33 -0
- package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25106.json +27 -0
- package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25107.json +27 -0
- package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25108.json +27 -0
- package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25109.json +33 -0
- package/blueprints/application-account-settings/contributions/user-stories/application-account-settings-us-25110.json +27 -0
- package/blueprints/application-account-settings/docs/topics.md +48 -0
- package/blueprints/application-account-settings/guide/application-account-settings.md +30 -0
- package/blueprints/application-account-settings/probe-packs/application-account-settings.pack.mjs +246 -0
- package/blueprints/application-admin-console/docs/topics.md +7 -0
- package/blueprints/application-api-rest/docs/topics.md +8 -1
- package/blueprints/application-charts/docs/topics.md +7 -0
- package/blueprints/application-dashboard/docs/topics.md +7 -0
- package/blueprints/application-datatable/docs/topics.md +7 -0
- package/blueprints/application-empty-error-states/CHANGELOG.md +9 -0
- package/blueprints/application-empty-error-states/README.md +88 -0
- package/blueprints/application-empty-error-states/blueprint.json +119 -0
- package/blueprints/application-empty-error-states/contributions/adrs/adr-2301-application-empty-error-states-status-contract.json +25 -0
- package/blueprints/application-empty-error-states/contributions/adrs/adr-2302-application-empty-error-states-stack-trace-visibility.json +25 -0
- package/blueprints/application-empty-error-states/contributions/adrs/adr-2303-application-empty-error-states-offline-strategy.json +25 -0
- package/blueprints/application-empty-error-states/contributions/requirements/application-empty-error-states-req-001.json +18 -0
- package/blueprints/application-empty-error-states/contributions/requirements/application-empty-error-states-req-002.json +18 -0
- package/blueprints/application-empty-error-states/contributions/requirements/application-empty-error-states-req-003.json +18 -0
- package/blueprints/application-empty-error-states/contributions/requirements/application-empty-error-states-req-004.json +18 -0
- package/blueprints/application-empty-error-states/contributions/requirements/application-empty-error-states-req-005.json +18 -0
- package/blueprints/application-empty-error-states/contributions/tacs/tac-2301-application-empty-error-states-state-machine.json +46 -0
- package/blueprints/application-empty-error-states/contributions/tacs/tac-2302-application-empty-error-states-recovery-router.json +36 -0
- package/blueprints/application-empty-error-states/contributions/tacs/tac-2303-application-empty-error-states-offline-buffer.json +40 -0
- package/blueprints/application-empty-error-states/contributions/user-stories/application-empty-error-states-us-22101.json +29 -0
- package/blueprints/application-empty-error-states/contributions/user-stories/application-empty-error-states-us-22102.json +29 -0
- package/blueprints/application-empty-error-states/contributions/user-stories/application-empty-error-states-us-22103.json +29 -0
- package/blueprints/application-empty-error-states/contributions/user-stories/application-empty-error-states-us-22104.json +29 -0
- package/blueprints/application-empty-error-states/contributions/user-stories/application-empty-error-states-us-22105.json +29 -0
- package/blueprints/application-empty-error-states/contributions/user-stories/application-empty-error-states-us-22106.json +29 -0
- package/blueprints/application-empty-error-states/contributions/user-stories/application-empty-error-states-us-22107.json +29 -0
- package/blueprints/application-empty-error-states/contributions/user-stories/application-empty-error-states-us-22108.json +29 -0
- package/blueprints/application-empty-error-states/docs/topics.md +53 -0
- package/blueprints/application-empty-error-states/guide/application-empty-error-states.md +50 -0
- package/blueprints/application-empty-error-states/probe-packs/application-empty-error-states.pack.mjs +284 -0
- package/blueprints/application-error-handling/docs/topics.md +7 -0
- package/blueprints/application-file-upload/CHANGELOG.md +9 -0
- package/blueprints/application-file-upload/README.md +85 -0
- package/blueprints/application-file-upload/blueprint.json +114 -0
- package/blueprints/application-file-upload/contributions/adrs/adr-2401-application-file-upload-transport.json +25 -0
- package/blueprints/application-file-upload/contributions/adrs/adr-2402-application-file-upload-accepted-set.json +25 -0
- package/blueprints/application-file-upload/contributions/adrs/adr-2403-application-file-upload-virus-scan.json +25 -0
- package/blueprints/application-file-upload/contributions/requirements/application-file-upload-req-001.json +18 -0
- package/blueprints/application-file-upload/contributions/requirements/application-file-upload-req-002.json +18 -0
- package/blueprints/application-file-upload/contributions/requirements/application-file-upload-req-003.json +18 -0
- package/blueprints/application-file-upload/contributions/requirements/application-file-upload-req-004.json +18 -0
- package/blueprints/application-file-upload/contributions/requirements/application-file-upload-req-005.json +18 -0
- package/blueprints/application-file-upload/contributions/tacs/tac-2401-application-file-upload-input.json +46 -0
- package/blueprints/application-file-upload/contributions/tacs/tac-2402-application-file-upload-transport.json +47 -0
- package/blueprints/application-file-upload/contributions/tacs/tac-2403-application-file-upload-progress-announcer.json +46 -0
- package/blueprints/application-file-upload/contributions/user-stories/application-file-upload-us-23101.json +28 -0
- package/blueprints/application-file-upload/contributions/user-stories/application-file-upload-us-23102.json +28 -0
- package/blueprints/application-file-upload/contributions/user-stories/application-file-upload-us-23103.json +29 -0
- package/blueprints/application-file-upload/contributions/user-stories/application-file-upload-us-23104.json +28 -0
- package/blueprints/application-file-upload/contributions/user-stories/application-file-upload-us-23105.json +29 -0
- package/blueprints/application-file-upload/contributions/user-stories/application-file-upload-us-23106.json +28 -0
- package/blueprints/application-file-upload/contributions/user-stories/application-file-upload-us-23107.json +28 -0
- package/blueprints/application-file-upload/docs/topics.md +58 -0
- package/blueprints/application-file-upload/guide/application-file-upload.md +48 -0
- package/blueprints/application-file-upload/probe-packs/application-file-upload.pack.mjs +238 -0
- package/blueprints/application-forms-wizard/CHANGELOG.md +9 -0
- package/blueprints/application-forms-wizard/README.md +102 -0
- package/blueprints/application-forms-wizard/blueprint.json +120 -0
- package/blueprints/application-forms-wizard/contributions/adrs/adr-2501-application-forms-wizard-navigation.json +25 -0
- package/blueprints/application-forms-wizard/contributions/adrs/adr-2502-application-forms-wizard-save-and-return.json +25 -0
- package/blueprints/application-forms-wizard/contributions/adrs/adr-2503-application-forms-wizard-step-indicator.json +25 -0
- package/blueprints/application-forms-wizard/contributions/requirements/application-forms-wizard-req-001.json +18 -0
- package/blueprints/application-forms-wizard/contributions/requirements/application-forms-wizard-req-002.json +18 -0
- package/blueprints/application-forms-wizard/contributions/requirements/application-forms-wizard-req-003.json +18 -0
- package/blueprints/application-forms-wizard/contributions/requirements/application-forms-wizard-req-004.json +18 -0
- package/blueprints/application-forms-wizard/contributions/requirements/application-forms-wizard-req-005.json +18 -0
- package/blueprints/application-forms-wizard/contributions/tacs/tac-2501-application-forms-wizard-task-list.json +46 -0
- package/blueprints/application-forms-wizard/contributions/tacs/tac-2502-application-forms-wizard-error-summary.json +40 -0
- package/blueprints/application-forms-wizard/contributions/tacs/tac-2503-application-forms-wizard-draft-store.json +40 -0
- package/blueprints/application-forms-wizard/contributions/user-stories/application-forms-wizard-us-24101.json +28 -0
- package/blueprints/application-forms-wizard/contributions/user-stories/application-forms-wizard-us-24102.json +29 -0
- package/blueprints/application-forms-wizard/contributions/user-stories/application-forms-wizard-us-24103.json +28 -0
- package/blueprints/application-forms-wizard/contributions/user-stories/application-forms-wizard-us-24104.json +29 -0
- package/blueprints/application-forms-wizard/contributions/user-stories/application-forms-wizard-us-24105.json +28 -0
- package/blueprints/application-forms-wizard/contributions/user-stories/application-forms-wizard-us-24106.json +28 -0
- package/blueprints/application-forms-wizard/contributions/user-stories/application-forms-wizard-us-24107.json +28 -0
- package/blueprints/application-forms-wizard/contributions/user-stories/application-forms-wizard-us-24108.json +29 -0
- package/blueprints/application-forms-wizard/docs/topics.md +49 -0
- package/blueprints/application-forms-wizard/guide/application-forms-wizard.md +48 -0
- package/blueprints/application-forms-wizard/probe-packs/application-forms-wizard.pack.mjs +233 -0
- package/blueprints/application-notifications-in-app/docs/topics.md +7 -0
- package/blueprints/application-onboarding-tour/CHANGELOG.md +12 -0
- package/blueprints/application-onboarding-tour/README.md +77 -0
- package/blueprints/application-onboarding-tour/blueprint.json +164 -0
- package/blueprints/application-onboarding-tour/contributions/adrs/adr-2701-application-onboarding-tour-dismissal-policy.json +20 -0
- package/blueprints/application-onboarding-tour/contributions/adrs/adr-2702-application-onboarding-tour-completion-store-shape.json +20 -0
- package/blueprints/application-onboarding-tour/contributions/adrs/adr-2703-application-onboarding-tour-checklist-anchor.json +20 -0
- package/blueprints/application-onboarding-tour/contributions/requirements/application-onboarding-tour-req-001.json +18 -0
- package/blueprints/application-onboarding-tour/contributions/requirements/application-onboarding-tour-req-002.json +18 -0
- package/blueprints/application-onboarding-tour/contributions/requirements/application-onboarding-tour-req-003.json +18 -0
- package/blueprints/application-onboarding-tour/contributions/requirements/application-onboarding-tour-req-004.json +18 -0
- package/blueprints/application-onboarding-tour/contributions/tacs/tac-2701-application-onboarding-tour-step-runner.json +41 -0
- package/blueprints/application-onboarding-tour/contributions/tacs/tac-2702-application-onboarding-tour-checklist-slot.json +35 -0
- package/blueprints/application-onboarding-tour/contributions/tacs/tac-2703-application-onboarding-tour-completion-store.json +34 -0
- package/blueprints/application-onboarding-tour/contributions/user-stories/application-onboarding-tour-us-26101.json +27 -0
- package/blueprints/application-onboarding-tour/contributions/user-stories/application-onboarding-tour-us-26102.json +27 -0
- package/blueprints/application-onboarding-tour/contributions/user-stories/application-onboarding-tour-us-26103.json +27 -0
- package/blueprints/application-onboarding-tour/contributions/user-stories/application-onboarding-tour-us-26104.json +27 -0
- package/blueprints/application-onboarding-tour/contributions/user-stories/application-onboarding-tour-us-26105.json +27 -0
- package/blueprints/application-onboarding-tour/contributions/user-stories/application-onboarding-tour-us-26106.json +27 -0
- package/blueprints/application-onboarding-tour/contributions/user-stories/application-onboarding-tour-us-26107.json +27 -0
- package/blueprints/application-onboarding-tour/docs/topics.md +48 -0
- package/blueprints/application-onboarding-tour/guide/application-onboarding-tour.md +59 -0
- package/blueprints/application-onboarding-tour/probe-packs/application-onboarding-tour.pack.mjs +231 -0
- package/blueprints/application-spa/docs/topics.md +8 -1
- package/blueprints/delivery-ci-workflows/docs/topics.md +8 -1
- package/blueprints/deploy-cloudflare-workers/docs/topics.md +8 -1
- package/blueprints/email-smtp-resend/docs/topics.md +8 -1
- package/blueprints/object-storage-s3/CHANGELOG.md +13 -0
- package/blueprints/object-storage-s3/README.md +108 -0
- package/blueprints/object-storage-s3/blueprint.json +72 -0
- package/blueprints/object-storage-s3/contributions/adrs/adr-2901-object-storage-s3-adapter.json +30 -0
- package/blueprints/object-storage-s3/contributions/adrs/adr-2902-object-storage-s3-presigned-ttl-floor.json +25 -0
- package/blueprints/object-storage-s3/contributions/adrs/adr-2903-object-storage-s3-multipart-threshold.json +25 -0
- package/blueprints/object-storage-s3/contributions/adrs/adr-2904-object-storage-s3-contract.json +25 -0
- package/blueprints/object-storage-s3/contributions/probes/event-secrecy.mjs +103 -0
- package/blueprints/object-storage-s3/contributions/probes/facade-round-trip.mjs +43 -0
- package/blueprints/object-storage-s3/contributions/probes/multipart-upload.mjs +84 -0
- package/blueprints/object-storage-s3/contributions/probes/presigned-url.mjs +101 -0
- package/blueprints/object-storage-s3/contributions/probes/probe-utils.mjs +85 -0
- package/blueprints/object-storage-s3/contributions/probes/put-get-round-trip.mjs +84 -0
- package/blueprints/object-storage-s3/contributions/probes/r2-real-account-smoke.mjs +64 -0
- package/blueprints/object-storage-s3/contributions/probes/run-event-secrecy.mjs +4 -0
- package/blueprints/object-storage-s3/contributions/probes/run-facade-round-trip.mjs +10 -0
- package/blueprints/object-storage-s3/contributions/probes/run-multipart-upload.mjs +4 -0
- package/blueprints/object-storage-s3/contributions/probes/run-presigned-url.mjs +4 -0
- package/blueprints/object-storage-s3/contributions/probes/run-put-get-round-trip.mjs +7 -0
- package/blueprints/object-storage-s3/contributions/probes/run-r2-real-account-smoke.mjs +4 -0
- package/blueprints/object-storage-s3/contributions/requirements/object-storage-s3-req-001.json +18 -0
- package/blueprints/object-storage-s3/contributions/requirements/object-storage-s3-req-002.json +18 -0
- package/blueprints/object-storage-s3/contributions/requirements/object-storage-s3-req-003.json +18 -0
- package/blueprints/object-storage-s3/contributions/requirements/object-storage-s3-req-004.json +18 -0
- package/blueprints/object-storage-s3/contributions/requirements/object-storage-s3-req-005.json +18 -0
- package/blueprints/object-storage-s3/contributions/requirements/object-storage-s3-req-006.json +18 -0
- package/blueprints/object-storage-s3/contributions/tacs/tac-2901-object-storage-s3-facade.json +57 -0
- package/blueprints/object-storage-s3/contributions/tacs/tac-2902-object-storage-s3-multipart-uploader.json +36 -0
- package/blueprints/object-storage-s3/contributions/tacs/tac-2903-object-storage-s3-event-sink.json +36 -0
- package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28101.json +34 -0
- package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28102.json +43 -0
- package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28103.json +25 -0
- package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28104.json +34 -0
- package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28105.json +25 -0
- package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28106.json +34 -0
- package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28107.json +34 -0
- package/blueprints/object-storage-s3/contributions/user-stories/object-storage-s3-us-28108.json +34 -0
- package/blueprints/object-storage-s3/docs/topics.md +62 -0
- package/blueprints/object-storage-s3/guide/object-storage-s3.md +207 -0
- package/blueprints/observability-essentials/docs/topics.md +8 -1
- package/blueprints/observability-logging/CHANGELOG.md +4 -0
- package/blueprints/observability-logging/README.md +3 -0
- package/blueprints/observability-logging/blueprint.json +3 -2
- package/blueprints/observability-logging/docs/topics.md +7 -0
- package/blueprints/observability-probe-endpoints/docs/topics.md +8 -1
- package/blueprints/persistence-data-d1/docs/topics.md +8 -1
- package/blueprints/persistence-data-postgres/CHANGELOG.md +12 -0
- package/blueprints/persistence-data-postgres/README.md +101 -0
- package/blueprints/persistence-data-postgres/blueprint.json +80 -0
- package/blueprints/persistence-data-postgres/contributions/adrs/adr-2801-persistence-data-postgres-driver.json +30 -0
- package/blueprints/persistence-data-postgres/contributions/adrs/adr-2802-persistence-data-postgres-migration-shape.json +25 -0
- package/blueprints/persistence-data-postgres/contributions/adrs/adr-2803-persistence-data-postgres-runner-mode.json +25 -0
- package/blueprints/persistence-data-postgres/contributions/adrs/adr-2804-persistence-data-postgres-recovery.json +25 -0
- package/blueprints/persistence-data-postgres/contributions/adrs/adr-2805-persistence-data-postgres-connection-pool-posture.json +25 -0
- package/blueprints/persistence-data-postgres/contributions/probes/facade-round-trip.mjs +56 -0
- package/blueprints/persistence-data-postgres/contributions/probes/migration-apply.mjs +75 -0
- package/blueprints/persistence-data-postgres/contributions/probes/pool-posture-smoke.mjs +56 -0
- package/blueprints/persistence-data-postgres/contributions/probes/prepared-statement-scan.mjs +186 -0
- package/blueprints/persistence-data-postgres/contributions/probes/probe-utils.mjs +76 -0
- package/blueprints/persistence-data-postgres/contributions/probes/recovery-restore-round-trip.mjs +173 -0
- package/blueprints/persistence-data-postgres/contributions/probes/run-facade-round-trip.mjs +10 -0
- package/blueprints/persistence-data-postgres/contributions/probes/run-migration-apply.mjs +10 -0
- package/blueprints/persistence-data-postgres/contributions/probes/run-pool-posture-smoke.mjs +9 -0
- package/blueprints/persistence-data-postgres/contributions/probes/run-prepared-statement-scan.mjs +10 -0
- package/blueprints/persistence-data-postgres/contributions/probes/run-recovery-restore-round-trip.mjs +9 -0
- package/blueprints/persistence-data-postgres/contributions/probes/run-transaction-atomicity.mjs +10 -0
- package/blueprints/persistence-data-postgres/contributions/probes/transaction-atomicity.mjs +79 -0
- package/blueprints/persistence-data-postgres/contributions/requirements/persistence-data-postgres-req-001.json +18 -0
- package/blueprints/persistence-data-postgres/contributions/requirements/persistence-data-postgres-req-002.json +18 -0
- package/blueprints/persistence-data-postgres/contributions/requirements/persistence-data-postgres-req-003.json +18 -0
- package/blueprints/persistence-data-postgres/contributions/requirements/persistence-data-postgres-req-004.json +18 -0
- package/blueprints/persistence-data-postgres/contributions/requirements/persistence-data-postgres-req-005.json +18 -0
- package/blueprints/persistence-data-postgres/contributions/requirements/persistence-data-postgres-req-006.json +18 -0
- package/blueprints/persistence-data-postgres/contributions/requirements/persistence-data-postgres-req-007.json +18 -0
- package/blueprints/persistence-data-postgres/contributions/tacs/tac-2801-persistence-data-postgres-facade.json +58 -0
- package/blueprints/persistence-data-postgres/contributions/tacs/tac-2802-persistence-data-postgres-migration-runner.json +40 -0
- package/blueprints/persistence-data-postgres/contributions/tacs/tac-2803-persistence-data-postgres-transaction-helper.json +35 -0
- package/blueprints/persistence-data-postgres/contributions/tacs/tac-2804-persistence-data-postgres-recovery-runner.json +40 -0
- package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27101.json +34 -0
- package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27102.json +25 -0
- package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27103.json +25 -0
- package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27104.json +25 -0
- package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27105.json +25 -0
- package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27106.json +25 -0
- package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27107.json +25 -0
- package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27108.json +25 -0
- package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27109.json +25 -0
- package/blueprints/persistence-data-postgres/contributions/user-stories/persistence-data-postgres-us-27110.json +25 -0
- package/blueprints/persistence-data-postgres/docs/topics.md +64 -0
- package/blueprints/persistence-data-postgres/guide/persistence-data-postgres.md +172 -0
- package/blueprints/persistence-data-sqlite/docs/topics.md +8 -1
- package/blueprints/security-auth-clerk/CHANGELOG.md +4 -0
- package/blueprints/security-auth-clerk/README.md +3 -0
- package/blueprints/security-auth-clerk/blueprint.json +147 -30
- package/blueprints/security-auth-clerk/docs/topics.md +8 -1
- package/blueprints/security-auth-keycloak/CHANGELOG.md +4 -0
- package/blueprints/security-auth-keycloak/README.md +3 -0
- package/blueprints/security-auth-keycloak/blueprint.json +182 -37
- package/blueprints/security-auth-keycloak/docs/topics.md +8 -1
- package/blueprints/security-auth-magic-link/CHANGELOG.md +4 -0
- package/blueprints/security-auth-magic-link/README.md +3 -0
- package/blueprints/security-auth-magic-link/blueprint.json +159 -33
- package/blueprints/security-auth-magic-link/docs/topics.md +8 -1
- package/blueprints/security-auth-oauth2/CHANGELOG.md +4 -0
- package/blueprints/security-auth-oauth2/README.md +3 -0
- package/blueprints/security-auth-oauth2/blueprint.json +158 -32
- package/blueprints/security-auth-oauth2/docs/topics.md +8 -1
- package/blueprints/security-secrets-management/CHANGELOG.md +11 -0
- package/blueprints/security-secrets-management/blueprint.json +2 -1
- package/blueprints/security-secrets-management/docs/topics.md +8 -1
- package/fixtures/canary-manifest.json +9 -9
- package/package.json +1 -1
- package/rcf/code-nodes/cn-134.json +13 -0
- package/rcf/code-nodes/cn-135.json +12 -0
- package/rcf/code-nodes/cn-136.json +13 -0
- package/rcf/code-nodes/cn-137.json +13 -0
- package/rcf/code-nodes/cn-138.json +12 -0
- package/rcf/code-nodes/cn-139.json +12 -0
- package/rcf/code-nodes/cn-140.json +13 -0
- package/rcf/code-nodes/cn-141.json +13 -0
- package/rcf/code-nodes/cn-142.json +12 -0
- package/rcf/code-nodes/cn-143.json +13 -0
- package/rcf/code-nodes/cn-144.json +13 -0
- package/rcf/code-nodes/cn-145.json +12 -0
- package/rcf/code-nodes/cn-146.json +12 -0
- package/rcf/code-nodes/cn-147.json +13 -0
- package/rcf/code-nodes/cn-148.json +13 -0
- package/rcf/code-nodes/cn-149.json +12 -0
- package/rcf/code-nodes/cn-150.json +13 -0
- package/rcf/code-nodes/cn-151.json +13 -0
- package/rcf/code-nodes/cn-152.json +12 -0
- package/rcf/code-nodes/cn-153.json +12 -0
- package/rcf/code-nodes/cn-154.json +13 -0
- package/rcf/code-nodes/cn-155.json +14 -0
- package/rcf/code-nodes/cn-156.json +13 -0
- package/rcf/code-nodes/cn-157.json +13 -0
- package/rcf/code-nodes/cn-158.json +12 -0
- package/rcf/code-nodes/cn-159.json +13 -0
- package/rcf/code-nodes/cn-160.json +12 -0
- package/rcf/code-nodes/cn-161.json +12 -0
- package/rcf/code-nodes/cn-162.json +13 -0
- package/rcf/code-nodes/cn-163.json +12 -0
- package/rcf/code-nodes/cn-164.json +13 -0
- package/rcf/code-nodes/cn-165.json +12 -0
- package/rcf/code-nodes/cn-166.json +12 -0
- package/rcf/code-nodes/cn-167.json +12 -0
- package/rcf/code-nodes/cn-168.json +12 -0
- package/rcf/code-nodes/cn-169.json +12 -0
- package/rcf/code-nodes/cn-170.json +12 -0
- package/rcf/code-nodes/cn-171.json +12 -0
- package/rcf/code-nodes/cn-172.json +12 -0
- package/rcf/code-nodes/cn-173.json +12 -0
- package/rcf/code-nodes/cn-174.json +12 -0
- package/rcf/code-nodes/cn-175.json +13 -0
- package/rcf/code-nodes/cn-176.json +12 -0
- package/rcf/code-nodes/cn-177.json +12 -0
- package/rcf/code-nodes/cn-178.json +12 -0
- package/rcf/code-nodes/cn-179.json +12 -0
- package/rcf/code-nodes/cn-180.json +13 -0
- package/rcf/code-nodes/cn-181.json +12 -0
- package/rcf/code-nodes/cn-182.json +13 -0
- package/rcf/code-nodes/cn-183.json +12 -0
- package/rcf/code-nodes/cn-184.json +13 -0
- package/rcf/code-nodes/cn-185.json +12 -0
- package/rcf/code-nodes/cn-186.json +12 -0
- package/rcf/code-nodes/cn-200.json +14 -0
- package/rcf/code-nodes/cn-201.json +13 -0
- package/rcf/code-nodes/cn-202.json +14 -0
- package/rcf/code-nodes/cn-203.json +14 -0
- package/rcf/code-nodes/cn-204.json +13 -0
- package/rcf/code-nodes/cn-205.json +14 -0
- package/rcf/fbs/fbs-043.json +23 -0
- package/rcf/fbs/fbs-044.json +23 -0
- package/rcf/fbs/fbs-045.json +23 -0
- package/rcf/fbs/fbs-046.json +24 -0
- package/rcf/fbs/fbs-047.json +24 -0
- package/rcf/fbs/fbs-060.json +22 -0
- package/rcf/fbs/fbs-061.json +20 -0
- package/rcf/requirements/req-024.json +69 -0
- package/rcf/requirements/req-025.json +59 -0
- package/rcf/requirements/req-026.json +154 -0
- package/rcf/requirements/req-027.json +33 -0
- package/rcf/requirements/req-028.json +13 -0
- package/rcf/requirements/req-040.json +13 -0
- package/rcf/requirements/req-041.json +125 -0
- package/rcf/test-suites/ts-053.json +70 -0
- package/rcf/test-suites/ts-054.json +70 -0
- package/rcf/test-suites/ts-055.json +77 -0
- package/rcf/test-suites/ts-056.json +78 -0
- package/rcf/test-suites/ts-057.json +78 -0
- package/rcf/test-suites/ts-070.json +62 -0
- package/rcf/test-suites/ts-071.json +62 -0
- package/rcf/user-stories/us-2401.json +62 -0
- package/rcf/user-stories/us-2501.json +58 -0
- package/rcf/user-stories/us-2601.json +51 -0
- package/rcf/user-stories/us-2701.json +55 -0
- package/rcf/user-stories/us-2801.json +55 -0
- package/rcf/user-stories/us-4001.json +69 -0
- package/rcf/user-stories/us-4101.json +69 -0
- package/releases/releases.yaml +11 -1
- package/src/blueprint/apply.js +10 -1
- package/src/blueprint/capabilities.js +41 -2
- package/src/cli/blueprint.js +8 -1
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"tacId": "TAC-2804-persistence-data-postgres-recovery-runner",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"tadId": "TAD-001",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "approved",
|
|
7
|
+
"name": "Postgres scheduled-export runner",
|
|
8
|
+
"purpose": "The scheduled export runner that drives pg_dump against the live database, writes the artefact to the elicited destination, and emits backupExported with the artefact path and completion timestamp. Pairs with the deploy target's own point-in-time recovery on ADR-2804; the runner covers the portable-artefact half of the two-path recovery model.",
|
|
9
|
+
"responsibilities": [
|
|
10
|
+
"Invoke pg_dump via child_process.execFile against the elicited connection URL with an elicited pg_dump argument set (default: --no-owner --no-acl --format=plain) (AC-27105-1).",
|
|
11
|
+
"Stream the pg_dump stdout to a temporary file, atomically rename to the elicited destination path (a filesystem path in the shipped fixture; an operator-owned path in production) (AC-27105-1).",
|
|
12
|
+
"On successful completion, emit backupExported on the injected event sink with { artefactPath, completedAt } (AC-27105-1).",
|
|
13
|
+
"On pg_dump non-zero exit, emit backupExportFailed with the exit code and stderr tail, delete the partial temp file, exit non-zero.",
|
|
14
|
+
"Cadence is elicited (a cron string, a systemd timer spec, or off for CI-only invocation); the runner does not schedule itself; a project-side scheduler invokes it."
|
|
15
|
+
],
|
|
16
|
+
"internalStructure": "One Node module exporting an exportDatabase({ connectionUrl, destination, onEvent, pgDumpArgs }) async function. The module resolves pg_dump on PATH via child_process.execFile, streams stdout to a temp file inside the destination's directory, and atomically renames on success. The recovery-drill helper in the same module invokes exportDatabase, brings up a fresh Postgres via docker compose or podman, streams the artefact into psql, and compares row-count and checksum on both databases.",
|
|
17
|
+
"interfaces": [
|
|
18
|
+
{
|
|
19
|
+
"name": "exportDatabase",
|
|
20
|
+
"kind": "read-write-api",
|
|
21
|
+
"description": "await exportDatabase({ connectionUrl, destination, onEvent, pgDumpArgs }) -> { artefactPath, completedAt }. Runs pg_dump, writes the artefact, fires backupExported."
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"name": "recoveryDrill",
|
|
25
|
+
"kind": "read-write-api",
|
|
26
|
+
"description": "await recoveryDrill({ sourceUrl, destination, onEvent }) -> { count, checksum }. Runs exportDatabase, primes a fresh Postgres from the artefact, compares row-count and checksum on the fixture table, fires recoveryDrillPassed."
|
|
27
|
+
}
|
|
28
|
+
],
|
|
29
|
+
"dependencies": [
|
|
30
|
+
{
|
|
31
|
+
"name": "Postgres facade",
|
|
32
|
+
"kind": "tac",
|
|
33
|
+
"tacId": "TAC-2801-persistence-data-postgres-facade",
|
|
34
|
+
"description": "Shares the facade's event sink for backupExported and recoveryDrillPassed."
|
|
35
|
+
}
|
|
36
|
+
],
|
|
37
|
+
"tradeoffs": "child_process.execFile against pg_dump requires the pg_dump binary to be on PATH (or a full path passed via config). On a container platform the runner ships a Postgres client image alongside the app for pg_dump availability; the guide names the CI-seam pattern. The runner does not implement WAL-shipping or a streaming backup; that path is the deploy target's own PITR obligation on ADR-2804.",
|
|
38
|
+
"createdAt": "2026-09-06T15:47:00.000Z",
|
|
39
|
+
"updatedAt": "2026-09-06T15:47:00.000Z"
|
|
40
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"usId": "persistence-data-postgres-US-27101",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"reqId": "persistence-data-postgres-REQ-001",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "approved",
|
|
7
|
+
"title": "One facade module opens a pg.Pool on boot and emits facadeReady with the database name",
|
|
8
|
+
"asA": "developer whose Node process needs a durable Postgres store behind a swappable boundary",
|
|
9
|
+
"iWant": "one facade module to hold the pg client and expose named domain verbs, with a facadeReady lifecycle event on the first successful pool ready-check",
|
|
10
|
+
"soThat": "the boundary between the domain and the pg vendor surface is the only place that has to move when the driver changes and the boot ordering is observable via the event",
|
|
11
|
+
"acceptanceCriteria": [
|
|
12
|
+
{
|
|
13
|
+
"id": "AC-27101-1",
|
|
14
|
+
"description": "On process boot, the facade opens a pg.Pool against the elicited connection URL; once the first successful pool ready-check completes, a facadeReady event fires on the injected event sink carrying the database name.",
|
|
15
|
+
"given": "a Node process with the facade module imported and its factory invoked",
|
|
16
|
+
"when": "the process boots and the facade's pool ready-check returns",
|
|
17
|
+
"then": "a facadeReady event fires on the injected event sink with a payload containing databaseName, and the pool is ready to accept queries; the facade exposes named domain verbs and does not re-export the raw pg client",
|
|
18
|
+
"testable": true,
|
|
19
|
+
"scope": "runtime"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"id": "AC-27101-2",
|
|
23
|
+
"description": "Exactly one source-tree module inside the facade directory imports pg; every other module in the applied project's source tree that touches persistence imports the facade and calls its named domain verbs, verified by a targeted grep on the applied fixture.",
|
|
24
|
+
"given": "the applied project's source tree after apply",
|
|
25
|
+
"when": "grep 'from \\'pg\\'' or grep 'require(\\'pg\\')' walks the tree outside the facade directory",
|
|
26
|
+
"then": "no match is found outside the facade directory; the facade's public surface exports named domain verbs only, no raw pg reference",
|
|
27
|
+
"testable": true,
|
|
28
|
+
"scope": "runtime"
|
|
29
|
+
}
|
|
30
|
+
],
|
|
31
|
+
"tacIds": ["TAC-2801-persistence-data-postgres-facade"],
|
|
32
|
+
"createdAt": "2026-09-06T15:47:00.000Z",
|
|
33
|
+
"updatedAt": "2026-09-06T15:47:00.000Z"
|
|
34
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"usId": "persistence-data-postgres-US-27102",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"reqId": "persistence-data-postgres-REQ-002",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "approved",
|
|
7
|
+
"title": "Numbered forward-only .sql migrations apply one file one transaction; schema_version advances",
|
|
8
|
+
"asA": "operator who needs deploys reproducible from a git ref with no schema state outside version control",
|
|
9
|
+
"iWant": "every schema change to be a new numbered .sql file under the elicited migrations directory, applied by the in-tree runner one file at a time inside its own transaction",
|
|
10
|
+
"soThat": "the schema shape at any deployed version can be read from committed files, each apply either commits or leaves the schema exactly as it was, and the schema_version bookkeeping table is the one source of truth on what has been applied",
|
|
11
|
+
"acceptanceCriteria": [
|
|
12
|
+
{
|
|
13
|
+
"id": "AC-27102-1",
|
|
14
|
+
"description": "Given a fresh Postgres database at schema_version 0 and three numbered forward-only .sql migration files (001, 002, 003), when the migration runner opens the store and applies them, then each file applies inside its own transaction (BEGIN, file body, COMMIT), a migrationsApplied event fires with the applied filename list, and the schema_version bookkeeping table records three rows keyed by filename.",
|
|
15
|
+
"given": "a fresh Postgres instance and a migrations directory with 001_*.sql, 002_*.sql, 003_*.sql each a single statement inside an implicit transaction",
|
|
16
|
+
"when": "the migration runner applies the directory against the database",
|
|
17
|
+
"then": "each file runs inside a BEGIN/COMMIT pair; after all three succeed a migrationsApplied event fires with the filename list ['001_*.sql', '002_*.sql', '003_*.sql'] and the schema_version table (or the runner's configured bookkeeping table name) carries a row per applied filename",
|
|
18
|
+
"testable": true,
|
|
19
|
+
"scope": "runtime"
|
|
20
|
+
}
|
|
21
|
+
],
|
|
22
|
+
"tacIds": ["TAC-2802-persistence-data-postgres-migration-runner"],
|
|
23
|
+
"createdAt": "2026-09-06T15:47:00.000Z",
|
|
24
|
+
"updatedAt": "2026-09-06T15:47:00.000Z"
|
|
25
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"usId": "persistence-data-postgres-US-27103",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"reqId": "persistence-data-postgres-REQ-003",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "approved",
|
|
7
|
+
"title": "Every pg.query call site inside the facade passes a static string literal as its first argument",
|
|
8
|
+
"asA": "reviewer of an rcf-lite Postgres project auditing for SQL injection risk at the driver boundary",
|
|
9
|
+
"iWant": "an AST scan over the facade directory to prove every pg.query first argument is a static string literal with $N parameters, per the node-postgres parameterised-queries contract",
|
|
10
|
+
"soThat": "a call site that concatenates or template-literal-interpolates consumer values into SQL text is caught at build time before it ships",
|
|
11
|
+
"acceptanceCriteria": [
|
|
12
|
+
{
|
|
13
|
+
"id": "AC-27103-1",
|
|
14
|
+
"description": "An AST scan over every .ts/.js/.mjs file under the applied fixture's facade directory finds every call to pg.query and asserts each first-argument node is a StringLiteral (Literal node with a string value), not a TemplateLiteral, not a BinaryExpression whose operator is '+' with a string operand. Parameters are supplied as an array whose values bind to $1, $2, ... $N placeholders in the string.",
|
|
15
|
+
"given": "the applied fixture's src/store.mjs and any sibling module inside the facade directory",
|
|
16
|
+
"when": "a Node built-in AST parser walks every call expression whose callee is 'pg.query' or resolves to a method named 'query' on a pg.Client, pg.Pool, or pg.PoolClient reference",
|
|
17
|
+
"then": "every first-argument node is a Literal with typeof value === 'string'; no first-argument node is a TemplateLiteral or a string-concatenation expression",
|
|
18
|
+
"testable": true,
|
|
19
|
+
"scope": "runtime"
|
|
20
|
+
}
|
|
21
|
+
],
|
|
22
|
+
"tacIds": ["TAC-2801-persistence-data-postgres-facade"],
|
|
23
|
+
"createdAt": "2026-09-06T15:47:00.000Z",
|
|
24
|
+
"updatedAt": "2026-09-06T15:47:00.000Z"
|
|
25
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"usId": "persistence-data-postgres-US-27104",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"reqId": "persistence-data-postgres-REQ-004",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "approved",
|
|
7
|
+
"title": "Transaction helper rolls back on any statement error and fires transactionRolledBack with the failing index",
|
|
8
|
+
"asA": "developer whose domain requires atomic multi-statement writes",
|
|
9
|
+
"iWant": "a transaction helper that wraps BEGIN and COMMIT around a callback and issues ROLLBACK on any error",
|
|
10
|
+
"soThat": "no partial commit lands on the shipped database and the failing statement's index is observable on the event sink",
|
|
11
|
+
"acceptanceCriteria": [
|
|
12
|
+
{
|
|
13
|
+
"id": "AC-27104-1",
|
|
14
|
+
"description": "Given the transaction helper wrapping a callback that issues two INSERTs where the second violates a UNIQUE constraint, when the helper runs, then client.query('BEGIN') is issued, the first INSERT lands on the transaction, the second INSERT throws a constraint error the helper catches, client.query('ROLLBACK') is issued, a transactionRolledBack event fires with statementIndex 1, the client is released back to the pool, and the underlying error is re-thrown to the caller. The database after rollback carries neither row from the aborted transaction.",
|
|
15
|
+
"given": "the facade's withTransaction helper, a table with a UNIQUE constraint on a column, and a callback issuing two INSERTs with the same value for that column",
|
|
16
|
+
"when": "await withTransaction(callback) runs",
|
|
17
|
+
"then": "BEGIN is issued, the first INSERT lands inside the transaction, the second INSERT throws, ROLLBACK is issued, transactionRolledBack fires on the event sink with { statementIndex: 1, code: '<pg error code>' }, the client is released, the promise rejects with the underlying error, and a subsequent SELECT against the table returns no rows from the aborted transaction",
|
|
18
|
+
"testable": true,
|
|
19
|
+
"scope": "runtime"
|
|
20
|
+
}
|
|
21
|
+
],
|
|
22
|
+
"tacIds": ["TAC-2803-persistence-data-postgres-transaction-helper"],
|
|
23
|
+
"createdAt": "2026-09-06T15:47:00.000Z",
|
|
24
|
+
"updatedAt": "2026-09-06T15:47:00.000Z"
|
|
25
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"usId": "persistence-data-postgres-US-27105",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"reqId": "persistence-data-postgres-REQ-005",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "approved",
|
|
7
|
+
"title": "Scheduled pg_dump lands an artefact and a fresh Postgres primed from it round-trips the row set",
|
|
8
|
+
"asA": "operator responsible for restoring a Postgres project after a cluster loss or a data-integrity incident",
|
|
9
|
+
"iWant": "a scheduled export runner that drives pg_dump against the live database and writes an artefact to the elicited destination",
|
|
10
|
+
"soThat": "a fresh Postgres primed from the artefact returns the row set the source held at the artefact's completion timestamp",
|
|
11
|
+
"acceptanceCriteria": [
|
|
12
|
+
{
|
|
13
|
+
"id": "AC-27105-1",
|
|
14
|
+
"description": "Given a live Postgres containing a small fixture rowset, when the scheduled export runner runs, then it invokes pg_dump via child_process.execFile against the elicited connection URL, writes the artefact to the elicited destination, and emits backupExported with { artefactPath, completedAt }. A fresh Postgres primed by psql-restoring the artefact returns the same rowset (row count and row checksum both equal) as the source.",
|
|
15
|
+
"given": "a live Postgres seeded with a fixture rowset and the recovery runner configured to write to a temporary destination",
|
|
16
|
+
"when": "the recovery runner runs pg_dump against the source and a second Postgres is primed from the artefact",
|
|
17
|
+
"then": "the runner exits 0, backupExported fires with the artefact path and completion timestamp, the artefact file exists at the elicited destination, and a query against the restored Postgres returns the same row count and same checksum of the fixture rowset as the source",
|
|
18
|
+
"testable": true,
|
|
19
|
+
"scope": "runtime"
|
|
20
|
+
}
|
|
21
|
+
],
|
|
22
|
+
"tacIds": ["TAC-2804-persistence-data-postgres-recovery-runner"],
|
|
23
|
+
"createdAt": "2026-09-06T15:47:00.000Z",
|
|
24
|
+
"updatedAt": "2026-09-06T15:47:00.000Z"
|
|
25
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"usId": "persistence-data-postgres-US-27106",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"reqId": "persistence-data-postgres-REQ-006",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "approved",
|
|
7
|
+
"title": "Two facades at pool size 5 handle twenty concurrent queries with no timeout",
|
|
8
|
+
"asA": "developer running a long-lived Node process with a warm pg pool",
|
|
9
|
+
"iWant": "the shipped pool defaults to handle a burst of twenty concurrent queries across two facade instances at pool size 5 without timing out",
|
|
10
|
+
"soThat": "the pool posture per deploy target is proven at the shape the shipped defaults name, not just at the single-query level",
|
|
11
|
+
"acceptanceCriteria": [
|
|
12
|
+
{
|
|
13
|
+
"id": "AC-27106-1",
|
|
14
|
+
"description": "Given two facade instances opened concurrently against the same Postgres at pool size 5 each, when twenty concurrent SELECT queries are issued across the two facades, then all twenty return with no timeout inside the shipped connectionTimeoutMillis (5000) and idleTimeoutMillis (30000) defaults, and the pool metric on each facade reports at most 5 in-use connections at any point.",
|
|
15
|
+
"given": "two facade instances opened against the same postgres:17-alpine container at pool size 5 each",
|
|
16
|
+
"when": "twenty SELECT queries are dispatched concurrently across the two facades via Promise.all",
|
|
17
|
+
"then": "all twenty promises resolve inside the connectionTimeoutMillis budget; no query throws; the observed maximum concurrent in-use pool connections on either facade is at most the configured pool size (5)",
|
|
18
|
+
"testable": true,
|
|
19
|
+
"scope": "runtime"
|
|
20
|
+
}
|
|
21
|
+
],
|
|
22
|
+
"tacIds": ["TAC-2801-persistence-data-postgres-facade"],
|
|
23
|
+
"createdAt": "2026-09-06T15:47:00.000Z",
|
|
24
|
+
"updatedAt": "2026-09-06T15:47:00.000Z"
|
|
25
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"usId": "persistence-data-postgres-US-27107",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"reqId": "persistence-data-postgres-REQ-007",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "approved",
|
|
7
|
+
"title": "Advisory-lock helper is elicited off by default; when enabled it wraps pg_advisory_lock or pg_advisory_xact_lock per the elicited scope",
|
|
8
|
+
"asA": "developer building a workflow that needs cross-process coordination on a shared Postgres",
|
|
9
|
+
"iWant": "an optional advisory-lock helper on the facade that acquires and releases a session-level or transaction-level lock per an elicited key",
|
|
10
|
+
"soThat": "cross-process ordering is expressible through the engine's own primitive without a bespoke locks table",
|
|
11
|
+
"acceptanceCriteria": [
|
|
12
|
+
{
|
|
13
|
+
"id": "AC-27107-1",
|
|
14
|
+
"description": "The elicited advisoryLockHelper parameter has one of three values (off, session, transaction) with default off; when off the facade does not expose the helper on its public surface. When session or transaction, the facade exposes a withAdvisoryLock(key, callback) verb that acquires pg_advisory_lock (session) or pg_advisory_xact_lock (transaction) with the integer key, runs the callback, and releases the lock via pg_advisory_unlock on the session-level shape; the transaction-level shape releases automatically at COMMIT or ROLLBACK per the Postgres explicit-locking reference.",
|
|
15
|
+
"given": "the facade's public surface after apply, with the advisoryLockHelper elicit answered on each of the three permitted values",
|
|
16
|
+
"when": "the surface is inspected and the helper is invoked with a valid integer key on a supported answer",
|
|
17
|
+
"then": "the surface exposes withAdvisoryLock only when the answer is session or transaction; the helper acquires the correct lock verb per the answer, runs the callback, and releases (session) or lets COMMIT release (transaction); the sidecar records the elicited answer for later validation",
|
|
18
|
+
"testable": true,
|
|
19
|
+
"scope": "runtime"
|
|
20
|
+
}
|
|
21
|
+
],
|
|
22
|
+
"tacIds": ["TAC-2801-persistence-data-postgres-facade"],
|
|
23
|
+
"createdAt": "2026-09-06T15:47:00.000Z",
|
|
24
|
+
"updatedAt": "2026-09-06T15:47:00.000Z"
|
|
25
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"usId": "persistence-data-postgres-US-27108",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"reqId": "persistence-data-postgres-REQ-001",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "approved",
|
|
7
|
+
"title": "Facade boot survives a first-connect race and does not double-emit facadeReady",
|
|
8
|
+
"asA": "developer whose process may issue queries against the facade before its pool's first ready-check completes",
|
|
9
|
+
"iWant": "the facade to serialise consumer queries behind the pool's ready-check without dropping any and to emit facadeReady exactly once per facade instance",
|
|
10
|
+
"soThat": "boot-time races do not surface as unhandled promise rejections and the ready event is not double-counted by an observability sink",
|
|
11
|
+
"acceptanceCriteria": [
|
|
12
|
+
{
|
|
13
|
+
"id": "AC-27108-1",
|
|
14
|
+
"description": "Given a facade instance and five concurrent domain-verb calls issued before the pool's first ready-check completes, when the pool becomes ready, then all five calls succeed against the pool once ready, the facadeReady event fires exactly once with the database name, and no consumer sees a NotReady error.",
|
|
15
|
+
"given": "a fresh facade instance and five concurrent getUserById calls issued immediately after construction",
|
|
16
|
+
"when": "the pool completes its first ready-check",
|
|
17
|
+
"then": "all five calls resolve successfully; facadeReady fires exactly once on the event sink; no unhandled rejection is raised",
|
|
18
|
+
"testable": true,
|
|
19
|
+
"scope": "runtime"
|
|
20
|
+
}
|
|
21
|
+
],
|
|
22
|
+
"tacIds": ["TAC-2801-persistence-data-postgres-facade"],
|
|
23
|
+
"createdAt": "2026-09-06T15:47:00.000Z",
|
|
24
|
+
"updatedAt": "2026-09-06T15:47:00.000Z"
|
|
25
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"usId": "persistence-data-postgres-US-27109",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"reqId": "persistence-data-postgres-REQ-002",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "approved",
|
|
7
|
+
"title": "A failing migration rolls back its own transaction and the runner exits non-zero without advancing schema_version",
|
|
8
|
+
"asA": "operator running migrations at boot on a long-lived Node process",
|
|
9
|
+
"iWant": "a failing migration to roll back its own transaction and stop the runner with a non-zero exit and the failing filename in the diagnostic",
|
|
10
|
+
"soThat": "the runner never leaves a partially-applied migration on the database and the operator can name the failing file to un-jam the deploy",
|
|
11
|
+
"acceptanceCriteria": [
|
|
12
|
+
{
|
|
13
|
+
"id": "AC-27109-1",
|
|
14
|
+
"description": "Given a migrations directory whose second file contains an invalid SQL statement (simulated in the fixture by the SIMULATE_MIGRATION_FAILURE switch), when the migration runner runs, then the first file commits, the second file's transaction rolls back on the invalid statement, the runner exits non-zero, and the failing filename appears in the runner's diagnostic output. The schema_version bookkeeping table records only the first file's row.",
|
|
15
|
+
"given": "a Postgres at schema_version 0 and three migration files where the second is intentionally broken",
|
|
16
|
+
"when": "the migration runner applies the directory with SIMULATE_MIGRATION_FAILURE=true",
|
|
17
|
+
"then": "the first file's transaction commits and its row lands in the bookkeeping table; the second file's transaction rolls back; the runner exits non-zero with the failing filename in its stderr; the third file is not attempted; the bookkeeping table shows exactly one applied row",
|
|
18
|
+
"testable": true,
|
|
19
|
+
"scope": "runtime"
|
|
20
|
+
}
|
|
21
|
+
],
|
|
22
|
+
"tacIds": ["TAC-2802-persistence-data-postgres-migration-runner"],
|
|
23
|
+
"createdAt": "2026-09-06T15:47:00.000Z",
|
|
24
|
+
"updatedAt": "2026-09-06T15:47:00.000Z"
|
|
25
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"usId": "persistence-data-postgres-US-27110",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"reqId": "persistence-data-postgres-REQ-005",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "approved",
|
|
7
|
+
"title": "A recovery drill primes a fresh Postgres from the pg_dump artefact and the row-count and checksum match the source",
|
|
8
|
+
"asA": "operator running a recovery drill on a schedule to prove the pg_dump path works",
|
|
9
|
+
"iWant": "the drill to prime a fresh Postgres from the artefact and compare the restored dataset against the source by row-count and checksum",
|
|
10
|
+
"soThat": "the recovery path is proven end to end and drift on the artefact shape is caught before an incident forces a live restore",
|
|
11
|
+
"acceptanceCriteria": [
|
|
12
|
+
{
|
|
13
|
+
"id": "AC-27110-1",
|
|
14
|
+
"description": "Given a live Postgres with a fixture rowset and a pg_dump artefact produced by the scheduled runner, when the drill primes a fresh Postgres from the artefact and computes the row-count and checksum of the fixture table on both databases, then the row-count and checksum on the restored Postgres equal those on the source and a recoveryDrillPassed event fires on the event sink carrying the two matched values.",
|
|
15
|
+
"given": "a source Postgres seeded with a fixture rowset and a pg_dump artefact at the elicited destination",
|
|
16
|
+
"when": "the drill primes a fresh Postgres from the artefact and runs SELECT count(*) and a checksum aggregate on the fixture table against both databases",
|
|
17
|
+
"then": "the two counts are equal; the two checksums are equal; recoveryDrillPassed fires on the event sink with { count, checksum }; the fresh Postgres and its artefact primer are torn down on exit",
|
|
18
|
+
"testable": true,
|
|
19
|
+
"scope": "runtime"
|
|
20
|
+
}
|
|
21
|
+
],
|
|
22
|
+
"tacIds": ["TAC-2804-persistence-data-postgres-recovery-runner"],
|
|
23
|
+
"createdAt": "2026-09-06T15:47:00.000Z",
|
|
24
|
+
"updatedAt": "2026-09-06T15:47:00.000Z"
|
|
25
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# persistence-data-postgres blueprint coordination vocabulary
|
|
2
|
+
|
|
3
|
+
This file is the persistence-data-postgres half of the cross-blueprint contract. The Phase 1 conflict detector matches scope:global ADR topics by EXACT string equality, and AC ids are unnamespaced by the 0.4.4 grammar. Any blueprint intended to compose with this one must reuse these exact strings and respect these bands.
|
|
4
|
+
|
|
5
|
+
## Global ADR topics this blueprint contributes (exact strings)
|
|
6
|
+
|
|
7
|
+
| Topic string | persistence-data-postgres contribution | Origin | Composition note |
|
|
8
|
+
|---|---|---|---|
|
|
9
|
+
| `persistenceStore` | ADR-2801-persistence-data-postgres-driver | Reused from persistence-data-sqlite and persistence-data-d1 (both contribute the same topic string). This blueprint contributes a Postgres store on the same topic string on purpose. | The one project-wide decision on the primary durable store engine. Composing this blueprint with persistence-data-sqlite or persistence-data-d1 conflicts here by design; expected resolution is one project-level ADR that fixes the engine end to end |
|
|
10
|
+
| `migrationDiscipline` | ADR-2802-persistence-data-postgres-migration-shape | Reused from persistence-data-sqlite (boot-time forward-only runner discipline) and persistence-data-d1 (wrangler-CLI-owned deploy-pipeline discipline). This blueprint contributes numbered forward-only .sql migrations applied by an in-tree runner one file one transaction. | The one project-wide schema-evolution discipline. Composing this blueprint with persistence-data-sqlite or persistence-data-d1 conflicts here by design; expected resolution is one project-level ADR |
|
|
11
|
+
|
|
12
|
+
The persistence-data-postgres blueprint claims two global topics. Every other contribution is scope-local (ADR-2803 runner mode, ADR-2804 recovery, ADR-2805 connection-pool posture do not contribute global topics; a composing blueprint that holds an opinion on any of them authors its own project-level ADR).
|
|
13
|
+
|
|
14
|
+
Note on the round-6 reserved Hyperdrive adapter slot: the v1.0.0 facade holds the driver reference OPAQUE at ADR-2801 boundary so the round-6 v1.1.0 Hyperdrive adapter slots in as an additive minor without a topic conflict. See infra round 5 spec section 5.7 for the reserved-slot register.
|
|
15
|
+
|
|
16
|
+
Rules for new topics: lower camel case, one concept per topic, no version suffixes. A topic names the decision area, not the chosen answer.
|
|
17
|
+
|
|
18
|
+
## Id number bands (registry bootstrap)
|
|
19
|
+
|
|
20
|
+
This table is maintained shelf-wide across every blueprint's `docs/topics.md`. Rows are recorded at ship, never predicted.
|
|
21
|
+
|
|
22
|
+
| Blueprint | US band | ADR/TAC suffix block | Status | Global topics |
|
|
23
|
+
|---|---|---|---|---|
|
|
24
|
+
| application-spa | 1101-1899 | 2xx | shipped v1.3.0 | `clientRouting`, `theming`, `clientState`, `errorEnvelope`, `authModel` |
|
|
25
|
+
| application-api-rest | 2101-2899 | 3xx | shipped v1.0.0 | `errorEnvelope`, `authModel`, `apiVersioning`, `logging` |
|
|
26
|
+
| security-auth-magic-link | 3101-3899 | 5xx | shipped v1.0.0 | `authModel` |
|
|
27
|
+
| email-smtp-resend | 4101-4899 | 4xx | shipped v1.0.0 | none |
|
|
28
|
+
| hello-panel (walkthrough exemplar) | 4101-4899 | 4xx | doc-reserved; teaching exemplar in `packages/rcf-lite/docs/blueprint-authoring-walkthrough.md`, not shipped as a blueprint directory | `operatorPanel` |
|
|
29
|
+
| persistence-data-sqlite | 5101-5899 | 6xx | shipped v1.0.0 | `persistenceStore`, `migrationDiscipline` |
|
|
30
|
+
| delivery-ci-workflows | 6101-6899 | 7xx | shipped v2.0.0 (renamed from ci-pipeline) | `ciGates`, `strictCoverageGate`, `releaseArtefacts` |
|
|
31
|
+
| observability-essentials | 7101-7899 | 8xx | shipped v2.0.0 | `statusPageContract` |
|
|
32
|
+
| security-secrets-management | 8101-8899 | 9xx | shipped v1.0.1 | `secretsSource` |
|
|
33
|
+
| security-auth-clerk | 9101-9899 | 10xx | shipped v1.0.0 | `authModel` |
|
|
34
|
+
| security-auth-oauth2 | 10101-10899 | 11xx | shipped v1.0.0 | `authModel` |
|
|
35
|
+
| security-auth-keycloak | 11101-11899 | 12xx | shipped v1.0.0 | `authModel` |
|
|
36
|
+
| deploy-cloudflare-workers | 12101-12899 | 13xx | shipped v1.0.0 | `deploymentTarget` |
|
|
37
|
+
| persistence-data-d1 | 13101-13899 | 14xx | shipped v1.0.0 | `persistenceStore`, `migrationDiscipline` |
|
|
38
|
+
| observability-probe-endpoints | 14101-14899 | 15xx | shipped v1.1.0 | `healthProbes`, `readinessSemantics` |
|
|
39
|
+
| observability-logging | 15101-15899 | 16xx | shipped v1.0.0 | `logging` |
|
|
40
|
+
| application-error-handling | 16101-16899 | 17xx | shipped v1.0.0 | `errorHandling` |
|
|
41
|
+
| application-datatable | 17101-17899 | 18xx | shipped v1.0.0 | none |
|
|
42
|
+
| application-charts | 18101-18899 | 19xx | shipped v1.0.0 | none |
|
|
43
|
+
| application-dashboard | 19101-19899 | 20xx | shipped v1.0.0 | none |
|
|
44
|
+
| application-notifications-in-app | 20101-20899 | 21xx | shipped v1.0.0 | none |
|
|
45
|
+
| application-admin-console | 21101-21899 | 22xx | shipped v1.0.0 | none |
|
|
46
|
+
| application-forms-wizard | 24101-24899 | 25xx | shipped v1.0.0 | none |
|
|
47
|
+
| application-account-settings | 25101-25899 | 26xx | shipped v1.0.0 | none |
|
|
48
|
+
| application-onboarding-tour | 26101-26899 | 27xx | shipped v1.0.0 | none |
|
|
49
|
+
| persistence-data-postgres | 27101-27899 | 28xx | shipped v1.0.0 | `persistenceStore`, `migrationDiscipline` |
|
|
50
|
+
| object-storage-s3 | 28101-28899 | 29xx | shipped v1.0.0 | `objectStorageContract` |
|
|
51
|
+
|
|
52
|
+
US 27101-27110 sit at the LOW end of the 27101-27899 band on purpose (watchpost run-4 lesson). A project-side story mechanically derived from a persistence-data-postgres REQ id into the number 27110 would collide against the shipped US-27110; band headroom (27111-27899) leaves that space.
|
|
53
|
+
|
|
54
|
+
Postgres suffixes for this blueprint use the 2801-2899 block, continuing the widening pattern (persistence-data-sqlite 6xx, persistence-data-d1 14xx, and persistence-data-postgres 28xx).
|
|
55
|
+
|
|
56
|
+
## Shared expectations for future composing blueprints
|
|
57
|
+
|
|
58
|
+
- Reuse `persistenceStore` exactly as spelled here when your blueprint holds an opinion on the project's primary durable store engine; contribute your own scope:global ADR on that string and let composition surface the pairing.
|
|
59
|
+
- Reuse `migrationDiscipline` exactly as spelled here when your blueprint holds an opinion on schema evolution.
|
|
60
|
+
- Round-6 reserved slot: the Hyperdrive adapter inside `persistence-data-postgres` v1.1.0 wraps the same facade contract with the Cloudflare Hyperdrive connection-pool and query-cache surface. No topic conflict, no facade re-shape; the driver reference is opaque at the ADR-2801 boundary.
|
|
61
|
+
|
|
62
|
+
## Deliberate-conflict statement
|
|
63
|
+
|
|
64
|
+
This blueprint's ADR-2801 on `persistenceStore` and ADR-2802 on `migrationDiscipline` are a Postgres-committed vendor sibling to persistence-data-sqlite (ADR-601, ADR-602) and persistence-data-d1 (ADR-1401, ADR-1402) on the same two topic strings. Applying two of the three on one project raises two `globalAdrTopic` conflicts the operator resolves via one of the four documented resolutions per topic (adopt one, keep the existing one, author a project-level supersede ADR, or `--resolve <topic>=project:<ADR-id>` on the add).
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# persistence-data-postgres guide
|
|
2
|
+
|
|
3
|
+
## What this blueprint gets you
|
|
4
|
+
|
|
5
|
+
Postgres as your project's primary durable relational store on any server-tier deployment (a long-lived Node process, a container platform, a non-Workers serverless target). The store facade is the sole reader of the `pg` (node-postgres) client in your source tree; consumer code calls named domain verbs on the facade and never touches `pg` directly. Schema evolution is numbered forward-only `.sql` files applied one file per transaction; a `schema_version` bookkeeping table is the single source of truth on what has been applied. Multi-statement writes with atomicity go through a transaction helper that wraps `BEGIN` and `COMMIT` around a callback and rolls back on any error. Recovery is two-path: a scheduled `pg_dump` artefact plus the deploy target's own point-in-time recovery. The v1.0.0 facade holds the driver reference opaque at the ADR-2801 boundary so the round-6 Hyperdrive v1.1.0 adapter slots in as an additive minor without a facade re-shape.
|
|
6
|
+
|
|
7
|
+
## Apply this blueprint
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
rcf define blueprint add persistence-data-postgres
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
On a fresh project this applies cleanly. On a project that already applied `persistence-data-sqlite` or `persistence-data-d1`, `rcf define blueprint add persistence-data-postgres` surfaces a DELIBERATE conflict on the `persistenceStore` and `migrationDiscipline` global-ADR topics. Resolve with one project-level ADR per topic; the operator picks the engine end to end.
|
|
14
|
+
|
|
15
|
+
## Facade shape
|
|
16
|
+
|
|
17
|
+
```js
|
|
18
|
+
import { createStore } from './store.mjs';
|
|
19
|
+
|
|
20
|
+
const store = createStore({
|
|
21
|
+
connectionUrl: process.env.DATABASE_URL,
|
|
22
|
+
onEvent: (evt) => logger.info(evt),
|
|
23
|
+
poolConfig: { max: 10 },
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
await store.ready();
|
|
27
|
+
const id = await store.createUser('alice', 'alice@example.com');
|
|
28
|
+
const row = await store.getUserById(id);
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
The facade opens a `pg.Pool` against the elicited connection URL and emits `facadeReady` exactly once on the first successful ready-check. Every `.query` call passes a static string literal as its first argument with parameters as `$1, $2, ... $N` per the node-postgres parameterised-queries contract at https://node-postgres.com/features/queries. Consumers destructure the verbs they need at their top level and hold the facade reference for the process lifetime (or, on a request-scoped container platform, for the request lifetime).
|
|
32
|
+
|
|
33
|
+
## Migrations
|
|
34
|
+
|
|
35
|
+
Numbered forward-only `.sql` files under an elicited `migrations/` directory. Each filename begins with a monotonic integer (`001_...`, `002_...`, `003_...`); the file body is engine-native SQL. The in-tree runner (TAC-2802) applies each file inside its own transaction and records the applied filename in `schema_version`.
|
|
36
|
+
|
|
37
|
+
```sh
|
|
38
|
+
node src/migrate.mjs
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Which runner tool the project reaches for is elicited on ADR-2802 (bespoke Node runner is the shipped default; `node-pg-migrate`, `sqitch`, and `flyway` are named alternatives). Every runner honours the same discipline: numbered forward-only files, one file one transaction, a `schema_version` bookkeeping row per applied file.
|
|
42
|
+
|
|
43
|
+
Runner mode is elicited on ADR-2803:
|
|
44
|
+
|
|
45
|
+
- `atBoot` (default for long-lived Node): the facade invokes the runner on process start before opening the first query.
|
|
46
|
+
- `ciStep` (default for Workers-adjacent or request-scoped container targets): the CI pipeline invokes the runner as a deploy step against the target's own connection before the artefact promotes.
|
|
47
|
+
|
|
48
|
+
## Transactions
|
|
49
|
+
|
|
50
|
+
```js
|
|
51
|
+
await store.withTransaction(async (tx) => {
|
|
52
|
+
await tx.query('INSERT INTO orders(user_id, total) VALUES ($1, $2)', [userId, total]);
|
|
53
|
+
await tx.query('INSERT INTO order_lines(order_id, sku, qty) VALUES ($1, $2, $3)', [orderId, sku, qty]);
|
|
54
|
+
});
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
The helper wraps `BEGIN` and `COMMIT` around the callback. If any statement throws, the helper issues `ROLLBACK`, fires `transactionRolledBack` with the failing statement's zero-based index and the pg error code, and re-throws the underlying error. No partial commit lands on the shipped database.
|
|
58
|
+
|
|
59
|
+
## Recovery
|
|
60
|
+
|
|
61
|
+
Two paths, both required:
|
|
62
|
+
|
|
63
|
+
```js
|
|
64
|
+
import { exportDatabase, recoveryDrill } from './recovery.mjs';
|
|
65
|
+
|
|
66
|
+
const { artefactPath, completedAt } = await exportDatabase({
|
|
67
|
+
connectionUrl: process.env.DATABASE_URL,
|
|
68
|
+
destination: process.env.BACKUP_DESTINATION,
|
|
69
|
+
onEvent: (evt) => logger.info(evt),
|
|
70
|
+
});
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Scheduled `pg_dump` runs on your project's cadence (an elicited cron string, a systemd timer spec, or off for CI-only invocation); the runner writes the artefact via `child_process.execFile` and emits `backupExported` on completion. The deploy target's own point-in-time recovery is enabled with an elicited retention window; on a managed cluster, the window is the cluster's PITR setting; on a self-managed cluster, the WAL-archive retention.
|
|
74
|
+
|
|
75
|
+
Run a periodic recovery drill (US-27110):
|
|
76
|
+
|
|
77
|
+
```js
|
|
78
|
+
const { count, checksum } = await recoveryDrill({
|
|
79
|
+
sourceUrl: process.env.DATABASE_URL,
|
|
80
|
+
destination: process.env.BACKUP_DESTINATION,
|
|
81
|
+
onEvent: (evt) => logger.info(evt),
|
|
82
|
+
});
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
The drill primes a fresh Postgres from the artefact and compares row-count and checksum on a fixture table on both databases; a mismatch signals artefact-shape drift before an incident forces a live restore.
|
|
86
|
+
|
|
87
|
+
## Pool posture per deploy target
|
|
88
|
+
|
|
89
|
+
Elicited on ADR-2805:
|
|
90
|
+
|
|
91
|
+
- `longLivedNode` (default): long-lived `pg.Pool` for the process lifetime; shipped defaults pool size 10, `idleTimeoutMillis 30000`, `connectionTimeoutMillis 5000`.
|
|
92
|
+
- `requestScopedContainer`: a pool sized to the request budget, disposed at request end; shipped defaults pool size 2, `idleTimeoutMillis 5000`, `connectionTimeoutMillis 3000`.
|
|
93
|
+
- `hyperdriveManaged` (reserved for the round-6 v1.1.0 adapter): inherits Hyperdrive's own pool settings and holds no Node-side pool.
|
|
94
|
+
|
|
95
|
+
Every default is overridable by the operator via elicited pool-config fields at apply time.
|
|
96
|
+
|
|
97
|
+
## Advisory-lock helper (optional)
|
|
98
|
+
|
|
99
|
+
Elicited on REQ-007 default `off`. When enabled to `session` or `transaction`, the facade exposes `withAdvisoryLock(key, callback)` that acquires and releases a session-level (via `pg_advisory_lock` / `pg_advisory_unlock`) or transaction-level (via `pg_advisory_xact_lock`; released automatically at COMMIT or ROLLBACK) lock per https://www.postgresql.org/docs/current/explicit-locking.html.
|
|
100
|
+
|
|
101
|
+
Session-level locks survive rolled-back transactions; use `transaction` for the common case and pick `session` only when cross-transaction locking is the intent.
|
|
102
|
+
|
|
103
|
+
## CI seam (GitHub Actions service containers)
|
|
104
|
+
|
|
105
|
+
Add a `services:` block declaring `postgres:17-alpine` to your workflow. Per https://docs.github.com/en/actions/using-containerized-services/about-service-containers, the runner exposes the service either at the label hostname (for container-hosted jobs) or at the mapped port (for host-runner jobs); both patterns are supported.
|
|
106
|
+
|
|
107
|
+
Container-hosted job (hostname exposure):
|
|
108
|
+
|
|
109
|
+
```yaml
|
|
110
|
+
jobs:
|
|
111
|
+
postgres-integration:
|
|
112
|
+
runs-on: ubuntu-latest
|
|
113
|
+
container: node:24
|
|
114
|
+
services:
|
|
115
|
+
postgres:
|
|
116
|
+
image: postgres:17-alpine
|
|
117
|
+
env:
|
|
118
|
+
POSTGRES_USER: rcf
|
|
119
|
+
POSTGRES_PASSWORD: rcf-dev-only
|
|
120
|
+
POSTGRES_DB: rcf_test
|
|
121
|
+
options: >-
|
|
122
|
+
--health-cmd "pg_isready -U rcf -d rcf_test"
|
|
123
|
+
--health-interval 2s
|
|
124
|
+
--health-timeout 3s
|
|
125
|
+
--health-retries 20
|
|
126
|
+
steps:
|
|
127
|
+
- uses: actions/checkout@v4
|
|
128
|
+
- run: pnpm install --frozen-lockfile
|
|
129
|
+
- run: node src/migrate.mjs
|
|
130
|
+
env:
|
|
131
|
+
DATABASE_URL: postgres://rcf:rcf-dev-only@postgres:5432/rcf_test
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Host-runner job (port mapping):
|
|
135
|
+
|
|
136
|
+
```yaml
|
|
137
|
+
jobs:
|
|
138
|
+
postgres-integration:
|
|
139
|
+
runs-on: ubuntu-latest
|
|
140
|
+
services:
|
|
141
|
+
postgres:
|
|
142
|
+
image: postgres:17-alpine
|
|
143
|
+
env:
|
|
144
|
+
POSTGRES_USER: rcf
|
|
145
|
+
POSTGRES_PASSWORD: rcf-dev-only
|
|
146
|
+
POSTGRES_DB: rcf_test
|
|
147
|
+
ports:
|
|
148
|
+
- 5432:5432
|
|
149
|
+
options: >-
|
|
150
|
+
--health-cmd "pg_isready -U rcf -d rcf_test"
|
|
151
|
+
--health-interval 2s
|
|
152
|
+
--health-timeout 3s
|
|
153
|
+
--health-retries 20
|
|
154
|
+
steps:
|
|
155
|
+
- uses: actions/checkout@v4
|
|
156
|
+
- uses: actions/setup-node@v4
|
|
157
|
+
with:
|
|
158
|
+
node-version: 24
|
|
159
|
+
- run: pnpm install --frozen-lockfile
|
|
160
|
+
- run: node src/migrate.mjs
|
|
161
|
+
env:
|
|
162
|
+
DATABASE_URL: postgres://rcf:rcf-dev-only@localhost:5432/rcf_test
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Adding this seam is the applying project's concern per `delivery-ci-workflows` v2.2.0. The `delivery-ci-workflows` blueprint's alternate-provider four-point mapping (job trigger, Node setup, entry-point invocation, artefact upload) covers non-GHA CI targets against the same `postgres:17-alpine` image.
|
|
166
|
+
|
|
167
|
+
## What this blueprint does not do
|
|
168
|
+
|
|
169
|
+
- It does not choose an ORM. Kysely, Drizzle, Prisma, or your team's own module sits inside the facade at operator choice; the outward interface stays orm-neutral.
|
|
170
|
+
- It does not build the Hyperdrive adapter. That is a round-6 v1.1.0 additive minor; the v1.0.0 facade holds the driver reference opaque at ADR-2801 so the minor slots in without a facade re-shape.
|
|
171
|
+
- It does not schedule the recovery runner. Cadence is elicited (a project-side cron string, a systemd timer, or off for CI-only); a project-side scheduler invokes `exportDatabase`.
|
|
172
|
+
- It does not choose a migration tool. Numbered forward-only `.sql` files with one file one transaction is the discipline; the tool is elicited.
|
|
@@ -31,7 +31,7 @@ This table is maintained shelf-wide across every blueprint's `docs/topics.md`. R
|
|
|
31
31
|
| persistence-data-sqlite | 5101-5899 | 6xx | shipped v1.0.0 | `persistenceStore`, `migrationDiscipline` |
|
|
32
32
|
| delivery-ci-workflows | 6101-6899 | 7xx | shipped v2.0.0 (renamed from ci-pipeline) | `ciGates`, `strictCoverageGate`, `releaseArtefacts` |
|
|
33
33
|
| observability-essentials | 7101-7899 | 8xx | shipped v2.0.0 | `statusPageContract` |
|
|
34
|
-
| security-secrets-management | 8101-8899 | 9xx | shipped v1.0.
|
|
34
|
+
| security-secrets-management | 8101-8899 | 9xx | shipped v1.0.1 | `secretsSource` |
|
|
35
35
|
| security-auth-clerk | 9101-9899 | 10xx | shipped v1.0.0 | `authModel` |
|
|
36
36
|
| security-auth-oauth2 | 10101-10899 | 11xx | shipped v1.0.0 | `authModel` |
|
|
37
37
|
| security-auth-keycloak | 11101-11899 | 12xx | shipped v1.0.0 | `authModel` |
|
|
@@ -43,6 +43,13 @@ This table is maintained shelf-wide across every blueprint's `docs/topics.md`. R
|
|
|
43
43
|
| application-dashboard | 19101-19899 | 20xx | shipped v1.0.0 | none |
|
|
44
44
|
| application-notifications-in-app | 20101-20899 | 21xx | shipped v1.0.0 | none |
|
|
45
45
|
| application-admin-console | 21101-21899 | 22xx | shipped v1.0.0 | none |
|
|
46
|
+
| application-empty-error-states | 22101-22899 | 23xx | shipped v1.0.0 | none |
|
|
47
|
+
| application-file-upload | 23101-23899 | 24xx | shipped v1.0.0 | none |
|
|
48
|
+
| application-forms-wizard | 24101-24899 | 25xx | shipped v1.0.0 | none |
|
|
49
|
+
| application-account-settings | 25101-25899 | 26xx | shipped v1.0.0 | none |
|
|
50
|
+
| application-onboarding-tour | 26101-26899 | 27xx | shipped v1.0.0 | none |
|
|
51
|
+
| persistence-data-postgres | 27101-27899 | 28xx | shipped v1.0.0 | `persistenceStore`, `migrationDiscipline` |
|
|
52
|
+
| object-storage-s3 | 28101-28899 | 29xx | shipped v1.0.0 | `objectStorageContract` |
|
|
46
53
|
|
|
47
54
|
US 5101-5111 sit at the LOW end of the 5101-5899 band on purpose. A project-side story that mechanically derives from `persistence-data-sqlite-REQ-011` into the number `5111` would collide against persistence-data-sqlite-US-5111 in this package; the band leaves headroom at the HIGH end (US 5181-5899) so a project's own stories anchored to persistence-data-sqlite REQs can allocate without conflict. The watchpost run4 lesson applies here too.
|
|
48
55
|
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# security-auth-clerk CHANGELOG
|
|
2
2
|
|
|
3
|
+
## 1.3.0 (visual round T-4, spec 2026-09-06 section 5.4.2, Baz Q2 default)
|
|
4
|
+
|
|
5
|
+
- Declares `capabilities: [principalDirectory, roleModel, sessionInventory, hostedIdentityUi]` on `blueprint.json`. Additive per section 6 of `blueprint-authoring.md` (an additive optional field with no global-topic change is a minor bump). Consumed at apply time by the visual round T-4 `application-account-settings` blueprint to gate the sessions surface (probe pack check `AC-25106-1`) and the security surface hosted-UI branch (`AC-25105-1`). Clerk exposes an inventory of active sessions with device labels and a terminate action, and hosts identity screens (sign-in, sign-up, account, security) that a link-out or embed can consume.
|
|
6
|
+
|
|
3
7
|
## 1.2.0 (visual round T-5, spec 2026-09-04 section 5.5.2, Baz Q2 default)
|
|
4
8
|
|
|
5
9
|
- Declares `capabilities: [principalDirectory, roleModel]` on `blueprint.json`. No other change. The new field is additive per section 6 of `blueprint-authoring.md` (an additive optional field with no global-topic change is a minor bump), and it is consumed by the visual round T-5 `application-admin-console` blueprint at apply time to gate surfaces on what the applied identity blueprint actually provides.
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
The tenth content blueprint on the rcf-build-lite blueprint mechanism, category `security`. A Clerk-committed sibling to `security-auth-magic-link` on the `authModel` global topic: Clerk hosts the identity surface (users, sessions, sign-in UX, credential storage, MFA, account recovery); the project owns a framework-agnostic middleware boundary, a session verifier confined to one module, a Clerk-claim-to-project-verb authorisation adapter, and a reduced principal shape the rest of the codebase reasons against. Targeted at small greenfield rcf-lite projects that want hosted identity without building the user-and-session surface themselves; larger deployments supersede the vendor by superseding ADR-1001 with a project-level ADR and swapping the middleware and verifier adapters.
|
|
4
4
|
|
|
5
|
+
|
|
6
|
+
> Latest: **v1.3.0** (visual round T-4, 2026-09-06). `capabilities: [principalDirectory, roleModel, sessionInventory, hostedIdentityUi]`. See [CHANGELOG.md](CHANGELOG.md).
|
|
7
|
+
|
|
5
8
|
## Apply
|
|
6
9
|
|
|
7
10
|
```
|