Zum Inhalt

UC-Kunden – Vorentscheide (vor Spezifikation)

Status: Vorentscheide gesammelt — fliessen in UC-Kunden-Spezifikation ein
Stand: April 2026 | Version: 0.2 (Schema-Vorbereitung V1 ergänzt)
Autor: David


V1 – Datenmodell-Entscheide

KE1: Kunde = Person (Szenario A)

  • In V1 ist ein Kunde immer eine einzelne natürliche Person
  • Keine Organisationsstruktur in V1
  • Passt zum primären Anwendungsfall: Eigentümer von Tauchgeräten (Flaschen, Regler)

KE2: V2-Vorbereitung — Kunde optional einer Organisation zuordnen (Szenario C)

  • Das customers-Schema in V1 enthält bereits ein nullable organization_id-Feld (FK → organizations)
  • In V1 bleibt dieses Feld immer NULL — kein UI, keine Logik
  • In V2 wird die organizations-Tabelle hinzugefügt und das Feld befüllt
  • Kein Breaking Change, keine Migration bestehender Daten erforderlich

KE3: Aufträge gehören immer zur Person

  • orders.customer_id zeigt immer auf die Person (nie direkt auf eine Organisation)
  • Bestehende Aufträge bleiben bei Zuordnung einer Person zu einer Organisation unverändert
  • Die Organisation ist technisch nur ein Gruppierungsmerkmal

KE4: Rechnungsstellung flexibel auf Auftragsebene (V2)

  • Neues Feld orders.bill_to mit Werten customer | organization
  • Standard bei neuem Auftrag: customer (Rechnungsstellung an Person)
  • Wenn Person einer Organisation zugeordnet ist: wählbar → Person oder Organisation
  • Anwendungsfall: Firmenmitarbeiter lässt Flasche prüfen, Rechnung geht an Firma

Offene Fragen für UC-Kunden-Spezifikation

ID Frage Priorität
KOF1 Welche Pflichtfelder hat ein Kunde in V1? (Name, E-Mail, Telefon, Adresse?) Hoch
KOF2 Kann ein Kunde mehrere Geräte besitzen? (1:n Kunde → Ausrüstung) Hoch
KOF3 Wie wird ein Kunde mit einem Auftrag verknüpft? Hoch
KOF4 Gibt es eine Kundennummer / externe Referenz? Mittel
KOF5 Mitarbeiter-Einladungsmodell: Mitarbeiter werden via Einladungslink hinzugefügt (analog UC00 Modell C1) — in UC-Mitarbeiter definieren Mittel

Hinweis Mitarbeiter-Einladungsmodell

Entscheid aus UC00-Diskussion (April 2026):
Mitarbeiter werden via Einladungslink hinzugefügt — analog UC00 Modell C1.
Sie registrieren sich selbst, setzen ihr Passwort und richten 2FA ein.
Danach sind sie aktive Systembenutzer mit Login.
→ Details in UC-Mitarbeiter-Spezifikation festhalten.


Schema-Vorbereitung V1

Das organization_id-Feld muss beim Anlegen der customers-Tabelle
(Schritt 3 – Datenmodell UC-Kunden) von Anfang an enthalten sein.
Die organizations-Tabelle selbst wird erst in V2 erstellt.

SQL-Snippet (verbindliche Vorgabe für schema-final.sql)

-- ── CUSTOMERS ──────────────────────────────────────────────────────────────
-- V1: Kunde = Person. organization_id ist nullable (V2-Vorbereitung).
-- Die organizations-Tabelle existiert in V1 noch nicht — der FK-Constraint
-- wird daher erst in V2 aktiviert. In V1 bleibt das Feld immer NULL.

CREATE TABLE customers (
  id               UUID        PRIMARY KEY DEFAULT gen_random_uuid(),
  tenant_id        UUID        NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
  name             TEXT        NOT NULL,
  email            TEXT,
  phone_landline   TEXT,
  phone_mobile     TEXT,
  address_street   TEXT,
  address_zip      TEXT,
  address_city     TEXT,
  address_country  CHAR(2),                          -- ISO 3166-1 alpha-2
  organization_id  UUID,                             -- nullable, V2: FK → organizations(id)
  notes            TEXT,
  is_active        BOOLEAN     NOT NULL DEFAULT TRUE,
  created_at       TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  updated_at       TIMESTAMPTZ NOT NULL DEFAULT NOW(),

  CONSTRAINT chk_customers_phone
    CHECK (phone_landline IS NOT NULL OR phone_mobile IS NOT NULL)
    -- mind. eine Telefonnummer Pflicht (analog Schulprofil)
    -- → in V1 als NOT ENFORCED vorbereiten, Pflicht via App-Logik
);

-- Index für Tenant-Isolation (RLS-Unterstützung)
CREATE INDEX idx_customers_tenant_id ON customers(tenant_id);

-- Index für spätere Organization-Zuordnung (V2)
CREATE INDEX idx_customers_organization_id ON customers(organization_id);

Prisma-Schema-Snippet (verbindliche Vorgabe)

model Customer {
  id              String    @id @default(uuid()) @db.Uuid
  tenantId        String    @map("tenant_id") @db.Uuid
  name            String
  email           String?
  phoneLandline   String?   @map("phone_landline")
  phoneMobile     String?   @map("phone_mobile")
  addressStreet   String?   @map("address_street")
  addressZip      String?   @map("address_zip")
  addressCity     String?   @map("address_city")
  addressCountry  String?   @map("address_country") @db.Char(2)
  organizationId  String?   @map("organization_id") @db.Uuid  // V2-Vorbereitung
  notes           String?
  isActive        Boolean   @default(true) @map("is_active")
  createdAt       DateTime  @default(now()) @map("created_at")
  updatedAt       DateTime  @updatedAt @map("updated_at")

  tenant          Tenant    @relation(fields: [tenantId], references: [id])
  // organization  Organization? @relation(...)  // V2: einkommentieren

  @@index([tenantId])
  @@index([organizationId])
  @@map("customers")
}

Was in V2 hinzukommt (zur Erinnerung)

-- V2: organizations-Tabelle anlegen
CREATE TABLE organizations (
  id          UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  tenant_id   UUID NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
  name        TEXT NOT NULL,
  ...
);

-- V2: FK-Constraint nachträglich aktivieren
ALTER TABLE customers
  ADD CONSTRAINT fk_customers_organization
  FOREIGN KEY (organization_id) REFERENCES organizations(id);