CareerVector UI shell

The CareerVector UI lives under ui/ as a SvelteKit app that SSRs on Cloudflare Workers, hydrates in the browser, and persists durable state through the @cv/workspace-client SDK to D1 and the realtime relay. This document is the canon entry point for the human-facing surface.

Three top-level routes inside a workspace

Route Surface Primary components
/[wsId]/dashboard The matrix — every job in the workspace, scored, filterable, groupable Dashboard.svelte, table/*, job-detail/*
/[wsId]/kanban Phase-oriented pipeline view of the same jobs KanbanBoard.svelte, PhaseColumn.svelte
/[wsId]/cvl/[pane] Quarry editor (CV / CL / Notes / Settings) CVLEditor.svelte, editors/*

A read-only mirror at /view/[wsId]/... projects the same data with every write path globally disabled — see no-user-accounts.md and the read-only view canon doc.

Dashboard table

The dashboard is CareerVector's main product surface, not the CV generator. The matrix renders jobs as rows and a configurable column set:

  • Built-in columns — title, company, location, salary, score, status, added-at, score breakdown. Always available.
  • Custom columns — user-defined evaluation dimensions (boolean K.O.s, numeric 0–10, hard facts). Created via the Columns modal; populated by the evaluate stage; render through the same DataCell as built-ins.
  • Origin tinting — every cell carries actor identity from workspace_sub_doc_ops; the dashboard projects that into the per-cell origin map and tints by provider (see tinted-cell-by-actor).

Column order, widths, and visibility are stored in the layout and order-state sub-docs so peers see the same arrangement.

Per-job detail panel

Clicking a row opens JobDetail.svelte as a slide-over panel with five tabs:

Tab Tone Purpose
Overview neutral Identity fields, status, raw job posting metadata
Description primary Scraped / pasted description, edit access
Intel success Enrichment-derived facts: industry, signals
Scorecard error Multi-dimensional score breakdown
Commute warning Google Maps directions vs home address

Each tab is its own component so the panel hydrates lazily and the realtime patches scope to the touched tab.

Toolbar and modal stack

Toolbar.svelte and the toolbar modals under components/toolbar/modals/ provide the entry points for every workspace-wide configuration:

  • AddJob, JobImport, Import — bring jobs into the workspace.
  • CloudKeys, ai/ChainEditor — manage BYOK chains.
  • Columns, Kanban, Visuals — configure the dashboard / kanban surfaces.
  • Commute, Docs, Icons — workspace settings.

Each modal commits through the op catalog so the change syncs to other peers the same way a job-cell write does. See the toolbar-config-modals feature file for the contract.

Kanban view

KanbanBoard.svelte is the second projection over the same jobs. Phases come from settings.kanbanPhases; dragging a card across phases dispatches a job.update op so the dashboard's status column updates in real time.

Offline shell

service-worker.ts caches the app shell so a cold reload over flaky network still paints the workspace. The service worker does not cache realtime data — the workspace document arrives through the realtime channel — but it does keep navigation, modals, and the editor reachable while waiting for the relay.

Cloudflare Worker bindings

app.d.ts declares the SvelteKit Platform.env shape for +server.ts and *.server.ts files: CV_DB (D1), CV_BUCKET (R2), RELAY_CF (service binding), APP_MODE, JOBCACHE_* vars, ADMIN_TOKEN. Provider keys are typed loosely because the canonical set lives in lib/domain and is mirrored by wrangler.toml.

What this shell is not

  • Not the CV/PDF generator. PDF rendering happens inside the CVL editor via the Typst WASM client. The dashboard table is the product.
  • Not the place to add per-user state. Settings live in workspace sub-docs; browser localStorage is only for cosmetic preferences (see no-user-accounts.md).
  • Not the realtime broker. The Durable Object in relay/cf/ is. The UI is a client of that broker via the @cv/workspace-client SDK.
Source: wiki/content/canon/cv-ui-shell.md