📦 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"}
- Response: enthält das
reservation_token – daraus wird der Link zum
Aufheben gebildet.
POST /api/v1/items/{id}/release
- Setzt Status zurück auf
available und löscht reserved_by.
- Erlaubt für: den Reservierenden (mit gültigem
token) oder den
angemeldeten Betreiber. Ohne beides: 403. Sonst könnte jeder Besucher
fremde Reservierungen löschen.
POST /api/v1/items/{id}/mark-given
- Setzt Status auf
given_away.
Stammdaten
GET /api/v1/categories
GET /api/v1/sizes
📂 Empfohlene Projekt-Struktur
📋 Meilensteine / Roadmap