Module Architecture

System Context (C4 Level 1)

The Membership platform operates as an independent product that communicates with external systems exclusively through APIs. Members interact with the system through mobile and web applications. Club and studio administrators use a dedicated admin frontend. The system delegates all payment processing to the Cash360 Payment API and integrates with external financial services (SEPA clearing, EBICS banking), identity providers, and third-party accounting software.

C4Context title System Context Diagram -- Membership Platform Person(member, "Member", "Sports club member, gym customer, course participant") Person(admin, "Club/Studio Admin", "Manages members, billing, resources, settings") Person(trainer, "Trainer/Coach", "Manages classes, tracks attendance") Person(sysadmin, "System Admin", "Platform operations, tenant provisioning") Person(vendor, "Vendor Admin", "Membership One platform operator, cross-tenant management") Person(franchise, "Franchise Admin", "Multi-location network management") System(membership, "Membership Platform", "Member management, contracts, check-in, resources, communication, events") System_Ext(cash360, "Cash360 Payment API", "Transaction processing, SEPA generation, EBICS banking, invoice PDF") System_Ext(sepa, "SEPA Clearing Network", "Direct debit processing via Cash360") System_Ext(ebics, "EBICS Banking", "Electronic banking via Cash360") System_Ext(datev, "DATEV", "Accounting export (bookkeeping entries)") System_Ext(email, "Email Service", "SMTP/transactional email delivery") System_Ext(push, "Push Notification Service", "FCM/APNs for mobile push") System_Ext(idp, "Keycloak (v2.0+)", "Optional external IdP for Enterprise SSO, SAML, Social Login, WebAuthn — see ADR-AUTH-001") System_Ext(iot, "IoT Devices", "Turnstiles, NFC readers, chip scanners, sensors") System_Ext(gantner, "Gantner Essecca", "Professional access control hardware (turnstiles, doors, lockers)") System_Ext(osdp, "OSDP Controllers", "SIA standard door lock controllers") Rel(member, membership, "Uses", "Mobile App / Web") Rel(admin, membership, "Manages", "Admin Web App") Rel(trainer, membership, "Uses", "Trainer features in App") Rel(sysadmin, membership, "Configures", "System Admin Portal") Rel(membership, cash360, "Billing, SEPA, invoices", "REST API") Rel(cash360, sepa, "Submits direct debits") Rel(cash360, ebics, "Bank communication") Rel(membership, datev, "Exports bookkeeping", "CSV/API") Rel(membership, email, "Sends emails", "SMTP") Rel(membership, push, "Sends notifications", "FCM/APNs") Rel(membership, idp, "Authenticates", "OAuth2/OIDC") Rel(iot, membership, "Check-in events", "MQTT/REST") Rel(vendor, membership, "Manages platform", "Vendor Admin Portal") Rel(franchise, membership, "Manages network", "Admin Web App") Rel(membership, gantner, "Access control", "GAT REST API") Rel(membership, osdp, "Door commands", "OSDP v2 / RS-485")

Key architectural boundaries:

  • Membership owns member data, contracts, resources, events, communication, and check-in logic.
  • Cash360 owns payment processing, SEPA file generation, EBICS banking, and invoice PDF rendering. Membership never talks directly to banks or payment networks.
  • IoT devices connect to the Membership backend for access control decisions. The backend maintains the authorization rules; devices are stateless clients.

Container Diagram (C4 Level 2)

The platform consists of five primary containers: a Java backend (API server), three Flutter-based frontends (consumer app, admin app, trainer app -- or alternatively a single app with role-based views), a PostgreSQL database, and supporting infrastructure services.

