175 lines
6.7 KiB
Markdown
175 lines
6.7 KiB
Markdown
# Haushalt — Aufgabenverwaltung
|
||
|
||
## Tech-Stack
|
||
|
||
| Schicht | Technologie |
|
||
|---------|------------|
|
||
| Backend | Symfony 7.4, PHP 8.2+, Doctrine ORM 3.6 |
|
||
| Frontend Web | Vue 3 (Composition API), Vite 8, Pinia, Vue Router 4 |
|
||
| Datenbank | MySQL/MariaDB (utf8mb4) |
|
||
| CORS | Nelmio CORS Bundle |
|
||
| Umgebung | DDEV |
|
||
|
||
## Domain-Modell
|
||
|
||
**Task** — Einzelne Aufgabe
|
||
- Felder: id, name, status, date, schema (nullable FK), category (nullable FK), createdAt
|
||
- TaskStatus: Active (`active`), Done (`done`)
|
||
- Tasks mit schema=null sind standalone (z.B. aus Single-Schemas erstellt)
|
||
- Tasks mit schema!=null gehören zu einem wiederkehrenden Schema
|
||
|
||
**TaskSchema** — Template für wiederkehrende Aufgaben
|
||
- Felder: id, name, status, taskType, category, startDate, endDate, days, createdAt
|
||
- TaskSchemaStatus: Active (`active`), Disabled (`disabled`)
|
||
- TaskSchemaType: Single (`single`), Daily (`daily`), Custom (`custom`)
|
||
- `days`: JSON-Feld mit optionalen Keys: `week` (1-7), `month` (1-31), `year` ([{month, day}])
|
||
- Single: Erstellt Tasks via YearPicker, Tasks werden detached (schema=null), Schema löscht sich automatisch
|
||
- Daily: Erstellt Tasks für jeden Tag im Zeitraum start–end
|
||
- Custom: Erstellt Tasks basierend auf days-Konfiguration im Zeitraum start–end
|
||
- Disabled: Generiert keine neuen Tasks, bestehende bleiben
|
||
|
||
**Category** — Farbkodierte Kategorie
|
||
- Felder: id, name, color (Hex #RRGGBB)
|
||
|
||
Enum-Case-Namen und DB-Werte sind Englisch.
|
||
|
||
## Architektur (Backend)
|
||
|
||
```
|
||
Controller → Service (Manager) → Repository → Entity
|
||
↓
|
||
DTO (Request)
|
||
```
|
||
|
||
**Prinzipien:**
|
||
- Controller: nur Routing + Response, keine Geschäftslogik
|
||
- Manager-Services: Geschäftslogik (CRUD, Validierung, Toggle)
|
||
- DTOs: typisierter Input (Request)
|
||
- Validierung: nur auf Request-DTOs (`#[Assert\...]`), nicht auf Entities
|
||
- Entities: Doctrine-Mapping + Getter/Setter, Serializer-Groups für API-Output
|
||
- Task-Generierung: Lazy beim Aufruf von GET /api/tasks (nicht per Cronjob)
|
||
|
||
## Verzeichnisstruktur (Backend)
|
||
|
||
```
|
||
backend/src/
|
||
Controller/Api/
|
||
CategoryController.php — Category CRUD
|
||
TaskController.php — Task CRUD + index + toggle
|
||
TaskSchemaController.php — Schema CRUD
|
||
DTO/
|
||
Request/ — CreateSchemaRequest, UpdateSchemaRequest, CreateTaskRequest,
|
||
UpdateTaskRequest, CreateCategoryRequest, UpdateCategoryRequest,
|
||
SchemaValidationTrait
|
||
Entity/
|
||
Category.php, Task.php, TaskSchema.php
|
||
Enum/
|
||
TaskStatus.php, TaskSchemaStatus.php, TaskSchemaType.php
|
||
Repository/
|
||
CategoryRepository.php, TaskRepository.php, TaskSchemaRepository.php
|
||
Service/
|
||
CategoryManager.php — Category CRUD-Logik
|
||
TaskManager.php — Task Create/Update/Delete/Toggle
|
||
TaskSchemaManager.php — Schema CRUD + Single-Flow + Sync-Auslösung
|
||
TaskGenerator.php — Erzeugt Task-Instanzen für Zeiträume (lazy)
|
||
TaskSynchronizer.php — Sync nach Schema-Update (löschen/erstellen/reset)
|
||
DeadlineCalculator.php — Berechnet Fälligkeitsdaten für Daily/Custom-Schemas
|
||
```
|
||
|
||
## API-Routen
|
||
|
||
### Tasks (`/api/tasks`)
|
||
```
|
||
GET / — Alle Tasks (triggert Task-Generierung)
|
||
GET /{id} — Task-Details
|
||
POST / — Task direkt erstellen (schema=null)
|
||
PUT /{id} — Task aktualisieren
|
||
DELETE /{id} — Task löschen
|
||
PATCH /{id}/toggle — Status Active↔Done umschalten
|
||
```
|
||
|
||
### Schemas (`/api/schemas`)
|
||
```
|
||
GET / — Alle Schemas
|
||
GET /{id} — Einzelnes Schema
|
||
POST / — Erstellen (Single: erstellt Tasks + löscht Schema)
|
||
PUT /{id} — Aktualisieren (synchronisiert zukünftige Tasks)
|
||
DELETE /{id} — Löschen (?deleteTasks=1 für Task-Löschung)
|
||
```
|
||
|
||
### Categories (`/api/categories`)
|
||
```
|
||
GET / — Alle Kategorien
|
||
GET /{id} — Einzelne Kategorie
|
||
POST / — Erstellen
|
||
PUT /{id} — Aktualisieren
|
||
DELETE /{id} — Löschen
|
||
```
|
||
|
||
## Verzeichnisstruktur (Frontend)
|
||
|
||
```
|
||
frontend/src/
|
||
views/
|
||
HomeView.vue — Startseite, Wochenansicht (client-seitig berechnet)
|
||
AllTasksView.vue — Übersicht aller Schemas/Tasks
|
||
SchemaView.vue — Schema erstellen/bearbeiten (3 Typen)
|
||
TaskDetailView.vue — Einzelne Aufgabe bearbeiten
|
||
CategoriesView.vue — Kategorien verwalten
|
||
components/
|
||
TaskCard.vue — Aufgaben-Karte (klickbar zum Toggle)
|
||
DayColumn.vue — Tages-Spalte in Wochenansicht
|
||
CategoryBadge.vue — Kategorie-Badge mit Farbe
|
||
Icon.vue — SVG-Icons (eyeOpen, eyeClosed, plus, arrowLeft, save, trash, edit, close)
|
||
WeekdayPicker.vue — Wochentag-Auswahl (Mo-So)
|
||
MonthdayPicker.vue — Monatstag-Auswahl (Kalender-Grid)
|
||
YearPicker.vue — Jahreskalender-Auswahl
|
||
router/index.js — Routen mit Breadcrumb-Meta
|
||
services/api.js — REST-Client (fetch-basiert)
|
||
stores/categories.js — Pinia Store für Kategorien
|
||
style.css — Globale Styles, CSS-Variablen, Light/Dark Mode
|
||
App.vue — Root-Layout mit Breadcrumb-Navigation
|
||
main.js — Vue-App-Init (Pinia + Router)
|
||
```
|
||
|
||
## Frontend-Routen
|
||
|
||
```
|
||
/ → HomeView (Wochenansicht)
|
||
/tasks/all → AllTasksView (Übersicht)
|
||
/tasks/new → SchemaView (Schema erstellen)
|
||
/tasks/:id → TaskDetailView (Aufgabe bearbeiten)
|
||
/schemas/:id → SchemaView (Schema bearbeiten)
|
||
/categories → CategoriesView
|
||
```
|
||
|
||
## Code-Konventionen
|
||
|
||
- **Sprache Code**: Englisch (Klassen, Methoden, Variablen, CSS-Klassen)
|
||
- **Sprache UI**: Deutsch (Labels, Fehlermeldungen, Platzhalter)
|
||
- **Enum-Werte**: Englisch in DB und Code (`active`, `done`, `single`, `daily`, `custom`, `disabled`)
|
||
- **API-Serialisierung**: Symfony Serializer-Groups auf Entities (`schema:read`, `task:read`, `category:read`)
|
||
- **Validierung**: Auf Request-DTOs, nicht auf Entities
|
||
- **Error-Handling**: `HttpException` → Symfony built-in
|
||
- **Frontend**: Vue 3 Composition API mit `<script setup>`, fetch-basierter API-Client
|
||
- **Wochenansicht**: Frontend berechnet Mo-So client-seitig aus allen Tasks
|
||
|
||
## Development
|
||
|
||
```bash
|
||
# DDEV starten
|
||
ddev start
|
||
|
||
# Backend
|
||
ddev exec "cd backend && php bin/console cache:clear"
|
||
ddev exec "cd backend && php bin/console doctrine:migrations:migrate --no-interaction"
|
||
|
||
# Frontend
|
||
ddev exec "cd frontend && npm install"
|
||
ddev exec "cd frontend && npm run dev -- --host 0.0.0.0"
|
||
|
||
# URLs
|
||
Frontend: https://haushalt.ddev.site:5173
|
||
API: https://haushalt.ddev.site/api
|
||
```
|