Agent skill
skriptoteket-frontend-specialist
Skriptoteket frontend development (FastAPI backend + full Vue/Vite SPA) using the HuleEdu-aligned stack (Vue 3.5.x + Vite + TypeScript, Pinia, Vue Router, Tailwind CSS v4 tokens/@theme, HuleEdu design tokens, pnpm). Use for working in the `frontend/` pnpm workspace, SPA hosting/history fallback, implementing SPA features (auth, routing, state, API clients), and keeping the UI/auth model compatible with future HuleEdu teacher login integration (same entry point, no separate login).
Stars
163
Forks
31
Install this agent skill to your Project
npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/data/skriptoteket-frontend-specialist
SKILL.md
Skriptoteket Frontend Specialist
Defaults
- SPA-only: do not re-introduce template/HTMX UI (ADR-0027 clean-break cutover).
- Use Vue 3.5 Composition API with
<script setup lang="ts">. - Keep the frontend HuleEdu-aligned so it can be integrated into HuleEdu later (shared design tokens and compatible auth model).
- Keep integration costs low: avoid hardcoded base paths, isolate auth transport (cookie vs bearer), and prefer token-driven styling over bespoke CSS.
- Styling is tokens-first:
tokens.css(canonical--huleedu-*) +tailwind-theme.css(Tailwind bridge via@theme inline). - Single CSS entry point:
frontend/apps/skriptoteket/src/assets/main.css(imports Tailwind + tokens + theme once). - Use SPA primitives from
frontend/apps/skriptoteket/src/assets/main.cssto avoid drift:- Buttons:
.btn-primary,.btn-cta,.btn-ghost - Panels (nested):
.panel-inset,.panel-inset-canvas - Toasts:
.toast-*(viaToastHost) - Inline messages:
.system-message*(viaSystemMessage) - Badges:
.status-pill
- Buttons:
- No stacked brutal shadows: only the outermost “card/panel” gets
shadow-brutal*. Nested panels/fields inside a shadowed surface useshadow-none+ thicker, uniform borders (panel-inset*, orborder-2 border-navy/20). - No Tailwind default palette leakage in product UI: avoid
bg-slate-*,text-gray-*, etc. Prefer token-mapped utilities (bg-canvas,text-navy,shadow-brutal-sm) or CSS variables. - Page/editor transitions: prefer opacity-only transitions (hard borders/shadows shimmer when translated).
- Admin editor features: extract logic into
frontend/apps/skriptoteket/src/composables/editor/and keep views UI-only.
Repo map (Skriptoteket monolith)
- Backend (FastAPI + SPA hosting + APIs):
src/skriptoteket/web/- Static assets:
src/skriptoteket/web/static/(/static/*) - Built SPA assets:
src/skriptoteket/web/static/spa/(served via history fallback)
- Static assets:
- Frontend workspace (pnpm):
frontend/- SPA app:
frontend/apps/skriptoteket/
- SPA app:
Workflow
- Work from the repo root:
- Backend dev:
pdm run dev(orpdm run dev-logsfor log piping) - Frontend install:
pdm run fe-install - SPA dev server:
pdm run fe-dev(orpdm run fe-dev-logsfor log piping) - Local combo (backend + SPA):
pdm run dev-local - Container dev:
pdm run dev-start(logs:pdm run dev-containers-logs, rebuild:pdm run dev-rebuild) - SPA tests:
pdm run fe-test(Vitest),pdm run fe-type-check,pdm run fe-lint
- Backend dev:
- Implement in this order:
- OpenAPI models (backend) -> regenerate TypeScript types (
pdm run fe-gen-api-types) - API client calls in SPA
- Pinia stores for shared state, views/components for UI
- OpenAPI models (backend) -> regenerate TypeScript types (
- Keep styling token-driven and HuleEdu-compatible (ADR-0032 +
@theme inlinebridge). - Keep auth integration "pluggable" so HuleEdu SSO can be added without rewriting the SPA (ADR-0006/ADR-0011 + current cookie/CSRF transport).
Patterns
Pinia state
- Define stores with
defineStore(...); keep state/actions cohesive and typed. - Avoid destructuring the store object; use
storeToRefs(store)when you need refs. - Centralize auth/session state in one store and let router guards depend on it.
Routing + hosting
- Use history mode routing with server-side fallback (backend serves
index.htmlfor non-API routes). - Avoid hardcoding absolute paths; keep router base aligned with Vite
base.
API contracts
- Treat OpenAPI as the source of truth and generate TypeScript types via
openapi-typescript. - Keep response/error envelopes consistent; handle 401/403 centrally.
Auth (integration-ready)
- Current Skriptoteket reality: cookie-session auth + CSRF for mutating requests.
- Future HuleEdu integration: identity federation without shared authorization (keep Skriptoteket roles local).
- In the SPA, isolate auth transport details behind a small adapter (cookie vs bearer) so the UI can run in both modes.
Layout + editor ergonomics
- Full-height editor routes:
- Wrap route content in
route-stage+route-stage-item(seefrontend/apps/skriptoteket/src/App.vue). - Use
route-stage--editorfor editor routes so nested flex/grid children can usemin-h-0. - In authenticated layout, use the editor variant (
auth-main-content--editor) to avoid double scrollbars and let the editor manage its own scroll regions (seefrontend/apps/skriptoteket/src/components/layout/AuthLayout.vue).
- Wrap route content in
- Focus mode (width matters):
- Persisted per user via
useLayoutStore(frontend/apps/skriptoteket/src/stores/layout.ts). - Editor is the primary entry point for toggling; ensure the user is never “trapped” without an exit control.
- Persisted per user via
- Drawers:
- Reuse the existing right-side drawer surface for editor chat/history; don’t introduce a second sidebar.
- Prefer
bg-canvas+border-navy+shadow-brutal-smfor drawer frames (seeEditorWorkspacePanel.vue).
- Dense toolbars:
- Use the editor micro-typography pattern:
text-[10px] font-semibold uppercase tracking-wide text-navy/60. - Use
.btn-ghostwith size/shadow overrides for 28px controls (seeEditorWorkspaceToolbar.vue).
- Use the editor micro-typography pattern:
Testing (Vitest)
- Config:
frontend/apps/skriptoteket/vitest.config.ts - Setup:
frontend/apps/skriptoteket/src/test/setup.ts - Tests:
frontend/apps/skriptoteket/src/**/*.spec.ts(colocate with code) - Commands:
pdm run fe-test/pdm run fe-test-watch/pdm run fe-test-coverage - Prefer testing pure helpers/composables and mocking HTTP via
vi.mockrather than snapshot-heavy component tests.
HuleEdu compatibility checklist
- Versions: Vue 3.5.x / Pinia 3.x / Vue Router 4.6.x / Vite 6.x (match HuleEdu minor lines).
- Paths: use
import.meta.env.BASE_URL+ relative URLs so the SPA can be hosted under a subpath. - Auth: handle 401 centrally; do not assume a separate Skriptoteket login UI exists in "integrated" mode.
- Styling: use HuleEdu tokens as the contract; avoid hard-coded colors/fonts.
Context7 lookups
Use Context7 when you need exact API details or version-specific behavior:
- Vue 3 docs:
/vuejs/docs(Composition API,<script setup>) - Pinia docs:
/vuejs/pinia(setup stores, TypeScript, best practices) - Vue Router docs:
/vuejs/vue-router(route meta, guards) - Vite v6 docs:
/websites/v6_vite_dev(config, proxy, dev server) - Tailwind v4 docs:
/websites/tailwindcss(theme variables,@theme,@reference) - Vitest v4 docs:
/vitest-dev/vitest/v4.0.7(mocking,vi.mock,vi.mocked)
References
- SPA adoption:
docs/adr/adr-0027-full-vue-vite-spa.md - SPA hosting + history fallback:
docs/adr/adr-0028-spa-hosting-and-history-fallback.md - OpenAPI + TS generation:
docs/adr/adr-0030-openapi-and-frontend-types.md - Tailwind v4 tokens bridge:
docs/adr/adr-0032-tailwind-4-theme-tokens.md - Testing runbook:
docs/runbooks/runbook-testing.md - SPA design system rules:
.agent/rules/045-huleedu-design-system.md - Testing standards:
.agent/rules/070-testing-standards.md
Didn't find tool you were looking for?