Files
pad/web
xarmian f2c14dca79 refactor: one write-door relation path, and neutral wording for two reasons (TASK-2878)
## 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.
2026-09-04 20:26:58 +00:00
..
2026-03-26 01:52:36 +00:00
2026-03-26 01:52:36 +00:00
2026-03-26 01:52:36 +00:00
2026-03-26 01:52:36 +00:00

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