Skip to content

Commit 1241c81

Browse files
committed
Keep the Platform zone absent for an organization the flag has not reached
With the zone built and the flag off, /org still rendered the full Platform for anyone who opened it; only the legacy redirect read the flag. The surface read now says whether the zone is open, and the shell answers not found when it is not. Undeployed runs with no base path keep working.
1 parent 4a15f13 commit 1241c81

7 files changed

Lines changed: 35 additions & 21 deletions

File tree

‎.github/scripts/http-e2e.sh‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -448,7 +448,7 @@ JS
448448
run_platform_live zone platform-live || live_status=$?
449449
stop_app
450450
start_app platform-live-flag-off 3027 'Platform main, flag off' record-http-status
451-
PLATFORM_LIVE_ZONE=1 run_platform_live flag-off platform-live-flag-off || live_status=$?
451+
run_platform_live flag-off platform-live-flag-off || live_status=$?
452452
exit "$live_status"
453453
;;
454454

‎.github/workflows/platform-design.yml‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,12 @@ jobs:
156156
- name: Run the live suite
157157
working-directory: apps/sim
158158
run: bash ../../.github/scripts/http-e2e.sh platform-live-${{ matrix.topology }}
159+
- name: Hold the parity ledger to this run
160+
if: always() && matrix.topology == 'zone'
161+
run: >-
162+
bun run scripts/check-platform-parity.ts
163+
--report "$RUNNER_TEMP/e2e/platform-live/report.json"
164+
--report "$RUNNER_TEMP/e2e/platform-live-flag-off/report.json"
159165
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
160166
if: always()
161167
with:

‎apps/sim/lib/api/contracts/organization.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -556,6 +556,8 @@ const organizationSurfaceResponseSchema = z.object({
556556
deployment: deploymentShapeSchema,
557557
/** Which destinations the viewer's navigation lists; none of these authorizes the page behind it. */
558558
navFlags: z.object({
559+
/** Whether the Platform zone is open to this organization at all. */
560+
platformOrgUi: z.boolean(),
559561
people: z.boolean(),
560562
simLinks: z.boolean(),
561563
benchmark: z.boolean(),

‎apps/sim/lib/organizations/application/surface.ts‎

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
import { resolveOrganizationSurfaceFlags } from '@/lib/organizations/surface-flags'
1717
import { canBrowsePeople } from '@/lib/people/feature-flag'
1818
import { isPlatformAdmin } from '@/lib/permissions/super-user'
19+
import { isPlatformOrgUiEnabled } from '@/lib/platform/rollout'
1920
import { isSimLinksEnabled } from '@/lib/sim-links/feature-flag'
2021
import { organizationSurfaceSettingsNavigation } from '@/app/o/[organizationId]/settings/navigation'
2122

@@ -48,18 +49,20 @@ export const readOrganizationSurface: OperationUseCase<
4849
const context = await getOrganizationSurfaceContext(organizationId, userId)
4950
if (!context) throw new OrganizationMembershipNotFoundError()
5051

51-
const [{ flags, benchmarkEnabled }, people, simLinks, platformAdmin] = await Promise.all([
52-
resolveOrganizationSurfaceFlags(organizationId, userId),
53-
canBrowsePeople(organizationId, context.viewer.role),
54-
isSimLinksEnabled(organizationId),
55-
// Decides which links are drawn; the pages behind them authorize for themselves.
56-
isPlatformAdmin(userId).catch((error: unknown) => {
57-
logger.warn('Could not resolve platform administration navigation', {
58-
error: getErrorMessage(error),
59-
})
60-
return false
61-
}),
62-
])
52+
const [{ flags, benchmarkEnabled }, people, simLinks, platformAdmin, platformOrgUi] =
53+
await Promise.all([
54+
resolveOrganizationSurfaceFlags(organizationId, userId),
55+
canBrowsePeople(organizationId, context.viewer.role),
56+
isSimLinksEnabled(organizationId),
57+
// Decides which links are drawn; the pages behind them authorize for themselves.
58+
isPlatformAdmin(userId).catch((error: unknown) => {
59+
logger.warn('Could not resolve platform administration navigation', {
60+
error: getErrorMessage(error),
61+
})
62+
return false
63+
}),
64+
isPlatformOrgUiEnabled(organizationId),
65+
])
6366

6467
return {
6568
organization: context.organization,
@@ -71,6 +74,7 @@ export const readOrganizationSurface: OperationUseCase<
7174
settingsFeatures: context.settingsFeatures,
7275
deployment: context.deployment,
7376
navFlags: {
77+
platformOrgUi,
7478
people,
7579
simLinks,
7680
benchmark: benchmarkEnabled,

‎apps/sim/platform/app/(shell)/_components/live-shell/live-shell.tsx‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { type ReactNode, Suspense } from 'react'
22
import { cookies } from 'next/headers'
3-
import { redirect } from 'next/navigation'
3+
import { notFound, redirect } from 'next/navigation'
44
import { AccessDenied, SurfaceUnavailable } from '@/platform/app/_components/shell-gate/shell-gate'
55
import { resolveLiveDestinations } from '@/platform/app/(shell)/_components/destinations'
66
import { LiveComposerHost } from '@/platform/app/(shell)/_components/live-shell/live-composer-host'
@@ -26,6 +26,10 @@ export async function LiveShell({ children }: { children: ReactNode }) {
2626
}
2727

2828
const { organization } = surface
29+
// Deployed, the zone exists only for an organization the rollout has reached.
30+
if (process.env.NEXT_PUBLIC_SIM_PLATFORM_BASE_PATH && !organization.navFlags.platformOrgUi) {
31+
notFound()
32+
}
2933
const cookieStore = await cookies()
3034
if (!hasOrganizationSurface(organization)) redirect(legacyRoutes(organization).workspaceSettings)
3135

‎apps/sim/platform/checks/live/flag-off/legacy-surface.spec.ts‎

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,9 @@ import { expect, type Page, test } from '@playwright/test'
22
import { adminEmail, organizationId, signIn } from '@/platform/checks/live/session'
33

44
/**
5-
* `PLATFORM_LIVE_ZONE=1` means the app was built with `SIM_PLATFORM_ORIGIN` and is running with the
6-
* flag off; unset, there is no zone at all, even with the flag on.
5+
* Runs twice: built with no `SIM_PLATFORM_ORIGIN`, with the flag on; and built with the zone, with
6+
* the flag off. Neither may change anything for the organization.
77
*/
8-
const zoneBuilt = process.env.PLATFORM_LIVE_ZONE === '1'
9-
108
const LEGACY_ROUTES = ['home', 'settings/members', 'people'] as const
119

1210
async function expectLegacySurface(page: Page, route: string) {
@@ -33,12 +31,11 @@ test('a client navigation stays on the legacy surface too', async ({ page }) =>
3331
await expect(page.locator('[data-platform-ui]')).toHaveCount(0)
3432
})
3533

36-
test('with no zone built, /org is absent', async ({ page }) => {
37-
test.skip(zoneBuilt, 'This build has a zone; its /org is exercised by the zone project')
34+
test('/org is absent', async ({ page }) => {
3835
for (const path of ['/org', '/org/home', '/org/settings/members']) {
3936
await signIn(page, adminEmail(), `/o/${organizationId()}/home`)
4037
const response = await page.goto(path)
4138
expect(response?.status(), path).toBe(404)
42-
await expect(page.locator('[data-platform-ui]')).toHaveCount(0)
39+
await expect(page.getByRole('button', { name: 'Organization menu' })).toHaveCount(0)
4340
}
4441
})

‎package.json‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
"check:actorless-executor-operations": "bun run scripts/check-actorless-executor-operations.ts",
4949
"check:permission-group-enforcement": "bun run scripts/check-permission-group-enforcement.ts",
5050
"check:platform-design": "bun run scripts/check-platform-design.ts",
51+
"check:platform-parity": "bun run scripts/check-platform-parity.ts",
5152
"check:platform-integration-metadata": "bun run scripts/sync-platform-integration-metadata.ts --check",
5253
"check:integration-access": "bun run scripts/check-integration-access.ts",
5354
"check:capability-subject": "bun run scripts/check-capability-subject.ts",

0 commit comments

Comments
 (0)