Skip to content

feat(server): org-aware bootstrap + NOT NULL backstop (PR3/4)#71

Merged
Isonimus merged 1 commit into
mainfrom
feat/organizations-layer-pr3
Jun 21, 2026
Merged

feat(server): org-aware bootstrap + NOT NULL backstop (PR3/4)#71
Isonimus merged 1 commit into
mainfrom
feat/organizations-layer-pr3

Conversation

@Isonimus

Copy link
Copy Markdown
Contributor

Why

PR3 of 4 for the organizations tenant layer. PRs 1–2 added the organizations entity and enforced org-scoped admin RBAC, but organization_id was still nullable and the bootstrap CLIs (create-admin/create-project) inserted tenant-less rows. This PR makes every writer org-aware and closes the gap at the DB level, so a tenant-less project or admin can never exist.

What

  • lib/organizations.ts findOrCreateOrgByName: idempotent on name; both CLIs use it to attach the first admin/project to a tenant. A fresh self-host install has no org until bootstrap; a hosted operator passes a per-customer name to add a second tenant.
  • create-admin / create-project: take an optional [orgName] (default Default) and set organization_id on insert.
  • Migration 014: enforces organization_id NOT NULL on admin_users and projects, first bucketing any stragglers (rows an older image could have created between the 013 deploy and the org-aware-writer deploy) into a Default org so the constraint applies cleanly.
  • Remaining data-only integration test helpers (events, queries, resolution, assess, retention) create + assign an org via the shared test-support/org helper.

Verification

  • Migration 014 applied to dev DB; 135 server tests pass; type-check + lint clean.
  • Smoke-tested both CLIs end-to-end: create-project "Smoke Proj" "Acme Corp" then create-admin … "Acme Corp" share one tenant (find-or-create reused the org).

Follow-up

PR4: docs — ADR-0005 (tenancy model), ROADMAP, OpenAPI note, CHANGELOG.

Every project and admin must belong to an organization. Make the bootstrap
CLIs provision one and close the gap at the DB level.

- New lib/organizations.ts findOrCreateOrgByName: idempotent on name, used by
  both CLIs to attach the first admin/project to a tenant (a fresh self-host
  install has no org until bootstrap; hosted operators pass a per-customer name).
- create-admin / create-project take an optional [orgName] (default 'Default')
  and set organization_id on insert.
- Migration 014 enforces organization_id NOT NULL on admin_users and projects,
  first bucketing any stragglers (rows an older image may have created between
  the 013 and the org-aware-writer deploys) into a Default org.
- Remaining data-only integration test helpers (events, queries, resolution,
  assess, retention) create and assign an org via the shared test-support helper.

135 server tests pass; type-check + lint clean. Smoke-tested both CLIs:
create-project then create-admin with the same org name share one tenant.
@Isonimus Isonimus merged commit b350fef into main Jun 21, 2026
4 checks passed
@Isonimus Isonimus deleted the feat/organizations-layer-pr3 branch June 21, 2026 09:56
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