Files
kleiderboerse/projekt.md
T
StefanandClaude Opus 5 c8f11e0642 Bauen über Gitea Actions in die Roadmap aufnehmen
Fehlte in Phase 4: das Image soll wie bei der Kantone-App über einen
Versions-Tag gebaut, vor dem Veröffentlichen getestet und in die Gitea-
Registry gestellt werden.

Der Plan hält dazu die Punkte fest, die dort nachträglich korrigiert werden
mussten - vor allem, Werte aus ${{ ... }} nicht direkt in die Shell zu
schreiben, weil Tag-Namen Sonderzeichen enthalten dürfen und der Job ein
Registry-Token hält.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GR4bNaj9GtRu57J4Niii8o
2026-08-29 21:29:21 +02:00

5.5 KiB

📦 Kinderkleider-Börse (Web-App)

Eine schlanke, mobile-optimierte Web-App zum Katalogisieren, Präsentieren und Reservieren von zu klein gewordener Kinderkleidung für Familie, Freunde und Nachbarn.


🚀 Zielsetzungs & Kern-Features

  • Schnelles Erfassen (Mobile First): Foto direkt mit dem Smartphone aufnehmen, Grösse & Kategorie wählen, fertig.
  • Übersichtliche Galerie & Filter: Schnelle Filterung nach Konfektionsgrösse, Kategorie, Geschlecht und Saison.
  • Einfaches Reservierungssystem: Interessierte können Kleidungsstücke mit einem Klick reservieren.
  • Bildoptimierung: Automatische Skalierung und WebP-Komprimierung beim Upload, um Speicherplatz und Bandbreite zu sparen.

🛠 Technologiestack (Python-basiert)

  • Backend: Python 3.11+ mit FastAPI (hohe Performance, automatische OpenAPI/Swagger-Dokumentation)
  • Datenbank & ORM: SQLite mit SQLAlchemy & Alembic (Migrations)
  • Bildverarbeitung: Pillow (PIL) für WebP-Konvertierung und Resizing
  • Frontend (Optionen):
    • Variante A (Single File / Monolith): Jinja2 Templates + HTMX + Tailwind CSS (sehr schnell zu entwickeln, kein Node.js Build-Step nötig)
    • Variante B (Decoupled): Vue.js / React SPA (greift auf die REST-API zu)
  • Deployment: Docker & Docker Compose (leicht auf Unraid / Server auszuführen)

🗄 Datenbank-Schema

1. categories

Feld Typ Beschreibung
id INTEGER (PK) Eindeutige ID
name VARCHAR(50) Name (z. B. Hosen, Jacken, Schuhe, Pullover)
slug VARCHAR(50) URL-freundlicher Name

2. items (Haupttabelle)

Feld Typ Beschreibung
id INTEGER / UUID (PK) Eindeutige ID
title VARCHAR(100) Kurzer Titel (z. B. "Warme Winterjacke rot")
description TEXT Optionale Details oder Mängel
size VARCHAR(20) Konfektionsgrösse (z. B. 98/104, 24, 80)
gender VARCHAR(10) boy, girl, unisex
season VARCHAR(15) spring_summer, autumn_winter, all_year
condition VARCHAR(20) new, very_good, good, worn
status VARCHAR(20) available, reserved, given_away
category_id FK -> categories.id Zuordnung zur Kategorie
reserved_by VARCHAR(100) Name/Kontakt der Person, die es reserviert hat
created_at TIMESTAMP Erstellungsdatum
updated_at TIMESTAMP Letztes Update

3. item_images

Feld Typ Beschreibung
id INTEGER / UUID (PK) Eindeutige ID
item_id FK -> items.id Referenz zum Kleidungsstück
image_url VARCHAR(255) Pfad zur Bilddatei (z. B. /static/uploads/img_1234.webp)
is_primary BOOLEAN Hauptbild für Galerie-Vorschau

🔌 API-Endpunkte (FastAPI REST)

Kleidung verwalten & durchsuchen

  • GET /api/v1/items
    • Query-Params: ?size=98/104&category_id=2&status=available&gender=unisex
    • Response: Liste gefilterter Kleidungsstücke mit Primärbild.
  • GET /api/v1/items/{id}
    • Response: Einzelnes Kleidungsstück inklusive aller Bilder und Details.
  • POST /api/v1/items
    • Content-Type: multipart/form-data
    • Body: JSON-Daten + Bild-Uploads.
  • PATCH /api/v1/items/{id}
    • Body: Partial Update für Status, Titel, Beschreibung etc.
  • DELETE /api/v1/items/{id}
    • Description: Kleidungsstück und zugehörige Bilder löschen.

Reservierung & Status

  • POST /api/v1/items/{id}/reserve
    • Body: {"reserved_by": "Familie Meier"}
  • POST /api/v1/items/{id}/release
    • Setzt Status zurück auf available und löscht reserved_by.
  • POST /api/v1/items/{id}/mark-given
    • Setzt Status auf given_away.

Stammdaten

  • GET /api/v1/categories
  • GET /api/v1/sizes

📂 Empfohlene Projekt-Struktur

kinderkleider-app/
├── app/
├── database.py       # DB-Engine & Session Setup
├── models.py         # SQLAlchemy Modelle
├── schemas.py        # Pydantic Schemas (Request/Response validation)
├── crud.py           # Datenbank-Zugriffslogik
├── main.py           # FastAPI App Entrypoint & Routen
├── utils.py          # Bild-Komprimierung & Helper
│   ├── static/       # Uploaded Images & CSS
│   └── templates/    # Jinja2 Templates (falls HTML direkt gerendert wird)
├── Dockerfile
├── docker-compose.yml
├── requirements.txt
└── README.md

📋 Meilensteine / Roadmap

  • Phase 1: Backend Basic MVP
    • FastAPI Setup mit SQLite & SQLAlchemy
    • Datenmodelle & Migrationen anlegen
    • CRUD Endpunkte für items und categories testen (Swagger UI)
  • Phase 2: Bild-Handling & Speicher
    • multipart/form-data Upload via FastAPI
    • Pillow-Integration zur Konvertierung aller Uploads nach WebP (max. 1200px Breite)
  • Phase 3: Frontend Setup
    • Mobile-First Layout mit Tailwind CSS
    • Filterleiste für Grösse, Kategorie & Status
    • Reservierungs-Modal / Button
  • Phase 4: Containerisierung & Deployment
    • Dockerfile & docker-compose.yml schreiben
    • Persistence per Volume-Mount für Datenbank & Bild-Uploads
    • Gitea Actions: Image bei einem Versions-Tag (v*) bauen, testen und in die Registry stellen — gleiches Vorgehen wie bei der Kantone-App (.gitea/workflows/docker-image.yml dort als Vorlage)
    • Zweite Compose-Datei zum Starten des fertigen Images (ohne Quellcode)