Commit Graph

1056 Commits

Author SHA1 Message Date
schalli 9ec6313f4d feat(05-03): calendar backend — model, crypto, source CRUD module
- Add CalendarSource Prisma model with encrypted credentials (AES-256-GCM)
- Create CalendarCryptoService with encrypt/decrypt using CALENDAR_ENCRYPTION_KEY
- Create CalendarController with source CRUD endpoints (GET/POST/PATCH/DELETE)
- Create CalendarService with ownership checks and SSRF URL validation
- Add DTOs with https-only URL validation and class-validator decorators
- Register CalendarModule in AppModule
- Install tsdav, node-ical, ews-javascript-api, @microsoft/microsoft-graph-client
- Stub provider files for Task 2 compilation
2026-06-24 15:09:03 +02:00
schalli 7616365cbe docs(05-02): complete search + notes widgets + settings plan 2026-06-24 15:03:55 +02:00
schalli 7e2592b2af feat(05-02): add widget settings panel with search provider form
- Settings > Dashboard page with per-widget-instance config
- Clock config: timezone select (IANA list) + date toggle (D-12/D-13)
- Note config: editable title field (D-17)
- Search config: SearchProviderForm with add/delete and {query} validation (D-15)
- Calendar config: link to calendar-specific settings
- i18n keys for search provider management (en + de)
- Fix useRef initialization for React 19 strict mode (note-widget)
- Fix unknown type narrowing in widget title display

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 14:58:42 +02:00
schalli 38dcfdfa6d feat(05-02): add SearchProvider backend with model, CRUD, and defaults
- Prisma model SearchProvider with userId/tenantId scoping
- Three default providers (Google/Bing/DuckDuckGo) as constants, always returned without DB seed
- GET/POST/DELETE search-providers endpoints on DashboardController
- Ownership verification on delete (T-05-07), default providers cannot be deleted
- CreateSearchProviderDto with class-validator: urlTemplate must contain {query} (T-05-08)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 11:34:45 +02:00
schalli dd0209898b feat(05-02): add search and note widgets with tests
- SearchWidget: provider dropdown, text input, button; opens search in new tab via window.open (D-14/D-15)
- NoteWidget: MDEditor with compact toolbar, debounced autosave (1500ms), AbortController for in-flight cancellation (D-16/D-17/D-18)
- rehype-sanitize enabled for Markdown XSS prevention (T-05-05)
- Widget registry updated with wireSearchWidget/wireNoteWidget (no more placeholders)
- dashboard-api.ts: added fetchSearchProviders, addSearchProvider, removeSearchProvider, signal support on updateWidgetConfig
- 9 new tests passing (search: 5, note: 4)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 11:33:01 +02:00
schalli 97c13809f5 test(05-02): add failing tests for search and note widgets
- SearchWidget: provider selection, window.open with encoded query, Enter key trigger
- NoteWidget: debounced autosave, rapid typing collapse, AbortController usage

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 11:30:45 +02:00
schalli afc555b18d docs(05-01): complete dashboard grid + clock widget plan 2026-06-24 11:27:59 +02:00
schalli 8a9c1ae6a9 feat(05-01): settings shell, header link, and i18n keys for dashboard phase
- Create settings/layout.tsx with SettingsSidebar and back-to-dashboard link
- Create settings/page.tsx with redirect to /settings/dashboard
- Create settings-sidebar.tsx with Widgets and Calendar nav items, aria-current
- Add Settings link in header user dropdown (gear icon, before logout)
- Add settings namespace (DE+EN) with all category and action keys
- Add widgets namespace (DE+EN) with all widget names, descriptions, error states
- Add header.settings key ("Einstellungen"/"Settings")

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 11:23:47 +02:00
schalli d5e1c42e64 feat(05-01): dashboard grid, clock widget, widget registry, store, and tests
- Install react-grid-layout@2.2.3 and react-resizable
- Create widget-registry.tsx with all 4 widget types, WIDGET_CONSTRAINTS, WidgetProps
- Create dashboard-api.ts with fetch/save layout and widget CRUD functions
- Create dashboard-store.ts (Zustand, NO persist — D-05) with edit mode and auto-save on exit
- Create DashboardGrid with react-grid-layout v2 Responsive, ResizeObserver width
- Create ClockWidget using Intl.DateTimeFormat (no manual UTC offsets)
- Create WidgetWrapper with drag handle and delete button in edit mode
- Create EditModeToggle (pencil/checkmark), WidgetCatalogModal (2x2 grid)
- Rewrite portal page.tsx as dashboard with grid, edit toggle, widget catalog
- Add ResizeObserver polyfill in test setup, CSS mock support in vitest config
- All 5 tests green (dashboard grid + clock widget)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 11:21:43 +02:00
schalli 792b7661d8 test(05-01): add failing tests for dashboard grid and clock widget
- DashboardGrid test: empty state, widget rendering, edit mode affordances
- ClockWidget test: timezone rendering, showDate toggle behavior

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 11:15:18 +02:00
schalli 950eebbc15 feat(05-01): dashboard backend — Prisma models, CRUD API, module wiring
- Add DashboardLayout and WidgetInstance Prisma models with userId/tenantId scoping
- Create DashboardController with 6 endpoints (layout CRUD + widget CRUD)
- Create DashboardService with ownership verification on all widget mutations (T-05-01)
- Add SaveLayoutDto, CreateWidgetDto, UpdateWidgetConfigDto with class-validator
- Register DashboardModule in app.module.ts imports

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 11:14:03 +02:00
schalli f925fd3654 docs(05): complete phase plan (5 plans, 5 waves, 10/10 coverage) 2026-06-24 10:13:22 +02:00
schalli 114edcf89b docs(05): complete phase plan (5 plans, 4 waves, 32/32 coverage)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 10:08:01 +02:00
schalli 6e99ccc2a1 fix(05): clean must_haves, trailing XML, update ROADMAP to 5 plans
- Remove frontend artifacts from 05-03 must_haves (belong to 05-04)
- Remove trailing XML generation artifacts from 05-04 and 05-05
- Update ROADMAP Phase 5: 5 plans across 4 waves

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 10:07:35 +02:00
schalli 271e71f901 fix(05): remove duplicate frontend tasks from 05-03, add requirements field
05-03 now backend-only (4 tasks/13 files): model+crypto+CRUD, providers,
aggregation, prisma push. Frontend tasks moved exclusively to 05-04.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 10:03:37 +02:00
schalli e60d34dc28 wip: phase 05 plan-phase paused at revision verify (checker v2 pending)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 09:54:43 +02:00
schalli c8852d2014 docs(05): create dashboard & calendar phase plan
4 plans across 4 waves covering DASH-01..07 + CAL-01..03.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 14:42:11 +02:00
schalli b5ab2c806e docs(05): research phase domain - dashboard calendar 2026-06-23 14:29:14 +02:00
schalli 2005448c51 fix(05): resolve UI-SPEC typography and copywriting checker issues
Reduce typography to 4 sizes (12/14/18/28) and 2 weights (400/600).
Clock scaling declared as responsive exception, not standalone size.
Destructive CTAs now include noun (Quelle loeschen / Delete source).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 14:12:40 +02:00
schalli cd9f74531a docs(05): UI design contract for dashboard-calendar phase
Defines visual and interaction contracts for Phase 05 including
dashboard grid, 4 widget types, settings page, and calendar integration.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 14:09:56 +02:00
schalli 0331d54e9a docs(state): record phase 05 context session 2026-06-23 14:01:18 +02:00
schalli b1101712df docs(05): capture phase context 2026-06-23 14:01:12 +02:00
schalli 7c35c17a07 docs(04-04): complete Phase 04 verification, close phase
Human verified marketplace features on localhost. 26 tests green.
Reverse proxy API URL config deferred. Phase 04 done, ready for Phase 05.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 12:26:33 +02:00
schalli a39322e7a6 wip: phase 04-04 paused at human verification (task 2/2)
Plans 04-01 through 04-03 complete. 26 tests green, stack running.
Awaiting human sign-off on 12-step verification checklist.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 11:04:28 +02:00
schalli 191135bae8 docs(04-03): complete plan summary, update STATE
Plan 04-03 done — sidebar migrated, 5 new tests (26 total).
Ready for Plan 04-04 (navigation polish).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 10:22:04 +02:00
schalli e967ea9660 feat(04-03): migrate sidebar to Link/usePathname, add search and refresh signal
Replace all raw <a> with Next.js Link. Add usePathname-based active
highlighting, SidebarSearch with category/module filtering, and
sidebarRefreshKey subscription for live activation updates. 26 tests pass.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 10:21:27 +02:00
schalli 9e705ab13a docs(04-02): complete plan summary, update STATE
Plan 04-02 done — 3 tasks, 12 tests added (21 total), 8 files.
Filters, tenant context, dialog, toast, detail page all operational.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 09:25:56 +02:00
schalli fdf2c38f67 feat(04-02): add module detail page at /marketplace/[slug]
Compact detail view with back link, full description (no line-clamp),
status indicator, and activation controls. Reuses ActivationDialog for
deactivation. 3 tests pass, 21 total green.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 09:25:00 +02:00
schalli 0f3379f263 feat(04-02): add TenantContextSelector, ActivationDialog, and asymmetric toggle UX
Super-Admin tenant dropdown fetches /tenants, sets selectedTenantId for
per-tenant activation. Deactivation gated by confirmation dialog;
activation immediate with toast. 18 tests pass.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 09:23:04 +02:00
schalli 06fb52da82 feat(04-02): add search, status tabs, category chips, toast, and client-side filtering
Build MarketplaceSearch (debounced 300ms), StatusFilter (3 tabs with
counts), CategoryFilter (horizontal chip row), and Toast (Zustand store
+ container). Wire useMemo filtering into page with filtered-empty state.
All 14 tests pass.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 09:20:08 +02:00
schalli 00a01b5b19 docs(04-01): complete plan summary, update STATE, clean handoff
Plan 04-01 (marketplace browse + activate) done — 3 tasks, 9 tests,
10 files. Remove HANDOFF.json and .continue-here.md, advance to 04-02.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 08:52:56 +02:00
schalli fb6a340799 feat(04-01): implement marketplace page and marketplace-store
Create marketplace-store (Zustand) with sidebarRefreshKey signal and
tenant context. Build /marketplace page with parallel fetch, activation
Map, role gate, empty state, and responsive card grid. All 9 tests pass.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 08:51:54 +02:00
schalli 2c526fccf6 wip: phase 04-01 paused at task 3/3 (RED done, GREEN pending) 2026-06-23 08:19:04 +02:00
schalli 0b7cf66abb test(04-01): add failing tests for marketplace page
- 4 tests: card grid rendering, activation status display,
  access-denied for non-admin, empty state
