2026-04-05 22:32:58 +02:00
|
|
|
|
# Projektstruktur & Modulreferenz
|
2026-04-05 21:53:57 +02:00
|
|
|
|
|
2026-04-05 22:32:58 +02:00
|
|
|
|
> **Token-Sparmaßnahme:** Dieses Dokument ist die erste Anlaufstelle.
|
|
|
|
|
|
> Vor dem Öffnen von Quellcode hier nachschlagen.
|
|
|
|
|
|
> Bei jeder Änderung an Funktionen, Modulen oder der Verzeichnisstruktur sofort aktualisieren.
|
2026-04-05 21:53:57 +02:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2026-04-05 22:32:58 +02:00
|
|
|
|
## Verzeichnisstruktur
|
2026-04-05 21:53:57 +02:00
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
gartenmanager/
|
feat: Phase 1 complete – full working application
Backend (FastAPI):
- REST API: auth, plants, beds, plantings
- CRUD layer with CRUDBase
- Pydantic v2 schemas for all entities
- Alembic migration: complete schema + all enums
- Seed data: 28 global plants + 15 compatibilities
Frontend (Vue 3 + PrimeVue):
- Axios client with JWT interceptor + auto-refresh
- Pinia stores: auth, beds, plants
- Views: Login, Beds, BedDetail, PlantLibrary
- Components: AppLayout, BedForm, PlantingForm, PlantForm
Docker:
- docker-compose.yml (production)
- docker-compose.dev.yml (development with hot-reload)
- Nginx config with SPA fallback + API proxy
- Multi-stage frontend Dockerfile
- .env.example, .gitignore
Version: 1.0.0-alpha
2026-04-06 07:45:00 +02:00
|
|
|
|
├── .claude/ # Claude-Tooling (kein Projektcode)
|
|
|
|
|
|
│ ├── scripts/bump.sh # Version bumpen + commit + push
|
|
|
|
|
|
│ ├── scripts/new-feature.sh # Feature-Branch erstellen
|
|
|
|
|
|
│ └── session-context.md # Sessionstart-Kontext
|
|
|
|
|
|
├── .gitea/PULL_REQUEST_TEMPLATE.md
|
|
|
|
|
|
├── backend/ # FastAPI Python Backend
|
|
|
|
|
|
│ ├── app/
|
|
|
|
|
|
│ │ ├── main.py # FastAPI App, CORS, Router-Include, /health
|
|
|
|
|
|
│ │ ├── core/
|
|
|
|
|
|
│ │ │ ├── config.py # pydantic-settings (DATABASE_URL, SECRET_KEY, ...)
|
|
|
|
|
|
│ │ │ ├── security.py # JWT erstellen/prüfen, Passwort-Hashing
|
|
|
|
|
|
│ │ │ └── deps.py # FastAPI-Dependencies: get_current_user, get_tenant_context, require_min_role()
|
|
|
|
|
|
│ │ ├── db/
|
|
|
|
|
|
│ │ │ ├── base.py # DeclarativeBase + alle Model-Imports für Alembic
|
|
|
|
|
|
│ │ │ └── session.py # async Engine, AsyncSessionLocal, get_session()
|
|
|
|
|
|
│ │ ├── models/ # SQLAlchemy ORM (alle UUID-PKs, async)
|
|
|
|
|
|
│ │ │ ├── user.py # User, UserTenant (+ TenantRole Enum)
|
|
|
|
|
|
│ │ │ ├── tenant.py # Tenant
|
|
|
|
|
|
│ │ │ ├── plant.py # PlantFamily, Plant, PlantCompatibility
|
|
|
|
|
|
│ │ │ ├── bed.py # Bed (+ LocationType, SoilType Enums)
|
|
|
|
|
|
│ │ │ └── planting.py # BedPlanting
|
|
|
|
|
|
│ │ ├── schemas/ # Pydantic v2 (Create/Update/Read)
|
|
|
|
|
|
│ │ │ ├── auth.py # LoginRequest, RefreshRequest, TokenResponse, AccessTokenResponse
|
|
|
|
|
|
│ │ │ ├── user.py # UserCreate, UserUpdate, UserRead
|
|
|
|
|
|
│ │ │ ├── tenant.py # TenantCreate, TenantUpdate, TenantRead
|
|
|
|
|
|
│ │ │ ├── plant.py # PlantCreate/Update/Read, PlantFamilyRead, PlantCompatibilityRead
|
|
|
|
|
|
│ │ │ ├── bed.py # BedCreate/Update/Read/DetailRead, PlantingInBed
|
|
|
|
|
|
│ │ │ └── planting.py # PlantingCreate/Update/Read
|
|
|
|
|
|
│ │ ├── crud/ # DB-Zugriff, keine Business-Logik
|
|
|
|
|
|
│ │ │ ├── base.py # CRUDBase[Model, Create, Update]: get, get_multi, create, update, remove
|
|
|
|
|
|
│ │ │ ├── user.py # get_by_email, authenticate, get_tenants
|
|
|
|
|
|
│ │ │ ├── plant.py # get_multi_for_tenant (global+tenant), create_for_tenant
|
|
|
|
|
|
│ │ │ ├── bed.py # get_multi_for_tenant, get_with_plantings, create_for_tenant
|
|
|
|
|
|
│ │ │ └── planting.py # get_multi_for_bed, create_for_bed
|
|
|
|
|
|
│ │ ├── api/v1/
|
|
|
|
|
|
│ │ │ ├── router.py # Alle Sub-Router unter /api/v1
|
|
|
|
|
|
│ │ │ ├── auth.py # POST /login, POST /refresh, GET /me
|
|
|
|
|
|
│ │ │ ├── plants.py # GET/POST/PUT/DELETE /plants, GET /plant-families
|
|
|
|
|
|
│ │ │ ├── beds.py # GET/POST/PUT/DELETE /beds
|
|
|
|
|
|
│ │ │ └── plantings.py # GET/POST /beds/{id}/plantings, PUT/DELETE /plantings/{id}
|
|
|
|
|
|
│ │ └── seeds/
|
|
|
|
|
|
│ │ └── initial_data.py # 28 globale Pflanzen + 15 Kompatibilitäten (idempotent)
|
|
|
|
|
|
│ ├── alembic/
|
|
|
|
|
|
│ │ ├── env.py # Async Alembic-Config, liest DATABASE_URL aus Settings
|
|
|
|
|
|
│ │ └── versions/001_initial.py # Vollständiges initiales Schema (alle Tabellen + Enums)
|
|
|
|
|
|
│ ├── requirements.txt
|
|
|
|
|
|
│ └── Dockerfile # python:3.11-slim, uvicorn
|
|
|
|
|
|
├── frontend/ # Vue 3 SPA
|
|
|
|
|
|
│ ├── src/
|
|
|
|
|
|
│ │ ├── main.js # App-Bootstrap: PrimeVue, Pinia, Router
|
|
|
|
|
|
│ │ ├── App.vue # Root: AppLayout (eingeloggt) / router-view (Login)
|
|
|
|
|
|
│ │ ├── api/
|
|
|
|
|
|
│ │ │ ├── client.js # Axios-Instanz, JWT-Interceptor, Auto-Refresh bei 401
|
|
|
|
|
|
│ │ │ └── index.js # authApi, plantsApi, bedsApi, plantingsApi
|
|
|
|
|
|
│ │ ├── stores/
|
|
|
|
|
|
│ │ │ ├── auth.js # user, tenants, activeTenantId, login(), logout(), setActiveTenant()
|
|
|
|
|
|
│ │ │ ├── beds.js # beds, currentBed, fetchBeds/Bed, createBed/Planting, deleteBed/Planting
|
|
|
|
|
|
│ │ │ └── plants.js # plants, families, fetchPlants/Families, create/update/deletePlant
|
|
|
|
|
|
│ │ ├── router/index.js # /login, /beete, /beete/:id, /pflanzen – auth guard
|
|
|
|
|
|
│ │ ├── views/
|
|
|
|
|
|
│ │ │ ├── LoginView.vue # Email+Passwort Formular
|
|
|
|
|
|
│ │ │ ├── BedsView.vue # DataTable aller Beete, Create/Edit-Dialog
|
|
|
|
|
|
│ │ │ ├── BedDetailView.vue # Beet-Infos + Bepflanzungs-Tabelle + Add-Dialog
|
|
|
|
|
|
│ │ │ └── PlantsView.vue # Pflanzenbibliothek DataTable, Filter, eigene Pflanze anlegen
|
|
|
|
|
|
│ │ └── components/
|
|
|
|
|
|
│ │ ├── AppLayout.vue # Navbar (Logo, Nav-Links, Tenant-Selector, Logout)
|
|
|
|
|
|
│ │ ├── BedForm.vue # Formular für Beet anlegen/bearbeiten
|
|
|
|
|
|
│ │ ├── PlantingForm.vue # Formular für Bepflanzung hinzufügen
|
|
|
|
|
|
│ │ └── PlantForm.vue # Formular für eigene Pflanze anlegen
|
|
|
|
|
|
│ ├── nginx.conf # SPA fallback + API-Proxy → backend:8000
|
|
|
|
|
|
│ ├── Dockerfile # Multi-stage: node:20 build → nginx:alpine
|
|
|
|
|
|
│ └── package.json
|
|
|
|
|
|
├── docker-compose.yml # Produktion: db + backend + frontend
|
|
|
|
|
|
├── docker-compose.dev.yml # Entwicklung: db + backend (reload) + Frontend lokal via npm run dev
|
|
|
|
|
|
├── .env.example # Vorlage für .env
|
|
|
|
|
|
├── .gitignore
|
2026-04-05 22:32:58 +02:00
|
|
|
|
├── CHANGELOG.md
|
|
|
|
|
|
├── CLAUDE.md
|
|
|
|
|
|
├── README.md
|
|
|
|
|
|
└── VERSION
|
2026-04-05 21:53:57 +02:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
feat: Phase 1 complete – full working application
Backend (FastAPI):
- REST API: auth, plants, beds, plantings
- CRUD layer with CRUDBase
- Pydantic v2 schemas for all entities
- Alembic migration: complete schema + all enums
- Seed data: 28 global plants + 15 compatibilities
Frontend (Vue 3 + PrimeVue):
- Axios client with JWT interceptor + auto-refresh
- Pinia stores: auth, beds, plants
- Views: Login, Beds, BedDetail, PlantLibrary
- Components: AppLayout, BedForm, PlantingForm, PlantForm
Docker:
- docker-compose.yml (production)
- docker-compose.dev.yml (development with hot-reload)
- Nginx config with SPA fallback + API proxy
- Multi-stage frontend Dockerfile
- .env.example, .gitignore
Version: 1.0.0-alpha
2026-04-06 07:45:00 +02:00
|
|
|
|
## Berechtigungslogik
|
2026-04-05 21:53:57 +02:00
|
|
|
|
|
feat: Phase 1 complete – full working application
Backend (FastAPI):
- REST API: auth, plants, beds, plantings
- CRUD layer with CRUDBase
- Pydantic v2 schemas for all entities
- Alembic migration: complete schema + all enums
- Seed data: 28 global plants + 15 compatibilities
Frontend (Vue 3 + PrimeVue):
- Axios client with JWT interceptor + auto-refresh
- Pinia stores: auth, beds, plants
- Views: Login, Beds, BedDetail, PlantLibrary
- Components: AppLayout, BedForm, PlantingForm, PlantForm
Docker:
- docker-compose.yml (production)
- docker-compose.dev.yml (development with hot-reload)
- Nginx config with SPA fallback + API proxy
- Multi-stage frontend Dockerfile
- .env.example, .gitignore
Version: 1.0.0-alpha
2026-04-06 07:45:00 +02:00
|
|
|
|
```
|
|
|
|
|
|
is_superadmin=True → alles erlaubt, Tenant-Prüfung wird übersprungen
|
|
|
|
|
|
TENANT_ADMIN → alles im eigenen Tenant (inkl. Beet löschen)
|
|
|
|
|
|
READ_WRITE → lesen + schreiben, kein Beet löschen
|
|
|
|
|
|
READ_ONLY → nur GET-Endpoints
|
|
|
|
|
|
```
|
2026-04-05 21:53:57 +02:00
|
|
|
|
|
feat: Phase 1 complete – full working application
Backend (FastAPI):
- REST API: auth, plants, beds, plantings
- CRUD layer with CRUDBase
- Pydantic v2 schemas for all entities
- Alembic migration: complete schema + all enums
- Seed data: 28 global plants + 15 compatibilities
Frontend (Vue 3 + PrimeVue):
- Axios client with JWT interceptor + auto-refresh
- Pinia stores: auth, beds, plants
- Views: Login, Beds, BedDetail, PlantLibrary
- Components: AppLayout, BedForm, PlantingForm, PlantForm
Docker:
- docker-compose.yml (production)
- docker-compose.dev.yml (development with hot-reload)
- Nginx config with SPA fallback + API proxy
- Multi-stage frontend Dockerfile
- .env.example, .gitignore
Version: 1.0.0-alpha
2026-04-06 07:45:00 +02:00
|
|
|
|
`require_min_role(TenantRole.READ_WRITE)` in `deps.py` gibt `(user, tenant_id, role)` zurück.
|
2026-04-05 21:53:57 +02:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
feat: Phase 1 complete – full working application
Backend (FastAPI):
- REST API: auth, plants, beds, plantings
- CRUD layer with CRUDBase
- Pydantic v2 schemas for all entities
- Alembic migration: complete schema + all enums
- Seed data: 28 global plants + 15 compatibilities
Frontend (Vue 3 + PrimeVue):
- Axios client with JWT interceptor + auto-refresh
- Pinia stores: auth, beds, plants
- Views: Login, Beds, BedDetail, PlantLibrary
- Components: AppLayout, BedForm, PlantingForm, PlantForm
Docker:
- docker-compose.yml (production)
- docker-compose.dev.yml (development with hot-reload)
- Nginx config with SPA fallback + API proxy
- Multi-stage frontend Dockerfile
- .env.example, .gitignore
Version: 1.0.0-alpha
2026-04-06 07:45:00 +02:00
|
|
|
|
## Datenbankschema (Kurzform)
|
2026-04-05 22:32:58 +02:00
|
|
|
|
|
feat: Phase 1 complete – full working application
Backend (FastAPI):
- REST API: auth, plants, beds, plantings
- CRUD layer with CRUDBase
- Pydantic v2 schemas for all entities
- Alembic migration: complete schema + all enums
- Seed data: 28 global plants + 15 compatibilities
Frontend (Vue 3 + PrimeVue):
- Axios client with JWT interceptor + auto-refresh
- Pinia stores: auth, beds, plants
- Views: Login, Beds, BedDetail, PlantLibrary
- Components: AppLayout, BedForm, PlantingForm, PlantForm
Docker:
- docker-compose.yml (production)
- docker-compose.dev.yml (development with hot-reload)
- Nginx config with SPA fallback + API proxy
- Multi-stage frontend Dockerfile
- .env.example, .gitignore
Version: 1.0.0-alpha
2026-04-06 07:45:00 +02:00
|
|
|
|
```
|
|
|
|
|
|
users → id, email, hashed_password, is_superadmin
|
|
|
|
|
|
tenants → id, name, slug
|
|
|
|
|
|
user_tenants → user_id, tenant_id, role
|
|
|
|
|
|
plant_families → id, name, latin_name
|
|
|
|
|
|
plants → id, tenant_id(nullable=global), family_id, nutrient_demand, water_demand, rest_years, ...
|
|
|
|
|
|
plant_compat. → plant_id_a, plant_id_b, rating, reason
|
|
|
|
|
|
beds → id, tenant_id, width_m, length_m, location, soil_type
|
|
|
|
|
|
bed_plantings → id, bed_id, plant_id, area_m2, count, planted_date, removed_date
|
|
|
|
|
|
```
|
2026-04-05 22:32:58 +02:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
feat: Phase 1 complete – full working application
Backend (FastAPI):
- REST API: auth, plants, beds, plantings
- CRUD layer with CRUDBase
- Pydantic v2 schemas for all entities
- Alembic migration: complete schema + all enums
- Seed data: 28 global plants + 15 compatibilities
Frontend (Vue 3 + PrimeVue):
- Axios client with JWT interceptor + auto-refresh
- Pinia stores: auth, beds, plants
- Views: Login, Beds, BedDetail, PlantLibrary
- Components: AppLayout, BedForm, PlantingForm, PlantForm
Docker:
- docker-compose.yml (production)
- docker-compose.dev.yml (development with hot-reload)
- Nginx config with SPA fallback + API proxy
- Multi-stage frontend Dockerfile
- .env.example, .gitignore
Version: 1.0.0-alpha
2026-04-06 07:45:00 +02:00
|
|
|
|
## API-Routen Übersicht
|
2026-04-05 21:53:57 +02:00
|
|
|
|
|
feat: Phase 1 complete – full working application
Backend (FastAPI):
- REST API: auth, plants, beds, plantings
- CRUD layer with CRUDBase
- Pydantic v2 schemas for all entities
- Alembic migration: complete schema + all enums
- Seed data: 28 global plants + 15 compatibilities
Frontend (Vue 3 + PrimeVue):
- Axios client with JWT interceptor + auto-refresh
- Pinia stores: auth, beds, plants
- Views: Login, Beds, BedDetail, PlantLibrary
- Components: AppLayout, BedForm, PlantingForm, PlantForm
Docker:
- docker-compose.yml (production)
- docker-compose.dev.yml (development with hot-reload)
- Nginx config with SPA fallback + API proxy
- Multi-stage frontend Dockerfile
- .env.example, .gitignore
Version: 1.0.0-alpha
2026-04-06 07:45:00 +02:00
|
|
|
|
```
|
|
|
|
|
|
POST /api/v1/auth/login
|
|
|
|
|
|
POST /api/v1/auth/refresh
|
|
|
|
|
|
GET /api/v1/auth/me
|
|
|
|
|
|
GET /api/v1/plant-families
|
|
|
|
|
|
GET /api/v1/plants
|
|
|
|
|
|
GET /api/v1/plants/{id}
|
|
|
|
|
|
POST /api/v1/plants (READ_WRITE+)
|
|
|
|
|
|
PUT /api/v1/plants/{id} (READ_WRITE+, global nur Superadmin)
|
|
|
|
|
|
DELETE /api/v1/plants/{id} (READ_WRITE+, global nur Superadmin)
|
|
|
|
|
|
GET /api/v1/beds
|
|
|
|
|
|
GET /api/v1/beds/{id} (mit Bepflanzungen)
|
|
|
|
|
|
POST /api/v1/beds (READ_WRITE+)
|
|
|
|
|
|
PUT /api/v1/beds/{id} (READ_WRITE+)
|
|
|
|
|
|
DELETE /api/v1/beds/{id} (TENANT_ADMIN+)
|
|
|
|
|
|
GET /api/v1/beds/{id}/plantings
|
|
|
|
|
|
POST /api/v1/beds/{id}/plantings (READ_WRITE+)
|
|
|
|
|
|
PUT /api/v1/plantings/{id} (READ_WRITE+)
|
|
|
|
|
|
DELETE /api/v1/plantings/{id} (READ_WRITE+)
|
|
|
|
|
|
GET /health
|
|
|
|
|
|
```
|