Repository navigation
feat(den): one place for an organization's plan and seats - #6516
Conversation
One pure rule (organization-plan.ts) decides how many users an organization may have, used by invitations, SSO, SCIM, /admin and /v1/billing. Admin-set Team/Enterprise plans allow their seats with no feature flag; a full plan answers org_limit_reached instead of the Team upgrade. Adds an optional display-only plan end date, the /admin Billing tab, and retires the enterprisePlan and organizationGrants flags (sandbox Free Auto now follows the sandbox row).
…to end; fix shared type import
|
The latest updates on your projects. Learn more about Vercel for GitHub.
1 Skipped Deployment
|
OpenWork evidence
Run details · Open the preview to inspect evidence and sandbox options. |
There was a problem hiding this comment.
Warden clearance. Complete security and confidentiality review of 66ec9ab3becb3379a9f0220b11a7bdd2916fead4 found no high or medium security findings and no confidentiality findings. Any new push dismisses this approval. Analysis run
Warden: approvedNo high or medium security findings and no confidentiality findings. Reviewed |
… grow past the Free limit - evals/worlds/plan-shapes.ts seeds, through public Den APIs only, an Enterprise trial set to 20 users with 2 joined and 3 invited, Free at its 5-user limit, an Enterprise plan for 6 users, and Team paid in the loopback test-mode Stripe. The same seed runs on dev and on this branch. - `pnpm world up preview-den --stage <stage> --seed plans` boots Den locally with those organizations and prints what to try in each. - The enterprise-trial-invites proof drives the owner's Members and Billing pages and the platform admin's Billing tab. On dev the sixth invitation on the trial opens "Upgrade to the Team plan"; on this branch it is sent.
Seeded plan situations: before (
|
# Conflicts: # packaging/helm/openwork-ee/values.yaml
There was a problem hiding this comment.
Warden clearance. Complete security and confidentiality review of ea36cb536e8754434c98c714cac6a2646f096f73 found no high or medium security findings and no confidentiality findings. Any new push dismisses this approval. Analysis run





What is this about?
Den admin and billing: the OpenWork team now sets an organization's plan (Free, Team or Enterprise) and how many users it allows in one place,
/admin› organization › Billing. Invitations, SSO and SCIM all enforce that number, and the customer Billing page shows the same plan.What problem does it solve?
An Enterprise trial set to "Enterprise, 20 seats" in
/adminwas blocked at 5 users with "Upgrade to the Team plan". Four different settings decided whether an org could add people, and they disagreed. "Seats" was stored but never enforced. The Free limit was edited somewhere else. TheenterprisePlanflag only lifted the limit for email invites, and SSO/SCIM had their own exemption.What was the situation before?
/admin: a per-row "Manage" panel ("Save access"), a separate "Free plan up to N" modal, and a flag-gated Control panel.teamPlanwas on.How is this implemented?
ee/apps/den-api/src/organization-plan.ts(unit tested), with an I/O wrapper inorganization-plan-state.ts. Users = joined members + unexpired invitations. The limit is:max(seats, 5);5 + seatsFreeAdditional.getOrganizationSeatAddEligibilityserves/v1/invitations, SSO JIT, verified-domain join and SCIM. A full admin-set plan gets409 org_limit_reached; Free keeps the 402 Team flow.metadata.plan { tier, source, seats, endsAt, grantedAt }. There is no migration.limits.membersis mirrored for one release. Saving Free writesseatsFreeAdditional; saving Team/Enterprise clears it.endsAtis display only.PATCH …/planandden_update_org_plansharesetOrganizationPlanByAdmin, takeendsAt, and return the resolved plan. The plan state was added to the admin org detail, the admin list rows and/v1/billing./free-seatsis kept, and/control-panelredirects to/billing.enterprisePlanandorganizationGrantsare retired (RETIRED_FEATURE_KEYS, Helm synced). The Control panel and grants code are removed. The grant tables, schema and typeid are kept, so no data is dropped (0 grants in production). Sandbox Free Auto is now refused in both Den API and the Gateway when the sandbox row is closed or expired.What else changed?
.spectral.yaml:OrganizationPlanState.endsAtis a calendar date, exempted fromow-timestamps-date-time.extraFreeAutoUsd.readAdminOpenWorkWebAccessmoved to its own module so the org detail can show OpenWork Web access.docs/enterprise-plan-gating.mdupdated.Deploy: ship Den API and the Gateway together. The Gateway's sandbox check replaces the benefit-setting check.
Pre-deploy ops step (not performed here): one grandfathered org (~32 users, joins via SSO) must get enough users in the new Billing tab first, or new SSO sign-ins are refused. List at-risk orgs read-only:
DECISION NEEDED: a Free org with
teamPlanoff still sees today's legacy Free seats card (with its Upgrade to Team button) instead of the plan card. Team and Enterprise orgs always get the plan card. I chose the most conservative option, which means no change for Free orgs.Release note
An organization's plan and allowed users are now set in one place, and an Enterprise or Team plan from OpenWork lets people join up to its users by invitation, SSO or SCIM.
Evidence
evals/proofs/organization-billing.proof.test.tsadmin-organizations-list,admin-accessandsandbox-organizationsproofs. API tests:enterprise-plan,sandbox-organizations,billing-plans.Design: P1, P2, P3, P4, S1, S2, S3, C1, C5, V1
Screenshots (real size, from the proof run)