diff --git a/plans/phase-2-enhanced-features/CONTEXT.md b/plans/phase-2-enhanced-features/CONTEXT.md new file mode 100644 index 0000000..f5cd083 --- /dev/null +++ b/plans/phase-2-enhanced-features/CONTEXT.md @@ -0,0 +1,21 @@ +# Feature Context: Phase 2 — Enhanced Features + +## Current State +MVP is complete and merged to master. All build/test/lint passes. 151 files, 115 tests. +Starting Phase 2 enhanced features on a new feature branch. + +## Temporary Workarounds +- None yet + +## Cross-Phase Dependencies +- Phase 1 (OAuth) is independent — touches auth system only +- Phase 2 (DnD) is independent — touches board editor UI only +- Phase 3 (Widgets) depends on existing widget system from MVP +- Phase 4 (Access Control) depends on existing permission system from MVP +- Phase 5 (Integration) depends on all prior phases + +## Implementation Notes +- Big Bang strategy: intermediate phases may not build. Phase 5 is the convergence phase. +- OAuth uses `openid-client` (already installed in MVP dependencies) +- DnD uses `svelte-dnd-action` (needs to be installed) +- New widget types extend the existing Widget model's `type` and `config` JSON fields diff --git a/plans/phase-2-enhanced-features/PLAN.md b/plans/phase-2-enhanced-features/PLAN.md new file mode 100644 index 0000000..27f6a0e --- /dev/null +++ b/plans/phase-2-enhanced-features/PLAN.md @@ -0,0 +1,44 @@ +# Feature: Phase 2 — Enhanced Features + +**Branch:** `feature/phase-2-enhanced-features` +**Base branch:** `master` +**Created:** 2026-03-24 +**Status:** 🟡 In Progress +**Strategy:** Big Bang +**Mode:** Automated +**Execution:** Orchestrator + +## Summary +Add OAuth/Authentik integration, drag-and-drop reordering, localization (EN/RU), additional widget types (bookmark, note, embed, status), and per-board access control UI. + +## Build & Test Commands +- **Build:** `npm run build` +- **Test:** `npm test` +- **Lint:** `npm run lint` +- **Type Check:** `npm run check` + +## Phases + +- [ ] Phase 1: OAuth/Authentik Integration [fullstack] → [subplan](./phase-1-oauth.md) +- [ ] Phase 2: Drag-and-Drop Reordering [frontend] → [subplan](./phase-2-dnd.md) +- [ ] Phase 3: Localization EN/RU [fullstack] → [subplan](./phase-3-localization.md) +- [ ] Phase 4: Additional Widget Types [fullstack] → [subplan](./phase-4-widgets.md) +- [ ] Phase 5: Per-Board Access Control UI [fullstack] → [subplan](./phase-5-access-control.md) +- [ ] Phase 6: Integration & Polish [fullstack] → [subplan](./phase-6-integration.md) + +## Phase Progress Log + +| Phase | Domain | Status | Review | Build | Committed | +|-------|--------|--------|--------|-------|-----------| +| Phase 1: OAuth | fullstack | ⬜ Not Started | ⬜ | ⬜ | ⬜ | +| Phase 2: DnD | frontend | ⬜ Not Started | ⬜ | ⬜ | ⬜ | +| Phase 3: Localization | fullstack | ⬜ Not Started | ⬜ | ⬜ | ⬜ | +| Phase 4: Widgets | fullstack | ⬜ Not Started | ⬜ | ⬜ | ⬜ | +| Phase 5: Access Control | fullstack | ⬜ Not Started | ⬜ | ⬜ | ⬜ | +| Phase 6: Integration | fullstack | ⬜ Not Started | ⬜ | ⬜ | ⬜ | + +## Final Review +- [ ] Comprehensive code review +- [ ] Full build passes +- [ ] Full test suite passes +- [ ] Merged to `master` diff --git a/plans/phase-2-enhanced-features/phase-1-oauth.md b/plans/phase-2-enhanced-features/phase-1-oauth.md new file mode 100644 index 0000000..63c7927 --- /dev/null +++ b/plans/phase-2-enhanced-features/phase-1-oauth.md @@ -0,0 +1,58 @@ +# Phase 1: OAuth/Authentik Integration + +**Status:** ⬜ Not Started +**Parent plan:** [PLAN.md](./PLAN.md) +**Domain:** fullstack + +## Objective +Add OIDC/OAuth2 authentication via Authentik, including redirect/callback flows, auto-provisioning users, and admin configuration UI. + +## Tasks + +- [ ] Task 1: Create `src/lib/server/services/oauthService.ts` — OIDC client setup, discovery, token exchange +- [ ] Task 2: Create `src/routes/auth/oauth/authorize/+server.ts` — redirect to Authentik with PKCE +- [ ] Task 3: Create `src/routes/auth/oauth/callback/+server.ts` — handle callback, exchange code, provision user +- [ ] Task 4: Update `src/lib/server/services/userService.ts` — add `findOrCreateByOAuth()` for auto-provisioning +- [ ] Task 5: Update `src/routes/login/+page.svelte` — show OAuth button when auth mode is OAUTH or BOTH +- [ ] Task 6: Update `src/routes/login/+page.server.ts` — load auth mode from SystemSettings +- [ ] Task 7: Update `src/routes/admin/settings/+page.svelte` — make OAuth config fields functional (client ID, secret, discovery URL) +- [ ] Task 8: Update `src/lib/components/admin/SettingsForm.svelte` — add OAuth test connection button +- [ ] Task 9: Update `src/hooks.server.ts` — handle OAuth sessions alongside local JWT sessions +- [ ] Task 10: Add env vars to `.env.example` — OAUTH_CLIENT_ID, OAUTH_CLIENT_SECRET, OAUTH_DISCOVERY_URL, OAUTH_REDIRECT_URI + +## Files to Modify/Create +- `src/lib/server/services/oauthService.ts` — NEW +- `src/routes/auth/oauth/authorize/+server.ts` — NEW +- `src/routes/auth/oauth/callback/+server.ts` — NEW +- `src/lib/server/services/userService.ts` — MODIFY +- `src/routes/login/+page.svelte` — MODIFY +- `src/routes/login/+page.server.ts` — MODIFY +- `src/routes/admin/settings/+page.svelte` — MODIFY +- `src/lib/components/admin/SettingsForm.svelte` — MODIFY +- `src/hooks.server.ts` — MODIFY +- `.env.example` — MODIFY + +## Acceptance Criteria +- OAuth login redirects to Authentik and returns with valid session +- New OAuth users are auto-provisioned with correct role/groups +- Existing users can link OAuth identity +- Admin can configure OAuth provider in settings +- Auth mode selector (local/oauth/both) controls which login options appear +- Login page shows appropriate buttons based on auth mode + +## Notes +- Use `openid-client` for OIDC discovery and token exchange +- Store OAuth state/nonce in HTTP-only cookies for CSRF protection +- Map Authentik groups to local groups by name +- OAuth users have nullable password field +- ⚠️ Big Bang: may not fully work until Phase 5 integration + +## Review Checklist +- [ ] All tasks completed +- [ ] Code follows project conventions +- [ ] No unintended side effects +- [ ] Build passes +- [ ] Tests pass (new + existing) + +## Handoff to Next Phase + diff --git a/plans/phase-2-enhanced-features/phase-2-dnd.md b/plans/phase-2-enhanced-features/phase-2-dnd.md new file mode 100644 index 0000000..07186b3 --- /dev/null +++ b/plans/phase-2-enhanced-features/phase-2-dnd.md @@ -0,0 +1,55 @@ +# Phase 2: Drag-and-Drop Reordering + +**Status:** ⬜ Not Started +**Parent plan:** [PLAN.md](./PLAN.md) +**Domain:** frontend + +## Objective +Add drag-and-drop reordering for sections within boards and widgets within/across sections using svelte-dnd-action. + +## Tasks + +- [ ] Task 1: Install `svelte-dnd-action` package +- [ ] Task 2: Create `src/lib/components/board/DraggableBoard.svelte` — board with draggable sections +- [ ] Task 3: Create `src/lib/components/section/DraggableSection.svelte` — section with draggable widgets +- [ ] Task 4: Create `src/lib/components/widget/DraggableWidget.svelte` — draggable widget wrapper +- [ ] Task 5: Update `src/routes/boards/[boardId]/edit/+page.svelte` — replace static editor with DnD editor +- [ ] Task 6: Create `src/routes/api/boards/[id]/reorder/+server.ts` — API to persist section order changes +- [ ] Task 7: Create `src/routes/api/boards/[id]/sections/[sid]/reorder/+server.ts` — API to persist widget order changes +- [ ] Task 8: Update `src/lib/server/services/boardService.ts` — add `reorderSections()` and `reorderWidgets()` functions +- [ ] Task 9: Add visual drag handles and drop zone indicators +- [ ] Task 10: Support moving widgets between sections via cross-section DnD + +## Files to Modify/Create +- `package.json` — add svelte-dnd-action +- `src/lib/components/board/DraggableBoard.svelte` — NEW +- `src/lib/components/section/DraggableSection.svelte` — NEW +- `src/lib/components/widget/DraggableWidget.svelte` — NEW +- `src/routes/boards/[boardId]/edit/+page.svelte` — MODIFY +- `src/routes/api/boards/[id]/reorder/+server.ts` — NEW +- `src/routes/api/boards/[id]/sections/[sid]/reorder/+server.ts` — NEW +- `src/lib/server/services/boardService.ts` — MODIFY + +## Acceptance Criteria +- Sections can be reordered via drag-and-drop in the board editor +- Widgets can be reordered within a section +- Widgets can be moved between sections +- Order changes persist via API calls +- Drag handles are visible and accessible +- Drop zones are visually indicated during drag + +## Notes +- `svelte-dnd-action` works well with Svelte 5 +- Use optimistic updates — reorder in UI immediately, sync to server in background +- Reorder APIs should accept an array of IDs in the new order +- ⚠️ Big Bang: may need integration fixes in Phase 5 + +## Review Checklist +- [ ] All tasks completed +- [ ] Code follows project conventions +- [ ] No unintended side effects +- [ ] Build passes +- [ ] Tests pass (new + existing) + +## Handoff to Next Phase + diff --git a/plans/phase-2-enhanced-features/phase-3-localization.md b/plans/phase-2-enhanced-features/phase-3-localization.md new file mode 100644 index 0000000..c739389 --- /dev/null +++ b/plans/phase-2-enhanced-features/phase-3-localization.md @@ -0,0 +1,61 @@ +# Phase 3: Localization (EN/RU) + +**Status:** ⬜ Not Started +**Parent plan:** [PLAN.md](./PLAN.md) +**Domain:** fullstack + +## Objective +Add internationalization (i18n) support with English and Russian locales. All UI strings should be translatable. Users can switch language in settings or header. + +## Tasks + +- [ ] Task 1: Install `paraglide-sveltekit` (or `svelte-i18n`) — choose the best Svelte 5 compatible i18n library +- [ ] Task 2: Create locale files: `src/lib/i18n/en.json` and `src/lib/i18n/ru.json` +- [ ] Task 3: Create `src/lib/i18n/index.ts` — i18n setup, locale detection, switcher +- [ ] Task 4: Create `src/lib/components/layout/LanguageSwitcher.svelte` — language toggle (EN/RU) in header +- [ ] Task 5: Extract all hardcoded strings from layout components (Sidebar, Header, MainLayout) +- [ ] Task 6: Extract all hardcoded strings from auth pages (login, register, logout) +- [ ] Task 7: Extract all hardcoded strings from board/section/widget components +- [ ] Task 8: Extract all hardcoded strings from app components (AppCard, AppForm, AppIconPicker, etc.) +- [ ] Task 9: Extract all hardcoded strings from admin pages (users, groups, settings) +- [ ] Task 10: Extract all hardcoded strings from search components +- [ ] Task 11: Add locale preference to user settings (stored in localStorage + optional DB field) +- [ ] Task 12: Add language setting to admin SystemSettings (default locale) +- [ ] Task 13: Translate all strings to Russian + +## Files to Modify/Create +- `src/lib/i18n/en.json` — NEW +- `src/lib/i18n/ru.json` — NEW +- `src/lib/i18n/index.ts` — NEW +- `src/lib/components/layout/LanguageSwitcher.svelte` — NEW +- `src/lib/components/layout/Header.svelte` — MODIFY +- `src/routes/login/+page.svelte` — MODIFY +- `src/routes/register/+page.svelte` — MODIFY +- `src/routes/boards/*.svelte` — MODIFY +- `src/routes/apps/+page.svelte` — MODIFY +- `src/routes/admin/**/*.svelte` — MODIFY +- `src/lib/components/**/*.svelte` — MODIFY (all UI components) + +## Acceptance Criteria +- All user-visible strings are translatable (no hardcoded text in components) +- English and Russian translations are complete +- Language switcher in the header toggles between EN/RU +- Locale preference persists across sessions (localStorage) +- Default locale is configurable in admin settings +- Date/number formatting respects locale + +## Notes +- Use a flat key structure: `{ "nav.boards": "Boards", "nav.apps": "Apps", ... }` +- Keep translation keys semantic and grouped by feature +- Validation error messages from Zod should also be translatable +- ⚠️ Big Bang: string extraction touches many files + +## Review Checklist +- [ ] All tasks completed +- [ ] Code follows project conventions +- [ ] No unintended side effects +- [ ] Build passes +- [ ] Tests pass (new + existing) + +## Handoff to Next Phase + diff --git a/plans/phase-2-enhanced-features/phase-4-widgets.md b/plans/phase-2-enhanced-features/phase-4-widgets.md new file mode 100644 index 0000000..a09f234 --- /dev/null +++ b/plans/phase-2-enhanced-features/phase-4-widgets.md @@ -0,0 +1,64 @@ +# Phase 3: Additional Widget Types + +**Status:** ⬜ Not Started +**Parent plan:** [PLAN.md](./PLAN.md) +**Domain:** fullstack + +## Objective +Add four new widget types: Bookmark, Note, Embed, and Status. Extend the widget system with type-specific rendering and configuration. + +## Tasks + +- [ ] Task 1: Update `src/lib/utils/constants.ts` — ensure WidgetType enum has BOOKMARK, NOTE, EMBED, STATUS +- [ ] Task 2: Update `src/lib/utils/validators.ts` — add Zod schemas for each widget type's config +- [ ] Task 3: Create `src/lib/components/widget/BookmarkWidget.svelte` — URL + label + optional icon, no healthcheck +- [ ] Task 4: Create `src/lib/components/widget/NoteWidget.svelte` — markdown/rich text display with edit mode +- [ ] Task 5: Create `src/lib/components/widget/EmbedWidget.svelte` — iframe embed with configurable URL and height +- [ ] Task 6: Create `src/lib/components/widget/StatusWidget.svelte` — aggregated status of multiple apps (green/red/yellow summary) +- [ ] Task 7: Create `src/lib/components/widget/WidgetRenderer.svelte` — universal widget renderer that switches by type +- [ ] Task 8: Update `src/lib/components/widget/WidgetGrid.svelte` — use WidgetRenderer instead of hardcoded AppWidget +- [ ] Task 9: Update board editor — add widget type selector when adding widgets +- [ ] Task 10: Update `src/routes/boards/[boardId]/edit/+page.svelte` — type-specific config forms for each widget type +- [ ] Task 11: Update `src/routes/boards/[boardId]/edit/+page.server.ts` — handle different widget types in create action +- [ ] Task 12: Install `marked` or `markdown-it` for Note widget markdown rendering + +## Files to Modify/Create +- `src/lib/utils/constants.ts` — MODIFY +- `src/lib/utils/validators.ts` — MODIFY +- `src/lib/components/widget/BookmarkWidget.svelte` — NEW +- `src/lib/components/widget/NoteWidget.svelte` — NEW +- `src/lib/components/widget/EmbedWidget.svelte` — NEW +- `src/lib/components/widget/StatusWidget.svelte` — NEW +- `src/lib/components/widget/WidgetRenderer.svelte` — NEW +- `src/lib/components/widget/WidgetGrid.svelte` — MODIFY +- `src/routes/boards/[boardId]/edit/+page.svelte` — MODIFY +- `src/routes/boards/[boardId]/edit/+page.server.ts` — MODIFY + +## Acceptance Criteria +- All four widget types render correctly in the board view +- Each widget type has a type-specific config form in the board editor +- Bookmark: displays URL with label and optional icon, opens in new tab +- Note: renders markdown content, supports inline editing +- Embed: renders iframe with configurable URL, shows loading state +- Status: shows aggregate health of selected apps (count online/offline/total) +- WidgetRenderer correctly dispatches to the right component by type + +## Notes +- Widget config JSON structure per type: + - APP: `{ appId: string }` + - BOOKMARK: `{ url: string, label: string, icon?: string, description?: string }` + - NOTE: `{ content: string, format: 'markdown' | 'text' }` + - EMBED: `{ url: string, height: number, sandbox?: string }` + - STATUS: `{ appIds: string[], label?: string }` +- Embed widget should use sandbox attribute for security +- ⚠️ Big Bang: may need integration fixes in Phase 5 + +## Review Checklist +- [ ] All tasks completed +- [ ] Code follows project conventions +- [ ] No unintended side effects +- [ ] Build passes +- [ ] Tests pass (new + existing) + +## Handoff to Next Phase + diff --git a/plans/phase-2-enhanced-features/phase-5-access-control.md b/plans/phase-2-enhanced-features/phase-5-access-control.md new file mode 100644 index 0000000..ce56843 --- /dev/null +++ b/plans/phase-2-enhanced-features/phase-5-access-control.md @@ -0,0 +1,51 @@ +# Phase 4: Per-Board Access Control UI + +**Status:** ⬜ Not Started +**Parent plan:** [PLAN.md](./PLAN.md) +**Domain:** fullstack + +## Objective +Add a user-friendly access control interface for boards, allowing admins to manage per-board permissions with user/group pickers and visual indicators. + +## Tasks + +- [ ] Task 1: Create `src/lib/components/board/BoardAccessControl.svelte` — inline permission editor for boards +- [ ] Task 2: Add access control tab/section to board editor page +- [ ] Task 3: Create `src/routes/api/boards/[id]/permissions/+server.ts` — GET/POST/DELETE permissions for a board +- [ ] Task 4: Update `src/lib/components/admin/PermissionEditor.svelte` — enhance with user/group search/autocomplete +- [ ] Task 5: Update `src/lib/components/board/BoardCard.svelte` — show access level indicator (icon/badge) +- [ ] Task 6: Update `src/routes/boards/+page.svelte` — show access indicators on board list +- [ ] Task 7: Add guest access toggle with preview description to board editor +- [ ] Task 8: Create `src/lib/components/board/BoardShareDialog.svelte` — quick share dialog for boards + +## Files to Modify/Create +- `src/lib/components/board/BoardAccessControl.svelte` — NEW +- `src/lib/components/board/BoardShareDialog.svelte` — NEW +- `src/routes/api/boards/[id]/permissions/+server.ts` — NEW +- `src/routes/boards/[boardId]/edit/+page.svelte` — MODIFY +- `src/routes/boards/[boardId]/edit/+page.server.ts` — MODIFY +- `src/lib/components/admin/PermissionEditor.svelte` — MODIFY +- `src/lib/components/board/BoardCard.svelte` — MODIFY +- `src/routes/boards/+page.svelte` — MODIFY + +## Acceptance Criteria +- Board editor has a permissions section for managing access +- Admins can grant/revoke view/edit/admin permissions per user or group +- Board list shows access indicators (shared icon, guest badge, etc.) +- Quick share dialog allows easy permission granting +- Guest access toggle works with visual feedback + +## Notes +- The permission system already exists from MVP (permissionService) +- This phase adds the UI layer on top of existing backend +- ⚠️ Big Bang: may need integration fixes in Phase 5 + +## Review Checklist +- [ ] All tasks completed +- [ ] Code follows project conventions +- [ ] No unintended side effects +- [ ] Build passes +- [ ] Tests pass (new + existing) + +## Handoff to Next Phase + diff --git a/plans/phase-2-enhanced-features/phase-6-integration.md b/plans/phase-2-enhanced-features/phase-6-integration.md new file mode 100644 index 0000000..2df3d23 --- /dev/null +++ b/plans/phase-2-enhanced-features/phase-6-integration.md @@ -0,0 +1,53 @@ +# Phase 5: Integration & Polish + +**Status:** ⬜ Not Started +**Parent plan:** [PLAN.md](./PLAN.md) +**Domain:** fullstack + +## Objective +Integrate all Phase 2 features, fix all build/type/lint errors, write tests, and ensure everything works together. + +## Tasks + +- [ ] Task 1: Fix all TypeScript/build errors across the codebase +- [ ] Task 2: Verify `npm run build` succeeds +- [ ] Task 3: Verify `npm run check` passes +- [ ] Task 4: Verify `npm run lint` passes +- [ ] Task 5: Write tests for oauthService +- [ ] Task 6: Write tests for new widget types (validators, rendering logic) +- [ ] Task 7: Write tests for reorder APIs +- [ ] Task 8: Write tests for board permissions API +- [ ] Task 9: Update seed script with example data for new widget types +- [ ] Task 10: Verify all existing tests still pass +- [ ] Task 11: Update `.env.example` with all new env vars documented + +## Files to Modify/Create +- Various source files — fix build errors +- New test files for Phase 2 features +- `prisma/seed.ts` — update +- `.env.example` — update + +## Acceptance Criteria +- `npm run build` succeeds +- `npm run check` passes +- `npm run lint` passes +- `npm test` passes (existing + new tests) +- All Phase 2 features work together +- OAuth flow works end-to-end (when configured) +- DnD reordering persists correctly +- All widget types render and edit correctly +- Board access control UI works with permission system + +## Notes +- Big Bang convergence — fix everything here +- Priority: build errors → type errors → lint → tests + +## Review Checklist +- [ ] All tasks completed +- [ ] Code follows project conventions +- [ ] No unintended side effects +- [ ] Build passes +- [ ] Tests pass (new + existing) + +## Handoff +