Files
Musify/frontend/CLAUDE.md
T

2.1 KiB

Musify — Frontend web

Web pública de Musify. Para diseño y recetas de UI usa el skill musify-web.

Stack

SvelteKit 2 (adapter-node) · Svelte 5 runes · Tailwind 4 · TypeScript strict · auth OIDC Zitadel (openid-client + jose).

No hay svelte.config.js (config inline en vite.config.ts) ni tailwind.config.js (config en src/routes/layout.css).

Comandos

npm run dev      # servidor de desarrollo (puerto 5173)
npm run build
npm run check    # svelte-check — debe salir 0 errores antes de cerrar un cambio

Reglas

  • Sin comentarios en el código salvo que sean imprescindibles.
  • Svelte 5 runes siempre: $props() con interface Props, $state, $derived, $effect. Nada de export let ni $:. {#each} siempre con clave.
  • Server-only bajo $lib/server/; nunca importado desde cliente.
  • Datos SSR vía load en +page.server.ts/+layout.server.ts → prop data.
  • Enlaces a endpoints +server.ts (login/logout) llevan data-sveltekit-reload.
  • Reutiliza los tokens/recetas del sistema de diseño; extrae a $lib/components/ui/ lo que se repita.

Auth

hooks.server.ts valida la cookie de sesión cifrada (mf_session), refresca el access_token y puebla locals.user / locals.accessToken. Para proteger una ruta, comprueba locals.user en su load y redirige a /login?returnTo=…. Para el backend, envía locals.accessToken como Bearer hacia API_BASE_URL.

Variables de entorno en .env (ver .env.example): ZITADEL_*, AUTH_REDIRECT_URI, AUTH_POST_LOGOUT_URI, SESSION_SECRET, API_BASE_URL.

Backend API

Cliente tipado con openapi-fetch sobre el OpenAPI de Musify.Api. En un load/action server:

import { createApiClient } from '$lib/server/api';
const api = createApiClient({ fetch, accessToken: locals.accessToken ?? undefined });
const { data, error: err } = await api.GET('/tracks');

Devuelve { data, error } (estilo ErrorOr), no lanza. Los tipos viven en src/lib/api/schema.d.ts y se regeneran con npm run gen:api (requiere la API dev levantada en API_BASE_URL, que expone /openapi/v1.json solo en Development).