@assembly-js/app-foundation 0.0.26 → 0.0.27-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +12 -0
- package/package.json +1 -1
package/CLAUDE.md
CHANGED
|
@@ -398,6 +398,16 @@ If `tsc --noEmit` is clean and the task says "verify the build", run `bun run bu
|
|
|
398
398
|
`bun run build` also **fails** if a page route is unreachable — no link, `router.push`, redirect, or other entry point elsewhere points at it. Fix as the error instructs by adding an entry point on a reachable page. Run `bun run check:route-reachability` to check it on its own.
|
|
399
399
|
<!-- /feature:app-owned-header -->
|
|
400
400
|
|
|
401
|
+
### What a passing build proves
|
|
402
|
+
|
|
403
|
+
`tsc --noEmit` and `bun run build` prove the code compiles and the static checks pass. Neither renders a page, so both stay green while a page 500s for every visitor — a function passed into a client component, a browser-only import in server code, a field the sample record happened to have. A query against the sandbox database or an SDK call shows the data is there, not that the page reading it renders.
|
|
404
|
+
|
|
405
|
+
You cannot open the app as a signed-in client or team member, and you cannot see the published app or its logs. The builder preview is the user's own signed-in session, so the one runtime signal you have is the dev-server log (`assembly-dev-server-logs`): after changing a page or route, read it for new errors before calling the change done, and when nothing has requested the changed screen yet, ask the user to open it in the preview.
|
|
406
|
+
|
|
407
|
+
Close every turn, and answer every "does it work" or "is it safe to publish", by naming the checks that ran in those terms and the screens you could not open — which page, as which kind of user — so the user opens them. Say this unprompted, every time, not only when the prompt asks for a manual check. Say "fixed", "working", or "good to publish" only for behaviour you exercised; otherwise say what you checked and what is still unseen.
|
|
408
|
+
|
|
409
|
+
When the user reports that the published app errors, do not blame a cold start, caching, or a stale tab without evidence. Ask for the page, who was signed in, and the exact error text or code; reproduce it in the sandbox — the same screen in the preview or the same request against the dev server — and read the dev-server log. If you cannot reproduce it, say so and ask for those details rather than asking the user to reload.
|
|
410
|
+
|
|
401
411
|
---
|
|
402
412
|
|
|
403
413
|
## Labels, copy, and dropdowns
|
|
@@ -1138,6 +1148,7 @@ Use `AssemblyBridge.header.*` for breadcrumbs, CTAs, and actions menu. See `.cla
|
|
|
1138
1148
|
<!-- /feature:app-owned-header -->
|
|
1139
1149
|
- ❌ Don't let two mounted components call `useAssemblyHeader` at once — e.g. a parent shell's scaffolding-era stub CTA left in place after a child took real ownership. Strict Mode hides the race in dev; the hook throws in dev and ignores the second caller in production. Delete the parent's stub the moment a child owns the slot.
|
|
1140
1150
|
- ❌ Don't `window.open(url, '_self')` or set `window.location` for external links — use `<a target="_blank" rel="noreferrer">`.
|
|
1151
|
+
- ❌ Don't open one of your own route handlers by plain navigation for a download or export — `<a href="/api/…/pdf" target="_blank">`, `window.open('/api/…')`. The bearer cookie is partitioned to the portal iframe, so a new tab arrives signed out and `requireAuth` rejects it; the build passes and the link only fails in a live test. Fetch it with `authFetch`, read the response with `res.blob()`, and click a programmatic anchor on `URL.createObjectURL(blob)` with a `download` name. (`assembly-storage` shows the same flow for a route that returns a pre-signed URL as JSON rather than the bytes.)
|
|
1141
1152
|
- ❌ Don't hardcode brand colors. The portal applies the workspace theme.
|
|
1142
1153
|
- ❌ Don't add dark mode support (`dark:` classes, `.dark` class toggling, `next-themes`, `ThemeProvider`, or `prefers-color-scheme` media queries). The assembly-ui registry is light-only and the layout forces `colorScheme: 'light'`.
|
|
1143
1154
|
- ❌ Don't handle the session token at all — no cookie you set, no `useAssembly().token`, no `x-assembly-token` header, no `searchParams.token`. The middleware already exchanged it for a bearer cookie; call `getAssembly()` / `getAssemblyForRequest(req)` server-side and the call is authenticated.
|
|
@@ -1163,6 +1174,7 @@ Use `AssemblyBridge.header.*` for breadcrumbs, CTAs, and actions menu. See `.cla
|
|
|
1163
1174
|
- ❌ Don't add a manual close button (a `<DialogClose>` render or any X button) inside `DialogContent`. `DialogContent` already ships a built-in close button (`showCloseButton` defaults to `true`); adding another produces two overlapping X icons in the top-right corner. Only pass `showCloseButton={false}` when a custom affordance genuinely replaces the built-in one.
|
|
1164
1175
|
- ❌ Don't edit `next.config.ts` — it's the platform-owned wrapper that keeps the preview working (cross-origin hydration, WebSocket-blocked networks), and `bun run build` fails if it's rewritten. Your Next configuration belongs in `app.config.ts`.
|
|
1165
1176
|
- ❌ Don't import a native or browser-only library into server code without the serverless setup — `bun run build` passes but the deployed route crashes at request time. Decide the layer first per "Server runs in serverless Node" above.
|
|
1177
|
+
- ❌ Don't call a change verified, working, or safe to publish because `tsc --noEmit` and `bun run build` passed — name the checks that ran and the signed-in screens left unopened. See "What a passing build proves" above.
|
|
1166
1178
|
- ❌ Don't pass a function — or an object that holds one, like a question/field config with `visibleWhen`, `validate`, `render`, or `format` callbacks — as a prop from a server component or page into a `'use client'` component. Props cross that boundary as serialized data, so the render throws `Functions cannot be passed directly to Client Components` and the page 500s for every visitor no matter what the record holds. `tsc --noEmit` and `bun run build` both pass. Keep such a config in a shared module the client component imports itself, or express the logic as data (`{ showWhen: { field: 'entityType', equals: 'llc' } }`) and interpret it client-side.
|
|
1167
1179
|
- ❌ Don't use `Select` or `Combobox` to pick any Assembly person or organization record (clients, internal users, team members, staff, companies). Always use `UserCompanySelector` — in forms, filters, dropdowns, "assign to" controls, everywhere.
|
|
1168
1180
|
- ❌ Don't use `Combobox` when the user asks for a "dropdown" or "select" — use `Select`. Only use `Combobox` when the user explicitly needs type-to-search/filter functionality for non-user/non-company data.
|