From 11f768b8e5ea5ce5f9a03442af20caf075c6507f Mon Sep 17 00:00:00 2001 From: Till JS Date: Mon, 20 Apr 2026 15:27:57 +0200 Subject: [PATCH] docs(invoices): ClubDesk vs. Mana comparison + invoices module plan Competitive analysis of ClubDesk (reeweb ag, ~20'000 DACH clubs) with a dual-use roadmap identifying features that benefit both clubs and general users (freelancers/creators). First chosen step: invoices module with Swiss QR-Bill as the CH-differentiator. Co-Authored-By: Claude Opus 4.7 (1M context) --- docs/plans/invoices-module.md | 374 ++++++++++++++++++++ docs/reports/clubdesk-vs-mana-comparison.md | 301 ++++++++++++++++ 2 files changed, 675 insertions(+) create mode 100644 docs/plans/invoices-module.md create mode 100644 docs/reports/clubdesk-vs-mana-comparison.md diff --git a/docs/plans/invoices-module.md b/docs/plans/invoices-module.md new file mode 100644 index 000000000..7fe8efbff --- /dev/null +++ b/docs/plans/invoices-module.md @@ -0,0 +1,374 @@ +# Invoices — Module Plan + +## Status (2026-04-20) + +**M0 Planning** — dieser Plan. Noch kein Code. + +Nächster Schritt: M1 Skelett (Modul registriert, Dexie-Table, Guest-Seed, leere ListView). + +--- + +## Ziel + +Ein Modul, mit dem der Nutzer **Rechnungen an Kunden stellt**: Rechnung anlegen → PDF generieren (inkl. **Schweizer QR-Rechnung**) → per Mail versenden → Zahlungs-Status nachhalten. Kernfrage: *"Hat der Kunde bezahlt — und wenn nein, wann muss ich mahnen?"* + +Solo-Zielgruppe: Freelancer/Selbstständige in CH (+DE). Später trivial auf Vereine erweiterbar (Empfänger = Mitgliedergruppe → Serienrechnungslauf für Mitgliederbeiträge). + +## Abgrenzung + +- **Kein Ersatz für `finance`** — das bleibt das private Einnahmen/Ausgaben-Tracker. `invoices` ist die **Outbound**-Seite: Rechnungen *stellen* statt Transaktionen *erfassen*. Ein bezahlter Rechnungseingang kann später automatisch eine `finance`-Einnahme erzeugen (Cross-Modul-Hook, Phase 3). +- **Keine vollständige Buchhaltung** — keine Kontenrahmen (SKR03/SKR42), keine doppelte Buchführung, keine MwSt-Voranmeldung. Das ist ClubDesk-Niveau Paket B-2 und explizit *nicht* MVP. +- **Kein Bankabgleich (camt.053)** — Phase 2/3, separater Plan. +- **Kein Payment-Provider** — keine Stripe/PayPal-Zahlungslinks im MVP. Zahlungseingang wird manuell markiert oder (später) per camt abgeglichen. +- **Kein CRM** — Kundendaten kommen aus dem bestehenden `contacts`-Modul, nicht aus einer eigenen Kunden-Tabelle. + +## Entscheidung: eigenes Modul, nicht Finance-Erweiterung + +Zwei Optionen wurden erwogen: + +1. **In `finance` integrieren** — Rechnung wäre ein Transaktions-Typ. +2. **Eigenes Modul `invoices`** (gewählt). + +Begründung für (2): +- Rechnungen haben komplexeres Schema (Positionen, PDF-Assets, QR-Zahldaten, Status-Maschine Entwurf/Versendet/Bezahlt/Überfällig) — das verunreinigt das schlanke Finance-Schema. +- Unterschiedliche Zielgruppe: `finance` ist Alltags-Tracking (jeder), `invoices` ist Selbstständigen-Workflow (Teilmenge). +- Separater Launcher-Eintrag, eigene Route, eigene AI-Tools. +- Finance bleibt encryption-minimal, invoices hat mehr sensitive Felder. + +Cross-Link: Bezahlte Rechnung → optional auto-erzeugte `finance`-Einnahme (Phase 3). + +## Modul-Struktur + +``` +apps/mana/apps/web/src/lib/modules/invoices/ +├── types.ts # LocalInvoice, Invoice, InvoiceLine, InvoiceStatus, Client +├── collections.ts # invoices + invoiceClients tables + guest-seed +├── queries.ts # useAllInvoices, useInvoicesByStatus, useInvoice(id), useStats, useOverdue +├── stores/ +│ ├── invoices.svelte.ts # create, update, markSent, markPaid, markOverdue, void, duplicate, delete +│ ├── clients.svelte.ts # createClient, updateClient, deleteClient (optional — kann auch in contacts) +│ └── settings.svelte.ts # Absender-Profil, Logo, Fußzeile, IBAN, MwSt-Nummer, Nummernkreis +├── components/ +│ ├── InvoiceCard.svelte # Listeneintrag: Nummer + Kunde + Betrag + Status-Badge + Fälligkeit +│ ├── InvoiceForm.svelte # Create/Edit inkl. Positionen-Editor +│ ├── LinesEditor.svelte # Positionen: Titel, Menge, Einheit, Einzelpreis, MwSt-Satz +│ ├── StatusBadge.svelte # draft / sent / paid / overdue / void +│ ├── StatusFilter.svelte # Filter-Chips +│ ├── ClientPicker.svelte # Auswahl aus contacts ODER invoiceClients +│ ├── SenderProfileForm.svelte # einmalige Einrichtung (Name, IBAN, MwSt, Logo) +│ └── InvoicePreview.svelte # Live-Preview des PDFs (iframe oder react-pdf react-free Variante) +├── pdf/ +│ ├── renderer.ts # erzeugt Blob via pdf-lib (Header, Tabelle, Footer, QR-Slip) +│ ├── qr-bill.ts # swissqrbill-Integration (SPC-kompatibel, CHF/EUR) +│ └── templates/ +│ └── default.ts # Layout-Konstanten (Margins, Fonts, Farben) +├── views/ +│ ├── ListView.svelte # komponiert Filter + Grid/Liste +│ ├── DetailView.svelte # Rechnungsdetail + PDF-Preview + Aktionen +│ └── SettingsView.svelte # Absender-Profil + Nummernkreis-Editor +├── tools.ts # AI-Tools — siehe §AI-Integration +├── constants.ts # STATUS_LABELS, VAT_RATES_CH, VAT_RATES_DE, DEFAULT_DUE_DAYS +├── module.config.ts # { appId: 'invoices', tables: [{ name: 'invoices' }, { name: 'invoiceClients' }, { name: 'invoiceSettings' }] } +└── index.ts # Re-Exports +``` + +## Daten-Schema + +### `LocalInvoice` (Dexie) + +```typescript +export type InvoiceStatus = 'draft' | 'sent' | 'paid' | 'overdue' | 'void'; +export type Currency = 'CHF' | 'EUR' | 'USD'; + +export interface LocalInvoiceLine { + id: string; // client-generated, stabil für Drag-Reorder + title: string; // encrypted + description?: string | null; // encrypted + quantity: number; // plaintext + unit?: string | null; // plaintext — "Std", "Stk", "Tag" + unitPrice: number; // plaintext — in kleinster Währungseinheit (Rappen/Cent), Integer + vatRate: number; // plaintext — 0, 2.6, 3.8, 8.1 (CH) oder 0, 7, 19 (DE) + discount?: number | null; // plaintext — Prozent (0..100) +} + +export interface LocalInvoice extends BaseRecord { + number: string; // plaintext — "2026-0042", aus Nummernkreis generiert + status: InvoiceStatus; // plaintext — filterbar + clientId: string | null; // plaintext — FK entweder contacts.id ODER invoiceClients.id + clientSource: 'contact' | 'invoice-client'; // plaintext — welche Tabelle + clientSnapshot: { // encrypted — Kunden-Daten zum Zeitpunkt des Versands eingefroren + name: string; + address?: string; + email?: string; + vatNumber?: string; + }; + currency: Currency; // plaintext + issueDate: string; // plaintext — YYYY-MM-DD + dueDate: string; // plaintext — YYYY-MM-DD + sentAt?: string | null; // plaintext — ISO timestamp + paidAt?: string | null; // plaintext — ISO timestamp + lines: LocalInvoiceLine[]; // teils encrypted (Titel/Description), teils plaintext (Zahlen) + subject?: string | null; // encrypted — "Beratungsleistung April 2026" + notes?: string | null; // encrypted — Freitext unterhalb der Positionen + terms?: string | null; // encrypted — AGB/Zahlungsbedingungen + referenceNumber?: string | null; // plaintext — QR-Referenz (CH) oder Kundenreferenz + pdfBlobKey?: string | null; // plaintext — uload/media-ID des gerenderten PDFs (Cache) + // Berechnete Totals — denormalisiert, bei jedem update neu + totals: { + net: number; // plaintext + vat: number; // plaintext + gross: number; // plaintext + vatBreakdown: Array<{ rate: number; base: number; tax: number }>; + }; +} +``` + +### `LocalInvoiceClient` (Dexie) — *optional, Phase 1.5* + +Separate Tabelle für Rechnungs-spezifische Kundendaten, falls `contacts` nicht reicht. Gleiche Felder wie `clientSnapshot`, aber zentral editierbar. MVP startet ohne — bestehende `contacts` reichen für solo-User. + +```typescript +export interface LocalInvoiceClient extends BaseRecord { + name: string; // encrypted + address?: string | null; // encrypted + email?: string | null; // encrypted + vatNumber?: string | null; // encrypted + iban?: string | null; // encrypted — für spätere SEPA-Lastschrift + defaultCurrency: Currency; // plaintext + defaultDueDays: number; // plaintext — 14, 30, 60 + notes?: string | null; // encrypted +} +``` + +### `LocalInvoiceSettings` (Dexie, Singleton pro User) + +```typescript +export interface LocalInvoiceSettings extends BaseRecord { + // Absender + senderName: string; // encrypted + senderAddress: string; // encrypted + senderEmail: string; // encrypted + senderVatNumber?: string | null; // encrypted — "CHE-123.456.789 MWST" + senderIban: string; // encrypted — CH-IBAN für QR-Rechnung + senderBic?: string | null; // encrypted — für SEPA + + // Branding + logoMediaId?: string | null; // plaintext — uload-ID + accentColor: string; // plaintext — Hex + footer?: string | null; // encrypted — Fußzeile unter jedem PDF + + // Nummernkreis + numberPrefix: string; // plaintext — "2026-" + numberPadding: number; // plaintext — 4 → "0042" + nextNumber: number; // plaintext — Zähler, wird atomisch inkrementiert + + // Defaults + defaultCurrency: Currency; + defaultVatRate: number; // plaintext — 8.1 (CH) oder 19 (DE) + defaultDueDays: number; + defaultTerms?: string | null; // encrypted +} +``` + +### Encryption-Registry + +`apps/mana/apps/web/src/lib/data/crypto/registry.ts`: + +```typescript +invoices: { + fields: ['clientSnapshot', 'subject', 'notes', 'terms', 'lines'], + version: 1, +}, +invoiceClients: { + fields: ['name', 'address', 'email', 'vatNumber', 'iban', 'notes'], + version: 1, +}, +invoiceSettings: { + fields: ['senderName', 'senderAddress', 'senderEmail', 'senderVatNumber', 'senderIban', 'senderBic', 'footer', 'defaultTerms'], + version: 1, +}, +``` + +**Wichtig zu `lines`:** Die komplette `lines`-Array wird encrypted serialisiert. Die Zahlenanteile wären zwar plaintext-fähig, aber die Trennung von encrypted Titel + plaintext Zahlen pro Line ist teuer in Dexie-Queries. Pragmatisch: ganze `lines`-Array encrypten, `totals` daneben plaintext halten für Filter/Summen. + +## Routing + +``` +apps/mana/apps/web/src/routes/(app)/invoices/ +├── +page.svelte # ListView mit Status-Filter +├── new/+page.svelte # InvoiceForm im Create-Mode +├── [id]/+page.svelte # DetailView +├── [id]/edit/+page.svelte # InvoiceForm im Edit-Mode +└── settings/+page.svelte # SettingsView (Absender, Nummernkreis) +``` + +## UI-Konzept + +### Landing (`/invoices`) + +- **Top-Leiste:** Status-Chips (Alle | Entwurf | Versendet | Bezahlt | **Überfällig** als rote Count-Badge), Zeitraum-Filter (Dieses Jahr | Letztes Jahr | Alle), Search +- **Kennzahlen-Karten:** Offene Summe, Überfällig, YTD fakturiert, YTD bezahlt +- **Liste:** `InvoiceCard` mit Nummer, Kunde, Fälligkeit, Bruttobetrag, Status-Badge; Click → DetailView +- **FAB:** "+" öffnet `new`-Route (oder Modal, konsistent mit anderen Modulen) +- **Scene-Scope**: Invoices ignorieren Scene-Scope per Default (kein Tag-System — Kunden/Nummer identifizieren, nicht Tags) + +### InvoiceForm + +Links Eingabe, rechts Live-Preview des PDFs (auf Desktop). Mobile: Tab-Switch. + +Sections: +1. **Kunde** — ClientPicker (sucht in Contacts + InvoiceClients) +2. **Metadaten** — Nummer (auto-generiert, editierbar), Issue-Date, Due-Date, Währung, Betreff +3. **Positionen** — `LinesEditor`: Tabelle mit Add/Remove/Reorder. Spalten: Titel, Menge, Einheit, Einzelpreis, MwSt%, Total (berechnet) +4. **Totals** — Auto-berechnet: Netto pro MwSt-Satz, MwSt, Brutto +5. **Notizen & AGB** — Markdown-Felder für zusätzlichen Text + +Save-Actions: "Als Entwurf speichern" (status: draft) oder "Speichern & Versenden" (status: sent, öffnet Mail-Flow). + +### DetailView + +- Header: Nummer, Status-Badge, Aktionen-Menu (Bearbeiten, Duplizieren, Als bezahlt markieren, Stornieren, PDF herunterladen, Per Mail senden) +- Linke Spalte: Rechnungs-Metadaten + Positionen als Read-Only-Tabelle +- Rechte Spalte: PDF-Preview (iframe) +- Footer: Activity-Log (erstellt, versendet, bezahlt, gemahnt) — aus `_activity` gefiltert + +### SettingsView + +- Absender-Profil-Form (einmalig auszufüllen, Onboarding-Block wenn leer) +- Logo-Upload via bestehende `uload`-Infrastruktur +- Nummernkreis-Konfigurator mit Preview ("Nächste Rechnung: 2026-0042") +- Default-Werte (Währung, MwSt, Zahlungsfrist) + +## PDF-Rendering + +### Library-Wahl + +- **`pdf-lib`** (npm, ~130 KB gzipped, WebAssembly-frei) — reicht für Tabellen + Text + Logo. +- **`swissqrbill`** (npm, CH-spezifisch, SPC-kompatibel) — generiert den Zahlteil als PDF-Seite oder PNG-Overlay. + +Alternativen verworfen: +- `@react-pdf/renderer` — React-only, Mana ist Svelte. +- `jsPDF` — großer Footprint, weniger flexibel bei komplexen Layouts. +- Server-Side-Rendering via Puppeteer in `apps/api` — wäre besser aber *Phase 2*. MVP bleibt client-side (local-first-Prinzip + keine neuen Service-Dependencies). + +### Render-Pipeline + +``` +invoice → renderer.ts + ├── Layout-Engine: Header (Absender + Logo) → Empfänger-Block → Rechnungsmeta → Positionen-Tabelle → Totals → Notes → Footer + ├── qr-bill.ts: swissqrbill.generate({ amount, iban, creditor, debtor, reference }) → PDF-Seite appendieren (nur wenn Currency=CHF) + └── → Blob (application/pdf) +``` + +Rendering dauert ~100-300ms für typische Rechnungen (akzeptabel für Live-Preview mit debounce 500ms). + +### QR-Rechnung (CH) — Kern-USP + +- Pflichtfelder: IBAN, Creditor (Name + Adresse), Amount, Currency=CHF, Reference (QRR oder SCOR) +- `referenceNumber` aus Invoice-Schema generiert via QRR-Algorithmus (27 Ziffern, Mod-10-Prüfziffer) ODER SCOR (ISO 11649 Creditor Reference) +- swissqrbill kümmert sich um Swiss Cross + Perforation + Zahlteil-Layout + +## Registrierung (Checklist) + +1. `apps/mana/apps/web/src/lib/modules/invoices/module.config.ts` anlegen +2. Config in `apps/mana/apps/web/src/lib/data/module-registry.ts` importieren + in `MODULE_CONFIGS` aufnehmen +3. Dexie-Schema-Migration: `db.version(N+1).stores({ invoices: 'id, number, status, userId, clientId, issueDate, dueDate', invoiceClients: 'id, userId', invoiceSettings: 'id, userId' })` hinzufügen — NICHT bestehende Versionen ändern +4. Encryption-Registry-Einträge (siehe oben) +5. Routes unter `(app)/invoices/` anlegen +6. App-Eintrag in `packages/shared-branding/src/mana-apps.ts`: + ```typescript + { id: 'invoices', name: 'Rechnungen', description: {...}, icon: APP_ICONS.invoices, color: '#059669', status: 'development', requiredTier: 'alpha' } + ``` +7. Icon in `packages/shared-branding/src/app-icons.ts` +8. `docs/MODULE_REGISTRY.md` unter "Arbeit & Finanzen" ergänzen +9. Guest-Seed in `collections.ts` (eine Demo-Rechnung im Status `draft` an einen seed-contact) +10. Vitest-Tests: + - Store-Mutationen (create, updateLines → totals neu berechnet, markPaid → paidAt gesetzt) + - Encryption-Roundtrip + - Nummer-Generator (atomisch, kein Duplikat bei gleichzeitigem Create) + - QRR-Prüfziffer + - PDF-Rendering smoke-test (Blob > 0 bytes) + +## AI-Integration (Phase 2) + +Nachdem MVP steht, Tools in `tools.ts` registrieren und in `@mana/shared-ai/src/tools/schemas.ts` + `AI_PROPOSABLE_TOOL_NAMES` aufnehmen: + +| Tool | Policy | Beschreibung | +|------|--------|--------------| +| `create_invoice` | propose | Rechnung als Entwurf anlegen — Kunde, Positionen, Fälligkeit aus Chat extrahieren | +| `mark_invoice_paid` | propose | Rechnung als bezahlt markieren (mit Datum) | +| `list_invoices` | auto | Status-Filter + Zeitraum für Planner-Kontext | +| `get_invoice_stats` | auto | Offene Summe, YTD-Umsatz, überfällige Anzahl | +| `suggest_dunning` | propose | Mahntext für überfällige Rechnung vorschlagen (nutzt Kundensnapshot + Fälligkeit + Betrag) | +| `draft_invoice_from_timesheet` | propose | Phase 3: verbindet `times`-Modul — "letzte 4 Wochen für Kunde X" → Rechnung | + +UX-Integration: `` auf ListView einbetten. Mission-Beispiel: *"Erinnere mich freitags an überfällige Rechnungen und schlag Mahntexte vor."* + +## Kommunikation / Versand + +### MVP (Phase 1) + +- Button "Per Mail senden" → öffnet bestehende `mail`-Compose mit pre-filled Empfänger (aus clientSnapshot.email), Betreff (`Rechnung {number}`), Body (Vorlage mit Platzhaltern), Anhang = gerendertes PDF +- User sendet manuell ab → Store setzt `status='sent'` + `sentAt=now` +- Optional: nach Versand automatisches Dexie-`_activity`-Event "Rechnung versendet" + +### Phase 2 — Automatisiert + +- Eigener Endpoint in `apps/api`: `POST /api/v1/invoices/:id/send` → serverseitig Mail verschicken via Stalwart +- E-Mail-Tracking (Opens) — analog zu Newsletter-Modul später +- Zahlungs-Reminder (cron im `mana-ai`): "Rechnung seit 5 Tagen überfällig" + +## Milestones + +| Milestone | Umfang | Geschätzter Aufwand | +|-----------|--------|---------------------| +| **M1 Skelett** | Modul registriert, Dexie-Tables, Encryption-Registry, leere ListView, Guest-Seed, App-Entry + Icon | 0.5 Tag | +| **M2 CRUD** | InvoiceForm + LinesEditor + DetailView, Totals-Berechnung, Status-Maschine, Nummer-Generator | 3 Tage | +| **M3 Settings** | SettingsView + Singleton-Store, Logo-Upload via uload, Nummernkreis-Editor | 1 Tag | +| **M4 PDF Basic** | pdf-lib-Renderer mit Header/Tabelle/Totals/Footer, Preview-iframe in DetailView, Download-Button | 2 Tage | +| **M5 QR-Rechnung** | swissqrbill-Integration, QRR-Referenz-Generator, IBAN-Validation, CHF-only Gating | 1.5 Tage | +| **M6 Versand** | "Per Mail senden"-Flow über bestehendes mail-Modul, status-Transition sent+sentAt | 0.5 Tag | +| **M7 Dashboard & Stats** | Kennzahlen-Karten, Overdue-Highlighting, `useStats()` + Dashboard-Widget | 1 Tag | +| **M8 AI-Tools** | 4 Tools (create_invoice, mark_paid, list, stats) + Proposal-Inbox | 1.5 Tage | + +**Summe MVP (M1–M7):** ~9.5 Arbeitstage → realistisch **~2.5 Wochen** mit Testing/Polishing. + +## Phase 2 (nach MVP) + +- camt.053/054-Bankabgleich (separater Plan, eigenes Backend-Feature in mana-api) +- SEPA-Lastschrift (pain.008-XML-Export) +- Mahnwesen (3-Stufen-Mahnlauf) +- Wiederkehrende Rechnungen (via `rituals`) +- PDF-Rendering server-side via Puppeteer (bessere Typografie, custom fonts) +- Auto-Sync bezahlter Rechnungen → `finance`-Transaktion + +## Phase 3 (Vereinsvariante) + +- Empfänger = Gruppe (aus contacts-Gruppen) → Serienrechnungslauf +- Integration Mitglieder-Entität (aus Paket A) +- Beitragsmodelle (Jahresbeitrag, Halbjahresbeitrag, gestaffelt nach Kategorie) +- QR-Rechnung mit Vereins-Referenz pro Mitglied + +## Offene Fragen + +1. **Nummernkreis-Atomicität**: Bei schnellem doppeltem Create-Klick ohne Sync darf keine doppelte Nummer entstehen. Dexie-Transaktion um `nextNumber`-Read + `nextNumber++` wrappen. Bei Sync-Konflikt (Offline Create auf zwei Geräten): LWW löst durch `__fieldTimestamps`, aber Nummern wären doppelt. Lösung: Beim Sync-Merge Kollision erkennen → älterer Eintrag behält Nummer, neuerer bekommt `nextNumber` neu zugewiesen. **Design nötig vor M2.** +2. **Kundensnapshot-Strategie**: Beim Versenden wird der Kunden-Stand eingefroren (`clientSnapshot`). Was passiert bei Edit der Rechnung im Status `sent`? Option A: Edit nur im Status `draft` erlauben. Option B: Jede Edit-Operation neuen Snapshot nehmen. **Empfehlung A** — einfacher, entspricht Realität (versendete Rechnung ist rechtsverbindlich). +3. **Logo-Upload-Pfad**: `uload` liefert Media-ID, aber PDF-Renderer braucht Bytes. Zwei Optionen: (a) Logo beim Render aus uload ziehen (async), oder (b) Base64-inline in `invoiceSettings` speichern. Empfehlung (a) weil Logos typischerweise >20 KB und wir encryption sparen wollen. +4. **Currency-Scope**: MVP CHF + EUR reicht für 95% der Zielgruppe. USD/GBP später. +5. **Mehrsprachigkeit**: Sollen Rechnungen sprachlich anpassbar sein (DE/EN/FR auf dem PDF)? Phase 2 — MVP: Sprache = UI-Sprache. +6. **Zero-Knowledge-Kompatibilität**: Der `clientSnapshot` ist encrypted. Wenn ZK aktiv ist, kann der Server kein PDF renderen/versenden (Phase 2). Für MVP (client-side-Render) kein Problem. + +## Abhängigkeiten + +- `contacts`-Modul: vorhanden, wird für ClientPicker genutzt. +- `mail`-Modul: vorhanden (beta), wird für Versand genutzt. +- `uload`-Modul: vorhanden, wird für Logo + PDF-Cache genutzt. +- npm: `pdf-lib@^1`, `swissqrbill@^4` — beide MIT-lizenziert, aktiv gewartet. +- Keine neue Backend-Service nötig für MVP. + +## Erfolgs-Kriterien + +- **Tag 1 nach Launch:** Till kann für einen realen Kunden eine QR-Rechnung stellen, als PDF herunterladen und manuell versenden. +- **Woche 2:** Rechnung wird aus Mana heraus per Mail versendet, PDF landet als Anhang. +- **Monat 1:** 3–5 externe Nutzer (Freelancer) testen das Modul und haben bezahlte Rechnungen generiert. +- **Monat 3:** Mission "Erinnere mich an überfällige Rechnungen" läuft und schlägt Mahnungen vor. diff --git a/docs/reports/clubdesk-vs-mana-comparison.md b/docs/reports/clubdesk-vs-mana-comparison.md new file mode 100644 index 000000000..a8c884d2b --- /dev/null +++ b/docs/reports/clubdesk-vs-mana-comparison.md @@ -0,0 +1,301 @@ +# ClubDesk vs. Mana — Vergleichsanalyse & Lückenplan + +**Erstellt:** 2026-04-20 +**Autor:** Till (Recherche + Aufbereitung: Claude) +**Zweck:** Gegenüberstellung des Schweizer Marktführers für Vereinsverwaltung (ClubDesk) mit dem aktuellen Stand von Mana, um zu identifizieren, welche Features fehlen, damit Mana ClubDesk als Vereinsplattform ablösen könnte. + +--- + +## 1. Executive Summary + +- **ClubDesk** ist eine seit 2008 etablierte, spezialisierte All-in-One-Vereinssoftware mit ca. **20'000 aktiven Vereinen in DACH** (Stand Mai 2025), hergestellt von der **reeweb ag** in Basel. Kernwertversprechen: Mitgliederverwaltung + vollwertige **Schweizer Vereinsbuchhaltung** + integrierter **Website-Baukasten mit Hosting** — alles aus einer Hand. +- **Mana** ist eine moderne, KI-first, local-first Personal-Productivity-Plattform mit 60+ Modulen und einer entstehenden Multi-Tenant-Infrastruktur (Organizations via Better Auth, geteilte Kalender, Events mit RSVP). Die **Basis** für Vereinsverwaltung existiert, aber die **vereinsspezifische Geschäftslogik** (Beiträge, doppelte Buchführung, CH-Zahlungsintegration, Website-Baukasten) fehlt vollständig. +- **Fazit:** Mana ist technisch deutlich moderner (local-first, AI-native, offenes Ökosystem), aber produktseitig nicht vereinsbereit. Ein Ablöseprojekt erfordert **5 größere Feature-Pakete** (siehe §5) — grob geschätzt **6–10 Personenmonate** Entwicklungsaufwand für ein MVP-gleichwertiges Produkt. + +--- + +## 2. ClubDesk — Profil + +### 2.1 Unternehmen + +| | | +|---|---| +| Hersteller | **reeweb ag**, Wettsteinplatz 7 / Picassoplatz 8, 4052 Basel (CHE-114.676.055) | +| Gründung | 2008/2009 | +| Gründer | Rolf Pfenninger, Tom Studer, Andreas Kling, Guido Hächler | +| Team | 21+ namentlich genannte Mitarbeitende (Entwicklung, Support, Marketing, Admin); 3-köpfige GL | +| Hosting | Nine Internet Solutions AG (CH, ISO 27001) | +| Marktreichweite | **~20'000 Vereine** (DACH), ~250 Neukundschaften/Monat, **3.8 Mio. verwaltete Kontakte** | +| Prominente Partner | Raiffeisen, PostFinance, Deutscher Tennisbund | +| Umsatz | nicht öffentlich (AG, nicht börsenkotiert). Grobschätzung aus Tarifstruktur: 20k Vereine × Ø ~CHF 180/Jahr ≈ **~3.6 Mio. CHF/Jahr ARR** (spekulativ, untere Grenze bei ~40% Free-Anteil) | + +### 2.2 Zielgruppe + +Ehrenamtlich geführte Vereine in CH/DE/AT — Sport, Musik/Chöre, Theater, Karneval/Fastnacht, Garten, Fanclubs, Fördervereine, Kirche, Feuerwehr-Jugend. Skaliert bis 5'000 Mitglieder/Verein. + +### 2.3 Preise (CHF, Jahresabo) + +| Tarif | Monatspreis | Mitglieder | Storage | Websites | +|---|---|---|---|---| +| Free | 0 | 50 | 100 MB | 1 (eingeschränkt) | +| S | 13 | 100 | 1 GB | 1 | +| M | 20 | 250 + 50 Kontakte | 2 GB | 2 (eig. Domain) | +| L | 36 | 500 + 200 | 5 GB | 3 | +| XL | 41 | 1'000 + 500 | 8 GB | 5 | + +30 Tage Testphase, Individualangebote bis 5'000 Mitglieder. + +### 2.4 Module & Features + +| Modul | Umfang | +|---|---| +| **Mitgliederverwaltung** | Unbegrenzte Gruppen/Mannschaften, freie Zusatzfelder (Trikotgröße, Instrument, Lizenz), Rollen (Trainer, Kassier, Vorstand), granulare Lese-/Schreibrechte, CSV-Import, Massenupdate, Geburtstags-/Jubiläums-Reminder | +| **Kontaktverwaltung** | Sponsoren, Lieferanten, Ehemalige; Dublettenprüfung; Filter | +| **Rechnungen & Buchhaltung** | **Drei Modi:** Kassenbuch, Einnahmen-Ausgaben, **doppelte Buchführung**. **CH-Zahlverkehr:** QR-Rechnung, ESR/ISR, **TWINT**, camt.053/054-Bankabgleich. **DE:** SEPA-Lastschrift. Mahnwesen, Kontenrahmen SKR42, Mehrwährung, MwSt., Kostenstellen | +| **E-Mail / Mailserver** | Eigener Mailserver, Gruppenadressen (vorstand@…), Serienmails, Newsletter | +| **Kalender & Events** | Zentraler Vereinskalender, wiederkehrende Termine, An-/Abmeldung ("Ja/Nein/Vielleicht"), Export Apple/Google, automatische Benachrichtigung bei Änderungen | +| **Online-Anmeldung** | Events & Kurse mit konfigurierbaren Deadlines, öffentliches Formular | +| **Website-Baukasten** | Drag-&-Drop, responsive, Bilderkarussell, Parallax, Video, News, Terminlisten, Teamseiten. **Auto-Sync** aus Mitglieder- & Kalendermodul. SSL + Hosting inklusive, bis 5 Websites (XL), barrierefreie Variante | +| **Dokumentenverwaltung** | Protokolle, Verträge, Statuten; Ordner; Rechte; Batch-Upload | +| **Berechtigungen** | Rollen-/Gruppenbasiert (frei konfigurierbar ab S-Tarif, 3 Stufen bei Free) | +| **DSGVO** | AVV verfügbar, CH-Datacenter, verschlüsselte Übertragung, Backups inkludiert | + +### 2.5 USPs + +1. **All-in-One mit integriertem Website-Baukasten + Hosting + SSL** — alles ein Anbieter, eine Rechnung. +2. **Tiefe Schweizer Zahlungsintegration**: QR-Rechnung, TWINT, ISR/ESR, camt-Bankabgleich. +3. **Vollwertige Vereinsbuchhaltung** (inkl. doppelter Buchführung) out-of-the-box. +4. **Marktführerschaft DACH** mit 20'000 Vereinen (Trust-Signal). +5. **Dauerhaft kostenlose Free-Version** bis 50 Mitglieder (Akquise-Trichter). +6. **Inkludierter Support** (Telefon, E-Mail, TeamViewer) — CH-Standard. + +### 2.6 Schwächen (aus Reviews / Forum) + +- **Keine native Mobile-App** — nur mobile-optimierter Browser-Zugriff. Seit Jahren wiederkehrender Kritikpunkt. +- **Rechnungs-/Finanzbereich unübersichtlich**; steile Lernkurve für Kassiere ohne Buchhaltungs-Background. +- **Kein Lohn-/Entschädigungsmodul** für Trainer/Funktionäre. +- **Storage knapp** (1–8 GB); Zusatzspeicher kostenpflichtig. +- **Wenig dedizierte Sport-Features** (Ligaverwaltung, Tabellen, Spielberichte). +- **Review-Landschaft sehr dünn** (OMR: 4.7/5 bei 55 Ratings, Capterra DE teils nur Einzelreviews). + +--- + +## 3. Mana — aktueller Stand + +### 3.1 Architektur-Stärken + +- **Local-First:** Alle CRUD-Operationen offline; ein IndexedDB, field-level LWW-Sync via mana-sync (Go, Port 3050) in PostgreSQL mit RLS. +- **AI-Native:** 59 AI-Tools in 19 Modulen, autonomer Mission Runner (mana-ai, Port 3067), Web-Research-Orchestrierung über 16+ Provider (mana-research, 3068). +- **Ein Ökosystem:** 60+ verschränkte Module, ein Session/JWT, SSO über `*.mana.how`. +- **Encryption-at-rest:** AES-GCM-256 in 27 Tables, optionales Zero-Knowledge mit Recovery-Codes. +- **GDPR-ready:** `.mana`-Export, Right-to-be-forgotten. +- **Moderner Stack:** SvelteKit 5, Hono/Bun, Drizzle, Better Auth (inkl. Organizations-Plugin). + +### 3.2 Bereits vorhandene vereinsrelevante Bausteine + +| Baustein | Zustand | +|---|---| +| **Kontakte** | ✅ Gruppen, Tags, Notizen, Massen-Import. Basis vorhanden, aber keine Rollen/Lizenzen/Zusatzfelder. | +| **Kalender** | ✅ Wiederkehrende Termine, geteilte Kalender, Reminder. | +| **Events** (`services/mana-events`, 3065) | ✅ Öffentliche Share-Links mit Token, RSVP ohne Login, Potluck-Item-Claiming. | +| **Finance** | ⚠️ Nur **persönliche** Einnahmen/Ausgaben — **keine** doppelte Buchführung, keine Rechnungen, keine Mitgliederbeiträge. | +| **Mail** (`services/mana-mail`, 3042 + Stalwart) | ✅ Vollwertiger IMAP/JMAP-Mailserver, Konto-Auto-Provisioning. Keine Newsletter-Kampagnen. | +| **Storage** | ✅ MinIO, Ordner, Versionierung. Keine berechtigungsbasierten Archiv-Funktionen. | +| **Organizations** (Better Auth Plugin) | ✅ Einladungen, Mitgliederrollen (owner/member/admin), active-org. Nur Grundschema — keine Verein-spezifischen Rollen. | +| **Landing Builder** (`services/mana-landing-builder`) | ⚠️ Existiert für interne Landing-Pages — **kein** Vereins-CMS mit Team-/News-/Termin-Bindings. | +| **Quiz / Forms** | ⚠️ Quiz-Builder vorhanden; kein dediziertes Formular-/Anmelde-System. | + +### 3.3 Was Mana klar besser kann als ClubDesk + +- **AI-Agents & Workbench** — ClubDesk hat null AI. +- **Mobile-First PWA** + Expo-basierte native Apps (im Aufbau). +- **Local-First / Offline** — ClubDesk benötigt Online-Verbindung. +- **Zero-Knowledge-Option** — in DACH-Vereinssoftware einzigartig. +- **Offene Architektur** — Custom-Tools, eigene Module, Open-Source-Prinzipien. + +--- + +## 4. Feature-Gap-Matrix + +| Bereich | ClubDesk | Mana heute | Gap-Schweregrad | +|---|---|---|---| +| Mitglieder-Datenmodell (Rollen, Lizenzen, Zusatzfelder) | ✅ voll | 🟡 Kontakte-Basis | **Mittel** | +| Mitgliederbeiträge / Dues | ✅ | ❌ | **Hoch** | +| Doppelte Vereinsbuchhaltung | ✅ | ❌ | **Hoch** | +| QR-Rechnung (CH) | ✅ | ❌ | **Hoch** (CH-Markt-kritisch) | +| TWINT-Integration | ✅ | ❌ | **Hoch** | +| camt.053/054-Bankabgleich | ✅ | ❌ | **Hoch** | +| SEPA-Lastschrift (DE) | ✅ | ❌ | **Hoch** | +| Mahnwesen | ✅ | ❌ | **Mittel** | +| Newsletter / Serienmails | ✅ | 🟡 (Stalwart SMTP da, kein Kampagnen-Tool) | **Mittel** | +| Gruppen-E-Mail-Adressen (vorstand@…) | ✅ | 🟡 (Stalwart kann's technisch) | Niedrig | +| SMS-Versand | ⚠️ optional | ❌ | Niedrig | +| Kalender mit RSVP | ✅ | ✅ | — | +| Online-Event-Anmeldung öffentlich | ✅ | ✅ (mana-events Share-Links) | — | +| Website-Baukasten mit Vereins-Bindings | ✅ (Kern-USP!) | ❌ | **Hoch** | +| Eigene Domain + Hosting + SSL | ✅ | ⚠️ technisch über Cloudflare machbar, kein Self-Service | **Mittel** | +| Dokumentenarchiv mit Rollen-Rechten | ✅ | 🟡 (Storage ohne Governance) | **Mittel** | +| Rollen-/Rechtematrix pro Modul | ✅ frei konfigurierbar | ❌ (nur owner/member/admin) | **Hoch** | +| Mehrere Vereine pro User | ✅ | ✅ (Organizations) | — | +| Mitglieder-Import CSV | ✅ | 🟡 (Kontakte-Import ja, aber ohne Verein-Felder) | Niedrig | +| Geburtstags-/Jubiläums-Reminder | ✅ | ❌ | Niedrig | +| Native Mobile-App | ❌ | 🟡 (Expo im Aufbau) | **Differenzierungs-Chance** | +| KI-Assistent / AI-Tools | ❌ | ✅ | **Differenzierungs-Chance** | +| Offline-Fähigkeit | ❌ | ✅ | **Differenzierungs-Chance** | +| Barrierefreie Website-Variante | ✅ | ❌ | Niedrig | + +--- + +## 5. Was Mana braucht, um ClubDesk zu ersetzen + +Die Lücke gliedert sich in **5 Arbeitspakete**. Reihenfolge nach Abhängigkeit und Markt-Kritikalität (CH-first). + +### Paket A — Vereins-Datenmodell & Rollen (Foundation) + +**Ziel:** Organizations-Schema zu vollwertiger Vereinsentität ausbauen. + +- Neues Modul `clubs/` (oder Erweiterung der Better-Auth-Organization) mit: Vereinsname, Logo, IBAN, UID, Rechtsform, Statuten-Upload. +- Mitglieder-Entität mit Zusatzfeldern: Eintrittsdatum, Austrittsdatum, Mitgliedskategorie (Aktiv/Passiv/Ehren), Lizenznummer, benutzerdefinierte Felder. +- **Rollen/Rechtematrix** pro Modul (read/write/admin × Mitglieder/Finanzen/Events/Dokumente). +- Mehrere Gruppen/Teams (Mannschaft U15, Vorstand, Junioren-Chor) mit eigenen Verteilern. +- **Aufwand:** ~1 PM + +### Paket B — Finanzen & Beiträge (Kernrisiko) + +**Ziel:** Mitgliederbeiträge + Vereinsrechnungen + Schweizer Zahlungsstandards. + +- Neues Modul `club-finance` (getrennt vom persönlichen Finance-Modul). +- **Rechnungs-Engine**: PDF-Generierung, fortlaufende Nummernkreise, Serien-Rechnungsläufe (Mitgliederbeitrag jährlich). +- **QR-Rechnung (CH)** via `swissqrbill`-Lib (JS) oder ähnlich — Pflicht für CH-Vereine. +- **camt.053/054-Parser** für Bankabgleich (Raiffeisen, PostFinance, Kantonalbanken liefern alle camt). +- **SEPA-Lastschrift (DE)** — XML-Export pain.008. +- **TWINT**: entweder Business-API (komplex) oder TWINT-QR via Postfinance (einfacher Einstieg). +- Mahnwesen (3 Stufen), Zahlungsstatus-Automatik. +- **Buchhaltung:** erstmal Einnahmen-Ausgaben-Rechnung reicht für 80% der Vereine; doppelte Buchführung als Phase 2. +- **Aufwand:** ~3–4 PM (CH-Banking ist aufwändig), Phase-2 doppelte Buchführung +2 PM. + +### Paket C — Website-Baukasten für Vereine (Differenzierungs-USP) + +**Ziel:** Öffentliche Vereinswebsite mit Live-Daten aus Mana. + +- `mana-landing-builder` von Astro-Templates zu konfigurierbarem Drag-&-Drop-Editor erweitern (oder Alternative wie Builder.io/Astro-Islands + eigenem Block-System). +- **Bindings**: Team-Seite zieht aus `members`, Terminliste aus `calendar`, News aus neuem `news`-Modul. +- Mehrere Seiten pro Verein, eigene (Sub-)Domain via Cloudflare for SaaS. +- SSL automatisch (Let's Encrypt via Cloudflare). +- Öffentliche Anmeldeformulare für Events (existiert teilweise via `mana-events` Share-Links). +- **Aufwand:** ~2 PM (MVP mit Template-Auswahl + Team/Termin-Blöcken) + +### Paket D — Kommunikation (Newsletter & Serienmails) + +**Ziel:** Vereinsmailings mit Tracking & Rechtssicherheit. + +- Neues Modul `club-broadcast`, sitzt auf bestehendem Stalwart-SMTP. +- Empfängerlisten aus Mitgliedergruppen + Filter. +- HTML-Editor (Unlayer oder selbst gebaut mit Svelte). +- Zustellstatistik (Bounces, Opens via Tracking-Pixel, Unsubscribe-Links — DSGVO-konform). +- Automatische Geburtstags-/Jubiläums-Mails. +- Optional: SMS via Twilio/MessageBird-Adapter. +- **Aufwand:** ~1–1.5 PM + +### Paket E — Dokumentenarchiv & Berechtigungen + +**Ziel:** Protokolle, Verträge, Statuten rechtssicher verwalten. + +- Storage-Modul um Archive-Funktion erweitern: Ordner mit Rollen-ACL (nur Vorstand, nur Revisoren). +- Versionierung existiert bereits — UI für Revisionsvergleich fehlt. +- Audit-Log pro Dokument (wer hat wann gelesen/geändert). +- **Aufwand:** ~0.75 PM + +### Paket F (optional/später) — Sport/Verbands-Spezifika + +Ligaverwaltung, Spielberichte, Tabellen, Platz-/Hallen-Buchung. Nur falls Zielmarkt Sportvereine explizit adressiert werden soll. ClubDesk hat das **selbst nicht stark** → Differenzierungsmöglichkeit, aber kein Blocker. + +--- + +## 6. Gesamtaufwand & Reihenfolge + +| Phase | Pakete | Aufwand | Ergebnis | +|---|---|---|---| +| **MVP Verein-Light** | A + D (Newsletter) + B-lite (nur Mitgliederbeitrag-Rechnungen ohne Bankabgleich) | ~3 PM | Small-Club-tauglich (Sport-Junioren-Verein, Chor, Freiwillige Feuerwehr-Jugend) | +| **MVP CH-tauglich** | + B-voll (QR + camt) + E | ~3 PM | Volles CH-Mittelstands-Vereinsprodukt | +| **Marktparität** | + C (Website-Baukasten) | ~2 PM | Ersatzfähig zu ClubDesk M/L | +| **Differenzierung** | + native Mobile-App + AI-Assistent für Kassier/Vorstand | ~1.5 PM | Klare Überlegenheit gegen ClubDesk | + +**Summe für vollwertigen Ersatz:** ~**9–10 Personenmonate**. + +Kritische externe Abhängigkeiten: (1) **swissqrbill**-Integration + PDF-Rendering, (2) Cloudflare for SaaS für Domain-Self-Service, (3) optional TWINT-Partnerprogramm über Postfinance, (4) DSGVO-AVV-Template + CH-DSG-Addendum. + +--- + +## 7. Dual-Use-Roadmap — Features mit Mehrwert über Vereine hinaus + +Nicht jedes ClubDesk-Feature ist nur für Vereine interessant. Viele Bausteine aus §5 bringen **auch dem allgemeinen Mana-User** (Freelancer, Creator, Familien, kleine Teams) massiven Mehrwert. Diese priorisieren wir — so finanziert jeder Sprint zwei Zielgruppen gleichzeitig. + +### 7.1 🟢 Schnelle Wins mit breitem Nutzen + +| # | Baustein | Dual-Use-Zielgruppe | Warum | +|---|---|---|---| +| 1 | **Rollen- & Rechtematrix pro Modul** (Paket A) | Familien, WGs, kleine Teams, Freelancer-Kollaborationen | Einmal gebaut → Storage, Events, Kalender, Finance & alle künftigen Module profitieren sofort. | +| 2 | **Rechnungs-Engine mit PDF + QR-Rechnung (CH)** (Paket B) | Freelancer, Selbstständige, Einzelunternehmer | Finance-Modul bekommt zweite Hälfte (bisher nur Tracking, kein Ausstellen). Eigenständiges Produkt ("Rechnung stellen mit Mana"). | +| 3 | **camt.053-Bankabgleich** (Paket B) | Jeder mit Business-Konto in CH | "Zieh dein camt, Mana ordnet Zahlungen automatisch Rechnungen zu" — starker Stand-Alone-Hook. | +| 4 | **Newsletter-/Broadcast-Modul** (Paket D) | Creator, Blogger, kleine Shops, Substack-Alternative | Sitzt auf vorhandenem Stalwart → günstig. Kombiniert mit AI (Betreff-Optimierung, Segmentierung) = klarer USP. | + +### 7.2 🟡 Mittlerer Aufwand, hoher Crossover + +| # | Baustein | Dual-Use-Zielgruppe | Warum | +|---|---|---|---| +| 5 | **Dokumentenarchiv mit Rollen + Audit-Log** (Paket E) | Familien, Steuer, Projektarchive | Storage bekommt den Governance-Layer, den es ohnehin braucht. | +| 6 | **Website-Baukasten mit Live-Daten-Bindings** (Paket C) | Creator, Freelancer | "One-Pager mit Terminen + Newsletter-Anmeldung + Kontakten aus Mana". Cloudflare-for-SaaS (Custom-Domain-Self-Service) auch für Power-User attraktiv. | +| 7 | **Mahnwesen & wiederkehrende Rechnungen** | Freelancer mit Retainer-Kunden | Verbindung zu `habits`/`rituals` (wiederkehrende Events automatisieren). | + +### 7.3 🔴 Eher vereinsspezifisch, geringerer Crossover + +Diese zuletzt einbauen — nur Vereine profitieren: + +- Mitglieder-Datenmodell mit Lizenzen, Trikotgrößen, Eintrittsdatum +- SEPA-Lastschrift-Massenläufe (DE) +- Doppelte Buchführung (Einnahmen-Ausgabe reicht 80% der User) +- Barrierefreie Website-Variante + +### 7.4 Empfohlene Sprint-Reihenfolge + +``` +Sprint 1–2: Rollen-/Rechtematrix → alle 27 Module profitieren sofort +Sprint 3–5: Rechnungs-Engine + QR-Rechnung → Freelancer-Zielgruppe erschlossen +Sprint 6: camt-Bankabgleich → Killer-Feature für CH-Solo-Self-Employed +Sprint 7–8: Newsletter-Broadcast + AI → Creator-Zielgruppe erschlossen +Sprint 9: Dokumentenarchiv mit ACL → Families/Teams +Sprint 10+: Vereinsspezifika (Mitglieder-Felder, Mahnwesen, Website-Bindings) +``` + +**Effekt:** Mit dieser Reihenfolge baust du **~70% der ClubDesk-Features** gleichzeitig als **eigenständige Produkte** für Freelancer, Creator und Familien — und erreichst Vereinstauglichkeit als Nebeneffekt. Jeder Sprint hat zwei Geschäftscases. + +--- + +## 8. Strategische Empfehlung + +1. **Nicht direkt gegen ClubDesk im Bestandsmarkt konkurrieren** — die 20'000 installierten Vereine werden nicht wegen Features wechseln, sondern nur wenn sie absolut unzufrieden sind (Mobile-App-Lücke!). +2. **Einfallsflanke: Neugründungen + Vereine mit Digital-First-Vorstand.** Diese suchen heute: Mobile-App + AI-Assistent + moderne UX. Das ist Manas Stärke. +3. **CH-first ausrollen** — QR-Rechnung + camt sind non-negotiable; der Invest lohnt sich, weil in CH die Zahlungsbereitschaft höher ist und ClubDesk dort am stärksten. +4. **Free-Tier dauerhaft** (wie ClubDesk) als Akquise-Trichter bis 50 Mitglieder — passt zu den bestehenden Mana-Tiers. +5. **MVP in ~3 PM** (Paket A + D + B-lite) ermöglicht erste Pilotvereine im eigenen Umfeld, mit denen B-voll und C ko-entwickelt werden können. +6. **AI als Killer-Feature vermarkten**: "Dein Kassier, der mitdenkt" — automatische Beitragsberechnung, Mahnungs-Vorschläge, Protokoll-Zusammenfassungen durch mana-ai-Agenten. + +--- + +## 9. Quellen + +- [clubdesk.ch — Startseite](https://www.clubdesk.ch/) +- [clubdesk.ch — Preise](https://www.clubdesk.ch/de/preise) +- [clubdesk.ch — Das Unternehmen](https://www.clubdesk.ch/de/das-unternehmen) +- [clubdesk.ch — Rechnungen & Vereinsbuchhaltung](https://www.clubdesk.ch/de/rechnungen-und-vereinsbuchhaltung) +- [clubdesk.ch — Mitgliederverwaltung](https://www.clubdesk.ch/de/mitgliederverwaltung) +- [clubdesk.ch — News: 20'000 Vereine](https://www.clubdesk.ch/de/news/20-000-vereine-vertrauen-auf-clubdesk) +- [clubdesk.de — Vereinshomepage erstellen](https://www.clubdesk.de/de/vereinshomepage-erstellen) +- [Moneyhouse — reeweb ag](https://www.moneyhouse.ch/en/company/reeweb-ag-4839791831) +- [trusted.de — ClubDesk Test 2026](https://trusted.de/clubdesk) +- [trusted.de — ClubDesk Bewertung (Nachteile)](https://trusted.de/clubdesk-bewertung) +- [OMR Reviews — ClubDesk](https://omr.com/en/reviews/product/clubdesk) +- [Capterra DE — ClubDesk](https://www.capterra.com.de/software/214621/clubdesk) +- [ClubDesk-Forum — "Lebt Clubdesk?"](https://forum.clubdesk.com/topic/2037-lebt-clubdesk/) +- Internes Repo-Audit (Mana-Module, Services, Organizations-Plugin, mana-events, mana-mail, mana-research)