4d941f566f
Add app CRUD API endpoints, healthcheck service with node-cron scheduler, icon resolver (Lucide, Simple Icons, CDN, uploads), app management UI with Superforms, health badge component, and Docker health endpoint.
36 lines
3.7 KiB
Markdown
36 lines
3.7 KiB
Markdown
# Feature Context: Web App Launcher — MVP
|
|
|
|
## Current State
|
|
|
|
Phase 4 (App Registry & Healthcheck) is complete. All app CRUD API routes are implemented at `/api/apps` (GET/POST) and `/api/apps/[id]` (GET/PATCH/DELETE) with Zod validation and auth middleware. Status history is served from `/api/apps/[id]/status`. The healthcheck service performs HTTP HEAD/GET requests with AbortController timeouts, mapping responses to online/offline/degraded/unknown. The scheduler uses node-cron (default: every 60 seconds) with an initial delayed check on startup. Icon resolution supports lucide, simple-icons (CDN), direct URL, and emoji types. The app registry UI at `/apps` renders cards in a responsive grid with category filtering and an inline Superforms create form. Custom icon uploads are handled at `/api/uploads` with type (SVG/PNG/JPG/WebP) and size (<1MB) validation, saving to `static/uploads/`. A Docker healthcheck endpoint at `/api/health` returns 200 with no auth. All Svelte components use runes mode ($state, $derived, $props).
|
|
|
|
Phase 3 (Authentication System) is complete. The full local authentication flow is implemented: login, registration, logout, and JWT token refresh. `hooks.server.ts` validates access tokens on every request, injects `event.locals.user`/`session`, and silently rotates expired tokens via refresh tokens. Protected routes redirect to `/login`; guest-accessible board routes are exempt. Login and registration pages use Superforms + Zod with inline validation errors. Registration respects the `SystemSettings.registrationEnabled` toggle. Reusable middleware helpers (`requireAuth`, `requireAdmin`, `requireRole`) are available for downstream phases. The root layout injects user session into all page data. The root page redirects to the default board or login. `jwt.ts` and `password.ts` are thin re-exports from `authService` (no duplication). Build does not pass yet (Big Bang strategy — expected).
|
|
|
|
## Temporary Workarounds
|
|
|
|
- Permission model uses polymorphic pattern (entityType/targetType strings) without FK relations to avoid SQLite dual-FK constraint issues. Queries are done manually in `permissionService.ts`.
|
|
- JSON fields (backgroundConfig, config, healthcheckDefaults) are stored as String in SQLite and parsed at the application layer.
|
|
- `package.json` `prisma.seed` config triggers a deprecation warning — migrate to `prisma.config.ts` when upgrading to Prisma 7.
|
|
|
|
## Cross-Phase Dependencies
|
|
|
|
- Phase 2 depends on Phase 1 (project scaffolding, Prisma setup)
|
|
- Phase 3 depends on Phase 2 (user/group models, auth service) ✅
|
|
- Phase 4 depends on Phase 2 (app model, services layer)
|
|
- Phase 5 depends on Phase 2 (board/section/widget models) and Phase 4 (app widget references apps)
|
|
- Phase 6 depends on Phases 3-5 (admin needs auth, app, board entities)
|
|
- Phase 7 depends on Phase 1 (Tailwind, shadcn-svelte) and Phase 5 (board layout to polish)
|
|
- Phase 8 depends on all prior phases
|
|
|
|
## Implementation Notes
|
|
|
|
- Big Bang strategy: intermediate phases may not build/pass tests. Only Phase 8 must result in a fully working build.
|
|
- SQLite with Prisma — single file DB at `data/launcher.db`
|
|
- All env config via environment variables; `.env.example` provided as template
|
|
- Svelte 5 runes mode: use `$state`, `$derived`, `$effect` — NOT legacy stores for component state
|
|
- shadcn-svelte uses Bits UI primitives — each component is a local file, not a library import
|
|
- `App.Locals` uses `email` + `displayName` fields (aligned with User model, updated in Phase 2)
|
|
- Prisma client singleton at `src/lib/server/prisma.ts` — use this for all DB access
|
|
- Services export pure async functions (not classes), use immutable patterns
|
|
- `tsx` devDependency added for running the seed script
|