Skip to content

02 – Multi-Tenancy, Company & Settings

Reifegrad: 🟢 produktiv · Schicht: companies-Tabelle, src/app/settings/*, src/app/api/settings/*, @work7/storage

Zweck

Mandantentrennung (jeder Betrieb = eine company), Firmenstammdaten, Branding, Rechnungs-/ Steuer-Defaults und mandantenspezifische Integrations-/Storage-Einstellungen.

Tenancy-Modell

  • Wurzel ist companies mit dem fachlichen Schlüssel company_id (VARCHAR, UNIQUE) – nicht der numerischen id. Nahezu jede Tabelle referenziert company_id.
  • Nutzer ↔ Firma über users.company_id und memberships (role, status, department_id, manager_id; UNIQUE (user_id, company_id)).
  • Tenancy wird serverseitig erzwungen: requireSession liefert companyId, Domain-Guards (requireTenantScope) verhindern Cross-Tenant-Zugriffe.

Firmenstammdaten (companies)

Sehr breite Tabelle – die wichtigsten Feldgruppen:

GruppeFelder (Auswahl)
Identitätname, company_id, country_code (DE/AT…), legal_form, industry, founded_date
Adresse/Kontaktstreet, postal_code, city, state, phone, fax_number, email, website
Recht/Steuervat_number, tax_number, commercial_register, commercial_register_court, company_seat, jurisdiction
Bankiban, bic, bank_name
Brandingprimary_color, secondary_color, footer_text, logo (BYTEA), logo_mime
Rechnungs-Defaultsinvoice_number_format, quote_number_format, credit_number_format, payment_terms_default, default_vat_rate, default_tax_profile, cash_discount_percent/_days
E-Rechnungeinvoice_enabled, einvoice_format (XRechnung/…), reverse_charge_default
Bau-spezifischprogress_billing_mode, retention_enabled/_rate/_cap/_release, cost_code_schema, cost_center_required
Mahnwesendunning_enabled, dunning_levels (JSONB)
Aufbewahrungdata_retention_years, audit_log_retention_days

Settings-Oberfläche & APIs

UI: /settings (Stammdaten/Branding), /settings/integrations, /settings/leave.

EndpointFunktion
GET/PUT /api/settings/companyFirmenstammdaten lesen/ändern
POST /api/settings/company/logo · GET /api/company/logo/[companyId]Logo-Upload / Auslieferung
/api/settings/storage/*Mandanten-Storage (siehe unten + 13-integrationen-google-microsoft-storage)
/api/leave/types, /api/invoices/labor-ratesweitere mandantenweite Konfiguration

Mandanten-Storage (@work7/storage)

Pro Tenant konfigurierbarer Dokumentenspeicher; Default Azure Blob, optional OAuth-Provider.

  • Tabellen (Migration 034 tenant_storage): tenant_storage_settings (primary_provider ∈ {sharepoint, google_drive, dropbox, nextcloud, azure_blob}, status), tenant_storage_oauth_credentials (Tokens verschlüsselt, @work7/storage/crypto), document_storage_mappings (Dokument ↔ externe Datei).
  • Flow: POST /api/settings/storage/setupconnect/[provider]/start (PKCE-OAuth) → callbacktestconnections. Migration vorhandener Dateien: POST /api/settings/storage/migration/start.
  • Implementierung: service.ts, router.ts, providers/{azure,external,folder-bootstrap}.ts, graph-sharepoint.ts, oauth.ts, pkce.ts, crypto.ts, audit.ts, workspace.ts (Pfad-Helpers).
  • Bootstrap-Skript: scripts/bootstrap-tenant-storage.ts, scripts/check-storage-providers.ts.
  • Einheitliche Ordnerstruktur unter {company_id}/work7-app/ (Anfragen, Projekte, System) — Details und Zuordnungstabelle in 13-integrationen-google-microsoft-storage.

Geschäftsregeln

  • Auto-Nummerierung pro Mandant über Counter-Tabellen: customer_counters, invoice_counters (per Jahr), Trigger set_customer_number.
  • Branding (Logo/Farben/Footer) fließt in PDF-Templates ein (siehe 18-pdf-print-templates).
  • E-Rechnungs-/Steuer-Defaults steuern Rechnungs- und Export-Logik (siehe 10-rechnungen-e-rechnung).

Bekannte Befunde / offene Punkte

  • ⚠️ Doppelte Migrationsnummer 034: 034_customer_position.sql und 034_tenant_storage.sql existieren parallel. Funktioniert (idempotent), ist aber sauber zu deduplizieren/umzunummerieren.
  • logo als BYTEA in der DB (kein Blob-Storage) – pragmatisch, aber DB-lastig.
  • Storage-Provider außer Azure Blob sind als Beta einzustufen (OAuth-Pfad vorhanden, Reife je Provider unterschiedlich).

Verwandte Notes

Work7 · Software für Handwerksbetriebe