# Phase 1: Database Schema & Type Foundation **Status:** ✅ Complete **Parent plan:** [PLAN.md](./PLAN.md) **Domain:** backend ## Objective Define all new database models, extend existing models, add new widget type constants, create TypeScript type definitions, and write Zod validation schemas for every new entity across Phases 4–7. ## Tasks ### 1.1 Extend Prisma schema with new models - [x] Add `Tag` model (id, name, color, createdAt) - [x] Add `AppTag` junction model (appId, tagId) - [x] Add `AppLink` model (id, appId, label, url, icon, order) - [x] Add `UserFavorite` model (id, userId, appId, order) - [x] Add `AppClick` model (id, userId, appId, clickedAt) - [x] Add `NotificationChannel` model (id, userId, type, config JSON, enabled, createdAt) - [x] Add `Notification` model (id, userId, appId, event, message, sentAt, readAt) - [x] Add `ApiToken` model (id, userId, name, tokenHash, scope, lastUsedAt, expiresAt, createdAt) - [x] Add `AuditLog` model (id, userId, action, entityType, entityId, details JSON, createdAt) - [x] Add `BoardTemplate` model (id, name, description, icon, config JSON, isBuiltin, createdById, createdAt) ### 1.2 Extend existing Prisma models - [x] `Board`: add `themeHue` (Int?), `themeSaturation` (Int?), `backgroundType` (String?), `cardSize` (String?), `wallpaperUrl` (String?), `wallpaperBlur` (Int?), `wallpaperOverlay` (Float?), `customCss` (String?) - [x] `Section`: add `cardSize` (String?) - [x] `User`: add `onboardingComplete` (Boolean, default false), `trackRecentApps` (Boolean, default true) - [x] `SystemSettings`: add `customCss` (String?), `onboardingComplete` (Boolean, default false) ### 1.3 Add relations to existing models - [x] `App` → `tags` (via AppTag), `links` (AppLink[]), `clicks` (AppClick[]), `notifications` (Notification[]) - [x] `User` → `favorites` (UserFavorite[]), `clicks` (AppClick[]), `notificationChannels` (NotificationChannel[]), `notifications` (Notification[]), `apiTokens` (ApiToken[]), `auditLogs` (AuditLog[]), `boardTemplates` (BoardTemplate[]) - [x] `Board` → (themeHue, themeSaturation etc. are scalar fields, no new relations needed) ### 1.4 Generate and apply Prisma migration - [x] Run `npx prisma migrate dev --name phase4-7-schema` to create migration - [x] Run `npx prisma generate` to update Prisma client ### 1.5 Extend widget type constants - [x] Add to `WidgetType` in `src/lib/utils/constants.ts`: `CLOCK`, `SYSTEM_STATS`, `RSS`, `CALENDAR`, `MARKDOWN`, `METRIC`, `LINK_GROUP`, `CAMERA` - [x] Add `CardSize` constant: `COMPACT`, `MEDIUM`, `LARGE` - [x] Add `NotificationType` constant: `DISCORD`, `SLACK`, `TELEGRAM`, `HTTP` - [x] Add `NotificationEvent` constant: `APP_ONLINE`, `APP_OFFLINE`, `APP_DEGRADED` - [x] Add `ApiTokenScope` constant: `READ`, `WRITE`, `ADMIN` - [x] Add `AuditAction` constant: `USER_CREATED`, `USER_DELETED`, `USER_UPDATED`, `BOARD_CREATED`, `BOARD_DELETED`, `APP_CREATED`, `APP_DELETED`, `SETTINGS_UPDATED`, `IMPORT`, `EXPORT` - [x] Add `BackgroundType` extension if needed (wallpaper type) ### 1.6 Create TypeScript type definitions - [x] Create `src/lib/types/tag.ts` — Tag, AppTag, CreateTagInput, UpdateTagInput - [x] Create `src/lib/types/notification.ts` — NotificationChannel, Notification, CreateChannelInput, NotificationPreferences - [x] Create `src/lib/types/apiToken.ts` — ApiToken, CreateTokenInput, TokenScope - [x] Create `src/lib/types/auditLog.ts` — AuditLog, AuditAction, CreateAuditLogInput - [x] Create `src/lib/types/template.ts` — BoardTemplate, CreateTemplateInput - [x] Extend `src/lib/types/widget.ts` — add config interfaces for all 8 new widget types: - ClockWeatherWidgetConfig: { timezone, showWeather, latitude?, longitude?, clockStyle } - SystemStatsWidgetConfig: { sourceUrl, sourceType, metrics[], refreshInterval } - RssWidgetConfig: { feedUrl, maxItems, showSummary } - CalendarWidgetConfig: { icalUrls: Array<{url, color, label}>, daysAhead } - MarkdownWidgetConfig: { content, syntaxTheme } - MetricWidgetConfig: { label, source, value?, url?, jsonPath?, query?, unit?, refreshInterval } - LinkGroupWidgetConfig: { links: Array<{label, url, icon?}>, collapsible } - CameraWidgetConfig: { streamUrl, type, refreshInterval, aspectRatio } - [x] Extend `src/lib/types/app.ts` — add AppLink type, extend App type with links[] and tags[] - [x] Extend `src/lib/types/user.ts` — add UserFavorite, AppClick, extend User with new fields - [x] Extend `src/lib/types/board.ts` — add theme/visual fields to Board type ### 1.7 Create Zod validation schemas - [x] Add widget config schemas in `src/lib/utils/validators.ts` for all 8 new widget types - [x] Add `createTagSchema`, `updateTagSchema` - [x] Add `createAppLinkSchema`, `updateAppLinkSchema` - [x] Add `createNotificationChannelSchema`, `updateNotificationChannelSchema` - [x] Add `createApiTokenSchema` - [x] Add `createBoardTemplateSchema` - [x] Add `auditLogQuerySchema` (filters: action, entityType, dateRange) - [x] Update `createWidgetSchema` to accept new widget type values - [x] Update `updateBoardSchema` to accept new theme/visual fields - [x] Update `updateSectionSchema` to accept cardSize - [x] Update `updateUserSchema` to accept onboardingComplete, trackRecentApps ## Files to Modify/Create - `prisma/schema.prisma` — extend with all new models and fields - `src/lib/utils/constants.ts` — new constant objects - `src/lib/types/tag.ts` — new file - `src/lib/types/notification.ts` — new file - `src/lib/types/apiToken.ts` — new file - `src/lib/types/auditLog.ts` — new file - `src/lib/types/template.ts` — new file - `src/lib/types/widget.ts` — extend with 8 new config interfaces - `src/lib/types/app.ts` — extend with AppLink, tags - `src/lib/types/user.ts` — extend with favorites, clicks, new fields - `src/lib/types/board.ts` — extend with visual/theme fields - `src/lib/utils/validators.ts` — all new Zod schemas ## Acceptance Criteria - All new Prisma models have correct fields, types, relations, and indexes - Migration applies cleanly to a fresh SQLite database - Prisma client generates without errors - All TypeScript types use `readonly` for immutability - All Zod schemas validate correct inputs and reject invalid ones - New widget types are added to WidgetType constant - Existing code is not broken by schema additions (additive changes only) ## Notes - All new fields on existing models must be optional or have defaults to avoid breaking existing data - Use `cuid()` for all new model IDs consistent with existing schema - Store JSON configs as String in Prisma (SQLite limitation), parse with Zod on read - Keep immutable patterns — all type interfaces use `readonly` ## Review Checklist - [x] All tasks completed - [x] Code follows project conventions - [x] No unintended side effects - [ ] Build passes (Big Bang: code quality check only) - [ ] Tests pass (Big Bang: skipped for intermediate phase) ## Handoff to Next Phase ### What was done - Extended Prisma schema with 10 new models: Tag, AppTag, AppLink, UserFavorite, AppClick, NotificationChannel, Notification, ApiToken, AuditLog, BoardTemplate - Extended existing models (User, Board, Section, SystemSettings) with new fields - Added all relations between new and existing models - Migration `20260325092024_phase4_7_schema` created and applied successfully - Prisma client regenerated - Added 7 new constant objects: CardSize, NotificationType, NotificationEvent, ApiTokenScope, AuditAction, BackgroundType, plus 8 new widget types - Created 5 new type files: tag.ts, notification.ts, apiToken.ts, auditLog.ts, template.ts - Extended 4 existing type files: widget.ts (8 new config interfaces), app.ts (AppLink + AppWithRelations), user.ts (UserFavorite, AppClick, UserWithPreferences), board.ts (theme/visual fields) - Added 19 new Zod schemas and updated 4 existing schemas in validators.ts ### What the next phase needs to know - All new Prisma models are available via the generated client - Widget type enum in constants.ts now has 13 values (5 original + 8 new) - All widget config Zod schemas follow the naming pattern `{type}WidgetConfigSchema` - New entity schemas follow the naming pattern `create{Entity}Schema` / `update{Entity}Schema` - `auditLogQuerySchema` supports pagination (page, limit) and date filtering (dateFrom, dateTo) - `App` model still has legacy `tags` string field; the new `AppTag` junction table provides structured tagging - All changes are additive — no breaking changes to existing API contracts ### Potential concerns - The legacy `App.tags` (comma-separated string) field still exists alongside the new `AppTag` junction. Later phases should decide whether to migrate data and deprecate the string field. - `updateSystemSettingsSchema` was extended with `customCss` and `onboardingComplete` — existing settings API route handlers will need to pass these through.