Files
leocrm/specs/current/requirements.md
T

5.9 KiB

leocrm — Requirements (v0.1, Mini-CRM, Single-Tenant)

1. Ziel

Ein schlankes, in sich geschlossenes Mini-CRM, das folgende Kern-Workflows abdeckt:

  • Anmeldung (Login/Logout) per Session-Cookie
  • Verwaltung von Firmen (Anlegen, Anzeigen, Bearbeiten, Löschen, Liste mit Suche)
  • Verwaltung von Kontaktpersonen (Anlegen, Anzeigen, Bearbeiten, Löschen, Zuordnung zu Firma)
  • Übersichts-Dashboard mit Anzahl Firmen, Kontakten und letzten Änderungen

Single-Tenant, eine Org, eine SQLite-Datei. Keine Rollen, keine Multi-User-Berechtigungen jenseits Login ja/nein.

2. Personas

  • Admin/Nutzer (1 Person pro Org): meldet sich an, verwaltet Daten.
  • Entwickler: betreibt die App lokal und in Coolify.

3. Funktionale Anforderungen (Must-Have)

ID Anforderung Akzeptanzkriterium
F-1 Login-Formular GET /login zeigt Formular; POST mit gültigen Credentials setzt Session-Cookie und leitet auf / weiter; ungültige Credentials → 401 + Fehlermeldung.
F-2 Logout POST /logout löscht Session und leitet auf /login weiter.
F-3 Auth-Schutz Alle Seiten außer /login und /api/health erfordern eine aktive Session; ohne Session → 302 → /login.
F-4 Dashboard GET / zeigt Anzahl Companies, Anzahl Contacts, letzte 5 Änderungen (Companies + Contacts).
F-5 Companies-Liste GET /companies zeigt Tabelle mit Name, Stadt, Land, Anzahl Contacts; Volltextsuche über Name/Stadt filtert.
F-6 Company anlegen GET /companies/new zeigt Formular; POST erstellt Datensatz, Redirect auf Detail.
F-7 Company-Detail GET /companies/{id} zeigt Stammdaten + Liste der zugeordneten Contacts + Link „Contact hinzufügen".
F-8 Company bearbeiten GET /companies/{id}/edit zeigt vorausgefülltes Formular; PATCH speichert, Redirect auf Detail.
F-9 Company löschen POST /companies/{id}/delete löscht inkl. zugeordneter Contacts (cascade).
F-10 Contact anlegen GET /contacts/new?company_id={id} zeigt Formular; POST erstellt Datensatz mit FK auf Company.
F-11 Contact-Detail GET /contacts/{id} zeigt alle Felder + Link zur Firma.
F-12 Contact bearbeiten GET /contacts/{id}/edit zeigt Formular; PATCH speichert.
F-13 Contact löschen POST /contacts/{id}/delete löscht. FK-Company bleibt erhalten.
F-14 API parallel zu HTML Für jede HTML-Aktion gibt es einen äquivalenten JSON-API-Endpoint (siehe API-Spec unten), damit Tests Headless durchlaufen können.
F-15 Health-Endpoint GET /api/health → 200 {"status":"ok","db":"ok"}.
F-16 Demo-Seed Beim ersten Start wird automatisch 1 Admin-User (admin/admin), 2 Beispiel-Firmen und 3 Beispiel-Kontakte angelegt, falls DB leer.

4. Datenmodell

User
  id            INTEGER PK
  username      TEXT UNIQUE NOT NULL
  password_hash TEXT NOT NULL
  created_at    TIMESTAMP DEFAULT now

Company
  id          INTEGER PK
  name        TEXT NOT NULL
  street      TEXT
  zip         TEXT
  city        TEXT
  country     TEXT DEFAULT 'DE'
  email       TEXT
  phone       TEXT
  website     TEXT
  notes       TEXT
  created_at  TIMESTAMP DEFAULT now
  updated_at  TIMESTAMP DEFAULT now

Contact
  id          INTEGER PK
  company_id  INTEGER FK -> Company.id ON DELETE CASCADE
  first_name  TEXT NOT NULL
  last_name   TEXT NOT NULL
  email       TEXT
  phone       TEXT
  position    TEXT
  notes       TEXT
  created_at  TIMESTAMP DEFAULT now
  updated_at  TIMESTAMP DEFAULT now

5. API-Spec (für Headless-Tests)

Methode Pfad Body / Params Erfolg Fehler
GET /api/health 200
POST /api/auth/login {username,password} 200 + Set-Cookie 401
POST /api/auth/logout 204
GET /api/companies ?q=&limit=&offset= 200 List
POST /api/companies JSON 201 400
GET /api/companies/{id} 200 404
PATCH /api/companies/{id} JSON 200 404, 400
DELETE /api/companies/{id} 204 404
GET /api/contacts ?company_id= 200
POST /api/contacts JSON 201 400, 404 (Company)
GET /api/contacts/{id} 200 404
PATCH /api/contacts/{id} JSON 200 404
DELETE /api/contacts/{id} 204 404

6. Nicht-Ziele (Out of Scope für v0.1)

  • Multi-Tenant / Multi-Org
  • Rollen-/Rechtesystem (jeder Login-User darf alles)
  • E-Mail-Versand, Datei-Upload, Bilder
  • Audit-Log, Soft-Delete, Papierkorb
  • 2FA, OAuth, Passwort-Reset per Mail
  • Internationalisierung (deutsche UI, hartkodiert)
  • Mobile-Apps, Push-Notifications
  • Reporting, Dashboards mit Charts (nur Counts)

7. Annahmen

  • Coolify-Host server.media-on.de ist erreichbar; Coolify-Token liegt in der Plugin-Config
  • Forgejo-Host forgejo.media-on.de ist erreichbar; Token liegt in der Plugin-Config
  • SQLite reicht für v0.1 (< 100k Datensätze), Migration auf Postgres später möglich
  • Deployment erfolgt als einzelner Coolify-Service (Docker Compose mit 1 Container)
  • Default-Admin-Credentials admin/admin werden beim ersten Start geseeded und sind nur in v0.1; im v0.2 verpflichtender Passwort-Change

8. Qualitätskriterien

  • Type-Check: python -m mypy app/ ohne Fehler (oder bewusst als nicht-blockend dokumentiert)
  • Tests: pytest mit mindestens 15 Tests, alle grün (Health, Auth happy + fail, Company CRUD 5, Contact CRUD 5, Cascade-Delete 1, Search 1)
  • Server-Start: uvicorn app.main:app startet ohne ImportError oder 500er
  • Health-Endpoint: 200, nicht 500
  • API-Endpoints: alle 13 oben genannten Endpunkte liefern die spezifizierten Status-Codes
  • Build: Docker-Image buildet ohne Fehler, Image-Größe < 300 MB
  • Deploy: Coolify-Service ist running:healthy nach POST /api/v1/deploy
  • Git: alle Änderungen committed, git status ist sauber