Repository navigation
Commit 29d0ed3
fix(platform-objects,spec)!: sys_organization no longer declares change_slug, whose door only cloud mounts (#24657)
Fixes #24318
Clause-②: no (narrowing) (a platform object stops declaring an action
whose door exists only in cloud; owes a `CONTRACT_REVIEW_TIER` review on
the narrowing face before the queue, and the `repo:cloud#2` seat's
pointer before landing)
Dev session `session_015mj2S1LnzLNur4rJeZuMbN`, dispatched by the
`domain:engine` seat 1 (`session_01JtSQQ3EWsbNPzyYMug1tXy`) under claim
6275837047. Shape B of the release 6255698861: the composition that
serves `/api/v1/cloud/organizations/{id}/change-slug` declares
`change_slug` itself, through the top-level action bound by `objectName`
that PR #24458 attaches, and `sys_organization` stops declaring it.
## What changes
-
**`packages/platform-objects/src/identity/sys-organization.object.ts`**:
`change_slug` is removed with its comments. The comments on
`leave_organization` and `rename_organization` now say what is true: the
header carries Invite User, Set Active and Rename Organization inline
and Leave Organization in the overflow, and the slug action is declared
by the composition that serves its route. The action order is unchanged.
`defaultRowScope` (PR #24623's region) is not touched.
- **The four generated locales** lose
`sys_organization._actions.change_slug`, regenerated with `node
scripts/check-i18n-bundles.mjs --write` (20 lines removed, nothing else
moved).
- **`packages/spec/src/kernel/public-auth-features.ts`**: the
`multiOrgEnabled.gatedInputs` row `sys_organization.actions.change_slug`
is removed. It is the platform objects' own census:
`feature-gate-guard.test.ts` walks only the platform-objects modules,
and its forward direction reds when a booked path names an action that
no longer exists. It is not a gate on other packages (measured below),
so cloud does not need it.
- **`packages/platform-objects/src/pages/sys-organization.page.ts`**:
the docblock that listed Change Slug in the header overflow (comment
only). Outside the claim's file surface; the removal made it false.
- **Pins and changesets** below.
## Measured on a booted multi-organization showcase (M)
The harness: `bootShowcase({ multiTenant: 'posture-only' })`,
`/auth/config` serving `multiOrgEnabled: true`. The cloud-shaped
composition adds one `AppPlugin` whose stack declares a top-level
`change_slug` with `objectName: 'sys_organization'` and the platform's
former declaration byte for byte (target, `method: 'POST'`,
`record_header`, the one `slug` param, `requiresFeature:
'multiOrgEnabled'`, description, success message).
Before, on `origin/main` `1e8b6284c0`:
| composition | `change_slug` served | its `visible` | `POST
/api/v1/cloud/organizations/org_x/change-slug` | boot report |
|---|---|---|---|---|
| showcase | once (the platform's) | `features.multiOrgEnabled != false`
| `404` `ENDPOINT_NOT_FOUND` | none |
| + cloud-shaped, identical declaration | once (the platform's) | same |
`404` | none (`sameActionDeclaration` reads one declaration) |
| + cloud-shaped, label differs | once, label `Change Slug` (the
platform's) | same | `404` | one `WARN`: declared twice,
`com.objectstack.plugin-auth` served, `com.measure.cloud-shaped` not
listed |
After, on this branch:
| composition | `change_slug` served | its `visible` | header position |
|---|---|---|---|
| showcase | **absent**; the record serves create, update, delete, set
active, invite, leave and rename | n/a | n/a |
| + cloud-shaped, identical declaration | once, attached after the
object's own actions | `features.multiOrgEnabled != false`, the same
lowering as the platform's own `requiresFeature` actions | after rename,
before leave: the `⋯` overflow, where the platform copy sat |
| + cloud-shaped, label differs | once, the binder's (`Change Slug
(cloud)`) | same | same |
Nothing refuses a non-platform action that declares `requiresFeature:
'multiOrgEnabled'`: the boot succeeds, the sugar is lowered at parse
like any action's, and no `gatedInputs` row is consulted at runtime.
## What the cloud repository needs (for the `repo:cloud#2` seat's
pointer)
1. One top-level action in cloud's composition, bound by `objectName`:
```ts
{
name: 'change_slug',
objectName: 'sys_organization',
label: 'Change Slug',
icon: 'edit-3',
variant: 'secondary',
mode: 'custom',
locations: ['record_header'],
type: 'api',
target: '/api/v1/cloud/organizations/{id}/change-slug',
method: 'POST',
requiresFeature: 'multiOrgEnabled',
description: 'Renaming the slug rewrites every platform subdomain for this org and parks the old slug for 90 days. Continue?',
successMessage: 'Organization slug changed',
refreshAfter: true,
params: [{ field: 'slug', required: true, defaultFromRow: true }],
}
```
2. Its translations, the keys this PR removes from platform-objects'
bundles (`objects.sys_organization._actions.change_slug`):
| locale | label | description | successMessage |
|---|---|---|---|
| en | Change Slug | Renaming the slug rewrites every platform subdomain
for this org and parks the old slug for 90 days. Continue? |
Organization slug changed |
| zh-CN | 修改标识符 | 重命名标识符会重写该组织所有平台子域名,旧标识符将保留占用 90 天。继续吗? | 组织标识符已修改 |
| ja-JP | スラッグを変更 | スラッグを変更すると、この組織のすべてのプラットフォームサブドメインが書き換えられ、旧スラッグは 90
日間確保されます。続行しますか? | 組織のスラッグを変更しました |
| es-ES | Cambiar slug | Renombrar el slug reescribe todos los
subdominios de la plataforma para esta organización y reserva el slug
anterior durante 90 días. ¿Continuar? | Slug de la organización cambiado
|
Whether a translation bundle in cloud's package reaches another
package's object's `_actions` was not measured here; the cloud seat owns
that check.
3. Land it before, or with, cloud's pin bump past this PR. Until then
cloud's record page has no Change Slug. If cloud declares it while this
platform copy is still in its pin, the identical declaration is served
once and nothing is reported; a declaration that differs is reported at
boot and the platform's copy is the one served.
## Pins
Pin sweep: `git grep -n "change_slug\|change-slug"` over the tree. Every
hit outside CHANGELOGs and landed `.changeset/pre` entries moved:
- `sys-organization-rename-action.test.ts`: the header order is now
asserted exactly (invite, set active, rename inline; leave in the
overflow). The `change_slug` control is replaced by "every api action
targets better-auth's `organization/` routes, none the cloud
orchestrator, and no `change_slug` is declared".
- `platform-objects.test.ts`: the `change_slug` lowering row is removed,
and a new case holds the matrix's `SysOrganization` rows equal to every
action the object gates on `multiOrgEnabled`.
- `action-confirm-one-dialog.test.ts`: the `sys_organization` entry
leaves the converted map (13 of #7309's 14 remain platform
declarations).
- `confirm-question-carryover.test.ts`: the pair leaves the set, and a
new case asserts 13 pairs and that no locale bundle (en included)
carries `sys_organization.change_slug`, with `rename_organization` as
the control.
- `runtime/action-execution-destructive.test.ts`: the flipped set is 5
and the full set is 13, and a new case asserts `SysOrganization`
declares no `change_slug`.
- `qa/dogfood/org-record-admin-reach.dogfood.test.ts`: the `UNDECIDED`
hold-out is gone. The served set is asserted equal to the seven graded
actions, and the door probe calls **every** api action the record
serves, so the record offers no action whose target answers `404` (the
first new pin of the claim).
- New: `qa/dogfood/org-change-slug-bound-action.dogfood.test.ts` boots
the showcase with the cloud-shaped package and asserts `change_slug` is
served once with the orchestrator target, `POST`, `record_header` and
its one `slug` param; its `visible` equals
`featureGatePredicate('multiOrgEnabled')` and `leave_organization`'s;
under `celEngine` it is admitted with multi-org on and hidden with it
off; it sorts after rename and before leave; and the boot names no
collision for it (the second new pin).
## Verification
Tests (head `91dc52d3e`, after merging `origin/main` `7c7741dcb`, unless
noted):
- `pnpm --filter @objectstack/platform-objects test`: 78 files, 1191
tests passed.
- `pnpm --filter @objectstack/spec test`: 701 files, 21313 passed, 1
todo (pre-merge head `048de3158`).
- `pnpm --filter @objectstack/runtime test`: 425 files, 6668 passed, 19
skipped (pre-merge head `048de3158`).
- dogfood: `org-record-admin-reach` and `org-change-slug-bound-action`:
2 files, 12 tests passed.
- `pnpm --filter @objectstack/core test:repo`: 6 files, 82 passed.
- typecheck, exit 0 on each: `@objectstack/platform-objects`,
`@objectstack/spec`, `@objectstack/runtime`, `@objectstack/dogfood`
(after the merge).
- `pnpm --filter @objectstack/spec check:generated`: all 14 artifacts up
to date (after the merge and a spec rebuild). `node
scripts/check-i18n-bundles.mjs`: exit 0.
Ablation (`scripts/ablation-replace.mjs`, trap-restored; dist proved by
`scripts/ablation-dist-preflight.mjs`): the platform copy put back into
`sys-organization.object.ts` and platform-objects rebuilt (marker
present in 6 built files):
- dogfood `org-record-admin-reach`: **red**, 2 cases ("every grade is
served the same action set", and "every api action ... none answers
ENDPOINT_NOT_FOUND").
- platform-objects: **red**, 4 cases (the rename file's header order and
api-target cases, the matrix completeness case, and
`feature-gate-guard`'s reverse direction, which reds because the row is
gone).
- runtime: **red**, 1 case ("sys_organization no longer declares
change_slug, the sixth").
- `org-change-slug-bound-action` stays green under the ablation, as
expected: with an identical platform copy present the served declaration
is the same bytes.
Restored: `git diff HEAD` empty and the blob hash equals HEAD's;
rebuilt, marker absent from all 66 built files; the dogfood pair green
again (12/12).
Gates: `node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` derived 88 families; all 88 ran on
`91dc52d3e` with exit 0, and `--ran` reconciled "88 derived, 88 run, 0
NOT-MEASURED, 0 UNRUN (a DERIVED zero)". `check:dual-build-cjs-loads`
first exited 3 (eight packages had no `dist/`); they were built and it
passed. The last commit, `44da7fe8d`, touches only the two changesets
(the claim's `Clause-②` line carried verbatim), and the nine changeset
families were re-run on it, all exit 0.
## Acceptance notes
- `sys-organization.page.ts` is outside the claim's `File surface:`
list; its docblock named Change Slug in the header overflow, which this
change made false.
- The new dogfood file is not the ablation target for the platform copy;
`org-record-admin-reach` is, and it reds.
- Cloud-side items not measured here: whether cloud's translation bundle
reaches `sys_organization._actions` of another package's object; cloud's
own boot with the declaration.
---
_Generated by [Claude
Code](https://claude.ai/code/session_015mj2S1LnzLNur4rJeZuMbN)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 92ce3af commit 29d0ed3
16 files changed
Lines changed: 306 additions & 121 deletions
File tree
- .changeset
- packages
- platform-objects/src
- apps/translations
- identity
- pages
- qa/dogfood/test
- runtime/src
- spec/src/kernel
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
4 | | - | |
5 | | - | |
| 4 | + | |
| 5 | + | |
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
| |||
32 | 32 | | |
33 | 33 | | |
34 | 34 | | |
35 | | - | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
36 | 41 | | |
37 | 42 | | |
38 | 43 | | |
| |||
41 | 46 | | |
42 | 47 | | |
43 | 48 | | |
44 | | - | |
45 | 49 | | |
46 | 50 | | |
47 | 51 | | |
| |||
78 | 82 | | |
79 | 83 | | |
80 | 84 | | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
81 | 94 | | |
82 | 95 | | |
83 | 96 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
605 | 605 | | |
606 | 606 | | |
607 | 607 | | |
608 | | - | |
609 | | - | |
610 | | - | |
611 | | - | |
612 | | - | |
613 | 608 | | |
614 | 609 | | |
615 | 610 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
605 | 605 | | |
606 | 606 | | |
607 | 607 | | |
608 | | - | |
609 | | - | |
610 | | - | |
611 | | - | |
612 | | - | |
613 | 608 | | |
614 | 609 | | |
615 | 610 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
605 | 605 | | |
606 | 606 | | |
607 | 607 | | |
608 | | - | |
609 | | - | |
610 | | - | |
611 | | - | |
612 | | - | |
613 | 608 | | |
614 | 609 | | |
615 | 610 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
605 | 605 | | |
606 | 606 | | |
607 | 607 | | |
608 | | - | |
609 | | - | |
610 | | - | |
611 | | - | |
612 | | - | |
613 | 608 | | |
614 | 609 | | |
615 | 610 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
54 | 54 | | |
55 | 55 | | |
56 | 56 | | |
57 | | - | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
58 | 63 | | |
59 | 64 | | |
60 | 65 | | |
| |||
63 | 68 | | |
64 | 69 | | |
65 | 70 | | |
66 | | - | |
67 | 71 | | |
68 | 72 | | |
69 | 73 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
8 | | - | |
9 | | - | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
10 | 11 | | |
11 | 12 | | |
12 | 13 | | |
| |||
16 | 17 | | |
17 | 18 | | |
18 | 19 | | |
19 | | - | |
20 | | - | |
| 20 | + | |
| 21 | + | |
21 | 22 | | |
22 | | - | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
23 | 26 | | |
24 | 27 | | |
25 | 28 | | |
| |||
117 | 120 | | |
118 | 121 | | |
119 | 122 | | |
120 | | - | |
| 123 | + | |
121 | 124 | | |
122 | | - | |
123 | | - | |
124 | | - | |
| 125 | + | |
125 | 126 | | |
126 | | - | |
127 | | - | |
| 127 | + | |
128 | 128 | | |
129 | 129 | | |
130 | 130 | | |
131 | | - | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
132 | 148 | | |
133 | 149 | | |
134 | 150 | | |
135 | 151 | | |
136 | 152 | | |
137 | 153 | | |
138 | | - | |
139 | | - | |
140 | | - | |
141 | | - | |
142 | | - | |
143 | | - | |
144 | | - | |
145 | 154 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
202 | 202 | | |
203 | 203 | | |
204 | 204 | | |
205 | | - | |
206 | | - | |
207 | | - | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
208 | 208 | | |
209 | 209 | | |
210 | 210 | | |
| |||
226 | 226 | | |
227 | 227 | | |
228 | 228 | | |
229 | | - | |
230 | | - | |
231 | | - | |
232 | | - | |
233 | | - | |
234 | | - | |
235 | | - | |
236 | | - | |
237 | | - | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
238 | 236 | | |
239 | 237 | | |
240 | 238 | | |
| |||
255 | 253 | | |
256 | 254 | | |
257 | 255 | | |
258 | | - | |
259 | | - | |
260 | | - | |
261 | | - | |
262 | | - | |
263 | | - | |
264 | | - | |
265 | | - | |
266 | | - | |
267 | | - | |
268 | | - | |
269 | | - | |
270 | | - | |
271 | | - | |
272 | | - | |
273 | | - | |
274 | | - | |
275 | | - | |
276 | | - | |
277 | | - | |
278 | | - | |
279 | | - | |
280 | | - | |
281 | | - | |
282 | | - | |
283 | | - | |
284 | | - | |
285 | | - | |
286 | | - | |
287 | | - | |
288 | 256 | | |
289 | 257 | | |
290 | 258 | | |
| |||
0 commit comments