- Tests fail as expected (RED phase) - page and store not yet implemented
2026-06-22 14:48:39 +02:00
schalli 1e494b36ea feat(04-01): implement MarketplaceCard component and marketplace i18n namespace
- Add marketplace namespace to de.json and en.json with all copywriting contract strings
- Add sidebar.search and sidebar.noResults i18n keys
- Create MarketplaceCard with icon, name, localized description, category badge,
  status badge (role="status"), and activate/deactivate button
- All 5 unit tests pass (GREEN phase)
2026-06-22 14:47:53 +02:00
schalli a64f889251 test(04-01): add failing tests for MarketplaceCard component
- 5 tests: name+description rendering, category badge, activate button,
  activated status badge, onToggle callback
- Tests fail as expected (RED phase) - component not yet implemented
2026-06-22 14:46:30 +02:00
schalli e50b3c76c5 chore(04-01): install and configure Vitest test infrastructure for apps/web
- Add vitest, @testing-library/react, @testing-library/jest-dom, jsdom, @vitejs/plugin-react as dev deps
- Create vitest.config.ts with jsdom environment and @ path alias
- Create test setup file importing jest-dom/vitest matchers
- Add test scripts to apps/web and root package.json
- Add test task to turbo.json pipeline
2026-06-22 14:45:54 +02:00
schalli fb6e90d78e docs(04): create phase plan 2026-06-22 14:20:01 +02:00
schalli 0470d500b2 docs(04): create phase plan — marketplace & portal navigation (4 plans, 3 waves)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 14:17:02 +02:00
schalli 670fe088a4 docs(04): research phase domain — marketplace & portal navigation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 14:06:42 +02:00
schalli 728a4c3ee4 docs(state): record phase 4 UI-SPEC session 2026-06-22 13:55:16 +02:00
schalli 4ea1b6144f docs(04): UI design contract for marketplace & portal navigation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 13:53:44 +02:00
schalli 7fb0ed6646 docs(state): record phase 4 context session 2026-06-22 13:48:48 +02:00
schalli bf56aa6a2d docs(04): capture phase context 2026-06-22 13:48:36 +02:00
schalli 27a75ab990 docs(03-04): phase 03 verified — all 11 checks passed, 2 bugs fixed 2026-06-20 10:31:22 +02:00
schalli 576e311262 fix(03): strip TLD from domaincheck input before sending to API
Users naturally type full domains (e.g. "google.de") but the API
validates DNS labels only. Extract the label part before the first
dot to prevent 400 validation errors.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-20 09:37:39 +02:00
schalli 5708127dbb fix(03): module guard uses JWT tenantId fallback for deactivation enforcement
ModuleGuard now reads tenantId from req.user?.tenantId as fallback
(same pattern as module-registry controller), and throws 403 instead
of silently allowing access when no tenant context exists.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-20 09:31:59 +02:00
schalli 46a6e277b8 fix(03): login redirect + API internal URL for Docker networking
- Use window.location.href for full page reload after login (ensures auth state)
- Add API_INTERNAL_URL for server-side requests within Docker network
- Remove unnecessary credentials:'include' from SSR fetch calls
- Update planning state for Phase 03 progress

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-20 09:28:05 +02:00
schalli f5a775c0df wip: phase-03 paused vor human verification (plan 04) 2026-06-19 14:51:31 +02:00
schalli 9b2b1eafcb fix(03): show actual error message in domaincheck page
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-19 14:43:27 +02:00