C4Container title Container Diagram -- Membership Platform Person(member, "Member") Person(admin, "Admin") Person(trainer, "Trainer") System_Boundary(membership, "Membership Platform") { Container(flutter_app, "Flutter App", "Dart/Flutter", "Single cross-platform app with role-based views for members, trainers, and admins") Container(admin_web, "Admin Web App", "Flutter Web", "Desktop-optimized admin interface for club management") Container(api, "API Server", "Java 25, Spring Boot 4", "REST API, business logic, authentication, authorization") Container(worker, "Background Worker", "Java 25, Spring Boot 4", "Scheduled jobs: billing cycles, reminders, data sync, report generation") ContainerDb(postgres, "PostgreSQL 18", "Relational DB", "Members, contracts, entities, transactions, resources, events") ContainerDb(redis, "Redis 7", "Cache/Session", "Session store, rate limiting, real-time counters, pub/sub") ContainerDb(elasticsearch, "Elasticsearch 8", "Search Engine", "Full-text search: members, documents, resources") Container(mq, "RabbitMQ", "Message Broker", "Async events: billing triggers, notifications, import jobs, IoT events") Container(storage, "Object Storage", "S3-compatible", "Documents, images, PDF templates, CSV imports") Container(acgw, "Access Control Gateway", "Java 25", "Gantner/OSDP/BLE protocol translation, credential sync, door commands") } System_Ext(cash360, "Cash360 Payment API") System_Ext(email_svc, "Email Service") System_Ext(push_svc, "Push Service") System_Ext(iot_devices, "IoT Devices") Rel(member, flutter_app, "Uses", "HTTPS") Rel(admin, admin_web, "Uses", "HTTPS") Rel(admin, flutter_app, "Uses", "HTTPS") Rel(trainer, flutter_app, "Uses", "HTTPS") Rel(flutter_app, api, "Calls", "REST/JSON + JWT") Rel(admin_web, api, "Calls", "REST/JSON + JWT") Rel(api, postgres, "Reads/Writes", "JDBC") Rel(api, redis, "Cache/Sessions", "Redis protocol") Rel(api, elasticsearch, "Search queries", "REST") Rel(api, mq, "Publishes events", "AMQP") Rel(worker, mq, "Consumes events", "AMQP") Rel(worker, postgres, "Reads/Writes", "JDBC") Rel(api, cash360, "Payment operations", "REST API") Rel(worker, email_svc, "Sends emails", "SMTP") Rel(worker, push_svc, "Push notifications", "FCM/APNs") Rel(iot_devices, api, "Check-in events", "REST/MQTT") Rel(api, storage, "File operations", "S3 API") Rel(acgw, api, "Access decisions", "REST") Rel(iot_devices, acgw, "Access events", "OSDP/GAT/BLE")

Container Responsibilities

Container Technology Purpose
API Server Java 25, Spring Boot 4, Hibernate Core REST API, authentication, authorization, business logic, real-time check-in decisions
Background Worker Java 25, Spring Boot 4 Billing cycle execution, notification dispatch, report generation, data import processing, scheduled maintenance
Flutter App Dart 3.x, Flutter, Riverpod Single cross-platform app (Android, iOS, web) with role-based views for members, trainers, and admins
Admin Web App Flutter Web Desktop-optimized admin interface for complex management tasks (data tables, reports, configuration)
PostgreSQL 18 PostgreSQL Primary data store for all domain entities, JSONB for custom attributes, full-text search for simple queries
Redis 7 Redis Session caching, rate limiting, real-time presence/counters, pub/sub for live updates
Elasticsearch 8 Elasticsearch Full-text search across members, documents, resources; analytics aggregations
RabbitMQ RabbitMQ (AMQP) Asynchronous event bus: decouples billing, notifications, imports, IoT events from the request/response cycle
Object Storage MinIO / AWS S3 Document storage: PDFs, images, CSV imports, email templates, club logos

Module Decomposition

The backend is organized into eleven software packages, each encapsulating a distinct bounded context. Every package follows the standard layer pattern: dto/, jpa/ (entity + repository), service/ (API + impl), rest/ (controller), data/ (migrations), exception/, mapper/.

graph TB subgraph "Package 1: Identity & Access" IAM[Authentication<br/>Authorization<br/>User Management<br/>Roles & Permissions<br/>API Keys] end subgraph "Package 2: Member & Organization" MO[Consumer/Member<br/>Entity/Organization<br/>Entity Settings<br/>Entity Hierarchy<br/>Custom Attributes] end subgraph "Package 3: Membership & Contracts" MC[Contract Templates<br/>Contract Lifecycle<br/>Pricing & Discounts<br/>Membership Categories<br/>Family/Group Plans] end subgraph "Package 4: Financial" FIN[Transaction Management<br/>Billing Cycles<br/>SEPA Integration<br/>Invoice Generation<br/>Bookkeeping Export] end subgraph "Package 5: Resource Management" RES[Rooms & Areas<br/>Equipment & Inventory<br/>Booking & Calendar<br/>Check-in & Access<br/>Hardware Integration] end subgraph "Package 6: Communication & Marketing" COM[Email Templates<br/>Push Notifications<br/>Newsletter<br/>In-App Messaging<br/>Landing Pages] end subgraph "Package 7: Events & Courses" EVT[Event Planning<br/>Course Scheduling<br/>Attendance Tracking<br/>Trainer Management<br/>Tournament Brackets] end subgraph "Package 8: Platform Services" PLT[Multi-Tenant<br/>Data Import/Export<br/>Reporting & Analytics<br/>Scheduler<br/>Audit Logging] end subgraph "Package 9: CRM and Sales" CRM[Lead Management<br/>Deal Pipeline<br/>Activity Tracking<br/>Trial Conversion<br/>Account Management] end subgraph "Package 10: Support and Ticketing" SUP[Ticket Management<br/>SLA Monitoring<br/>Knowledge Base<br/>Agent Tools<br/>Multi-Channel Intake] end subgraph "Package 11: Accounting" ACC[General Ledger<br/>DATEV Export<br/>Cost Centers<br/>Bank Reconciliation<br/>Financial Reports] end IAM --> MO MO --> MC MC --> FIN MO --> RES MO --> EVT MC --> EVT FIN --> PLT RES --> PLT COM --> PLT EVT --> PLT IAM --> PLT MO --> CRM CRM --> FIN MO --> SUP SUP --> COM FIN --> ACC ACC --> PLT

Package Details

Package 1: Identity and Access Management

Handles all authentication, authorization, user lifecycle, and API key management. Supports both admin logins (username/password via McLogin) and consumer logins (email/password via MbLogin). JWT tokens with refresh token rotation. Role-based access control with hierarchical permissions (system > franchisor > group > club > team leader > member).

IdP Abstraction Layer (ADR-AUTH-001): Authentication is mediated through an IdentityProvider interface. In v1.0, a LocalIdentityProvider handles JWT RS256 token issuance, bcrypt password validation, and Redis-based brute-force protection. In v2.0+, a KeycloakIdentityProvider can be activated per tenant for Enterprise customers requiring SSO (SAML/OIDC), Social Login (Google/Apple), WebAuthn/FIDO2 (Passkeys), or LDAP/AD federation. Standard/Starter/Professional tenants continue using the local provider. The abstraction ensures that all downstream code (controllers, services, security filters) remains agnostic to the authentication source. See Chapter 13 (ADR-AUTH-001) for full rationale.

Key entities: MbLogin, McLogin, McUser, McRole, McPermission, MbApiKey Reuse from Cash360: JWT authentication (java-jwt 4.5.x), AuthenticatedMbLoginDetails, OTP (aerogear), password policy enforcement

Package 2: Member and Organization Management

Core domain: members (consumers) and organizations (entities). Members hold personal data, contact information, emergency contacts, custom attributes (JSONB), and relationships to organizations. Organizations form a tree hierarchy (parent-child) supporting franchise structures, umbrella associations, and multi-location chains. Entity settings control branding, payment methods, and feature toggles per organization.

