chore: add plan files for Phase 2 enhanced features

This commit is contained in:
2026-03-24 22:44:31 +03:00
parent c4754f23a5
commit ae114ab9ce
8 changed files with 407 additions and 0 deletions
@@ -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
+44
View File
@@ -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`
@@ -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
<!-- Filled in by the implementation agent after completing this phase. -->
@@ -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
<!-- Filled in by the implementation agent after completing this phase. -->
@@ -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
<!-- Filled in by the implementation agent after completing this phase. -->
@@ -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
<!-- Filled in by the implementation agent after completing this phase. -->
@@ -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
<!-- Filled in by the implementation agent after completing this phase. -->
@@ -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
<!-- Final phase — no handoff needed -->