mirror of
https://github.com/PerpetualSoftware/pad.git
synced 2026-09-10 15:05:40 +00:00
f2c14dca79
## The web round, which had never had one The TypeScript union and CopyItemDialog changed across three commits with only the Go-side parity gate looking at them. First review round on those files found two, both in the sentences a user actually reads: `not_found` said "the item it refers to no longer exists". That reason is ALSO what the server collapses a hidden target to — telling the two apart is the existence oracle the collapse exists to prevent — so asserting non-existence is wrong for half the cases and is a claim the response cannot support. Now "could not be found". `target_missing` said "the field declares no collection to link to". It is emitted for two causes: no target declared, AND a declared target that is not a collection in this workspace. The wording named only the first and misdiagnosed the second as a schema that says nothing when it says something broken. Now "has no valid collection to link to", and the store's own message for the same reason was over-claiming identically and is fixed with it. Neither is a code defect. Both are the write-up half of the same rule this unit keeps enforcing: say what is true, not what is convenient. ## The consolidation, per the lead's CONVE-139 ruling Create and full-`fields` update each spelled out the SAME four steps — resolve the whole map, keep only the caller's issues, resolve the defaults validation injected after the main pass, drop a default whose target the caller cannot see. Round 10 was the third time one of those steps had to be stated separately, which is what showed the shape. Extracted into `resolveRelationsForWrite`, called twice, with the rule written once above it. NOT extended to the migrate doors, and stated in the code rather than left to look like an omission: they reach the same rule through `store.MigrateRelationReferents`, which cannot call this — the visibility layer is request-scoped by construction and `store` cannot import `server`. Unifying the families needs a caller-supplied visibility predicate on the store API. That is IDEA-2886, filed, with the shape it would take. Gates: internal/server ok 359.4s · internal/store ok 365.5s · go vet clean · gofmt clean · make lint 0 issues · npm run check 0 errors. Postgres green on the parent commit: store 543.9s, server 298.4s.
Pad Web UI
SvelteKit 2 + Svelte 5 frontend for Pad, compiled to static files and embedded into the Go binary.
Development
npm install
npm run dev # Dev server at localhost:5173 (proxies API to localhost:7777)
npm run build # Production build to build/
npm run check # Type checking with svelte-check
When developing, run the Go backend separately with make dev from the project root.
Building for Production
Do not build in isolation. Always use make build from the project root — this builds the web frontend, then compiles the Go binary with the build output embedded via //go:embed.
Stack
- Svelte 5 with runes (
$state,$derived,$effect) - SvelteKit 2 with
adapter-static(SPA mode) - Tiptap block editor with markdown round-trip
- svelte-dnd-action for drag-and-drop in board/list views
- SSE for real-time updates
- TypeScript throughout
Structure
src/
routes/ SvelteKit pages
+layout.svelte App shell (sidebar + main)
+page.svelte Landing/redirect
[workspace]/
+page.svelte Dashboard (collections, phases, activity)
+layout.svelte SSE connection per workspace
[collection]/
+page.svelte Collection view (board/list)
[collection]/[item]/
+page.svelte Item detail + editor
conventions/ Purpose-built conventions page
playbooks/ Purpose-built playbooks page
settings/ Workspace settings
lib/
api/client.ts HTTP API client
components/
layout/ Sidebar, navigation
editor/ Tiptap editor, raw markdown editor
fields/ FieldEditor, relation picker
items/ ItemCard, ItemDetail
collections/ BoardView, ListView
common/ StatusBadge, badges, modals
search/ CommandPalette
stores/ Svelte 5 reactive stores
workspace.svelte.ts Workspace state
collections.svelte.ts Collection + item state
ui.svelte.ts Sidebar, mobile state
types/index.ts TypeScript types and constants
app.css Global styles and design tokens