| name | skriptoteket-frontend-specialist |
| description | 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). |
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.
- Lock styling down with a tokens-first setup:
tokens.css(canonical--huleedu-*) +tailwind-theme.css(Tailwind bridge via@theme inline). - Use the SPA button primitives (
btn-primary,btn-cta,btn-ghost) fromfrontend/apps/skriptoteket/src/assets/main.cssto avoid drift. - 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/ - (Legacy) islands:
frontend/islands/
- SPA app:
Workflow
- Work from the repo root:
- Backend dev:
pdm run dev - Frontend install:
pdm run fe-install - SPA dev server:
pdm run fe-dev - 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.
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