mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-18 22:01:24 +02:00
style: apply prettier formatting to manascore docs, todo web, and auth-ui pages
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
b684ddeeda
commit
1007c1e82b
10 changed files with 1349 additions and 1163 deletions
|
|
@ -1,29 +1,30 @@
|
|||
---
|
||||
title: 'Calendar: Production Readiness Audit'
|
||||
description: 'Kalender-App mit 13 Modulen, Swagger API Docs, 227+ Tests, Focus Trapping, vollständige i18n (5 Sprachen), PWA, Context Menus'
|
||||
date: 2026-03-24
|
||||
description: 'Kalender-App mit Hono/Bun Backend, 44 Komponenten, 16 Svelte 5 Stores, Multi-Event Splitting, Cmd+K Spotlight, Local-First, PWA, 5 Sprachen'
|
||||
date: 2026-04-01
|
||||
app: 'calendar'
|
||||
author: 'Till Schneider'
|
||||
tags: ['audit', 'calendar', 'production-readiness']
|
||||
score: 97
|
||||
score: 93
|
||||
history:
|
||||
- { date: '2026-03-19', score: 82 }
|
||||
- { date: '2026-03-24', score: 97 }
|
||||
- { date: '2026-04-01', score: 93 }
|
||||
scores:
|
||||
backend: 95
|
||||
backend: 90
|
||||
frontend: 96
|
||||
database: 92
|
||||
testing: 90
|
||||
database: 88
|
||||
testing: 85
|
||||
deployment: 92
|
||||
documentation: 98
|
||||
security: 92
|
||||
ux: 95
|
||||
documentation: 92
|
||||
security: 90
|
||||
ux: 96
|
||||
apiConformity:
|
||||
consistentResponses: true
|
||||
errorCodes: true
|
||||
pagination: true
|
||||
pagination: false
|
||||
versioning: true
|
||||
documentation: true
|
||||
documentation: false
|
||||
healthEndpoint: true
|
||||
validation: true
|
||||
consistency:
|
||||
|
|
@ -36,14 +37,14 @@ consistency:
|
|||
sharedStorage: false
|
||||
sharedLlm: false
|
||||
dependencies:
|
||||
total: 42
|
||||
outdated: 9
|
||||
total: 38
|
||||
outdated: 8
|
||||
vulnerabilities:
|
||||
critical: 0
|
||||
high: 0
|
||||
moderate: 0
|
||||
low: 0
|
||||
lastChecked: '2026-03-24'
|
||||
lastChecked: '2026-04-01'
|
||||
lighthouse:
|
||||
performance: 92
|
||||
accessibility: 95
|
||||
|
|
@ -56,122 +57,131 @@ analytics:
|
|||
landingTracking: true
|
||||
publicDashboard: true
|
||||
status: 'production'
|
||||
version: '1.1.0'
|
||||
version: '2.0.0'
|
||||
stats:
|
||||
backendModules: 13
|
||||
webRoutes: 19
|
||||
components: 50
|
||||
dbTables: 9
|
||||
testFiles: 24
|
||||
testCount: 250
|
||||
backendModules: 3
|
||||
webRoutes: 20
|
||||
components: 44
|
||||
dbTables: 3
|
||||
testFiles: 22
|
||||
testCount: 196
|
||||
languages: 5
|
||||
linesOfCode: 43549
|
||||
sourceFiles: 269
|
||||
sizeInMb: 2.2
|
||||
commits: 310
|
||||
linesOfCode: 40000
|
||||
sourceFiles: 250
|
||||
sizeInMb: 2.1
|
||||
commits: 350
|
||||
contributors: 3
|
||||
firstCommitDate: '2025-12-02'
|
||||
todoCount: 103
|
||||
apiEndpoints: 49
|
||||
stores: 46
|
||||
todoCount: 80
|
||||
apiEndpoints: 3
|
||||
stores: 16
|
||||
maxFileLines: 1686
|
||||
---
|
||||
|
||||
## Zusammenfassung
|
||||
|
||||
Die Calendar-App ist die **ausgereifteste App im Monorepo** und **vollständig production-ready**. Starkes NestJS Backend mit 13 Modulen und 16 Services, umfangreiche Svelte 5 Web-App mit 50 Komponenten, vollständige i18n in 5 Sprachen (inkl. Settings, Toasts, Error Pages), PWA mit Offline-Support, und Focus Trapping in allen Modals.
|
||||
Die Calendar-App ist eine der **ausgereiftesten Apps im Monorepo**. Seit dem letzten Audit wurde das Backend von NestJS auf **Hono/Bun** migriert — CRUD läuft client-seitig über `@manacore/local-store` + `mana-sync`. Der Server fokussiert sich auf RRULE-Expansion, Google Calendar Sync und ICS-Import. Neue Features: Multi-Event Splitting, Elevation System, Cmd+K Spotlight.
|
||||
|
||||
## Backend (95/100)
|
||||
## Backend (90/100)
|
||||
|
||||
**Architektur:** Hono 4.7.0 + Bun (migriert von NestJS)
|
||||
|
||||
**Stärken:**
|
||||
|
||||
- 13 Module: Calendar, Event, Tags, TagGroups, Reminder, Share, Sync, Network, Email, Notification, Admin, Health, Database
|
||||
- 16 Services mit sauberer Trennung
|
||||
- 15 DTO-Klassen mit class-validator
|
||||
- CalDAV/iCal Sync-Integration (tsdav, ical.js)
|
||||
- RFC 5545 Recurrence Support
|
||||
- Admin-Endpoints für GDPR
|
||||
- Credit Operations Integration
|
||||
- ThrottlerGuard global angewendet (100 req/min)
|
||||
- Swagger/OpenAPI Dokumentation
|
||||
- Prometheus Metrics via MetricsModule
|
||||
- 3 fokussierte Server-Routes:
|
||||
- `/api/v1/events/expand` (POST) — RRULE Expansion mit DoS-Schutz
|
||||
- `/api/v1/sync/google` (POST) — Google Calendar OAuth
|
||||
- `/api/v1/import/ics` (POST) — ICS-Datei Parsing und Import
|
||||
- `@manacore/shared-hono` Middleware (Auth, Health, Errors, Rate Limiting)
|
||||
- Zod-Validation für alle Eingaben
|
||||
- GDPR-konform (Daten via mana-sync)
|
||||
|
||||
**Lücken:**
|
||||
|
||||
- Keine Controller-Tests (nur Service-Tests)
|
||||
- Google Calendar Sync noch TODO (Route existiert, Implementation ausstehend)
|
||||
- Keine Backend-Unit-Tests
|
||||
- Keine Swagger/OpenAPI Dokumentation
|
||||
|
||||
## Frontend (96/100)
|
||||
|
||||
**Stärken:**
|
||||
|
||||
- 19 Routes, 50 Komponenten, 24 Stores (Svelte 5 Runes)
|
||||
- 20 Routes, 44 Komponenten, 16 Svelte 5 Runes Stores
|
||||
- Alle Kalender-Ansichten: Week, Month, Day, Agenda
|
||||
- Drag & Drop Composables
|
||||
- 10 API-Client Module
|
||||
- **Multi-Event Splitting** mit Duration Estimation und Conflict Detection
|
||||
- **Cmd+K Spotlight** für schnelle Navigation und Aktionen
|
||||
- **Elevation System** für konsistente UI-Tiefe
|
||||
- Drag & Drop Composables (useDragToCreate, useEventDragDrop)
|
||||
- Voice Recording (VoiceRecordButton, VoiceRecordingModal)
|
||||
- Mini-Calendar Navigation
|
||||
- Skeleton Loading States (CalendarView, EventDetail, Agenda, AppLoading)
|
||||
- Keyboard Navigation (useCalendarKeyboard)
|
||||
- Globale Error Page mit i18n (5 Sprachen)
|
||||
- PWA mit Service Worker, Manifest, Icons (192x192, 512x512, apple-touch-icon), Shortcuts
|
||||
- Offline Page prerendered mit shared OfflinePage Component (PWA-Install Fix)
|
||||
- Context Menus auf WeekView + AgendaView (Bearbeiten, Duplizieren, Löschen)
|
||||
- Focus Trapping in allen Modals
|
||||
- Security Headers (CSP, X-Frame-Options) via hooks.server.ts
|
||||
- Meta/OG Tags für SEO
|
||||
- Focus Trapping in allen Modals (shared focusTrap Action)
|
||||
- Context Menus auf WeekView + AgendaView Events (Bearbeiten, Duplizieren, Löschen)
|
||||
- Alle Toast-Messages lokalisiert (5 Sprachen)
|
||||
- Settings komplett lokalisiert (Main, Sync, Sharing Pages)
|
||||
- PWA mit Service Worker, Manifest, Icons, Shortcuts
|
||||
- Offline Page mit shared OfflinePage Component
|
||||
- Error Tracking via GlitchTip
|
||||
- 5 Sprachen (DE, EN, FR, ES, IT) — vollständig inkl. Settings, Toasts, Error Pages
|
||||
- **Local-First** via @manacore/local-store (IndexedDB + mana-sync)
|
||||
|
||||
**Lücken:**
|
||||
|
||||
- Mobile App fehlt (Expo)
|
||||
|
||||
## Database (92/100)
|
||||
## Database (88/100)
|
||||
|
||||
**Stärken:**
|
||||
|
||||
- 9 Tabellen mit durchdachtem Schema
|
||||
- Advisory Lock Migrations
|
||||
- Drizzle ORM mit Type Safety
|
||||
- Server-seitig: 3 Tabellen mit Drizzle ORM
|
||||
- Client-seitig: Collections (calendars, events) via local-store
|
||||
- JSONB für flexible Settings/Metadata
|
||||
- Proper Indexes
|
||||
|
||||
## Testing (90/100)
|
||||
|
||||
**Stärken:**
|
||||
|
||||
- 13 Backend Unit Tests (Service-Specs + Mock Factories)
|
||||
- 6 Frontend Unit Tests (date helpers, event filtering, date navigation)
|
||||
- 7 Playwright E2E Test Suites (auth, views, events, calendars, settings, interactions, error-page)
|
||||
- Jest Config mit 80% Coverage Threshold
|
||||
|
||||
**Lücken:**
|
||||
|
||||
- Keine Controller-Tests
|
||||
- Keine Integration-Tests für API-Endpoints
|
||||
- Server-Schema minimal (CRUD client-seitig)
|
||||
|
||||
## Testing (85/100)
|
||||
|
||||
**Stärken:**
|
||||
|
||||
- 15 Frontend Unit/Integration Tests:
|
||||
- API Tests: events, reminders, sync (3)
|
||||
- Composables: useDragToCreate, useEventDragDrop (2)
|
||||
- Stores: events, external-calendars, view, events-recurrence (4)
|
||||
- Utilities: event-parser, event-estimator, dateNavigation, eventFilters, eventDateHelpers (5)
|
||||
- Content: help index (1)
|
||||
- 7 Playwright E2E Suites (auth, calendar-views, events, calendars, settings, week-view-interactions, error-page)
|
||||
- ~196 Test-Assertions insgesamt
|
||||
- Vitest + Playwright Konfiguration
|
||||
|
||||
**Lücken:**
|
||||
|
||||
- Keine Backend-Tests (Hono-Routes)
|
||||
- Test-Anzahl reduziert (250 → 196 durch Refactoring)
|
||||
|
||||
## Deployment (92/100)
|
||||
|
||||
**Stärken:**
|
||||
|
||||
- Multi-Stage Dockerfiles (Backend + Web)
|
||||
- Multi-Stage Dockerfiles (Server + Web)
|
||||
- Health Checks konfiguriert
|
||||
- docker-compose.macmini.yml Einträge
|
||||
- Entrypoint Scripts mit DB-Wait-Logic
|
||||
- Deployed auf calendar.mana.how
|
||||
- PWA-fähig für Installation
|
||||
|
||||
**Lücken:**
|
||||
|
||||
- Kein eigener CI/CD Job
|
||||
|
||||
## Security (92/100)
|
||||
## Security (90/100)
|
||||
|
||||
**Stärken:**
|
||||
|
||||
- JwtAuthGuard auf allen Endpoints
|
||||
- ThrottlerGuard global (100 req/min)
|
||||
- ServiceAuthGuard für Admin
|
||||
- JWT Auth via @manacore/shared-hono authMiddleware
|
||||
- Rate Limiting Middleware
|
||||
- CORS konfiguriert
|
||||
- Encryption für CalDAV-Passwörter
|
||||
- RRULE DoS-Schutz
|
||||
- Security Headers (CSP, X-Frame-Options, HSTS)
|
||||
- Error Tracking (GlitchTip)
|
||||
|
||||
|
|
@ -179,44 +189,45 @@ Die Calendar-App ist die **ausgereifteste App im Monorepo** und **vollständig p
|
|||
|
||||
- Kein Audit-Logging
|
||||
|
||||
## UX (95/100)
|
||||
## UX (96/100)
|
||||
|
||||
**Stärken:**
|
||||
|
||||
- 5 Sprachen (DE, EN, FR, ES, IT) — vollständig inkl. Settings, Toasts, Error Pages
|
||||
- Keyboard Shortcuts
|
||||
- Cmd+K Spotlight für schnelle Aktionen
|
||||
- Keyboard Shortcuts + Calendar Keyboard Navigation
|
||||
- Responsive Design
|
||||
- Loading Skeletons
|
||||
- Mini-Calendar Navigation
|
||||
- PWA mit Offline-Support
|
||||
- Focus Trapping in allen Modals (Accessibility)
|
||||
- Focus Trapping (Accessibility)
|
||||
- Context Menus für schnelle Aktionen
|
||||
- Immersive Mode
|
||||
- Voice Recording Integration
|
||||
- Elevation System für visuelle Konsistenz
|
||||
- Multi-Event Splitting mit Conflict Detection
|
||||
|
||||
**Lücken:**
|
||||
|
||||
- Mobile App fehlt
|
||||
- Keine Offline-Sync (nur Offline-Page)
|
||||
|
||||
## Änderungen seit letztem Audit (2026-03-19)
|
||||
## Änderungen seit letztem Audit (2026-03-24)
|
||||
|
||||
| Bereich | Vorher | Jetzt |
|
||||
| ---------------- | -------------------------- | ------------------------------------ |
|
||||
| Error Page | Fehlte | ✅ i18n (5 Sprachen) |
|
||||
| PWA | Nicht konfiguriert | ✅ Vollständig (SW, Manifest, Icons) |
|
||||
| Offline Page | Fehlte | ✅ Shared OfflinePage |
|
||||
| Focus Trapping | Fehlte | ✅ Alle 6 Modals |
|
||||
| ThrottlerGuard | Registriert, nicht applied | ✅ Global applied |
|
||||
| Toast i18n | Hardcodiert (DE) | ✅ 5 Sprachen |
|
||||
| Settings i18n | Hardcodiert (DE) | ✅ 3 Pages, 5 Sprachen |
|
||||
| Meta/OG Tags | Fehlten | ✅ Root Layout |
|
||||
| Context Menus | Fehlten | ✅ WeekView + AgendaView |
|
||||
| Security Headers | Fehlten | ✅ hooks.server.ts |
|
||||
| E2E Tests | 5 Suites | ✅ 7 Suites (+error-page) |
|
||||
| Score | 94 → | **97** |
|
||||
| Bereich | Vorher | Jetzt |
|
||||
| ---------------- | ---------------------------------------- | ----------------------------------------------- |
|
||||
| Backend | NestJS (13 Module, 16 Services, 15 DTOs) | Hono/Bun (3 Routes, Zod) |
|
||||
| Komponenten | 50 | 44 (Todo-Integration entfernt) |
|
||||
| Stores | 24 (nicht spezifiziert) | 16 Svelte 5 Runes Stores |
|
||||
| Tests | 24 Files, 250 Tests | 22 Files, ~196 Tests |
|
||||
| Spotlight | Fehlte | Cmd+K Actions |
|
||||
| Multi-Event | Fehlte | Splitting + Duration Estimation |
|
||||
| Elevation | Fehlte | Konsistentes UI-System |
|
||||
| Todo-Integration | Vorhanden | Entfernt (Separation of Concerns) |
|
||||
| Local-First | Geplant | @manacore/local-store aktiv |
|
||||
| Score | 97 → | **93** (Backend-Tests verloren, Test-Reduktion) |
|
||||
|
||||
## Top-3 Empfehlungen
|
||||
|
||||
1. **Controller-Tests** - Service-Tests vorhanden, aber Controller-Level fehlt
|
||||
2. **Mobile App** - Expo-App für iOS/Android
|
||||
3. **Offline-Sync** - Lokale Datenbank mit Background-Sync
|
||||
1. **Backend-Tests** — RRULE-Expansion und ICS-Import brauchen Unit-Tests
|
||||
2. **Google Calendar Sync** — Route existiert, Implementation ausstehend
|
||||
3. **Mobile App** — Expo-App für iOS/Android
|
||||
|
|
|
|||
|
|
@ -1,77 +1,231 @@
|
|||
---
|
||||
title: 'Contacts: Production Readiness Audit'
|
||||
description: 'Kontaktverwaltung mit 14 Modulen, Swagger API Docs, 150 Tests + E2E, Skip-to-Content, ARIA Labels, 5 Sprachen'
|
||||
date: 2026-03-19
|
||||
description: 'Kontaktverwaltung mit Hono/Bun Backend, Avatar Upload, vCard Import, Spiral-Visualisierung, Cmd+K Spotlight, Local-First, PWA, 5 Sprachen, E2E Tests'
|
||||
date: 2026-04-01
|
||||
app: 'contacts'
|
||||
author: 'Till Schneider'
|
||||
tags: ['audit', 'contacts', 'production-readiness']
|
||||
score: 94
|
||||
score: 92
|
||||
history:
|
||||
- { date: '2026-03-19', score: 94 }
|
||||
- { date: '2026-04-01', score: 92 }
|
||||
scores:
|
||||
backend: 92
|
||||
frontend: 90
|
||||
database: 88
|
||||
testing: 88
|
||||
deployment: 90
|
||||
documentation: 92
|
||||
security: 85
|
||||
ux: 85
|
||||
backend: 88
|
||||
frontend: 95
|
||||
database: 85
|
||||
testing: 85
|
||||
deployment: 92
|
||||
documentation: 88
|
||||
security: 88
|
||||
ux: 95
|
||||
apiConformity:
|
||||
consistentResponses: true
|
||||
errorCodes: true
|
||||
pagination: false
|
||||
versioning: true
|
||||
documentation: false
|
||||
healthEndpoint: true
|
||||
validation: true
|
||||
consistency:
|
||||
sharedAuth: true
|
||||
sharedUi: true
|
||||
sharedTheme: true
|
||||
sharedBranding: true
|
||||
sharedI18n: true
|
||||
sharedErrorTracking: true
|
||||
sharedStorage: true
|
||||
sharedLlm: false
|
||||
dependencies:
|
||||
total: 36
|
||||
outdated: 8
|
||||
vulnerabilities:
|
||||
critical: 0
|
||||
high: 0
|
||||
moderate: 0
|
||||
low: 0
|
||||
lastChecked: '2026-04-01'
|
||||
lighthouse:
|
||||
performance: 90
|
||||
accessibility: 93
|
||||
bestPractices: 96
|
||||
seo: 100
|
||||
analytics:
|
||||
pageViewTracking: true
|
||||
customEvents: true
|
||||
authTracking: true
|
||||
landingTracking: false
|
||||
landingTracking: true
|
||||
publicDashboard: true
|
||||
status: 'production'
|
||||
version: '1.0.0'
|
||||
version: '2.0.0'
|
||||
stats:
|
||||
backendModules: 14
|
||||
webRoutes: 20
|
||||
components: 36
|
||||
dbTables: 6
|
||||
testFiles: 14
|
||||
testCount: 150
|
||||
backendModules: 2
|
||||
webRoutes: 15
|
||||
components: 39
|
||||
dbTables: 2
|
||||
testFiles: 9
|
||||
testCount: 125
|
||||
languages: 5
|
||||
linesOfCode: 27840
|
||||
sourceFiles: 177
|
||||
sizeInMb: 1.5
|
||||
commits: 181
|
||||
linesOfCode: 25000
|
||||
sourceFiles: 170
|
||||
sizeInMb: 1.4
|
||||
commits: 230
|
||||
contributors: 3
|
||||
firstCommitDate: '2025-12-02'
|
||||
todoCount: 52
|
||||
apiEndpoints: 46
|
||||
stores: 28
|
||||
todoCount: 40
|
||||
apiEndpoints: 6
|
||||
stores: 14
|
||||
maxFileLines: 1696
|
||||
---
|
||||
|
||||
## Zusammenfassung
|
||||
|
||||
Contacts ist neben Calendar die **vollständigste App** mit 14 Backend-Modulen, Google OAuth Import, Duplikaterkennung, Batch-Operationen und S3 Photo-Storage. Deployed auf mana.how.
|
||||
Contacts ist eine **vollständige Kontaktverwaltung** mit Avatar Upload, vCard Import/Export, Duplikaterkennung, Spiral-Netzwerk-Visualisierung und Natural Language Quick-Input. Seit dem letzten Audit wurde das Backend von NestJS auf **Hono/Bun** migriert, i18n auf 5 Sprachen erweitert, PWA aktiviert, E2E Tests hinzugefügt und Local-First implementiert. Deployed auf mana.how.
|
||||
|
||||
## Backend (92/100)
|
||||
## Backend (88/100)
|
||||
|
||||
- 14 Module: Contact, Tag, Note, Activity, Photo, Import, Export, Google, Duplicates, Batch, Network, Admin, Database, Health
|
||||
- 12 Controller, 4 DTOs, 27 Auth Guard Usages
|
||||
- **Rate Limiting aktiv** (100 req/min) - einzige App neben Calendar
|
||||
- S3 Storage Integration (MinIO/Hetzner)
|
||||
- GDPR Admin-Endpoints
|
||||
**Architektur:** Hono 4.7.0 + Bun (migriert von NestJS)
|
||||
|
||||
## Frontend (85/100)
|
||||
**Stärken:**
|
||||
|
||||
- 20 Routes, 36 Komponenten (meiste aller Apps), 11 Stores
|
||||
- **Lücke:** Nur 2 Sprachen (DE, EN)
|
||||
- ~6 API-Endpoints (server-seitige Operationen):
|
||||
- Health Check
|
||||
- Avatar Upload (S3/MinIO via @manacore/shared-storage)
|
||||
- vCard Import (Parsing + Validation)
|
||||
- `@manacore/shared-hono` Middleware (Auth, Health, Errors, Rate Limiting)
|
||||
- S3 Storage Integration für Contact-Fotos
|
||||
- CRUD delegiert an mana-sync (Local-First)
|
||||
|
||||
## Testing (58/100)
|
||||
**Lücken:**
|
||||
|
||||
- 5 Test-Files mit 62 Tests + Service-Specs
|
||||
- Mock Factories vorhanden
|
||||
- **Lücke:** Keine E2E Tests
|
||||
- Minimale Server-Logik (Großteil client-seitig)
|
||||
- Keine Backend-Unit-Tests
|
||||
- Keine Swagger/OpenAPI Dokumentation
|
||||
- Google OAuth Import nicht mehr verfügbar (NestJS-Migration)
|
||||
|
||||
## Security (85/100)
|
||||
## Frontend (95/100)
|
||||
|
||||
- Rate Limiting ✓, Auth Guards ✓, Google OAuth ✓, GDPR ✓, CORS ✓
|
||||
**Stärken:**
|
||||
|
||||
- 15 Routes, 39 Komponenten (27 Standard + 12 Skeleton), 14 Svelte 5 Stores
|
||||
- **Spiral-Netzwerk-Visualisierung** (@manacore/spiral-db)
|
||||
- **Cmd+K Spotlight** für schnelle Navigation und Aktionen
|
||||
- **NL Quick-Input** mit Client-seitiger Duplikaterkennung (Fuzzy Matching)
|
||||
- Context Menus (Alphabet-Navigation, Grid-View)
|
||||
- Import/Export (vCard, CSV)
|
||||
- Duplikaterkennung und Merge-Management
|
||||
- Archive-Ansicht für gelöschte Kontakte
|
||||
- Skeleton Loading States (12 Skeleton-Komponenten)
|
||||
- Focus Trapping in allen Modals
|
||||
- Security Headers (CSP, X-Frame-Options) via hooks.server.ts
|
||||
- PWA mit Service Worker, Manifest, Icons, Shortcuts
|
||||
- Offline Page mit shared OfflinePage Component
|
||||
- Error Tracking via GlitchTip
|
||||
- 5 Sprachen (DE, EN, FR, ES, IT)
|
||||
- **Local-First** via @manacore/local-store (IndexedDB + mana-sync)
|
||||
- SyncIndicator UI (visueller Sync-Status)
|
||||
|
||||
**Lücken:**
|
||||
|
||||
- Mobile App fehlt (Expo)
|
||||
|
||||
## Database (85/100)
|
||||
|
||||
**Stärken:**
|
||||
|
||||
- Server-seitig: 2 Tabellen mit Drizzle ORM
|
||||
- Client-seitig: Collections (contacts, tags) via local-store
|
||||
- Reactive Queries via useLiveQuery
|
||||
|
||||
**Lücken:**
|
||||
|
||||
- Server-Schema minimal (CRUD client-seitig)
|
||||
|
||||
## Testing (85/100)
|
||||
|
||||
**Stärken:**
|
||||
|
||||
- 6 Frontend Unit Tests (~115 Assertions)
|
||||
- 3 Playwright E2E Suites (auth, contacts, tags) — **NEU seit letztem Audit**
|
||||
- ~10 E2E Szenarien
|
||||
- ~125 Tests insgesamt
|
||||
- Vitest + Playwright Konfiguration
|
||||
|
||||
**Lücken:**
|
||||
|
||||
- Keine Backend-Tests
|
||||
- E2E für Import/Export fehlt
|
||||
- E2E für Duplikaterkennung fehlt
|
||||
|
||||
## Deployment (92/100)
|
||||
|
||||
**Stärken:**
|
||||
|
||||
- Multi-Stage Dockerfiles (Server + Web)
|
||||
- Health Checks konfiguriert
|
||||
- docker-compose.macmini.yml Einträge
|
||||
- Deployed auf contacts.mana.how
|
||||
- PWA-fähig für Installation
|
||||
- **Landing Page** (Astro) vorhanden — **NEU seit letztem Audit**
|
||||
|
||||
**Lücken:**
|
||||
|
||||
- Kein eigener CI/CD Job
|
||||
|
||||
## Security (88/100)
|
||||
|
||||
**Stärken:**
|
||||
|
||||
- JWT Auth via @manacore/shared-hono authMiddleware
|
||||
- Rate Limiting Middleware
|
||||
- CORS konfiguriert
|
||||
- Security Headers (CSP, X-Frame-Options)
|
||||
- Error Tracking (GlitchTip)
|
||||
- WebAuthn/Passkey Support (Auth)
|
||||
|
||||
**Lücken:**
|
||||
|
||||
- Google OAuth Import nicht mehr verfügbar
|
||||
- Kein Audit-Logging
|
||||
|
||||
## UX (95/100)
|
||||
|
||||
**Stärken:**
|
||||
|
||||
- 5 Sprachen (DE, EN, FR, ES, IT) — **erweitert von 2 Sprachen**
|
||||
- Cmd+K Spotlight für schnelle Aktionen
|
||||
- NL Quick-Input mit Duplikaterkennung
|
||||
- Spiral-Netzwerk-Visualisierung
|
||||
- Responsive Design
|
||||
- Loading Skeletons (12 Varianten)
|
||||
- PWA mit Offline-Support
|
||||
- Focus Trapping (Accessibility)
|
||||
- Context Menus
|
||||
- SyncIndicator
|
||||
- Archive-Ansicht
|
||||
|
||||
**Lücken:**
|
||||
|
||||
- Mobile App fehlt
|
||||
|
||||
## Änderungen seit letztem Audit (2026-03-19)
|
||||
|
||||
| Bereich | Vorher | Jetzt |
|
||||
| -------------- | ----------------------------------------- | ------------------------------------------------- |
|
||||
| Backend | NestJS (14 Module, 12 Controller, 4 DTOs) | Hono/Bun (2 Route-Files, Zod) |
|
||||
| i18n | 2 Sprachen (DE, EN) | 5 Sprachen (DE, EN, FR, ES, IT) |
|
||||
| E2E Tests | Keine | 3 Playwright Suites (auth, contacts, tags) |
|
||||
| PWA | Nicht konfiguriert | Aktiv (@vite-pwa/sveltekit) |
|
||||
| Landing Page | Fehlte | Astro Landing Page |
|
||||
| Local-First | Nicht vorhanden | @manacore/local-store aktiv |
|
||||
| Spiral-Viz | Nicht vorhanden | @manacore/spiral-db integriert |
|
||||
| Spotlight | Fehlte | Cmd+K Actions |
|
||||
| NL Quick-Input | Fehlte | Mit Fuzzy Duplikaterkennung |
|
||||
| SyncIndicator | Fehlte | Visueller Sync-Status |
|
||||
| Google OAuth | Vorhanden (NestJS) | Entfernt (Migration) |
|
||||
| Score | 94 → | **92** (Backend-Reduktion, Google OAuth verloren) |
|
||||
|
||||
## Top-3 Empfehlungen
|
||||
|
||||
1. **i18n erweitern** - Mindestens FR, IT, ES wie Chat/Calendar
|
||||
2. **E2E Tests** - Import/Export Flows, Duplikaterkennung
|
||||
3. **PWA aktivieren**
|
||||
1. **Backend-Tests** — Avatar Upload und vCard Import brauchen Unit-Tests
|
||||
2. **Google OAuth wiederherstellen** — Import-Feature bei NestJS-Migration verloren
|
||||
3. **E2E für Import/Export** — vCard/CSV Import/Export Flows testen
|
||||
|
|
|
|||
|
|
@ -1,29 +1,30 @@
|
|||
---
|
||||
title: 'Todo: Production Readiness Audit'
|
||||
description: 'Aufgabenverwaltung mit 19 DTOs, Swagger API Docs, 200+ Tests + E2E, Focus Trapping, PWA, Auto-Save, Context Menus, 5 Sprachen'
|
||||
date: 2026-03-24
|
||||
description: 'Aufgabenverwaltung mit Hono/Bun Backend, 55 Komponenten, Paper-UI, Cmd+K Spotlight, Reminders Worker, Local-First, PWA, 5 Sprachen'
|
||||
date: 2026-04-01
|
||||
app: 'todo'
|
||||
author: 'Till Schneider'
|
||||
tags: ['audit', 'todo', 'production-readiness']
|
||||
score: 96
|
||||
score: 93
|
||||
history:
|
||||
- { date: '2026-03-19', score: 80 }
|
||||
- { date: '2026-03-24', score: 96 }
|
||||
- { date: '2026-04-01', score: 93 }
|
||||
scores:
|
||||
backend: 94
|
||||
frontend: 95
|
||||
database: 88
|
||||
testing: 90
|
||||
backend: 90
|
||||
frontend: 97
|
||||
database: 85
|
||||
testing: 85
|
||||
deployment: 92
|
||||
documentation: 95
|
||||
documentation: 90
|
||||
security: 90
|
||||
ux: 94
|
||||
ux: 97
|
||||
apiConformity:
|
||||
consistentResponses: true
|
||||
errorCodes: true
|
||||
pagination: false
|
||||
versioning: true
|
||||
documentation: true
|
||||
documentation: false
|
||||
healthEndpoint: true
|
||||
validation: true
|
||||
consistency:
|
||||
|
|
@ -36,14 +37,14 @@ consistency:
|
|||
sharedStorage: false
|
||||
sharedLlm: false
|
||||
dependencies:
|
||||
total: 38
|
||||
outdated: 9
|
||||
total: 35
|
||||
outdated: 8
|
||||
vulnerabilities:
|
||||
critical: 0
|
||||
high: 0
|
||||
moderate: 0
|
||||
low: 0
|
||||
lastChecked: '2026-03-24'
|
||||
lastChecked: '2026-04-01'
|
||||
lighthouse:
|
||||
performance: 90
|
||||
accessibility: 93
|
||||
|
|
@ -56,106 +57,117 @@ analytics:
|
|||
landingTracking: true
|
||||
publicDashboard: true
|
||||
status: 'production'
|
||||
version: '1.1.0'
|
||||
version: '2.0.0'
|
||||
stats:
|
||||
backendModules: 7
|
||||
webRoutes: 13
|
||||
components: 35
|
||||
dbTables: 8
|
||||
testFiles: 16
|
||||
testCount: 210
|
||||
backendModules: 3
|
||||
webRoutes: 15
|
||||
components: 55
|
||||
dbTables: 3
|
||||
testFiles: 12
|
||||
testCount: 300
|
||||
languages: 5
|
||||
linesOfCode: 26567
|
||||
sourceFiles: 187
|
||||
sizeInMb: 1.2
|
||||
commits: 223
|
||||
linesOfCode: 28000
|
||||
sourceFiles: 190
|
||||
sizeInMb: 1.3
|
||||
commits: 280
|
||||
contributors: 3
|
||||
firstCommitDate: '2025-12-03'
|
||||
todoCount: 98
|
||||
apiEndpoints: 50
|
||||
stores: 30
|
||||
todoCount: 70
|
||||
apiEndpoints: 14
|
||||
stores: 12
|
||||
maxFileLines: 1252
|
||||
---
|
||||
|
||||
## Zusammenfassung
|
||||
|
||||
Todo ist eine **feature-reiche Aufgabenverwaltung** mit Kanban-Boards, Projekten, Labels, Reminders, Notepad-Design, Auto-Save und die App mit den **meisten DTOs** (19). Vollständig production-ready mit PWA, Offline-Support, Focus Trapping, Context Menus und 5 Sprachen.
|
||||
Todo ist eine **feature-reiche Aufgabenverwaltung** mit Paper-UI Design, Fokus-Board, Kanban, Spiral-View, Reminders mit Background Worker, Auto-Save, Cmd+K Spotlight und Local-First Architektur. Seit dem letzten Audit wurde das Backend von NestJS auf **Hono/Bun** migriert — CRUD läuft jetzt client-seitig über `@manacore/local-store` + `mana-sync`.
|
||||
|
||||
## Backend (94/100)
|
||||
## Backend (90/100)
|
||||
|
||||
**Architektur:** Hono 4.7.0 + Bun (migriert von NestJS)
|
||||
|
||||
**Stärken:**
|
||||
|
||||
- 7 Module: Project, Task, Label, Reminder, Kanban, Network, Admin
|
||||
- 19 DTOs (beste Validation aller Apps)
|
||||
- Rate Limiting (ThrottlerGuard global, 100 req/min)
|
||||
- MetricsModule, ManaCoreModule
|
||||
- GDPR Admin-Endpoints
|
||||
- RRULE Validation mit DoS-Schutz (max 5000 Occurrences)
|
||||
- Swagger/OpenAPI Dokumentation
|
||||
- Error Tracking via GlitchTip
|
||||
- 3 fokussierte Route-Module: `rrule.ts`, `reminders.ts`, `admin.ts`
|
||||
- 14 API-Endpoints (server-seitige Compute-Operationen)
|
||||
- `@manacore/shared-hono` Middleware (Auth, Health, Errors, Rate Limiting)
|
||||
- RRULE Expansion mit DoS-Schutz (max 5000 Occurrences, 10-Jahres-Limit)
|
||||
- Background Reminder Worker mit Push/Email-Notifications via mana-notify
|
||||
- GDPR Admin-Endpoints (GET/DELETE User Data)
|
||||
- Drizzle ORM mit Zod-Validation
|
||||
|
||||
**Lücken:**
|
||||
|
||||
- Keine Controller-Tests
|
||||
- Keine Backend-Unit-Tests (Hono-Routes ohne Test-Coverage)
|
||||
- Keine Swagger/OpenAPI Dokumentation (NestJS hatte das automatisch)
|
||||
|
||||
## Frontend (95/100)
|
||||
## Frontend (97/100)
|
||||
|
||||
**Stärken:**
|
||||
|
||||
- 13 Routes, 35 Komponenten, 13 Stores
|
||||
- Kanban-Board, Spiral-View, Projekt-Views
|
||||
- Notepad-Design für Task-Liste (physisches Notizbuch-Feeling)
|
||||
- Auto-Save mit 500ms Debounce (kein Save/Cancel nötig)
|
||||
- Drag & Drop für Task-Reordering (Liste + Kanban)
|
||||
- Skeleton Loading States (TaskList, TaskItem, KanbanBoard, Statistics)
|
||||
- Globale Error Page mit i18n (5 Sprachen)
|
||||
- PWA mit Service Worker, Manifest, Icons (192x192, 512x512, apple-touch-icon), Shortcuts
|
||||
- Offline Page prerendered mit shared OfflinePage Component (PWA-Install Fix)
|
||||
- Security Headers (CSP, X-Frame-Options) via hooks.server.ts
|
||||
- Meta/OG Tags für SEO
|
||||
- Focus Trapping in allen Modals (shared focusTrap Action)
|
||||
- Context Menu auf TaskList (Bearbeiten, Complete, Priorität, Projekt verschieben, Löschen)
|
||||
- 15 Routes, 55 Komponenten, 12 Svelte 5 Stores
|
||||
- **Paper-UI Design** — physisches Notizbuch-Feeling mit Animationen
|
||||
- **Fokus-Board** als vereinheitlichte Einzelansicht
|
||||
- Kanban-Board mit Subtask Drag & Drop
|
||||
- Spiral-View Visualisierung (@manacore/spiral-db)
|
||||
- **Cmd+K Spotlight** für schnelle Navigation und Aktionen
|
||||
- Inline Title Editing direkt in der Liste
|
||||
- Auto-Save mit 500ms Debounce
|
||||
- Animated Completion mit "Heute erledigt" Sektion
|
||||
- QuickInputBar mit Natural Language Parsing
|
||||
- TagStrip + Unified TaskFilters
|
||||
- Context Menu auf TaskList (Bearbeiten, Complete, Priorität, Löschen)
|
||||
- Skeleton Loading States (TaskList, TaskItem, KanbanBoard)
|
||||
- Focus Trapping in allen Modals
|
||||
- Security Headers (CSP, X-Frame-Options) via hooks.server.ts
|
||||
- PWA mit Service Worker, Manifest, Icons, Shortcuts
|
||||
- Offline Page mit shared OfflinePage Component
|
||||
- Error Tracking via GlitchTip
|
||||
- 5 Sprachen (DE, EN, FR, ES, IT)
|
||||
- **Local-First** via @manacore/local-store (IndexedDB + mana-sync)
|
||||
|
||||
**Lücken:**
|
||||
|
||||
- Mobile App noch nicht auf gleichem Stand
|
||||
- Mobile App (Expo) noch nicht auf gleichem Stand
|
||||
|
||||
## Database (88/100)
|
||||
## Database (85/100)
|
||||
|
||||
**Stärken:**
|
||||
|
||||
- 8 Tabellen: projects, tasks, labels, task_labels, reminders + Hilfstabellen
|
||||
- Drizzle ORM mit Type Safety
|
||||
- Server-seitig: 3 Tabellen (tasks, projects, reminders) mit Drizzle ORM
|
||||
- Client-seitig: 5 Collections (tasks, labels, taskLabels, reminders, boardViews) via local-store
|
||||
- JSONB für Subtasks und Metadata
|
||||
- TEXT für user_id (Better Auth Format)
|
||||
|
||||
## Testing (90/100)
|
||||
|
||||
**Stärken:**
|
||||
|
||||
- 7 Backend Unit Tests (task, project, kanban, reminder, label services + controllers)
|
||||
- 3 Frontend Unit Tests (task-parser, task-filters, view store)
|
||||
- 3 Playwright E2E Test Suites (auth, projects, tasks)
|
||||
- Vitest + Jest Konfiguration
|
||||
- Indexes auf task_id, user_id
|
||||
|
||||
**Lücken:**
|
||||
|
||||
- Backend-Coverage ausbaubar
|
||||
- Server-Schema minimal (CRUD client-seitig)
|
||||
- Keine Migrations-Dokumentation
|
||||
|
||||
## Testing (85/100)
|
||||
|
||||
**Stärken:**
|
||||
|
||||
- 6 Frontend Unit Tests (task-parser, task-filters, time-estimator, tasks API, view store, help)
|
||||
- 3 Playwright E2E Test Suites (auth, projects, tasks)
|
||||
- ~300 Test-Assertions insgesamt
|
||||
- Vitest + Playwright Konfiguration
|
||||
|
||||
**Lücken:**
|
||||
|
||||
- Keine Backend-Tests (Hono-Routes)
|
||||
- E2E für Kanban fehlt
|
||||
- E2E für Reminders fehlt
|
||||
|
||||
## Deployment (92/100)
|
||||
|
||||
**Stärken:**
|
||||
|
||||
- Multi-Stage Dockerfiles (Backend + Web)
|
||||
- Multi-Stage Dockerfiles (Server + Web)
|
||||
- Health Checks konfiguriert
|
||||
- docker-compose.prod.yml mit Traefik Labels
|
||||
- docker-compose.macmini.yml Einträge
|
||||
- Deployed auf todo.mana.how
|
||||
- PWA-fähig für Installation
|
||||
- Landing Page (Astro) vorhanden
|
||||
|
||||
**Lücken:**
|
||||
|
||||
|
|
@ -165,54 +177,52 @@ Todo ist eine **feature-reiche Aufgabenverwaltung** mit Kanban-Boards, Projekten
|
|||
|
||||
**Stärken:**
|
||||
|
||||
- JwtAuthGuard auf allen Backend-Endpoints
|
||||
- ThrottlerGuard global (100 req/min)
|
||||
- JWT Auth via @manacore/shared-hono authMiddleware
|
||||
- Rate Limiting Middleware
|
||||
- CORS konfiguriert
|
||||
- RRULE DoS-Schutz (max 5000 Occurrences, 10-Jahres-Limit)
|
||||
- Security Headers (CSP, X-Frame-Options)
|
||||
- Error Tracking (GlitchTip)
|
||||
- Demo-Task Authentication Gate
|
||||
|
||||
## UX (94/100)
|
||||
## UX (97/100)
|
||||
|
||||
**Stärken:**
|
||||
|
||||
- 5 Sprachen (DE, EN, FR, ES, IT)
|
||||
- Keyboard Shortcuts (Ctrl+1-3, F für Immersive Mode)
|
||||
- Responsive Design
|
||||
- Loading Skeletons
|
||||
- Cmd+K Spotlight für schnelle Aktionen
|
||||
- Keyboard Shortcuts
|
||||
- Paper-UI Design mit Animationen
|
||||
- Auto-Save (kein manuelles Speichern nötig)
|
||||
- PWA mit Offline-Support
|
||||
- Focus Trapping in allen Modals (Accessibility)
|
||||
- Context Menu für schnelle Aktionen (Priorität, Projekt, Complete, Delete)
|
||||
- QuickInputBar mit Natural Language Parsing
|
||||
- Immersive Mode
|
||||
- Notepad-Design
|
||||
- Focus Trapping (Accessibility)
|
||||
- Context Menu für schnelle Aktionen
|
||||
- Inline Editing
|
||||
- Animated Completion
|
||||
- Responsive Design
|
||||
- Loading Skeletons
|
||||
|
||||
**Lücken:**
|
||||
|
||||
- Mobile App (Expo) noch nicht auf gleichem Stand
|
||||
|
||||
## Änderungen seit letztem Audit (2026-03-19)
|
||||
## Änderungen seit letztem Audit (2026-03-24)
|
||||
|
||||
| Bereich | Vorher | Jetzt |
|
||||
| ---------------- | ---------------------- | ------------------------------------ |
|
||||
| i18n | 2 Sprachen | ✅ 5 Sprachen (DE/EN/FR/ES/IT) |
|
||||
| PWA | Nicht konfiguriert | ✅ Vollständig (SW, Manifest, Icons) |
|
||||
| Error Page | Hardcodiert (DE) | ✅ i18n (5 Sprachen) |
|
||||
| Focus Trapping | Fehlte | ✅ Alle 2 Modals |
|
||||
| Meta/OG Tags | Fehlten | ✅ Root Layout |
|
||||
| Context Menus | Fehlten | ✅ TaskList mit 5 Aktionen |
|
||||
| Auto-Save | Fehlte | ✅ 500ms Debounce |
|
||||
| Notepad-Design | Standard-Liste | ✅ Physisches Notizbuch |
|
||||
| TaskFilters | 2 separate Komponenten | ✅ Unified TaskFilters |
|
||||
| QuickInputBar | Fehlte | ✅ Mit NLP Parsing |
|
||||
| Offline Page | Fehlte | ✅ Shared OfflinePage |
|
||||
| Security Headers | Fehlten | ✅ hooks.server.ts |
|
||||
| Score | 94 → | **96** |
|
||||
| Bereich | Vorher | Jetzt |
|
||||
| -------------- | -------------------------- | ------------------------------- |
|
||||
| Backend | NestJS (7 Module, 19 DTOs) | Hono/Bun (3 Routes, Drizzle) |
|
||||
| Komponenten | 35 | 55 (+20) |
|
||||
| UI Design | Standard-Liste | Paper-UI mit Animationen |
|
||||
| Navigation | Tabs (Matrix/Übersicht) | Fokus-Board (vereinheitlicht) |
|
||||
| Spotlight | Fehlte | Cmd+K Actions |
|
||||
| Inline Editing | Fehlte | Titel direkt editierbar |
|
||||
| Reminders | Server-seitig (NestJS) | Background Worker + mana-notify |
|
||||
| Completion | Standard | Animated + "Heute erledigt" |
|
||||
| Kanban | Basis | Subtask Drag & Drop |
|
||||
| Local-First | Konzept | @manacore/local-store aktiv |
|
||||
| Score | 96 → | **93** (Backend-Tests verloren) |
|
||||
|
||||
## Top-3 Empfehlungen
|
||||
|
||||
1. **Controller-Tests** - Service-Tests vorhanden, aber Controller-Level fehlt
|
||||
2. **E2E für Kanban** - Kanban-Board ist ein Key-Feature, braucht E2E Coverage
|
||||
3. **Mobile App updaten** - Expo-App auf gleichen Feature-Stand bringen
|
||||
1. **Backend-Tests** — Hono-Routes (RRULE, Reminders, Admin) brauchen Unit-Tests
|
||||
2. **E2E für Kanban + Reminders** — Key-Features ohne E2E Coverage
|
||||
3. **Mobile App updaten** — Expo-App auf gleichen Feature-Stand bringen
|
||||
|
|
|
|||
|
|
@ -240,7 +240,6 @@
|
|||
0 0 0 1px rgba(0, 0, 0, 0.04);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
:global(.dark) .fokus-sheet {
|
||||
background-color: #252220;
|
||||
|
|
@ -252,30 +251,10 @@
|
|||
opacity: 0.75;
|
||||
}
|
||||
|
||||
/* Scrollable wrapper for DnD zone + footer + completed section */
|
||||
.sheet-body {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: rgba(0, 0, 0, 0.08) transparent;
|
||||
}
|
||||
:global(.dark) .sheet-body {
|
||||
scrollbar-color: rgba(255, 255, 255, 0.1) transparent;
|
||||
}
|
||||
.sheet-body::-webkit-scrollbar {
|
||||
width: 4px;
|
||||
}
|
||||
.sheet-body::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
.sheet-body::-webkit-scrollbar-thumb {
|
||||
background: rgba(0, 0, 0, 0.08);
|
||||
border-radius: 2px;
|
||||
}
|
||||
:global(.dark) .sheet-body::-webkit-scrollbar-thumb {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.sheet-content {
|
||||
|
|
@ -291,11 +270,7 @@
|
|||
}
|
||||
|
||||
.sheet-footer {
|
||||
padding: 0.5rem 1rem 0.75rem;
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.04);
|
||||
}
|
||||
:global(.dark) .sheet-footer {
|
||||
border-top-color: rgba(255, 255, 255, 0.04);
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:global(.fokus-drop-target) {
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@
|
|||
</div>
|
||||
|
||||
<!-- Quick Add Task -->
|
||||
<div class="px-3 pb-3 pt-2">
|
||||
<div class="pb-2">
|
||||
<QuickAddTaskInline onAdd={handleAddTask} />
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
<script lang="ts">
|
||||
import { t } from 'svelte-i18n';
|
||||
import { Plus, X } from '@manacore/shared-icons';
|
||||
import { Plus } from '@manacore/shared-icons';
|
||||
|
||||
interface Props {
|
||||
onAdd: (title: string) => void;
|
||||
|
|
@ -33,88 +32,117 @@
|
|||
}
|
||||
|
||||
function handleBlur() {
|
||||
if (!title.trim()) {
|
||||
isAdding = false;
|
||||
if (title.trim()) {
|
||||
handleSubmit();
|
||||
}
|
||||
isAdding = false;
|
||||
}
|
||||
|
||||
function activate() {
|
||||
isAdding = true;
|
||||
}
|
||||
|
||||
$effect(() => {
|
||||
if (isAdding && inputRef) {
|
||||
inputRef.focus();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="quick-add-inline">
|
||||
<div class="inline-add-row" class:active={isAdding}>
|
||||
<!-- Circle matching TaskItem checkbox style -->
|
||||
{#if isAdding}
|
||||
<div class="add-form p-3">
|
||||
<input
|
||||
bind:this={inputRef}
|
||||
bind:value={title}
|
||||
onkeydown={handleKeydown}
|
||||
onblur={handleBlur}
|
||||
{placeholder}
|
||||
class="w-full px-0 py-1 text-sm bg-transparent outline-none text-foreground placeholder:text-muted-foreground"
|
||||
autofocus
|
||||
/>
|
||||
<div class="flex justify-between items-center mt-2 pt-2 border-t border-border/50">
|
||||
<button
|
||||
class="px-3 py-1.5 text-xs font-medium bg-primary text-primary-foreground rounded-full hover:bg-primary/90 transition-all shadow-sm flex items-center gap-1.5"
|
||||
onmousedown={(e) => e.preventDefault()}
|
||||
onclick={handleSubmit}
|
||||
>
|
||||
<Plus size={14} />
|
||||
{$t('kanban.add')}
|
||||
</button>
|
||||
<button
|
||||
class="p-1.5 text-muted-foreground hover:text-foreground hover:bg-muted rounded-full transition-colors"
|
||||
onmousedown={(e) => e.preventDefault()}
|
||||
onclick={() => {
|
||||
title = '';
|
||||
isAdding = false;
|
||||
}}
|
||||
>
|
||||
<X size={16} />
|
||||
</button>
|
||||
</div>
|
||||
<div class="add-checkbox">
|
||||
<Plus size={12} />
|
||||
</div>
|
||||
<input
|
||||
bind:this={inputRef}
|
||||
bind:value={title}
|
||||
onkeydown={handleKeydown}
|
||||
onblur={handleBlur}
|
||||
{placeholder}
|
||||
class="add-input"
|
||||
/>
|
||||
{:else}
|
||||
<button
|
||||
class="add-trigger group w-full p-2.5 text-sm text-muted-foreground hover:text-foreground transition-all flex items-center gap-2"
|
||||
onclick={() => (isAdding = true)}
|
||||
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
||||
<div
|
||||
class="inline-add-trigger"
|
||||
onclick={activate}
|
||||
onkeydown={(e) => e.key === 'Enter' && activate()}
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="w-5 h-5 rounded-full border-2 border-dashed border-current group-hover:border-primary group-hover:text-primary flex items-center justify-center transition-colors"
|
||||
>
|
||||
<Plus size={14} />
|
||||
<div class="add-checkbox placeholder">
|
||||
<Plus size={12} />
|
||||
</div>
|
||||
<span class="group-hover:text-foreground transition-colors">{$t('kanban.addTask')}</span>
|
||||
</button>
|
||||
<span class="add-placeholder">{placeholder}</span>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
/* Glass-Pill add form */
|
||||
.add-form {
|
||||
background: rgba(255, 255, 255, 0.85);
|
||||
backdrop-filter: blur(12px);
|
||||
-webkit-backdrop-filter: blur(12px);
|
||||
border: 1px solid rgba(0, 0, 0, 0.1);
|
||||
border-radius: 1rem;
|
||||
box-shadow:
|
||||
0 4px 6px -1px rgba(0, 0, 0, 0.1),
|
||||
0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||
.inline-add-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.625rem;
|
||||
padding: 0.2rem 1rem;
|
||||
transition: all 0.15s ease;
|
||||
}
|
||||
|
||||
:global(.dark) .add-form {
|
||||
background: rgba(255, 255, 255, 0.12);
|
||||
border: 1px solid rgba(255, 255, 255, 0.15);
|
||||
.inline-add-trigger {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.625rem;
|
||||
width: 100%;
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
/* Trigger button with subtle glass effect */
|
||||
.add-trigger {
|
||||
.add-checkbox {
|
||||
width: 1.25rem;
|
||||
height: 1.25rem;
|
||||
border-radius: 9999px;
|
||||
border: 2px dashed var(--color-muted-foreground);
|
||||
opacity: 0.4;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
color: var(--color-muted-foreground);
|
||||
transition: all 0.15s;
|
||||
}
|
||||
|
||||
.add-trigger:hover {
|
||||
background: rgba(255, 255, 255, 0.5);
|
||||
.inline-add-row.active .add-checkbox,
|
||||
.inline-add-trigger:hover .add-checkbox {
|
||||
opacity: 0.6;
|
||||
border-color: var(--color-primary);
|
||||
color: var(--color-primary);
|
||||
}
|
||||
|
||||
:global(.dark) .add-trigger:hover {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
.add-input {
|
||||
flex: 1;
|
||||
background: transparent;
|
||||
border: none;
|
||||
outline: none;
|
||||
font-size: 0.875rem;
|
||||
color: var(--color-foreground);
|
||||
padding: 0;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.add-input::placeholder {
|
||||
color: var(--color-muted-foreground);
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.add-placeholder {
|
||||
font-size: 0.875rem;
|
||||
color: var(--color-muted-foreground);
|
||||
opacity: 0.6;
|
||||
transition: all 0.15s;
|
||||
}
|
||||
|
||||
.inline-add-trigger:hover .add-placeholder {
|
||||
opacity: 0.8;
|
||||
color: var(--color-foreground);
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -159,7 +159,7 @@
|
|||
|
||||
<style>
|
||||
.board-page {
|
||||
height: calc(100vh - 140px);
|
||||
min-height: calc(100vh - 140px);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue