6.5 KiB
6.5 KiB
Enterprise Subscription
Beschreibung und Kontext
Enterprise-Kunden wollen mit Pauschalen arbeiten statt mit nutzungsbasierter Stripe-Abrechnung. Der Sysadmin (Platform Admin) erstellt ein individuelles Abo mit fixen Limiten (Users, Features, Storage, AI-Budget) und einem Pauschalpreis. Die Abrechnung erfolgt per E-Mail-Rechnung, nicht über Stripe. Alle Limiten sind hart — Überschreitung wird blockiert, nicht nachverrechnet.
Business-Treiber: Grosse Kunden verlangen Planbarkeit und interne Verrechnung statt Kreditkarten-Abrechnung.
Fokus und kritische Details
assertCapacitymuss bei Enterprise die Custom-Felder statt den Plan-Katalog lesencreditSubscriptionBudget,adjustAiBudgetForUserChange,reconcileMandateStorageBillingbrauchen Enterprise-Guards- AI-Budget Top-Up via Stripe bleibt für Enterprise-Mandanten weiterhin möglich (separater Flow)
syncQuantityToStripeist bereits sicher (Guard aufstripeSubscriptionId=None)SubscriptionCapacityException.userActiondarf bei Enterprise nichtUPGRADE_SUBSCRIPTIONsein
Ziel und Nicht-Ziele
- Ziel: Sysadmin kann Enterprise-Abo erstellen, erneuern, anpassen; fixe Limiten mit Hard-Block; Rechnung per E-Mail an Mandate Admins
- Ziel: Auto-Renewal via Cron-Job (eventManager) für Enterprise-Abos mit autoRenew=True
- Ziel: Mandate Admin sieht Enterprise-Abo readonly im Dashboard
- Explizit NICHT: PDF-Invoice-System, Frontend Enterprise-Formular (Phase 2)
- Explizit NICHT: Enterprise als Self-Service für Mandate Admin
Betroffene Module
- Gateway: datamodelSubscription, interfaceDbSubscription, interfaceDbBilling, interfaceDbApp, mainServiceSubscription, routeSubscription, routeBilling, enterpriseRenewalScheduler (neu), app.py
- Frontend: Subscription-Status-Anzeige (readonly für Enterprise), Sysadmin-Panel Enterprise-Badge
- DB-Migration: nein (neue Felder auf MandateSubscription, auto-schema)
- Andere Komponenten: E-Mail-Versand (notifyMandateAdmins, bestehende Logik)
Entscheidungen
| Datum | Entscheidung | Begründung |
|---|---|---|
| 2026-05-09 | Custom-Werte auf MandateSubscription statt eigene Plan-Tabelle | Einfacher, kein neues DB-Schema nötig, Plan-Katalog bleibt statisch |
| 2026-05-09 | Rechnung als strukturierte E-Mail, kein PDF | Vertrag wird extern geregelt, E-Mail reicht als Bestätigung |
| 2026-05-09 | Renew = altes Abo EXPIRED + neues ACTIVE (Duplikat) | Saubere Audit-History, Budget-Gutschrift wie bei Erstaktivierung |
| 2026-05-09 | Auto-Renewal via eventManager.registerCron (täglich 06:00 UTC) | Bestehende APScheduler-Infrastruktur nutzen, analog Audit-Log-Cleanup |
| 2026-05-09 | Rechnungs-E-Mail nur an Mandate Admins | Gleiche Logik wie bestehende Pläne, kein Sysadmin als Empfänger |
| 2026-05-09 | Storage-Overage bei Enterprise: Hard-Block statt Pool-Abzug | Konsistent mit dem Pauschalen-Konzept |
Umsetzungs-Checkliste
- Datenmodell:
ENTERPRISEinBUILTIN_PLANS+enterprise*-Felder aufMandateSubscription(isEnterprise,enterpriseFlatPriceCHF,enterpriseMaxUsers,enterpriseMaxFeatureInstances,enterpriseMaxDataVolumeMB,enterpriseBudgetAiCHF,enterpriseNote) - Helper:
getEffectiveLimits(sub, plan)indatamodelSubscription.py— liest beiisEnterprisedie Custom-Felder - Guard:
assertCapacity→ übergetEffectiveLimitsabgedeckt (Enterprise-Felder automatisch) - Guard:
creditSubscriptionBudget→ Enterprise-Budget-Gutschrift - Guard:
adjustAiBudgetForUserChange→ bei Enterprise übersprungen - Guard:
reconcileMandateStorageBilling→ bei Enterprise übersprungen - Guard:
getDataVolumeWarning→ Enterprise-Felder - Guard:
SubscriptionCapacityException→userAction=CONTACT_ADMINbei Enterprise - Service:
createEnterprise,renewEnterprise,updateEnterpriseinmainServiceSubscription.py - E-Mail:
_buildEnterpriseInvoiceHtml+_sendEnterpriseInvoiceEmailvianotifyMandateAdmins - Auto-Renewal:
enterpriseRenewalScheduler.pyviaeventManager.registerCron(täglich 06:00 UTC) - Routes:
POST enterprise/create,POST enterprise/renew,PUT enterprise/updateinrouteSubscription.py - Admin-View:
_buildEnrichedSubscriptions+_computeUsagefür Enterprise - RBAC / Permissions: alle 3 Endpoints
isPlatformAdmin-only - Neutralisierung betroffen? Nein
- Billing-Impact? Ja — neue Abrechnungsform
Akzeptanzkriterien
| # | Kriterium (Given-When-Then) | Prio |
|---|---|---|
| 1 | Given Sysadmin, When POST enterprise/create mit validen Parametern, Then Enterprise-Abo ACTIVE mit Custom-Limiten + AI-Budget gutgeschrieben + Rechnung per E-Mail an Mandate Admins + Sysadmin | must |
| 2 | Given Enterprise-Abo aktiv, When Mandate Admin User 21 hinzufügen will (Limit=20), Then Hard-Block mit Meldung "Enterprise-Limit erreicht, kontaktieren Sie den Administrator" | must |
| 3 | Given Enterprise-Abo aktiv, When User hinzugefügt wird (unter Limit), Then KEIN pro-rata AI-Budget-Adjustment | must |
| 4 | Given Enterprise-Abo aktiv, When Storage-Nutzung steigt über Limit, Then Hard-Block, KEIN Pool-Abzug | must |
| 5 | Given Enterprise-Abo aktiv, When Mandate Admin AI-Budget Top-Up via Stripe macht, Then funktioniert wie bei normalem Abo | must |
| 6 | Given Enterprise-Abo aktiv, When Sysadmin PUT enterprise/update mit neuen Limiten, Then Limiten sofort wirksam | must |
| 7 | Given Enterprise-Abo aktiv, When Sysadmin POST enterprise/renew, Then altes Abo EXPIRED + neues ACTIVE + Budget + Rechnung | must |
| 8 | Given Enterprise-Abo aktiv, When Mandate Admin GET /status, Then sieht Enterprise-Abo mit Limiten und Nutzung (readonly) | must |
| 9 | Given Enterprise-Abo aktiv, When Mandate Admin versucht Plan zu wechseln, Then nicht möglich (kein Self-Service) | must |
Testplan
| ID | AC | Art | Automatisiert | Repo-Pfad | Status |
|---|---|---|---|---|---|
| T1 | 1 | api | manuell | — | done |
| T2 | 2 | api | manuell | — | done |
| T3 | 3 | api | manuell | — | done |
| T4 | 4 | api | manuell | — | done |
| T5 | 5 | api | manuell | — | done |
| T6 | 6 | api | manuell | — | done |
| T7 | 7 | api | manuell | — | done |
| T8 | 8,9 | api | manuell | — | done |
Links
- Cursor Plan: enterprise_subscription_aca22e32.plan.md
Abschluss
- Dieses Dokument Status →
done(2026-05-15) - Eintrag in
c-work/_CHANGELOG.md