From 0c2434bd1d5019eff430a52e455f1753d48eb483 Mon Sep 17 00:00:00 2001 From: Till-JS <101404291+Till-JS@users.noreply.github.com> Date: Tue, 9 Dec 2025 14:29:56 +0100 Subject: [PATCH] feat(todo): add task metadata fields and mana page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add storyPoints, effectiveDuration, funRating to TaskMetadata - Add UI controls in TaskEditModal for new metadata fields - Add columns/kanban icon to shared-ui PillNavigation - Add Mana subscription page to todo app - Update TASK_METADATA.md documentation 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .../backend/src/db/schema/tasks.schema.ts | 11 +++ .../web/src/routes/(app)/mana/+page.svelte | 39 +++++++++++ apps/todo/docs/TASK_METADATA.md | 68 ++++++++++++++++++- apps/todo/packages/shared/src/types/task.ts | 11 +++ .../src/navigation/PillNavigation.svelte | 4 ++ 5 files changed, 131 insertions(+), 2 deletions(-) create mode 100644 apps/todo/apps/web/src/routes/(app)/mana/+page.svelte diff --git a/apps/todo/apps/backend/src/db/schema/tasks.schema.ts b/apps/todo/apps/backend/src/db/schema/tasks.schema.ts index 52da64654..573937582 100644 --- a/apps/todo/apps/backend/src/db/schema/tasks.schema.ts +++ b/apps/todo/apps/backend/src/db/schema/tasks.schema.ts @@ -23,10 +23,21 @@ export interface Subtask { order: number; } +export type DurationUnit = 'minutes' | 'hours' | 'days'; + +export interface EffectiveDuration { + value: number; + unit: DurationUnit; +} + export interface TaskMetadata { notes?: string; attachments?: string[]; linkedCalendarEventId?: string | null; + // Agile/Productivity metadata + storyPoints?: number | null; // Fibonacci: 1, 2, 3, 5, 8, 13, 21 + effectiveDuration?: EffectiveDuration | null; // Actual time spent + funRating?: number | null; // 1-10 scale } export const tasks = pgTable( diff --git a/apps/todo/apps/web/src/routes/(app)/mana/+page.svelte b/apps/todo/apps/web/src/routes/(app)/mana/+page.svelte new file mode 100644 index 000000000..dde8befae --- /dev/null +++ b/apps/todo/apps/web/src/routes/(app)/mana/+page.svelte @@ -0,0 +1,39 @@ + + + + Mana - Todo + + +
+ +
+ + diff --git a/apps/todo/docs/TASK_METADATA.md b/apps/todo/docs/TASK_METADATA.md index 1a4afda5a..c8c1a00d2 100644 --- a/apps/todo/docs/TASK_METADATA.md +++ b/apps/todo/docs/TASK_METADATA.md @@ -141,6 +141,44 @@ Das `metadata`-Objekt enthält erweiterte Informationen. | `metadata.notes` | `string` | Zusätzliche Notizen | | `metadata.attachments` | `string[]` | URLs zu Dateianhängen | | `metadata.linkedCalendarEventId` | `string \| null` | ID eines verknüpften Kalender-Events | +| `metadata.storyPoints` | `number \| null` | Storypoints (Fibonacci: 1, 2, 3, 5, 8, 13, 21) | +| `metadata.effectiveDuration` | `EffectiveDuration \| null` | Effektive Dauer der Aufgabe | +| `metadata.funRating` | `number \| null` | Spaß-Faktor (Skala 1-10) | + +### EffectiveDuration-Struktur + +```typescript +interface EffectiveDuration { + value: number; // Numerischer Wert + unit: DurationUnit; // 'minutes' | 'hours' | 'days' +} + +type DurationUnit = 'minutes' | 'hours' | 'days'; +``` + +### Storypoints + +Storypoints verwenden die Fibonacci-Sequenz zur Aufwandsschätzung: + +| Wert | Typischer Aufwand | +|------|-------------------| +| 1 | Sehr klein, wenige Minuten | +| 2 | Klein, unter einer Stunde | +| 3 | Mittel, ein paar Stunden | +| 5 | Größer, halber Tag | +| 8 | Groß, ganzer Tag | +| 13 | Sehr groß, mehrere Tage | +| 21 | Epic, aufteilen empfohlen | + +### Spaß-Faktor + +Der Spaß-Faktor ist eine Skala von 1-10: + +| Bereich | Bedeutung | Farbe | +|---------|-----------|-------| +| 1-3 | Unangenehm | Rot (#ef4444) | +| 4-6 | Neutral | Gelb (#eab308) | +| 7-10 | Macht Spaß | Grün (#22c55e) | ### Beispiel ```typescript @@ -151,7 +189,13 @@ Das `metadata`-Objekt enthält erweiterte Informationen. "https://storage.example.com/file1.pdf", "https://storage.example.com/image.png" ], - linkedCalendarEventId: "cal-event-123" + linkedCalendarEventId: "cal-event-123", + storyPoints: 5, + effectiveDuration: { + value: 2, + unit: "hours" + }, + funRating: 7 } } ``` @@ -223,7 +267,10 @@ const task: Task = { metadata: { notes: "Design-Specs sind im Anhang", attachments: ["https://storage.example.com/design-specs.pdf"], - linkedCalendarEventId: "cal-123" + linkedCalendarEventId: "cal-123", + storyPoints: 8, + effectiveDuration: { value: 4, unit: "hours" }, + funRating: 6 }, // Timestamps @@ -240,6 +287,20 @@ const task: Task = { - `priority` - Priorität-Picker (Niedrig, Mittel, Hoch, Dringend) - `projectId` - Projekt-Picker +### Im TaskEditModal implementiert +- Alle QuickAdd-Felder +- `description` - Textarea +- `dueTime` - Zeit-Picker +- `startDate` - Datum-Picker +- `status` - Select (Ausstehend, In Bearbeitung, Abgeschlossen, Abgebrochen) +- `labels` - Multi-Select Dropdown +- `subtasks` - Drag-and-Drop Liste +- `recurrenceRule` - Select (Täglich, Wöchentlich, etc.) +- `metadata.notes` - Textarea +- `metadata.storyPoints` - Fibonacci-Buttons (1, 2, 3, 5, 8, 13, 21) +- `metadata.effectiveDuration` - Quick-Select Chips + benutzerdefinierte Eingabe +- `metadata.funRating` - 10-Punkte-Skala mit Farbverlauf + ### Noch nicht im QuickAdd - Labels - Erinnerungen/Reminders @@ -248,3 +309,6 @@ const task: Task = { - Beschreibung - Startdatum - Uhrzeit +- Storypoints +- Effektive Dauer +- Spaß-Faktor diff --git a/apps/todo/packages/shared/src/types/task.ts b/apps/todo/packages/shared/src/types/task.ts index 9c1c567d1..74c97cd97 100644 --- a/apps/todo/packages/shared/src/types/task.ts +++ b/apps/todo/packages/shared/src/types/task.ts @@ -11,10 +11,21 @@ export interface Subtask { order: number; } +export type DurationUnit = 'minutes' | 'hours' | 'days'; + +export interface EffectiveDuration { + value: number; + unit: DurationUnit; +} + export interface TaskMetadata { notes?: string; attachments?: string[]; linkedCalendarEventId?: string | null; + // Agile/Productivity metadata + storyPoints?: number | null; // Fibonacci: 1, 2, 3, 5, 8, 13, 21 + effectiveDuration?: EffectiveDuration | null; // Actual time spent + funRating?: number | null; // 1-10 scale } export interface Task { diff --git a/packages/shared-ui/src/navigation/PillNavigation.svelte b/packages/shared-ui/src/navigation/PillNavigation.svelte index 2ceb37ef5..39b80b3ea 100644 --- a/packages/shared-ui/src/navigation/PillNavigation.svelte +++ b/packages/shared-ui/src/navigation/PillNavigation.svelte @@ -275,6 +275,10 @@ check: 'M5 13l4 4L19 7', checkCircle: 'M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z', plus: 'M12 4v16m8-8H4', + columns: + 'M9 4H5a1 1 0 00-1 1v14a1 1 0 001 1h4a1 1 0 001-1V5a1 1 0 00-1-1zM19 4h-4a1 1 0 00-1 1v14a1 1 0 001 1h4a1 1 0 001-1V5a1 1 0 00-1-1z', + kanban: + 'M9 4H5a1 1 0 00-1 1v14a1 1 0 001 1h4a1 1 0 001-1V5a1 1 0 00-1-1zM19 4h-4a1 1 0 00-1 1v14a1 1 0 001 1h4a1 1 0 001-1V5a1 1 0 00-1-1z', // Original icons mic: 'M19 11a7 7 0 01-7 7m0 0a7 7 0 01-7-7m7 7v4m0 0H8m4 0h4m-4-8a3 3 0 01-3-3V5a3 3 0 116 0v6a3 3 0 01-3 3z', calendar: