* Gate shared by every fork/promote route. The deployment/entitlement gate is * unchanged: on Sim Cloud the gate is the Enterprise plan; on self-hosted it's * `FORKING_ENABLED`, which 404s when unset so a newer image doesn't silently expose * forking. Mirrors the data-drains gate - this repo gate
(organizationId: string | null, userId: string)
| 22 | * deployments have no AppConfig, so their behaviour is untouched by the flag. |
| 23 | */ |
| 24 | async function assertForkingEnabled(organizationId: string | null, userId: string): Promise<void> { |
| 25 | if (!isBillingEnabled && !isForkingEnabled) { |
| 26 | throw new ForkError('Workspace forking is not enabled on this deployment', 404) |
| 27 | } |
| 28 | if (isBillingEnabled) { |
| 29 | const hasEnterprise = organizationId |
| 30 | ? await isOrganizationOnEnterprisePlan(organizationId) |
| 31 | : false |
| 32 | if (!hasEnterprise) { |
| 33 | throw new ForkError('Workspace forking is available on Enterprise plans only', 403) |
| 34 | } |
| 35 | } |
| 36 | if ( |
| 37 | isAppConfigEnabled && |
| 38 | !(await isFeatureEnabled('workspace-forking', { userId, orgId: organizationId })) |
| 39 | ) { |
| 40 | throw new ForkError('Workspace forking is not enabled on this deployment', 404) |
| 41 | } |
| 42 | } |
| 43 | |
| 44 | /** |
| 45 | * Domain error for fork/promote operations. Carries a concrete `statusCode` so |
no test coverage detected