@odla-ai/chapter 0.47.10 → 0.48.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@odla-ai/chapter",
3
- "version": "0.47.10",
3
+ "version": "0.48.1",
4
4
  "description": "A leader/follower foundation for branded membership sites: shared CRM, admin, auth, payments, booking, and explicit record delivery from one defineChapter config.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://odla.ai/docs/packages/chapter",
@@ -79,15 +79,15 @@
79
79
  "prepublishOnly": "npm run build && npm test"
80
80
  },
81
81
  "dependencies": {
82
- "@odla-ai/crm": ">=0.9.2 <0.10.0",
82
+ "@odla-ai/crm": ">=0.10.0 <0.11.0",
83
83
  "@odla-ai/promotion": "0.1.0",
84
- "@odla-ai/stripe": ">=0.1.0 <1.0.0",
84
+ "@odla-ai/stripe": ">=0.1.1 <1.0.0",
85
85
  "jose": "^6.2.3"
86
86
  },
87
87
  "peerDependencies": {
88
- "@odla-ai/auth-clerk": ">=0.4.1 <1.0.0",
88
+ "@odla-ai/auth-clerk": ">=0.5.0 <1.0.0",
89
89
  "@odla-ai/calendar": ">=0.2.0 <1.0.0",
90
- "@odla-ai/db": ">=0.9.0 <1.0.0",
90
+ "@odla-ai/db": ">=0.14.0 <1.0.0",
91
91
  "@odla-ai/ui": ">=0.20.0 <1.0.0",
92
92
  "preact": ">=10.29.7 <11"
93
93
  },
@@ -531,7 +531,10 @@ leader and follower are different websites and use different Clerk
531
531
  applications, publishable keys, issuers, roles, and local session tokens. A
532
532
  Clerk JWT never authenticates a cross-site delivery.
533
533
 
534
- Chapter claim mode requires session claims for both email and role; hub table
534
+ Prefer explicit `auth: { source: "clerk", superAdminSource: "odla" }` for
535
+ backend-only authorization. It resolves `private_metadata.role` from Clerk on
536
+ each check and never falls back to public metadata or a session role claim.
537
+ Legacy claim mode requires session claims for both email and role; hub table
535
538
  mode uses lowercase `admins` rows. Prove signed-out, allowed, forbidden,
536
539
  provisional, member, admin, super-admin, malformed, expired, wrong-issuer,
537
540
  sign-out, and return-target behavior. If the site's verifier intentionally
@@ -541,17 +544,50 @@ fixtures. If it never enforced those claims, mark those two cases `n/a` only
541
544
  after the full matrix is recorded; do not call their absence an auth success or
542
545
  use it to skip the remaining authorization tests.
543
546
 
544
- When Chapter needs server-side account/role operations, set the named
545
- app-readable `clerk_secret_key` through:
547
+ When Chapter needs server-side account/role operations, use the existing
548
+ environment-scoped reserved credential (Chapter reads its effective
549
+ `clerk_secret_key` alias):
546
550
 
547
551
  ```sh
548
- npx odla-ai secrets set clerk_secret_key --env dev --stdin
552
+ npx odla-ai secrets set-clerk-key --env dev --stdin
549
553
  ```
550
554
 
551
- Do not substitute `secrets set-clerk-key`; it writes the platform-reserved
552
- `$clerk_secret`, which Chapter cannot read under the named key. The generic
553
- command does not validate Clerk instance prefixes: independently confirm dev
554
- uses `sk_test_`. Never put `sk_live_` in dev.
555
+ Do not create a second secret pair. Confirm the selected instance and dev
556
+ `sk_test_` status without printing the secret; never put `sk_live_` in dev.
557
+
558
+ #### Coordinated dev private-role cutover
559
+
560
+ 1. Resolve every active runtime sharing the app's dev Clerk instance from odla.
561
+ All developer sandboxes are authoritative; do not infer the inventory from
562
+ one checkout or change a peer's deployment without authority.
563
+ 2. Have the human grant an existing operator's exact Clerk subject the protected
564
+ app-scoped role through odla Studio → Database → Users. Confirm an active,
565
+ nondeleted `$users` row. Never copy a legacy `superAdmins` row, email match,
566
+ or Clerk metadata value into a protected grant. Keep its ordinary Clerk
567
+ admin role separate. Do not switch live auth with no protected operator.
568
+ 3. Stage compatible private-role readers AND writers in every runtime. Pause
569
+ role-changing approval/refund/seat/admin operations everywhere during
570
+ migration; do not leave a legacy writer racing a private writer.
571
+ 4. Backend-read all Clerk users and run `planPrivateRoleMigration` with the exact
572
+ dev inventory, reviewed runtime versions/readiness, and existing protected
573
+ subject IDs. Resolve malformed/unknown/conflicting roles before proceeding.
574
+ The helper is dry-run only; a ready result is not a remote lock or write grant.
575
+ 5. For each reviewed change, re-read and compare both role fields immediately
576
+ before the metadata PATCH. If either changed, stop and regenerate the plan.
577
+ Merge the approved role into `private_metadata.role`, removing only the old
578
+ public role key; preserve unrelated metadata. Re-read to verify each result.
579
+ Keep writers paused throughout; regenerate the plan on interrupted resume.
580
+ 6. Switch all participating runtimes to the private configuration together and
581
+ verify admin/member access, denied stale/public-only admin claims, exact-ID
582
+ protected authority, and same-session promotion/revocation. Remove the unused
583
+ public role session claim only after every relying runtime is migrated.
584
+ Exercise approval, refund, seat, and admin role changes against the same
585
+ private field before resuming normal writes.
586
+ 7. Do not roll back only the Worker to a public-role reader after metadata has
587
+ migrated. Keep writes paused and review a coordinated recovery using fresh
588
+ provider state. Never replay a stale role snapshot or automatically recreate
589
+ public privileges. Old allowlist rows may remain stored but have no authority
590
+ in protected mode; deleting them is not required for this cutover.
555
591
 
556
592
  Chapter now reserves `public_metadata` for the small authorization role and
557
593
  stores its `applicationId`/allowlisted profile snapshot in backend-only