Key entities: CsrConsumer, McEntityV3, McEntitySettings, McBankAccountV3, McCountryV3 Reuse from Cash360: McEntity multi-tenant model (idMcEntity on all entities), CsrConsumer with custom attributes, entity hierarchy (parentIdMcEntity), statusCd/typeCd convention

Package 3: Membership and Contract Management

Manages the full contract lifecycle from template definition to active subscription. Predefined contract templates (CsrContractPreDefined) define pricing, duration, renewal rules, and visibility. Contracts link members to organizations with payment details, recurring billing configuration, and notification preferences. Supports one-time fees, recurring subscriptions, family/group plans, and promotional pricing.

Key entities: CsrContract, CsrContractPreDefined, CsrRecurringDetails, CsrPaymentDetails, CsrNotificationDetails, PpProductSnapshot Reuse from Cash360: CsrContract lifecycle, CsrContractPreDefined template pattern, recurring billing configuration, product snapshots for price immutability

Package 4: Financial Operations

All monetary operations: transaction recording, billing cycle execution, SEPA direct debit file generation, invoice creation, payment reconciliation, and bookkeeping export. Delegates heavy payment processing to Cash360 via REST API. Local transaction records provide the member-facing view (transaction history, open debt calculation, payment status).

Key entities: PmTransactionSimple, PmAdjustment, McBillingStatement, EbSepaExport Reuse from Cash360: pm-payment-simple module for transaction management, SEPA file generation, EBICS banking communication, billing statement pipeline

Package 5: Resource Management

Standalone-capable module for managing physical resources: rooms, sports fields, outdoor areas, equipment, and personnel. Includes a calendar/booking engine with single and recurring reservations, conflict detection, overbooking rules, and approval workflows. Inventory management tracks equipment issue/return via QR/NFC, monitors stock levels, and handles defect reporting. Hardware integration layer supports turnstiles, NFC readers, IoT sensors, and building automation protocols (KNX, BACnet, MQTT).

Key entities: Resource, ResourceBooking, ResourceCalendar, Equipment, EquipmentIssue, AccessPoint, AccessLog Design note: This module is architecturally independent -- it exposes its own REST API and can be deployed, marketed, and sold separately to non-Membership customers. The API contract is stable and versioned independently.

Package 6: Communication and Marketing

Manages all outbound communication: email templates (Thymeleaf), push notifications (FCM/APNs), in-app messaging, newsletter campaigns, and landing page generation. Supports personalization through template variables, audience segmentation, and delivery scheduling. Communication events are processed asynchronously via RabbitMQ.

Key entities: EmailTemplate, PushNotification, Newsletter, CommunicationLog, LandingPage Reuse from Cash360: Email template engine (Thymeleaf), PDF generation (Open HTML to PDF), McEmailAccount SMTP configuration

Package 7: Events and Courses

Event planning, course scheduling, and attendance tracking. Covers recurring classes (yoga at 10am every Tuesday), one-time events (summer tournament), and multi-day events (training camp). Trainer assignment, participant registration, waitlists, and check-in. Tournament bracket generation for competitive sports. Calendar integration supports iCal export and external calendar sync.

Key entities: Event, Course, CourseSchedule, Attendance, Trainer, TournamentBracket

Package 8: Platform Services

Cross-cutting infrastructure: multi-tenant isolation (all queries filtered by idMcEntity), data import/export (CSV with column mapping, three modes: import new, import+update, update existing), reporting and analytics (aggregation queries, PDF report generation), job scheduler (Quartz-based billing cycles, reminders, cleanup), and comprehensive audit logging (who changed what, when, with before/after snapshots).

Key entities: ImportJob, ExportJob, AuditLog, ScheduledTask, Report, McProcess Reuse from Cash360: McProcess state machine, data import framework (mc-data-import), Quartz scheduler configuration (mtcn-scheduler), audit logging patterns

Package 9: CRM and Sales

Lead-to-member conversion pipeline, deal tracking, and activity management. At the vendor level, this also manages the B2B sales pipeline for selling the platform to clubs and studios. Includes lead source tracking, configurable pipeline stages, activity logging (calls, emails, meetings, notes), trial-to-member conversion analytics, and sales forecasting.

Key entities: Lead, Deal, Activity Dependencies: Member and Organization (Package 2), Financial (Package 4) for deal value tracking

Package 10: Support and Ticketing

Professional support desk for handling member inquiries, technical issues, and operational requests. Supports ticket creation from multiple channels (email, in-app, web form, phone), configurable categories and priorities, SLA management with breach alerts, agent tools (canned responses, macros, collision detection), and a public knowledge base for member self-service.

Key entities: Ticket, TicketComment, KnowledgeBaseArticle Dependencies: Member and Organization (Package 2), Communication (Package 6) for notifications

Package 11: Accounting and DATEV

General ledger with chart of accounts (SKR03/SKR04 compatible), automated journal entry creation from billing events, cost center management, bank reconciliation, and DATEV export (CSV and XML formats). Provides P&L, balance overview, and cash flow reports for financial decision-making.

Key entities: AccountingEntry, CostCenter, ChartOfAccount Dependencies: Financial (Package 4) for transaction data, Platform Services (Package 8) for scheduled exports

Technology Stack Decisions

Backend: Java 25 on Spring Boot 4

Rationale: Proven in the Cash360 codebase with 6,662+ Java files and 150+ modules. Virtual threads (Project Loom) in Java 25 eliminate the need for reactive programming while delivering excellent concurrency. Spring Boot 4 provides the latest security, observability, and dependency management. The team already has deep expertise in this stack.

Key libraries carried forward from Cash360: - Hibernate 6.x with Querydsl 5.x for type-safe queries - Spring Security with JWT (auth0 java-jwt) - Flyway for database migrations - Lombok for boilerplate reduction - Jackson for JSON serialization - SpringDoc OpenAPI for API documentation

Frontend: Flutter (Dart)

Rationale: Single codebase for Android, iOS, web, and desktop. The Cash360 Flutter frontend (Phase 5) has proven the architecture with Riverpod state management, GoRouter navigation, Dio HTTP client, and Freezed immutable models. The MEMBERSHIP design system (IBM Plex Sans, #2CC5CE primary) is implemented as a Flutter theme.

Database: PostgreSQL 18

Rationale: Battle-tested in Cash360 with 204+ tables. JSONB support for custom attributes (member metadata, entity settings). Full-text search for basic queries. Row-level security can enforce multi-tenant isolation at the database layer. The existing schema patterns (statusCd, typeCd, idMcEntity FK, sequences with allocation size 50) are carried forward.

Cache: Redis 7

Rationale: Replaces Memcached from Cash360 (which lacks data structures, pub/sub, and persistence). Redis provides session storage, rate limiting (sliding window counters), real-time presence indicators (which members are checked in), pub/sub for live dashboard updates, and sorted sets for leaderboards. Redis Sentinel or Cluster for high availability.

Message Broker: RabbitMQ

Rationale: Already proven in Cash360. Used for asynchronous event processing: billing cycle triggers, notification dispatch, import job queuing, IoT event ingestion. RabbitMQ's exchange/routing model fits the event-driven patterns better than Kafka for this workload (low latency, moderate throughput, message acknowledgment). Kafka remains available for high-volume analytics streaming if needed later.

Search: Elasticsearch 8

Rationale: Member search across thousands of records with fuzzy matching, filters, and aggregations exceeds what PostgreSQL full-text search can deliver responsively. Also used for document search (contracts, invoices) and analytics dashboards (real-time aggregations).

Reuse Patterns from Cash360

The Membership platform inherits proven patterns from the Cash360 codebase rather than reinventing solutions for solved problems.

Multi-Tenant Entity Model

All domain entities carry an idMcEntity foreign key. Every query is automatically filtered by the current tenant context. The McEntityV3 hierarchy (parent-child relationships) directly supports franchise and umbrella organization structures.

McEntityV3 (Organization)
  ├── idParentMcEntity → parent org (franchise HQ, umbrella association)
  ├── McEntitySettings → branding, feature toggles, payment config
  ├── McBankAccountV3 → SEPA bank accounts (IBAN, BIC)
  └── children[] → sub-entities (branches, departments)

Consumer/Member Model

CsrConsumer is extended (not replaced) for the membership domain. Additional fields for sports-specific data (emergency contacts, health declarations, sport-specific attributes) are stored in JSONB custom attributes, avoiding schema changes for per-sport customization.

Generated Base Classes

The code generator pattern (*Generated suffix) is carried forward. Entity classes extend generated base classes that handle standard CRUD, field mapping, and boilerplate. Custom business logic goes into the entity class itself, not the generated base.

Status and Type Codes

The statusCd/typeCd string convention is reused for all domain entities. Status codes are defined as constants on the generated base class (e.g., STATUS_CD_ACTIVE, STATUS_CD_SUSPENDED, STATUS_CD_CANCELLED). This provides queryable, human-readable state without the rigidity of enum types.

SEPA and Banking Integration

Payment processing reuses the Cash360 pm-payment-simple module and SEPA export pipeline. Membership creates transactions and billing statements; Cash360 handles SEPA file generation, EBICS submission, and bank reconciliation. The integration boundary is clean: Membership calls Cash360 REST endpoints, never accesses banking tables directly.

Resource Module: Standalone Architecture

The Resource Management module (Package 5) is designed as a standalone-capable API that can be extracted, deployed independently, and offered to non-Membership customers (co-working spaces, event venues, equipment rental companies).

graph LR subgraph "Membership Platform" API[Membership API] RES_INT[Resource Module<br/>Internal Integration] end subgraph "Standalone Deployment" RES_API[Resource API<br/>Standalone] RES_DB[(Resource DB)] end subgraph "Third-Party Systems" EXT1[Co-working App] EXT2[Venue Booking Platform] end API --> RES_INT RES_API --> RES_DB EXT1 --> RES_API EXT2 --> RES_API

Standalone requirements: - Own database schema (can be same PostgreSQL instance or separate) - Own authentication (API keys + JWT, no dependency on Membership IAM) - Versioned REST API with OpenAPI spec - No import dependencies on Membership domain entities (uses interface contracts) - Configuration-driven: when deployed within Membership, integrates via Spring events; when standalone, operates independently

Deployment Topology

graph TB subgraph "CDN / Edge" CDN[CDN<br/>Static assets, Flutter web] end subgraph "Application Tier" LB[Load Balancer] API1[API Server 1] API2[API Server 2] W1[Worker 1] W2[Worker 2] end subgraph "Data Tier" PG[(PostgreSQL 18<br/>Primary + Replica)] RD[(Redis Cluster)] ES[(Elasticsearch Cluster)] RMQ[RabbitMQ Cluster] S3[(Object Storage)] end CDN --> LB LB --> API1 LB --> API2 API1 --> PG API2 --> PG API1 --> RD API2 --> RD API1 --> ES API1 --> RMQ W1 --> RMQ W2 --> RMQ W1 --> PG W1 --> S3 style CDN fill:#e1f5fe style PG fill:#e8f5e9 style RD fill:#fff3e0 style ES fill:#f3e5f5

Both on-premises and cloud deployment are supported. On-premises installations use Docker Compose (single server) or Kubernetes (multi-node). Cloud deployments use managed services (RDS for PostgreSQL, ElastiCache for Redis, managed Elasticsearch, SQS/SNS or managed RabbitMQ).