@openlup/platform 0.28.0 → 0.30.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 +369 -156
- package/README.md +220 -4
- package/dist/composition/index.d.ts +1 -0
- package/dist/composition/index.js +1 -0
- package/dist/composition/marketingContribution.d.ts +21 -0
- package/dist/composition/marketingContribution.js +29 -0
- package/dist/composition/nodeHost.d.ts +1 -1
- package/dist/composition/nodeHost.js +3 -2
- package/dist/lifecycle/appUpgrade.d.ts +52 -0
- package/dist/lifecycle/appUpgrade.js +180 -0
- package/dist/lifecycle/index.d.ts +2 -0
- package/dist/lifecycle/index.js +2 -0
- package/dist/lifecycle/postgresInstallQualification.d.ts +51 -0
- package/dist/lifecycle/postgresInstallQualification.js +74 -0
- package/dist/marketing/acquisitionCaseSchemas.d.ts +103 -0
- package/dist/marketing/acquisitionCaseSchemas.js +53 -0
- package/dist/marketing/acquisitionEvidenceSchemas.d.ts +105 -0
- package/dist/marketing/acquisitionEvidenceSchemas.js +55 -0
- package/dist/marketing/analytics/dataLayer.d.ts +18 -0
- package/dist/marketing/analytics/dataLayer.js +111 -0
- package/dist/marketing/analytics/noop.d.ts +9 -0
- package/dist/marketing/analytics/noop.js +8 -0
- package/dist/marketing/analytics/purchaseFacts.d.ts +4 -0
- package/dist/marketing/analytics/purchaseFacts.js +69 -0
- package/dist/marketing/analytics/routePolicy.d.ts +10 -0
- package/dist/marketing/analytics/routePolicy.js +59 -0
- package/dist/marketing/consentEvidence.d.ts +8 -0
- package/dist/marketing/consentEvidence.js +32 -0
- package/dist/marketing/contactLegal.d.ts +14 -0
- package/dist/marketing/contactLegal.js +19 -0
- package/dist/marketing/contracts/acquisition.d.ts +88 -0
- package/dist/marketing/contracts/acquisition.js +1 -0
- package/dist/marketing/contracts/acquisitionPorts.d.ts +49 -0
- package/dist/marketing/contracts/acquisitionPorts.js +1 -0
- package/dist/marketing/contracts/analytics.d.ts +144 -0
- package/dist/marketing/contracts/analytics.js +1 -0
- package/dist/marketing/contracts/contactLegal.d.ts +53 -0
- package/dist/marketing/contracts/contactLegal.js +1 -0
- package/dist/marketing/contracts/index.d.ts +6 -0
- package/dist/marketing/contracts/index.js +1 -0
- package/dist/marketing/contracts/prelaunch.d.ts +39 -0
- package/dist/marketing/contracts/prelaunch.js +1 -0
- package/dist/marketing/index.d.ts +16 -0
- package/dist/marketing/index.js +14 -0
- package/dist/marketing/prelaunchAcquisitionSchemas.d.ts +116 -0
- package/dist/marketing/prelaunchAcquisitionSchemas.js +51 -0
- package/dist/marketing/seo/jsonLd.d.ts +157 -0
- package/dist/marketing/seo/jsonLd.js +127 -0
- package/dist/marketing/seo/metadata.d.ts +41 -0
- package/dist/marketing/seo/metadata.js +36 -0
- package/dist/marketing/seo/serializeJsonLd.d.ts +1 -0
- package/dist/marketing/seo/serializeJsonLd.js +6 -0
- package/dist/marketing/seo/urls.d.ts +14 -0
- package/dist/marketing/seo/urls.js +23 -0
- package/dist/marketing/server/acquisitionCaseDirect.d.ts +4 -0
- package/dist/marketing/server/acquisitionCaseDirect.js +88 -0
- package/dist/marketing/server/acquisitionCaseHandlers.d.ts +28 -0
- package/dist/marketing/server/acquisitionCaseHandlers.js +40 -0
- package/dist/marketing/server/acquisitionCasePorts.d.ts +42 -0
- package/dist/marketing/server/acquisitionCasePorts.js +1 -0
- package/dist/marketing/server/acquisitionEvidenceDirect.d.ts +5 -0
- package/dist/marketing/server/acquisitionEvidenceDirect.js +100 -0
- package/dist/marketing/server/analyticsContext.d.ts +3 -0
- package/dist/marketing/server/analyticsContext.js +65 -0
- package/dist/marketing/server/analyticsContextPorts.d.ts +31 -0
- package/dist/marketing/server/analyticsContextPorts.js +1 -0
- package/dist/marketing/server/bindings.d.ts +14 -0
- package/dist/marketing/server/bindings.js +18 -0
- package/dist/marketing/server/directPorts.d.ts +26 -0
- package/dist/marketing/server/directPorts.js +1 -0
- package/dist/marketing/server/index.d.ts +14 -0
- package/dist/marketing/server/index.js +11 -0
- package/dist/marketing/server/postgres/acquisitionCaseRoutines.d.ts +10 -0
- package/dist/marketing/server/postgres/acquisitionCaseRoutines.js +204 -0
- package/dist/marketing/server/postgres/acquisitionEvidenceRoutines.d.ts +10 -0
- package/dist/marketing/server/postgres/acquisitionEvidenceRoutines.js +107 -0
- package/dist/marketing/server/postgres/index.d.ts +3 -0
- package/dist/marketing/server/postgres/index.js +3 -0
- package/dist/marketing/server/prelaunchAcquisitionDirect.d.ts +4 -0
- package/dist/marketing/server/prelaunchAcquisitionDirect.js +122 -0
- package/dist/marketing/server/privacyContributor.d.ts +66 -0
- package/dist/marketing/server/privacyContributor.js +87 -0
- package/dist/marketing/server/research/adminSurveyResponsesHandler.d.ts +9 -0
- package/dist/marketing/server/research/adminSurveyResponsesHandler.js +53 -0
- package/dist/marketing/server/research/managedSurveyResponseSubmit.d.ts +39 -0
- package/dist/marketing/server/research/managedSurveyResponseSubmit.js +102 -0
- package/dist/marketing/server/research/surveyResponseSubmitHandler.d.ts +8 -0
- package/dist/marketing/server/research/surveyResponseSubmitHandler.js +41 -0
- package/dist/marketing/validation.d.ts +2 -0
- package/dist/marketing/validation.js +3 -0
- package/dist/migrations/postgresRunner.d.ts +9 -0
- package/dist/migrations/postgresRunner.js +17 -10
- package/dist/operations/adminAlertsSchemas.d.ts +153 -0
- package/dist/operations/adminAlertsSchemas.js +69 -0
- package/dist/operations/adminAlertsView.d.ts +73 -0
- package/dist/operations/adminAlertsView.js +184 -0
- package/dist/operations/alertPagingPolicy.d.ts +15 -0
- package/dist/operations/alertPagingPolicy.js +43 -0
- package/dist/operations/alertThrottlePolicy.d.ts +3 -0
- package/dist/operations/alertThrottlePolicy.js +18 -0
- package/dist/operations/clients.d.ts +17 -0
- package/dist/operations/clients.js +32 -0
- package/dist/operations/contracts/admin.d.ts +93 -0
- package/dist/operations/contracts/admin.js +1 -0
- package/dist/operations/contracts/adminAlertsContracts.d.ts +40 -0
- package/dist/operations/contracts/adminAlertsContracts.js +1 -0
- package/dist/operations/contracts/alertHumanContext.d.ts +7 -0
- package/dist/operations/contracts/alertHumanContext.js +1 -0
- package/dist/operations/contracts/index.d.ts +6 -0
- package/dist/operations/contracts/index.js +6 -0
- package/dist/operations/contracts/observabilityContracts.d.ts +41 -0
- package/dist/operations/contracts/observabilityContracts.js +1 -0
- package/dist/operations/contracts/observabilityPorts.d.ts +18 -0
- package/dist/operations/contracts/observabilityPorts.js +1 -0
- package/dist/operations/contracts/ports.d.ts +19 -0
- package/dist/operations/contracts/ports.js +1 -0
- package/dist/operations/errors.d.ts +6 -0
- package/dist/operations/errors.js +6 -0
- package/dist/operations/index.d.ts +9 -0
- package/dist/operations/index.js +9 -0
- package/dist/operations/schemas.d.ts +138 -0
- package/dist/operations/schemas.js +104 -0
- package/dist/operations/server/adminAlertsHandlers.d.ts +16 -0
- package/dist/operations/server/adminAlertsHandlers.js +35 -0
- package/dist/operations/server/adminPipelineHandlers.d.ts +12 -0
- package/dist/operations/server/adminPipelineHandlers.js +48 -0
- package/dist/operations/server/adminSettingsHandlers.d.ts +14 -0
- package/dist/operations/server/adminSettingsHandlers.js +82 -0
- package/dist/operations/server/controlPlaneHandler.d.ts +7 -0
- package/dist/operations/server/controlPlaneHandler.js +54 -0
- package/dist/operations/server/controlPlaneStore.d.ts +12 -0
- package/dist/operations/server/controlPlaneStore.js +138 -0
- package/dist/operations/server/controlPlaneWatchdog.d.ts +7 -0
- package/dist/operations/server/controlPlaneWatchdog.js +20 -0
- package/dist/operations/server/index.d.ts +12 -0
- package/dist/operations/server/index.js +12 -0
- package/dist/operations/server/migrations.d.ts +14 -0
- package/dist/operations/server/migrations.js +7 -0
- package/dist/operations/server/platformWatchdogDecision.d.ts +34 -0
- package/dist/operations/server/platformWatchdogDecision.js +71 -0
- package/dist/operations/server/platformWatchdogDeliveryPolicy.d.ts +10 -0
- package/dist/operations/server/platformWatchdogDeliveryPolicy.js +53 -0
- package/dist/operations/server/platformWatchdogQueue.d.ts +11 -0
- package/dist/operations/server/platformWatchdogQueue.js +94 -0
- package/dist/operations/server/platformWatchdogService.d.ts +47 -0
- package/dist/operations/server/platformWatchdogService.js +105 -0
- package/dist/operations/validation.d.ts +2 -0
- package/dist/operations/validation.js +3 -0
- package/dist/portability/filesystemObjects.d.ts +12 -0
- package/dist/portability/filesystemObjects.js +191 -0
- package/dist/portability/index.d.ts +5 -0
- package/dist/portability/index.js +4 -0
- package/dist/portability/objects.d.ts +63 -0
- package/dist/portability/objects.js +138 -0
- package/dist/portability/postgresRows.d.ts +64 -0
- package/dist/portability/postgresRows.js +182 -0
- package/dist/scheduler/advisoryLock.js +20 -2
- package/dist/scheduler/nodeScheduler.d.ts +2 -2
- package/dist/scheduler/nodeScheduler.js +35 -6
- package/package.json +47 -2
- package/release-gates.json +143 -9
- package/sql/20260814010000_platform_control_plane.sql +286 -0
- package/src/composition/index.ts +1 -0
- package/src/composition/marketingContribution.ts +37 -0
- package/src/composition/nodeHost.ts +4 -3
- package/src/lifecycle/appUpgrade.ts +186 -0
- package/src/lifecycle/index.ts +19 -0
- package/src/lifecycle/postgresInstallQualification.ts +125 -0
- package/src/marketing/acquisitionCaseSchemas.ts +75 -0
- package/src/marketing/acquisitionEvidenceSchemas.ts +72 -0
- package/src/marketing/analytics/dataLayer.ts +100 -0
- package/src/marketing/analytics/noop.ts +14 -0
- package/src/marketing/analytics/purchaseFacts.ts +63 -0
- package/src/marketing/analytics/routePolicy.ts +55 -0
- package/src/marketing/consentEvidence.ts +36 -0
- package/src/marketing/contactLegal.ts +22 -0
- package/src/marketing/contracts/acquisition.ts +50 -0
- package/src/marketing/contracts/acquisitionPorts.ts +48 -0
- package/src/marketing/contracts/analytics.ts +88 -0
- package/src/marketing/contracts/contactLegal.ts +41 -0
- package/src/marketing/contracts/index.ts +17 -0
- package/src/marketing/contracts/prelaunch.ts +15 -0
- package/src/marketing/index.ts +16 -0
- package/src/marketing/prelaunchAcquisitionSchemas.ts +64 -0
- package/src/marketing/seo/jsonLd.ts +153 -0
- package/src/marketing/seo/metadata.ts +62 -0
- package/src/marketing/seo/serializeJsonLd.ts +6 -0
- package/src/marketing/seo/urls.ts +34 -0
- package/src/marketing/server/acquisitionCaseDirect.ts +67 -0
- package/src/marketing/server/acquisitionCaseHandlers.ts +57 -0
- package/src/marketing/server/acquisitionCasePorts.ts +42 -0
- package/src/marketing/server/acquisitionEvidenceDirect.ts +76 -0
- package/src/marketing/server/analyticsContext.ts +55 -0
- package/src/marketing/server/analyticsContextPorts.ts +28 -0
- package/src/marketing/server/bindings.ts +27 -0
- package/src/marketing/server/directPorts.ts +27 -0
- package/src/marketing/server/index.ts +14 -0
- package/src/marketing/server/postgres/acquisitionCaseRoutines.ts +218 -0
- package/src/marketing/server/postgres/acquisitionEvidenceRoutines.ts +103 -0
- package/src/marketing/server/postgres/index.ts +3 -0
- package/src/marketing/server/prelaunchAcquisitionDirect.ts +121 -0
- package/src/marketing/server/privacyContributor.ts +123 -0
- package/src/marketing/server/research/adminSurveyResponsesHandler.ts +78 -0
- package/src/marketing/server/research/managedSurveyResponseSubmit.ts +158 -0
- package/src/marketing/server/research/surveyResponseSubmitHandler.ts +57 -0
- package/src/marketing/validation.ts +3 -0
- package/src/migrations/postgresRunner.ts +24 -9
- package/src/operations/adminAlertsSchemas.ts +78 -0
- package/src/operations/adminAlertsView.ts +238 -0
- package/src/operations/alertPagingPolicy.ts +50 -0
- package/src/operations/alertThrottlePolicy.ts +22 -0
- package/src/operations/clients.ts +44 -0
- package/src/operations/contracts/admin.ts +24 -0
- package/src/operations/contracts/adminAlertsContracts.ts +13 -0
- package/src/operations/contracts/alertHumanContext.ts +17 -0
- package/src/operations/contracts/index.ts +6 -0
- package/src/operations/contracts/observabilityContracts.ts +40 -0
- package/src/operations/contracts/observabilityPorts.ts +30 -0
- package/src/operations/contracts/ports.ts +22 -0
- package/src/operations/errors.ts +6 -0
- package/src/operations/index.ts +9 -0
- package/src/operations/schemas.ts +122 -0
- package/src/operations/server/adminAlertsHandlers.ts +61 -0
- package/src/operations/server/adminPipelineHandlers.ts +73 -0
- package/src/operations/server/adminSettingsHandlers.ts +114 -0
- package/src/operations/server/controlPlaneHandler.ts +56 -0
- package/src/operations/server/controlPlaneStore.ts +150 -0
- package/src/operations/server/controlPlaneWatchdog.ts +28 -0
- package/src/operations/server/index.ts +12 -0
- package/src/operations/server/migrations.ts +7 -0
- package/src/operations/server/platformWatchdogDecision.ts +93 -0
- package/src/operations/server/platformWatchdogDeliveryPolicy.ts +92 -0
- package/src/operations/server/platformWatchdogQueue.ts +96 -0
- package/src/operations/server/platformWatchdogService.ts +209 -0
- package/src/operations/validation.ts +3 -0
- package/src/portability/filesystemObjects.ts +138 -0
- package/src/portability/index.ts +12 -0
- package/src/portability/objects.ts +160 -0
- package/src/portability/postgresRows.ts +169 -0
- package/src/scheduler/advisoryLock.ts +20 -5
- package/src/scheduler/nodeScheduler.ts +28 -8
package/release-gates.json
CHANGED
|
@@ -599,23 +599,154 @@
|
|
|
599
599
|
],
|
|
600
600
|
"entrypoint": "dist/account-support/contracts/index.d.ts",
|
|
601
601
|
"snapshot": "api/account-support-contracts.api.md"
|
|
602
|
+
},
|
|
603
|
+
"./operations": {
|
|
604
|
+
"role": "capability",
|
|
605
|
+
"maturity": "experimental",
|
|
606
|
+
"compatibilityPolicy": "internal-candidate",
|
|
607
|
+
"packageSmokeEvidence": [
|
|
608
|
+
"test/packageBoundary.test.ts",
|
|
609
|
+
"test/operations/controlPlaneHandler.test.ts",
|
|
610
|
+
"test/operations/platformWatchdogService.test.ts",
|
|
611
|
+
"test/operations/adminAlertsView.test.ts"
|
|
612
|
+
],
|
|
613
|
+
"entrypoint": "dist/operations/index.d.ts",
|
|
614
|
+
"snapshot": "api/operations.api.md"
|
|
615
|
+
},
|
|
616
|
+
"./operations/contracts": {
|
|
617
|
+
"role": "capability",
|
|
618
|
+
"maturity": "experimental",
|
|
619
|
+
"compatibilityPolicy": "internal-candidate",
|
|
620
|
+
"packageSmokeEvidence": [
|
|
621
|
+
"test/packageBoundary.test.ts",
|
|
622
|
+
"test/operations/controlPlaneHandler.test.ts",
|
|
623
|
+
"test/operations/platformWatchdogService.test.ts",
|
|
624
|
+
"test/operations/adminAlertsView.test.ts"
|
|
625
|
+
],
|
|
626
|
+
"entrypoint": "dist/operations/contracts/index.d.ts",
|
|
627
|
+
"snapshot": "api/operations-contracts.api.md"
|
|
628
|
+
},
|
|
629
|
+
"./operations/server": {
|
|
630
|
+
"role": "capability",
|
|
631
|
+
"maturity": "experimental",
|
|
632
|
+
"compatibilityPolicy": "internal-candidate",
|
|
633
|
+
"packageSmokeEvidence": [
|
|
634
|
+
"test/packageBoundary.test.ts",
|
|
635
|
+
"test/operations/controlPlaneHandler.test.ts",
|
|
636
|
+
"test/operations/platformWatchdogService.test.ts",
|
|
637
|
+
"test/operations/adminAlertsView.test.ts"
|
|
638
|
+
],
|
|
639
|
+
"entrypoint": "dist/operations/server/index.d.ts",
|
|
640
|
+
"snapshot": "api/operations-server.api.md"
|
|
641
|
+
},
|
|
642
|
+
"./marketing": {
|
|
643
|
+
"role": "capability",
|
|
644
|
+
"maturity": "experimental",
|
|
645
|
+
"compatibilityPolicy": "internal-candidate",
|
|
646
|
+
"packageSmokeEvidence": [
|
|
647
|
+
"test/packageBoundary.test.ts",
|
|
648
|
+
"test/marketing/schemas.test.ts",
|
|
649
|
+
"test/marketing/contracts.test.ts",
|
|
650
|
+
"test/marketing/browserBoundary.test.ts",
|
|
651
|
+
"test/marketing/noop.test.ts",
|
|
652
|
+
"test/marketing/dataLayer.test.ts",
|
|
653
|
+
"test/marketing/routePolicy.test.ts",
|
|
654
|
+
"test/marketing/purchaseFacts.test.ts",
|
|
655
|
+
"test/marketing/consentEvidence.test.ts"
|
|
656
|
+
],
|
|
657
|
+
"entrypoint": "dist/marketing/index.d.ts",
|
|
658
|
+
"snapshot": "api/marketing.api.md"
|
|
659
|
+
},
|
|
660
|
+
"./marketing/contracts": {
|
|
661
|
+
"role": "capability",
|
|
662
|
+
"maturity": "experimental",
|
|
663
|
+
"compatibilityPolicy": "internal-candidate",
|
|
664
|
+
"packageSmokeEvidence": [
|
|
665
|
+
"test/packageBoundary.test.ts",
|
|
666
|
+
"test/marketing/schemas.test.ts",
|
|
667
|
+
"test/marketing/contracts.test.ts",
|
|
668
|
+
"test/marketing/browserBoundary.test.ts",
|
|
669
|
+
"test/marketing/noop.test.ts",
|
|
670
|
+
"test/marketing/dataLayer.test.ts",
|
|
671
|
+
"test/marketing/routePolicy.test.ts",
|
|
672
|
+
"test/marketing/purchaseFacts.test.ts",
|
|
673
|
+
"test/marketing/consentEvidence.test.ts"
|
|
674
|
+
],
|
|
675
|
+
"entrypoint": "dist/marketing/contracts/index.d.ts",
|
|
676
|
+
"snapshot": "api/marketing-contracts.api.md"
|
|
677
|
+
},
|
|
678
|
+
"./marketing/server": {
|
|
679
|
+
"role": "capability",
|
|
680
|
+
"maturity": "experimental",
|
|
681
|
+
"compatibilityPolicy": "internal-candidate",
|
|
682
|
+
"packageSmokeEvidence": [
|
|
683
|
+
"test/packageBoundary.test.ts",
|
|
684
|
+
"test/marketing/browserBoundary.test.ts",
|
|
685
|
+
"test/marketing/server/acquisitionCaseHandlers.test.ts",
|
|
686
|
+
"test/marketing/server/acquisitionCaseDirect.test.ts",
|
|
687
|
+
"test/marketing/server/prelaunchAcquisitionDirect.test.ts",
|
|
688
|
+
"test/marketing/server/acquisitionEvidenceDirect.test.ts",
|
|
689
|
+
"test/marketing/server/research/surveyResponseSubmitHandler.test.ts",
|
|
690
|
+
"test/marketing/server/research/adminSurveyResponsesHandler.test.ts",
|
|
691
|
+
"test/marketing/server/research/managedSurveyResponseSubmit.test.ts",
|
|
692
|
+
"test/marketing/analyticsContext.test.ts"
|
|
693
|
+
],
|
|
694
|
+
"entrypoint": "dist/marketing/server/index.d.ts",
|
|
695
|
+
"snapshot": "api/marketing-server.api.md"
|
|
696
|
+
},
|
|
697
|
+
"./marketing/server/postgres": {
|
|
698
|
+
"role": "capability",
|
|
699
|
+
"maturity": "experimental",
|
|
700
|
+
"compatibilityPolicy": "internal-candidate",
|
|
701
|
+
"packageSmokeEvidence": [
|
|
702
|
+
"test/packageBoundary.test.ts",
|
|
703
|
+
"test/marketing/server/postgres/acquisitionCaseRoutines.test.ts",
|
|
704
|
+
"test/marketing/server/postgres/acquisitionEvidenceRoutines.test.ts"
|
|
705
|
+
],
|
|
706
|
+
"entrypoint": "dist/marketing/server/postgres/index.d.ts",
|
|
707
|
+
"snapshot": "api/marketing-server-postgres.api.md"
|
|
708
|
+
},
|
|
709
|
+
"./portability": {
|
|
710
|
+
"role": "rail",
|
|
711
|
+
"maturity": "experimental",
|
|
712
|
+
"compatibilityPolicy": "internal-candidate",
|
|
713
|
+
"packageSmokeEvidence": [
|
|
714
|
+
"test/packageBoundary.test.ts",
|
|
715
|
+
"test/portability/objects.test.ts",
|
|
716
|
+
"test/portability/filesystemObjects.test.ts",
|
|
717
|
+
"test/payments/tpay/effectAuthority.test.ts"
|
|
718
|
+
],
|
|
719
|
+
"entrypoint": "dist/portability/index.d.ts",
|
|
720
|
+
"snapshot": "api/portability.api.md"
|
|
721
|
+
},
|
|
722
|
+
"./lifecycle": {
|
|
723
|
+
"role": "rail",
|
|
724
|
+
"maturity": "experimental",
|
|
725
|
+
"compatibilityPolicy": "internal-candidate",
|
|
726
|
+
"packageSmokeEvidence": [
|
|
727
|
+
"test/packageBoundary.test.ts",
|
|
728
|
+
"test/lifecycle/appUpgrade.test.ts",
|
|
729
|
+
"test/lifecycle/postgresInstallQualification.test.ts"
|
|
730
|
+
],
|
|
731
|
+
"entrypoint": "dist/lifecycle/index.d.ts",
|
|
732
|
+
"snapshot": "api/lifecycle.api.md"
|
|
602
733
|
}
|
|
603
734
|
},
|
|
604
735
|
"pack": {
|
|
605
736
|
"code": {
|
|
606
|
-
"maxPackedBytes":
|
|
607
|
-
"maxFiles":
|
|
737
|
+
"maxPackedBytes": 1743872,
|
|
738
|
+
"maxFiles": 2574
|
|
608
739
|
},
|
|
609
740
|
"docs": {
|
|
610
|
-
"maxPackedBytes":
|
|
741
|
+
"maxPackedBytes": 73728,
|
|
611
742
|
"maxFiles": 10
|
|
612
743
|
},
|
|
613
|
-
"maxPackedBytes":
|
|
614
|
-
"maxUnpackedBytes":
|
|
615
|
-
"maxFiles":
|
|
744
|
+
"maxPackedBytes": 2029568,
|
|
745
|
+
"maxUnpackedBytes": 9447424,
|
|
746
|
+
"maxFiles": 2628,
|
|
616
747
|
"baseline": {
|
|
617
|
-
"version": "0.
|
|
618
|
-
"packedBytes":
|
|
748
|
+
"version": "0.29.0",
|
|
749
|
+
"packedBytes": 1870812
|
|
619
750
|
},
|
|
620
751
|
"browserEntries": {
|
|
621
752
|
"./catalog/contracts": 4096,
|
|
@@ -631,7 +762,10 @@
|
|
|
631
762
|
"./invoicing/contracts": 32,
|
|
632
763
|
"./commerce/contracts": 32,
|
|
633
764
|
"./pricing/browser": 25600,
|
|
634
|
-
"./account-support/contracts": 32
|
|
765
|
+
"./account-support/contracts": 32,
|
|
766
|
+
"./operations/contracts": 32,
|
|
767
|
+
"./operations": 30720,
|
|
768
|
+
"./marketing/contracts": 32
|
|
635
769
|
}
|
|
636
770
|
}
|
|
637
771
|
}
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
-- Provider-neutral platform operations control plane.
|
|
2
|
+
--
|
|
3
|
+
-- WHAT THIS FORWARD SHIPS. A capability-local operator allowlist, opaque
|
|
4
|
+
-- boolean operational controls, an idempotent operation ledger, the portable
|
|
5
|
+
-- watchdog alert ledger and fixed invoker-rights routines for control mutation,
|
|
6
|
+
-- heartbeat persistence and bounded readback.
|
|
7
|
+
--
|
|
8
|
+
-- WHAT IT DELIBERATELY DOES NOT SHIP. No private tester, email, auth, provider,
|
|
9
|
+
-- payment, fulfilment or rich observability snapshot tables; no message or
|
|
10
|
+
-- template content; no raw provider payload; no browser grant; no scheduler;
|
|
11
|
+
-- and no platform-specific seed value.
|
|
12
|
+
|
|
13
|
+
CREATE TABLE public.platform_control_operators (
|
|
14
|
+
principal_id uuid PRIMARY KEY,
|
|
15
|
+
active boolean NOT NULL DEFAULT true,
|
|
16
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
17
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
18
|
+
CONSTRAINT platform_control_operators_timestamp_check CHECK (updated_at >= created_at)
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
CREATE TABLE public.platform_operational_controls (
|
|
22
|
+
control_key text PRIMARY KEY,
|
|
23
|
+
enabled boolean NOT NULL DEFAULT false,
|
|
24
|
+
revision integer NOT NULL DEFAULT 1,
|
|
25
|
+
updated_by uuid NOT NULL REFERENCES public.platform_control_operators(principal_id),
|
|
26
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
27
|
+
CONSTRAINT platform_operational_controls_key_check
|
|
28
|
+
CHECK (control_key ~ '^[A-Za-z0-9][A-Za-z0-9._:-]{0,119}$'),
|
|
29
|
+
CONSTRAINT platform_operational_controls_revision_check CHECK (revision >= 1)
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
CREATE TABLE public.platform_control_operations (
|
|
33
|
+
idempotency_key text PRIMARY KEY,
|
|
34
|
+
command_fingerprint text NOT NULL,
|
|
35
|
+
action text NOT NULL CHECK (action IN ('set-control', 'record-heartbeat')),
|
|
36
|
+
operator_id uuid NOT NULL REFERENCES public.platform_control_operators(principal_id),
|
|
37
|
+
response jsonb NOT NULL,
|
|
38
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
39
|
+
CONSTRAINT platform_control_operations_key_check
|
|
40
|
+
CHECK (idempotency_key ~ '^[A-Za-z0-9][A-Za-z0-9._:-]{0,255}$'),
|
|
41
|
+
CONSTRAINT platform_control_operations_fingerprint_check
|
|
42
|
+
CHECK (command_fingerprint ~ '^[a-f0-9]{64}$')
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
CREATE TABLE IF NOT EXISTS public.platform_alerts (
|
|
46
|
+
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
47
|
+
dedupe_key text NOT NULL UNIQUE,
|
|
48
|
+
severity text NOT NULL CHECK (severity IN ('p0', 'p1', 'p2', 'p3')),
|
|
49
|
+
status text NOT NULL DEFAULT 'open' CHECK (status IN ('open', 'acknowledged', 'resolved')),
|
|
50
|
+
first_seen_at timestamptz NOT NULL DEFAULT now(),
|
|
51
|
+
last_seen_at timestamptz NOT NULL DEFAULT now(),
|
|
52
|
+
last_notified_at timestamptz,
|
|
53
|
+
last_notification_attempt_at timestamptz,
|
|
54
|
+
last_notification_status text CHECK (last_notification_status IS NULL OR last_notification_status IN ('sent', 'failed', 'skipped')),
|
|
55
|
+
next_notification_attempt_at timestamptz,
|
|
56
|
+
notification_failure_count integer NOT NULL DEFAULT 0 CHECK (notification_failure_count >= 0),
|
|
57
|
+
snoozed_until timestamptz,
|
|
58
|
+
acknowledged_at timestamptz,
|
|
59
|
+
resolved_at timestamptz,
|
|
60
|
+
support_code text NOT NULL,
|
|
61
|
+
owner text NOT NULL,
|
|
62
|
+
runbook_url text NOT NULL,
|
|
63
|
+
title text NOT NULL,
|
|
64
|
+
message text NOT NULL,
|
|
65
|
+
payload jsonb NOT NULL DEFAULT '{}'::jsonb,
|
|
66
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
67
|
+
updated_at timestamptz NOT NULL DEFAULT now()
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
CREATE TABLE IF NOT EXISTS public.platform_alert_notifications (
|
|
71
|
+
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
72
|
+
alert_id uuid NOT NULL REFERENCES public.platform_alerts(id) ON DELETE CASCADE,
|
|
73
|
+
channel text NOT NULL CHECK (channel IN ('webhook', 'resend')),
|
|
74
|
+
status text NOT NULL CHECK (status IN ('sent', 'failed', 'skipped')),
|
|
75
|
+
provider text,
|
|
76
|
+
provider_response jsonb NOT NULL DEFAULT '{}'::jsonb,
|
|
77
|
+
error text,
|
|
78
|
+
notified_at timestamptz NOT NULL DEFAULT now(),
|
|
79
|
+
created_at timestamptz NOT NULL DEFAULT now()
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
CREATE INDEX platform_control_operations_created_idx
|
|
83
|
+
ON public.platform_control_operations(created_at DESC, idempotency_key);
|
|
84
|
+
CREATE INDEX IF NOT EXISTS idx_platform_alerts_status_seen
|
|
85
|
+
ON public.platform_alerts(status, last_seen_at DESC);
|
|
86
|
+
CREATE INDEX IF NOT EXISTS idx_platform_alert_notifications_alert
|
|
87
|
+
ON public.platform_alert_notifications(alert_id, notified_at DESC);
|
|
88
|
+
|
|
89
|
+
REVOKE ALL ON TABLE
|
|
90
|
+
public.platform_control_operators,
|
|
91
|
+
public.platform_operational_controls,
|
|
92
|
+
public.platform_control_operations,
|
|
93
|
+
public.platform_alerts,
|
|
94
|
+
public.platform_alert_notifications
|
|
95
|
+
FROM PUBLIC, anon, authenticated;
|
|
96
|
+
|
|
97
|
+
CREATE FUNCTION public.platform_control_operator_is_active(p_principal_id uuid)
|
|
98
|
+
RETURNS boolean
|
|
99
|
+
LANGUAGE sql
|
|
100
|
+
STABLE
|
|
101
|
+
SET search_path = pg_catalog
|
|
102
|
+
AS $$
|
|
103
|
+
SELECT EXISTS (
|
|
104
|
+
SELECT 1 FROM public.platform_control_operators AS operator_row
|
|
105
|
+
WHERE operator_row.principal_id = p_principal_id AND operator_row.active IS TRUE
|
|
106
|
+
);
|
|
107
|
+
$$;
|
|
108
|
+
|
|
109
|
+
CREATE FUNCTION public.platform_control_require_operator(p_operator_id uuid)
|
|
110
|
+
RETURNS void
|
|
111
|
+
LANGUAGE plpgsql
|
|
112
|
+
STABLE
|
|
113
|
+
SET search_path = pg_catalog
|
|
114
|
+
AS $$
|
|
115
|
+
BEGIN
|
|
116
|
+
IF p_operator_id IS NULL OR NOT public.platform_control_operator_is_active(p_operator_id) THEN
|
|
117
|
+
RAISE EXCEPTION 'platform_control_operator_inactive' USING ERRCODE = '42501';
|
|
118
|
+
END IF;
|
|
119
|
+
END;
|
|
120
|
+
$$;
|
|
121
|
+
|
|
122
|
+
CREATE FUNCTION public.platform_control_set_control(
|
|
123
|
+
p_operator_id uuid,
|
|
124
|
+
p_idempotency_key text,
|
|
125
|
+
p_command_fingerprint text,
|
|
126
|
+
p_control_key text,
|
|
127
|
+
p_enabled boolean
|
|
128
|
+
)
|
|
129
|
+
RETURNS TABLE(action text, replayed boolean, revision integer, recorded_at timestamptz)
|
|
130
|
+
LANGUAGE plpgsql
|
|
131
|
+
SET search_path = pg_catalog
|
|
132
|
+
AS $$
|
|
133
|
+
DECLARE
|
|
134
|
+
v_existing public.platform_control_operations%ROWTYPE;
|
|
135
|
+
v_revision integer;
|
|
136
|
+
v_recorded_at timestamptz := clock_timestamp();
|
|
137
|
+
BEGIN
|
|
138
|
+
PERFORM public.platform_control_require_operator(p_operator_id);
|
|
139
|
+
SELECT * INTO v_existing
|
|
140
|
+
FROM public.platform_control_operations
|
|
141
|
+
WHERE idempotency_key = p_idempotency_key
|
|
142
|
+
FOR UPDATE;
|
|
143
|
+
IF FOUND THEN
|
|
144
|
+
IF v_existing.command_fingerprint <> p_command_fingerprint OR v_existing.action <> 'set-control' THEN
|
|
145
|
+
RAISE EXCEPTION 'platform_control_idempotency_conflict' USING ERRCODE = '23505';
|
|
146
|
+
END IF;
|
|
147
|
+
RETURN QUERY SELECT 'set-control'::text, true,
|
|
148
|
+
(v_existing.response->>'revision')::integer, v_existing.created_at;
|
|
149
|
+
RETURN;
|
|
150
|
+
END IF;
|
|
151
|
+
|
|
152
|
+
INSERT INTO public.platform_operational_controls AS control_row
|
|
153
|
+
(control_key, enabled, revision, updated_by, updated_at)
|
|
154
|
+
VALUES (p_control_key, p_enabled, 1, p_operator_id, v_recorded_at)
|
|
155
|
+
ON CONFLICT (control_key) DO UPDATE
|
|
156
|
+
SET enabled = EXCLUDED.enabled,
|
|
157
|
+
revision = control_row.revision + 1,
|
|
158
|
+
updated_by = EXCLUDED.updated_by,
|
|
159
|
+
updated_at = EXCLUDED.updated_at
|
|
160
|
+
RETURNING control_row.revision INTO v_revision;
|
|
161
|
+
|
|
162
|
+
INSERT INTO public.platform_control_operations
|
|
163
|
+
(idempotency_key, command_fingerprint, action, operator_id, response, created_at)
|
|
164
|
+
VALUES (
|
|
165
|
+
p_idempotency_key, p_command_fingerprint, 'set-control', p_operator_id,
|
|
166
|
+
jsonb_build_object('revision', v_revision, 'recordedAt', v_recorded_at), v_recorded_at
|
|
167
|
+
);
|
|
168
|
+
RETURN QUERY SELECT 'set-control'::text, false, v_revision, v_recorded_at;
|
|
169
|
+
END;
|
|
170
|
+
$$;
|
|
171
|
+
|
|
172
|
+
CREATE FUNCTION public.platform_control_record_heartbeat(
|
|
173
|
+
p_operator_id uuid,
|
|
174
|
+
p_idempotency_key text,
|
|
175
|
+
p_command_fingerprint text,
|
|
176
|
+
p_health text,
|
|
177
|
+
p_firing_count integer,
|
|
178
|
+
p_max_severity text,
|
|
179
|
+
p_promotion_ready boolean
|
|
180
|
+
)
|
|
181
|
+
RETURNS TABLE(action text, replayed boolean, revision integer, recorded_at timestamptz)
|
|
182
|
+
LANGUAGE plpgsql
|
|
183
|
+
SET search_path = pg_catalog
|
|
184
|
+
AS $$
|
|
185
|
+
DECLARE
|
|
186
|
+
v_existing public.platform_control_operations%ROWTYPE;
|
|
187
|
+
v_recorded_at timestamptz := clock_timestamp();
|
|
188
|
+
BEGIN
|
|
189
|
+
PERFORM public.platform_control_require_operator(p_operator_id);
|
|
190
|
+
IF p_health NOT IN ('healthy', 'degraded', 'failed')
|
|
191
|
+
OR p_firing_count < 0
|
|
192
|
+
OR (p_max_severity IS NOT NULL AND p_max_severity NOT IN ('p0', 'p1', 'p2', 'p3')) THEN
|
|
193
|
+
RAISE EXCEPTION 'platform_control_heartbeat_invalid' USING ERRCODE = '22023';
|
|
194
|
+
END IF;
|
|
195
|
+
SELECT * INTO v_existing
|
|
196
|
+
FROM public.platform_control_operations
|
|
197
|
+
WHERE idempotency_key = p_idempotency_key
|
|
198
|
+
FOR UPDATE;
|
|
199
|
+
IF FOUND THEN
|
|
200
|
+
IF v_existing.command_fingerprint <> p_command_fingerprint OR v_existing.action <> 'record-heartbeat' THEN
|
|
201
|
+
RAISE EXCEPTION 'platform_control_idempotency_conflict' USING ERRCODE = '23505';
|
|
202
|
+
END IF;
|
|
203
|
+
RETURN QUERY SELECT 'record-heartbeat'::text, true, NULL::integer, v_existing.created_at;
|
|
204
|
+
RETURN;
|
|
205
|
+
END IF;
|
|
206
|
+
|
|
207
|
+
INSERT INTO public.platform_job_controls AS job_row
|
|
208
|
+
(job_name, enabled, active_driver, last_started_at, last_finished_at,
|
|
209
|
+
last_success_at, last_status, metadata, updated_at)
|
|
210
|
+
VALUES (
|
|
211
|
+
'platform-watchdog', true, 'operator', v_recorded_at, v_recorded_at,
|
|
212
|
+
v_recorded_at, 'success',
|
|
213
|
+
jsonb_build_object('health', p_health, 'firingCount', p_firing_count,
|
|
214
|
+
'maxSeverity', p_max_severity, 'promotionReady', p_promotion_ready),
|
|
215
|
+
v_recorded_at
|
|
216
|
+
)
|
|
217
|
+
ON CONFLICT (job_name) DO UPDATE
|
|
218
|
+
SET last_started_at = EXCLUDED.last_started_at,
|
|
219
|
+
last_finished_at = EXCLUDED.last_finished_at,
|
|
220
|
+
last_success_at = EXCLUDED.last_success_at,
|
|
221
|
+
last_status = EXCLUDED.last_status,
|
|
222
|
+
metadata = EXCLUDED.metadata,
|
|
223
|
+
updated_at = EXCLUDED.updated_at;
|
|
224
|
+
|
|
225
|
+
INSERT INTO public.platform_control_operations
|
|
226
|
+
(idempotency_key, command_fingerprint, action, operator_id, response, created_at)
|
|
227
|
+
VALUES (
|
|
228
|
+
p_idempotency_key, p_command_fingerprint, 'record-heartbeat', p_operator_id,
|
|
229
|
+
jsonb_build_object('recordedAt', v_recorded_at), v_recorded_at
|
|
230
|
+
);
|
|
231
|
+
RETURN QUERY SELECT 'record-heartbeat'::text, false, NULL::integer, v_recorded_at;
|
|
232
|
+
END;
|
|
233
|
+
$$;
|
|
234
|
+
|
|
235
|
+
CREATE FUNCTION public.platform_control_list_controls(p_operator_id uuid)
|
|
236
|
+
RETURNS TABLE(control_key text, enabled boolean, revision integer, updated_at timestamptz)
|
|
237
|
+
LANGUAGE plpgsql
|
|
238
|
+
STABLE
|
|
239
|
+
SET search_path = pg_catalog
|
|
240
|
+
AS $$
|
|
241
|
+
BEGIN
|
|
242
|
+
PERFORM public.platform_control_require_operator(p_operator_id);
|
|
243
|
+
RETURN QUERY SELECT row.control_key, row.enabled, row.revision, row.updated_at
|
|
244
|
+
FROM public.platform_operational_controls AS row ORDER BY row.control_key;
|
|
245
|
+
END;
|
|
246
|
+
$$;
|
|
247
|
+
|
|
248
|
+
CREATE FUNCTION public.platform_control_list_jobs(p_operator_id uuid)
|
|
249
|
+
RETURNS TABLE(job_name text, enabled boolean, active_driver text, last_status text,
|
|
250
|
+
last_started_at timestamptz, last_finished_at timestamptz, last_success_at timestamptz)
|
|
251
|
+
LANGUAGE plpgsql
|
|
252
|
+
STABLE
|
|
253
|
+
SET search_path = pg_catalog
|
|
254
|
+
AS $$
|
|
255
|
+
BEGIN
|
|
256
|
+
PERFORM public.platform_control_require_operator(p_operator_id);
|
|
257
|
+
RETURN QUERY SELECT row.job_name, row.enabled, row.active_driver, row.last_status,
|
|
258
|
+
row.last_started_at, row.last_finished_at, row.last_success_at
|
|
259
|
+
FROM public.platform_job_controls AS row ORDER BY row.job_name;
|
|
260
|
+
END;
|
|
261
|
+
$$;
|
|
262
|
+
|
|
263
|
+
CREATE FUNCTION public.platform_control_list_alerts(p_operator_id uuid)
|
|
264
|
+
RETURNS TABLE(dedupe_key text, severity text, status text, owner text, title text,
|
|
265
|
+
first_seen_at timestamptz, last_seen_at timestamptz, resolved_at timestamptz)
|
|
266
|
+
LANGUAGE plpgsql
|
|
267
|
+
STABLE
|
|
268
|
+
SET search_path = pg_catalog
|
|
269
|
+
AS $$
|
|
270
|
+
BEGIN
|
|
271
|
+
PERFORM public.platform_control_require_operator(p_operator_id);
|
|
272
|
+
RETURN QUERY SELECT row.dedupe_key, row.severity, row.status, row.owner, row.title,
|
|
273
|
+
row.first_seen_at, row.last_seen_at, row.resolved_at
|
|
274
|
+
FROM public.platform_alerts AS row
|
|
275
|
+
ORDER BY row.last_seen_at DESC, row.dedupe_key
|
|
276
|
+
LIMIT 200;
|
|
277
|
+
END;
|
|
278
|
+
$$;
|
|
279
|
+
|
|
280
|
+
REVOKE ALL ON FUNCTION public.platform_control_operator_is_active(uuid) FROM PUBLIC, anon, authenticated;
|
|
281
|
+
REVOKE ALL ON FUNCTION public.platform_control_require_operator(uuid) FROM PUBLIC, anon, authenticated;
|
|
282
|
+
REVOKE ALL ON FUNCTION public.platform_control_set_control(uuid, text, text, text, boolean) FROM PUBLIC, anon, authenticated;
|
|
283
|
+
REVOKE ALL ON FUNCTION public.platform_control_record_heartbeat(uuid, text, text, text, integer, text, boolean) FROM PUBLIC, anon, authenticated;
|
|
284
|
+
REVOKE ALL ON FUNCTION public.platform_control_list_controls(uuid) FROM PUBLIC, anon, authenticated;
|
|
285
|
+
REVOKE ALL ON FUNCTION public.platform_control_list_jobs(uuid) FROM PUBLIC, anon, authenticated;
|
|
286
|
+
REVOKE ALL ON FUNCTION public.platform_control_list_alerts(uuid) FROM PUBLIC, anon, authenticated;
|
package/src/composition/index.ts
CHANGED
|
@@ -23,3 +23,4 @@ export { createFulfillmentContribution } from "./fulfillmentContribution.js";
|
|
|
23
23
|
export { createSubscriptionContribution } from "./subscriptionContribution.js";
|
|
24
24
|
export { createCommerceContribution } from "./commerceContribution.js";
|
|
25
25
|
export { createAccountSupportContribution } from "./accountSupportContribution.js";
|
|
26
|
+
export { createMarketingContribution } from "./marketingContribution.js";
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { Contribution, RequiredSchema } from "@openlup/core/readiness";
|
|
2
|
+
|
|
3
|
+
/** Describe existing selected marketing callables; never install another executor. */
|
|
4
|
+
export function createMarketingContribution(input: {
|
|
5
|
+
version: string;
|
|
6
|
+
requiredSchema: RequiredSchema;
|
|
7
|
+
marketing: Readonly<Record<string, ((...args: never[]) => unknown) | null>>;
|
|
8
|
+
handlers: Contribution["handlers"];
|
|
9
|
+
schedules: Contribution["schedules"];
|
|
10
|
+
routes: Contribution["routes"];
|
|
11
|
+
}) {
|
|
12
|
+
for (const [kind, names] of [
|
|
13
|
+
["handler", input.handlers.map(handler => handler.eventType)],
|
|
14
|
+
["schedule", input.schedules.map(schedule => schedule.id)],
|
|
15
|
+
["route", input.routes.map(route => route.id)],
|
|
16
|
+
] as const) {
|
|
17
|
+
if (new Set(names).size !== names.length) throw new Error(`marketing_duplicate_${kind}`);
|
|
18
|
+
}
|
|
19
|
+
const contribution: Contribution = {
|
|
20
|
+
manifest: {
|
|
21
|
+
name: "@openlup/platform", version: input.version, kind: "rail",
|
|
22
|
+
module: { id: "marketing", kind: "capability", provides: ["./marketing", "./marketing/contracts", "./marketing/server"],
|
|
23
|
+
// The server entry validates obligations with identity's runtime contract schema.
|
|
24
|
+
dependsOn: [{ module: "identity", entries: ["./identity/contracts"] }] },
|
|
25
|
+
emits: [], handles: input.handlers.map(handler => handler.eventType),
|
|
26
|
+
schedules: input.schedules.map(({ id, cadenceSeconds }) => ({ id, cadenceSeconds })), env: [],
|
|
27
|
+
requiredPorts: Object.keys(input.marketing), routes: input.routes.map(route => route.id), requiredSchema: input.requiredSchema,
|
|
28
|
+
},
|
|
29
|
+
handlers: input.handlers.map(({ eventType, timeoutMs }) => Object.freeze({ eventType, timeoutMs })), schedules: input.schedules, routes: input.routes,
|
|
30
|
+
};
|
|
31
|
+
return {
|
|
32
|
+
contributions: [contribution],
|
|
33
|
+
ports: Object.fromEntries(Object.entries(input.marketing).filter(([, fn]) => typeof fn === "function").map(([name, fn]) => [`@openlup/platform/marketing:${name}`, fn])),
|
|
34
|
+
routes: Object.fromEntries(input.routes.map(route => [`@openlup/platform/marketing:${route.id}`, route.handle])),
|
|
35
|
+
triggers: Object.fromEntries(input.schedules.map(schedule => [`@openlup/platform/marketing:${schedule.id}`, schedule.run])),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
@@ -120,7 +120,7 @@ export interface ServeNodeResult {
|
|
|
120
120
|
bundleId: string;
|
|
121
121
|
httpRuntime: HttpRuntimePort;
|
|
122
122
|
registeredJobs: string[];
|
|
123
|
-
/**
|
|
123
|
+
/** Fence timers, drain admitted jobs, then close their lock session; also close the local listener. Safe to call repeatedly. */
|
|
124
124
|
stop(): Promise<void>;
|
|
125
125
|
}
|
|
126
126
|
|
|
@@ -276,14 +276,15 @@ async function stopNodeHost(
|
|
|
276
276
|
advisoryLock: AdvisoryLock | undefined,
|
|
277
277
|
httpRuntime: HttpRuntimePort,
|
|
278
278
|
): Promise<void> {
|
|
279
|
-
const timers =
|
|
279
|
+
const timers = scheduler?.stopAll() ?? Promise.resolve();
|
|
280
280
|
const server = (httpRuntime as HttpRuntimePort & {
|
|
281
281
|
server?: { close(callback: (error?: Error) => void): void } | null;
|
|
282
282
|
}).server;
|
|
283
283
|
const listener = server
|
|
284
284
|
? new Promise<void>((resolveClose, reject) => server.close((error) => error ? reject(error) : resolveClose()))
|
|
285
285
|
: Promise.resolve();
|
|
286
|
-
const
|
|
286
|
+
const lock = timers.then(() => advisoryLock?.close(), () => advisoryLock?.close());
|
|
287
|
+
const results = await Promise.allSettled([timers, lock, listener]);
|
|
287
288
|
const failures = results.flatMap((result) => result.status === "rejected" ? [result.reason] : []);
|
|
288
289
|
if (failures.length > 0) throw new AggregateError(failures, "node_host_shutdown_failed");
|
|
289
290
|
}
|