ADR-014: Backend Service Consolidation β EMS + CUMS Primary; Speaker & Attendee Services Dormant
Status
Context
BATbern was originally scaffolded as five domain microservices (event-management, company-user-management, speaker-coordination, partner-coordination, attendee-experience). Reality has diverged from that scaffold:
speaker-coordination-serviceis a hollow stub (~4 files, no controllers). All speaker logic was migrated into event-management-service (EMS) during Epic 11 (Unified Speaker Workflow, ADR-009). The speaker workflow, pool, invitations, and portal endpoints are served by EMS controllers today.attendee-experience-serviceis a 1-file stub. The attendee-facing endpoints that exist (dashboard, feature flags, community topics) are served by EMS / partner-coordination.- EMS and CUMS (company-user-management) carry essentially all backend logic; EMS is
large enough that it is being internally modularized rather than split further
(see
docs/plans/ems-modularization-extension-points.md, whose explicit anti-goal is βdo not split into more microservicesβ). - The corresponding OpenAPI specs
docs/api/speakers-api.openapi.ymlandattendees-api.openapi.ymlhave their code-generation tasks commented out in the respectivebuild.gradlefiles, so they are neither generated nor enforced.
During the API-consolidation work (ADR-013) the question arose whether to re-enable generation for the speaker/attendee specs. Doing so would emit API interfaces that no controller implements and would require a contract-ownership decision (the real implementations live in EMS). The product owner confirmed the strategic direction instead.
Decision
The backend consolidates around two primary services β EMS and CUMS β plus the genuinely separate partner-coordination-service. We do not add microservices, and we do not revive the dormant ones.
speaker-coordination-serviceandattendee-experience-serviceare DORMANT. They are not developed against, and their logic stays in EMS (speaker) / EMS + partner (attendee).- Their OpenAPI specs are NOT generator-wired and are NOT maintained as live contracts.
speakers-api.openapi.yml/attendees-api.openapi.ymlare historical/reference only. Do not re-enable theiropenApiGeneratetasks. They are explicitly exempt from the ADR-013 conformance rules (shared-schema$ref, etc.) until/unless a service is revived. - New speaker/attendee API surface is added to EMS (or partner-coordination where it already owns the data), following the existing controller patterns.
- EMS is modularized internally, not split (ADR-006 generation patterns + the ems-modularization plan). Partner-coordination and CUMS remain independent services.
- Reviving a dormant service is a deliberate, separately-decided effort (a new ADR), not a side effect of touching its stale spec.
Consequences
Positive
- No effort wasted generating/maintaining contracts for services that implement nothing.
- Clear answer to βwhere does speaker/attendee code go?β β EMS (or partner), not the stubs.
- Fewer deployables to operate; aligns with the internal-modularization direction.
Costs / risks
- The stale
speakers-api/attendees-apispecs can mislead a reader into thinking those services are live. Mitigation: this ADR + a note in those specs; they are reference-only. - EMS keeps growing; the modularization plan is the counter-measure (vertical domain modules,
including the events-api decomposition in
api-consolidation-plan.mdPhase 6).
Related
- ADR-009 (Unified Speaker Workflow β moved speaker logic into EMS, Epic 11)
- ADR-006 (OpenAPI contract-first β generation wiring)
- ADR-013 (REST API CRUD conventions β exempts dormant/un-wired specs)
docs/plans/ems-modularization-extension-points.md(internal modularization; anti-goal: no new microservices)docs/plans/api-consolidation-plan.md(Phase 2 closed as βwonβt doβ per this ADR)