Review playground + API alignment for SvelteKit integration #65
Labels
No labels
domain:backend
domain:devops
domain:frontend
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
forgejo_admin/pal-e-docs-app#65
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Type
Feature
Lineage
Follows
forgejo_admin/pal-e-docs-playground#1(playground prototype). Prerequisite for pal-e-app SvelteKit port.Repo
forgejo_admin/pal-e-appUser Story
As a developer porting the playground to SvelteKit,
I want confirmed alignment between the playground HTML/CSS, the pal-e-docs API responses, and the pal-e-app component architecture,
So that the port is mechanical copy-paste with data bindings — not a redesign.
Context
The pal-e-docs-playground has 6 pages (dashboard, notes list, note detail, project page, board, graph) with data contract comments (
@route,@data,@api,@components). Before porting, we need to verify:@datafield actually exists in the API response@apiendpoint exists and returns the expected shapeapp.cssis compatible with the existingsrc/app.css(or replaces it)File Targets
Files to review (read-only, no changes):
~/pal-e-docs-playground/*.html— all 6 pages, their data contracts~/pal-e-docs-playground/app.css— design system to port~/pal-e-app/src/app.css— current design system to compare/replace~/pal-e-app/src/lib/components/blocks/— existing block renderers~/pal-e-app/src/routes/— existing route structure~/pal-e-app/src/lib/api.ts— API client, verify endpoints match data contracts~/pal-e-docs/src/pal_e_docs/routes/— backend API endpointsFiles NOT to touch:
Acceptance Criteria
@datafield in playground HTML maps to a real API response field@apiendpoint in playground HTML exists in pal-e-docs backendstory:superuser-query)Test Expectations
Constraints
Checklist
Related
forgejo_admin/pal-e-docs-playground#1— playground prototypesop-frontend-experiment— the pipeline this followsstory:reader-browse— the user story being servedstory:superuser-query— search user story (gap)board-pal-e-docs— project boardScope Review: NEEDS_REFINEMENT
Review note:
review-451-2026-03-26Four fixable issues found before this ticket is ready for execution.
~/pal-e-app/src/lib/api.tsdoes not exist -- actual path is~/pal-e-app/src/lib/api-client.tsnote.html:18data contract lists "callout" andapp.csshas callout styles. Clarify intent.todo. State whether this review can proceed with the 6 existing pages or is blocked.Fixes for review findings
1. Wrong file path —
api.ts→api-client.ts. Fixed in ticket body.2. Callout contradiction — Callouts have been removed from
note.html(committed in2266820). The CSS still has callout classes as dead code — will clean up. Acceptance criterion is correct: 6 types, no callouts.3. Review vs search page conflict — Removing "search page added to playground" from this ticket. Search page is a separate ticket. This review is read-only alignment.
4. Board item #422 dependency — The playground prototype is functionally complete (6 pages, committed, pushed). Board item hasn't been moved but the work is done. Will move to in_progress.
Observations noted:
GET /api/boards/items?column=in_progressendpoint needs verification — may need to beGET /boards/activityAlignment Review: Playground vs API vs pal-e-app
Systematic comparison of all 6 playground HTML files, the pal-e-docs backend API, and the pal-e-app SvelteKit codebase. Read-only review -- no code changes.
1. Matches -- What Copies As-Is
Block types (6/6 match):
The playground uses 6 block types and the BlockRenderer dispatches all 6 identically:
block--paragraphblock_type === 'paragraph'ParagraphBlock.svelteblock-heading(h2)block_type === 'heading'HeadingBlock.svelteblock--codeblock_type === 'code'CodeBlock.svelteblock--tableblock_type === 'table'TableBlock.svelteblock--list(ul/ol)block_type === 'list'ListBlock.svelteblock--mermaidblock_type === 'mermaid'MermaidBlock.svelteAPI endpoints (core reads all exist):
@apiGET /api/notes?sort=updated_at&limit=10GET /notes(orders byupdated_at desc)listNotes({limit:10})GET /api/notes?sort=updated_at&limit=50listNotes({limit:50})GET /api/notes/{slug}GET /notes/{slug}getNote(slug)GET /api/notes/{slug}/blocksGET /notes/{slug}/blocksgetNoteBlocks(slug)GET /api/notes/{slug}/tocGET /notes/{slug}/tocgetNoteToc(slug)GET /api/notes?parent_slug={slug}GET /notes?parent_slug=XlistNotes({parent_slug})GET /api/projectsGET /projectslistProjects()GET /api/boards/items?column=in_progressGET /boards/activity?column=in_progresslistBoardActivity({column:'in_progress'})/boards/items, real is/boards/activity)Data contract fields -- notes:
@datafor notes list:{ slug, title, note_type, project, status, tags[], updated_at }-- all present inNoteSummaryschema (hasid, title, slug, is_public, note_type, status, parent_slug, position, project, tags, created_at, updated_at). Playground is a subset. MATCH.@datafor note detail:{ title, slug, note_type, status, tags[], project, updated_at, parent_slug }-- all inNoteOut. MATCH.blocks: Block[]with types heading/paragraph/code/table/list/mermaid --BlockOutreturnsblock_type, content, anchor_id, position. MATCH.toc: { anchor_id, text, level }[]--TocEntryschema has exactly these 3 fields. MATCH.knownSlugs: Set<string>--slugCache.tsalready fetches all slugs for autolink. MATCH.Existing route structure:
/(dashboard)/(+page.svelte)/notes/notes/notes/[slug]/notes/[slug]/boards/[slug]/boards/[slug]/projects/[slug]/projects/[slug]/graph2. API Gaps
Gap A:
note_countandlast_updatedon projects@data:projects: { slug, name, note_count, last_updated }[]ProjectOut: returnsid, name, slug, platform, repo_url, is_public, page_note, created_at, updated_at-- nonote_countfieldupdated_at.note_countwould need either a new field onProjectOutor a client-side count from notes listupdated_atalready present.note_countis nice-to-have; could be derived client-side by counting notes per projectGap B: No
descriptionfield on ProjectOut (used in playground project cards)ProjectOutdoes NOT have adescriptionfield in the schema. But theProjectmodel likely has one sinceprojects/[slug]/+page.svelterendersproject.description. Let me check... The existing pal-e-app already rendersproject.descriptionsuccessfully, and theProjectinterface inapi-client.tsincludesdescription: string | null. So the field exists at the API level even if the formal Pydantic schema doesn't show it in the grep. Non-issue.Gap C:
GET /notes/{slug}/linksnot used by pal-e-appbacklinks: { slug, title, note_type }[]GET /notes/{slug}/linksexists inlinks.py-- returns outgoing + incoming links withdirectionfieldgetLinks().getLinks(slug)toapi-client.tsand wire intoNoteLayout.svelte.Gap D: No
sortquery parameter on notes endpointGET /api/notes?sort=updated_at&limit=10list_notes()always sorts byupdated_at desc(hardcoded). There is nosortquery param.Gap E: Playground board
@datausesforgejo_issue_urlon board itemsBoardItemOutincludesforgejo_issue_url. API clientBoardItemtype does NOT include it.api-client.tsBoardIteminterface is missing:forgejo_issue_url,board_note_id3. Component Gaps
Gap F:
calloutblock type mentioned in playground data contract but not implementednote.html@datacomment:blocks: Block[] (any combination of: heading, paragraph, code, table, list, mermaid, callout)calloutblock appears in the playground HTML, and BlockRenderer has no callout case@datacomment is aspirational. The{:else}fallback in BlockRenderer already handles unknown types gracefully.Gap G: Nav component differences
Dashboard | Projects | Notes | Boards | Graph(5 links)Dashboard | Notes | Projects | Boards | Tags | Repos(6 links, different order, no Graph)Gap H: Left sidebar component does not exist in pal-e-app
sidebar-leftwith: recently modified notes, parent/sibling hierarchy, project listGap I: Right sidebar -- backlinks missing
NoteLayout.svelteright sidebar: TOC + Child Notes sections (no backlinks)Gap J:
FilterBarcomponent does not existAll | sop | convention | doc | project-page | boardGap K:
BoardProgresssummary component on project pageGap L:
GraphViewcomponent does not exist in pal-e-app/graphrouteGap M: Breadcrumb component differences
Home > project > note-slugHome > Notes > project > parent > note-title4. Route Gaps
index.html(Dashboard)/notes.html(Notes list)/notesnote.html(Note detail)/notes/[slug]note-project.html(Project)/projects/[slug]note-board.html(Board)/boards/[slug]graph.html(Graph)/graph/search/dashboard/tags,/tags/[name]/repos/notes/[slug]/edit5. CSS Assessment
Playground
app.css(819 lines) vs pal-e-appsrc/app.css(478 lines)Shared design tokens:
--color-bg: #fafafa,--color-text: #1a1a1a,--color-accent: #0366d6--color-nav-bg: #1a1a1a)--radius-sm/md/lg)Key CSS differences:
.site-nav,.note-card,.block--paragraph).flex,.gap-2,.text-sm) + some semantic classes*, *::before, *::after { margin:0; padding:0; box-sizing:border-box; }font-size: 0.9375rem; line-height: 1.7line-height: 1.6(no explicit size)--color-surface,--color-accent-light,--color-pre-bg--color-card-bg,--color-card-border,--color-surface(partial overlap)--type-plan: #d97706,--type-issue: #2563eb, etc. via CSS varscolors.tsTypeScript map:plan: '#b8860b',issue: '#2563eb'.block,.block--paragraph,.block--code,.code-header<style>in each Svelte component.layout { display: flex }with.sidebar-left+.content+.sidebar-rightmin-width: 600px(mobile-first)max-width: 600px(desktop-first for some rules).board-card,.board-colwith CSS vars for column colors.flex,.gap-2, etc.)CSS assessment summary: The playground CSS is a complete, coherent design system with semantic class names and mobile-first breakpoints. The pal-e-app CSS is a hybrid of Tailwind-like utility classes and custom properties. The playground
app.cssshould REPLACE the pal-e-appapp.css, and components should be refactored to use playground class names instead of utility classes. This is the core CSS axiom fromsop-frontend-experiment: "The CSS is never rewritten."Color conflict detail: Playground uses CSS custom properties for type colors (
--type-plan, etc.) while pal-e-app uses a TypeScriptTYPE_COLORSmap with different hex values:plan: playground#d97706vs app#b8860bphase: playground#059669vs app#0e8a5fsop: playground uses--type-issue(#2563eb) vs app#c2185bconvention: playground uses--type-project(#7c3aed) vs app#b8860bDecision: Playground CSS vars should be the source of truth.
colors.tsshould read from CSS vars or be replaced.6. Conflicts
Conflict 1: Search page -- AC says "Search page spec added to playground" but ticket is read-only
The issue acceptance criteria include:
"Search page spec added to playground (currently missing -- story:superuser-query)". This contradicts the "Read-only review -- no code changes" constraint. The search page already exists in pal-e-app (/search/+page.svelte) with keyword/semantic/hybrid modes, but has no playground prototype. Recommendation: Flag this as discovered scope for a separate ticket. The existing search page works but doesn't have a playground design to port FROM. Create a new playground HTML for search, then port.Conflict 2: pal-e-app has features playground doesn't spec
/dashboard(DORA dashboard) -- detailed board analytics, needs-attention alerts, per-project breakdown. Not in playground./tags,/tags/[name]-- tag browsing. Not in playground./repos-- repo listing. Not in playground./notes/[slug]/edit-- note editor. Not in playground.QuickJot-- floating action button + modal for quick note creation. Not in playground.Decision needed: Do these pal-e-app-only features survive the playground port, or do they need playground prototypes first? The SOP says "playground IS production" -- does that mean features without a playground page get removed?
Conflict 3: Layout architecture mismatch
max-width: 48rem; margin: 2rem auto) with optional right sidebar only on note detail+layout.svelte. The<main>wrapper changes from max-width-constrained to flex-panel-based.Conflict 4: Dashboard identity
/is "What changed recently?" dashboard (recent notes, projects, in-progress)/is similar but styled differently/dashboardis a separate DORA analytics pageSummary Table
note_counton projects)/graph), 5 redesignsDesign Decisions (2026-03-27)
Based on the alignment review gap list and the design vision (
Notion content + Obsidian navigation + activity-first):/notesroute.app.cssreplaces pal-e-app's. Deletecolors.ts— pure CSS custom properties only. TS intermediary breaks playground→production copy-paste.These decisions unlock the SvelteKit port tickets.