Skip to content

docs: scope project lifecycle and org switching - #20

Open
marcorivm wants to merge 1 commit into
mainfrom
docs/project-lifecycle
Open

docs: scope project lifecycle and org switching#20
marcorivm wants to merge 1 commit into
mainfrom
docs/project-lifecycle

Conversation

@marcorivm

Copy link
Copy Markdown
Member

Scoping doc for the project-lifecycle work, plus the org-switching follow-up. Living document — the status table tracks each slice, and decisions that change during implementation get recorded here rather than drifting from the code.

Why

Groups (#12) and project access (#13) both bind permissions to projects, but there's no way to create a project, list the ones you can reach, or switch between them. That's why groups feel inert — the thing they grant access to barely exists as a user-facing concept.

What the investigation found

Multi-project is already live and headless. Agent, Secret, AppConnection, PolicyRuleV2, ApiKey and Budget all FK to Project; the gateway resolves everything off agent.project_id; resolveProjectId already honours x-project-id gated by canAccessProjectAsUser. ensureMemberDefaultProject is already creating one project per invited member — which is exactly why projectNameSchema is deliberately non-unique per org. Only create, list and switch are missing.

Switching on flat editions has no transport. proxy.ts strips the /p/<id> prefix when !CAPS.orgScopedUI, so on oss and onprem-slim a switcher has nothing to ride on. A cookie is the answer — and upstream is already building the same mechanism for orgs (DEFAULT_ORG_COOKIE, new in v1.45.0, absent from our v1.44.0 base). Ours should sit alongside it in navigation.ts rather than duplicate it.

Org switching is blocked on resolution precedence, not UI. session.ts derives organizationId from the resolved project and ignores x-organization-id whenever a project resolves — which on flat editions is always, because resolveProjectId falls back to findUserDefaultProject. Making that fallback org-aware fixes it without inverting precedence or touching the lockout invariant.

Slices

# Slice Size
1 GET /v1/projects — list S
2 POST /v1/projects — create M
3 Web: switcher + create dialog M
4 Org switching (follow-up) M–L

Slice 1 is stacked on this branch. Slice 4 should wait for the v1.45.0 adoption so it inherits the org cookie instead of racing it.

The invariant to watch

findUserDefaultProject and hasResolvableProjectExcluding must move together — the code comment is emphatic that drift is a lockout: a user whose last project disappears resolves nothing and session auth 401s them everywhere. Slice 4 edits that function directly.

Everything below the UI is already multi-project — Agent, Secret,
AppConnection, PolicyRuleV2, ApiKey and Budget all FK to Project, and the
gateway resolves off agent.project_id. What is missing is create, list and
switch.

Records what already works (so it is not rebuilt), the invariants that must
not break, and the sequencing. Two findings worth the write-up:

- Switching on flat editions has no transport today: proxy.ts strips the
  /p/<id> prefix when !CAPS.orgScopedUI, so a cookie is needed. Upstream is
  building the same mechanism for orgs (DEFAULT_ORG_COOKIE, new in v1.45.0),
  so ours should sit alongside it rather than duplicate it.
- Org switching is blocked on resolution precedence, not UI: session.ts
  derives organizationId FROM the resolved project and ignores
  x-organization-id whenever a project resolves, which on flat editions is
  always. Making findUserDefaultProject org-aware fixes it without inverting
  precedence.

Living document — the status table tracks each slice.
@marcorivm
marcorivm force-pushed the docs/project-lifecycle branch from da3417a to b844505 Compare August 8, 2026 19:34
@marcorivm
marcorivm changed the base branch from open-edition/reconciled to main August 8, 2026 19:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant