ADR-021: Customer Intelligence Bounded Context β
Date: 2026-04-17 Status: Proposed [future β Phase 3]Deciders: Julian BrΓΌning
Context β
The Busflow platform lists "360Β° Customer Profile" as a core differentiator (see PRODUCT_differentiators-10-percent.md Β§1). The current architecture stores passenger identity data on backoffice.passenger_profiles (8 columns: name, contact info, dietary needs) and links it to Commerce bookings and Communications contacts via soft FKs.
This baseline structure captures who the customer is but provides no mechanism to capture what they do, what they prefer, or what they are likely to want next. The planned feature surface requires:
- Intelligent per-user recommendations (personalized tour suggestions)
- Collaborative recommendations ("passengers who booked Nordsee also booked Ostsee")
- Behavioral aggregation (booking frequency, lifetime value, channel preference, no-show rate)
- Proactive anticipation (pre-fill checkout, seasonal rebooking prompts)
- Seamless cross-media experience (unified identity across booking widget, WhatsApp, email, phone)
None of these capabilities belong cleanly in any existing bounded context:
| Context | Why It Doesn't Fit |
|---|---|
| Backoffice | Owns PassengerProfile as master data, but behavioral analytics and ML models are outside its cohesion boundary. |
| Commerce | Owns bookings and payments, but recommendations span beyond purchases (boarding behavior, communication patterns, trip feedback). |
| Communications | Owns messaging delivery, but deciding what to say (personalized content) is a separate concern from how to deliver it. |
| Operations | Owns fleet execution. Customer analytics falls outside its responsibility. |
Decision β
We introduce a fifth bounded context β Customer Intelligence β as a [future β Phase 3] planned addition to the bounded context map. It operates as an event-sourced analytics domain that consumes activity signals from all four operational contexts and produces enrichment, segmentation, and recommendation outputs.
Subdomain Classification β
Core Subdomain. The 360Β° customer profile and intelligent recommendations are key competitive differentiators. A bus-tourism-specific CDP cannot be purchased off the shelf, and it directly drives customer retention and operator revenue.
Scope β
The Customer Intelligence context owns:
CustomerActivityLogβ event-sourced ledger of all customer touchpointsBehaviorAggregateβ materialized per-customer metrics (lifetime value, booking frequency, preferred seat, preferred boarding point, no-show rate)CustomerSegmentβ cohort definitions for targeted marketing (e.g., "frequent Nordsee travelers", "high-value one-time bookers")EngagementScoreβ computed customer health (NPS, satisfaction, churn risk)RecommendationModelβ ML pipeline outputs for per-user and collaborative suggestionsChannelPreferenceβ learned preferred communication channel per customer
The Customer Intelligence context does not own:
PassengerProfileβ stays in Backoffice (identity + operator-managed preferences)Contactβ stays in Communications (messaging identity + delivery)Booking/Passengerβ stays in Commerce (transactional records)
Event Consumption β
The context operates as a downstream consumer of domain events from all four operational contexts:
| Source Context | Events Consumed | Data Extracted |
|---|---|---|
| Commerce | BookingConfirmed, BookingCancelled, BookingNoShow, CheckoutAbandoned, AncillaryPurchased, PaymentCompleted | Booking frequency, revenue, cancellation patterns, upsell behavior |
| Operations | BoardingEventCreated, OnboardSaleRecorded, ServiceLegCompleted | Boarding behavior, onboard purchases, trip completion |
| Communications | MessageDelivered, MessageRead, ConversationResolved | Channel preference, response rates, engagement patterns |
| Backoffice | PassengerProfileUpdated | Identity changes, dietary preference updates |
Enrichment Outputs β
The context produces enrichment signals consumed by other contexts:
| Target Context | Output | Purpose |
|---|---|---|
| Commerce | PersonalizedOfferGenerated | Tour recommendations for booking widget personalization |
| Communications | EngagementTrigger, ChannelPreferenceResolved | Optimal channel selection, re-engagement timing |
| Backoffice | ProfileEnrichmentAvailable | Aggregated metrics surfaced on the CRM screen and CTI pop-up |
Relationship to PassengerProfile β
PassengerProfile remains the identity anchor in Backoffice. Customer Intelligence reads it (via PassengerProfileUpdated events) but never writes to it. Instead, CI exposes a CustomerInsight read model that the Workspace UI consumes alongside the PassengerProfile β giving dispatchers the full 360Β° view without coupling Backoffice to analytics logic.
βββββββββββββββββββββββββββββββββββββββββββββββ
β Workspace UI (CRM Screen) β
β β
β ββββββββββββββββ βββββββββββββββββββββ β
β β Passenger β β Customer Insight β β
β β Profile β β Read Model β β
β β (Backoffice) β β (CI Context) β β
β β β β β β
β β Name, email, β β Lifetime value, β β
β β phone, DOB, β β booking count, β β
β β dietary needs β β preferred seat, β β
β β β β NPS score, β β
β β β β recommendations, β β
β β β β churn risk β β
β ββββββββββββββββ βββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββConsequences β
Positive β
- Clean separation of concerns: Operational contexts remain focused on their core workflows. Analytics logic does not bloat Backoffice or Commerce.
- Event-sourced by design: The
CustomerActivityLogcan retroactively replay historical events once the context starts, filling the behavioral history from day one data. - ML-ready architecture: Dedicated context provides a natural home for recommendation models, feature stores, and training pipelines without polluting operational schemas.
- GDPR-compliant by design: All customer analytics data concentrates in one context, simplifying erasure cascades and consent management.
Negative β
- Not implemented in Phase 1 or Phase 2. The operational contexts must emit the consumed events regardless β this creates a "publish now, consume later" pattern. All events listed above should already exist in the event catalog for operational purposes; CI simply adds a new consumer.
- Cross-context read model complexity. The CustomerInsight read model requires Hasura Remote Relationships or a dedicated API endpoint to join with Backoffice data in the Workspace UI.
Risks β
- Premature optimization. Building the full CI context before understanding real usage patterns could lead to wrong aggregation choices. Mitigation: defer to Phase 3, let Phases 1β2 generate real data.
- Event schema coupling. CI depends on a stable event schema from all four operational contexts. Breaking changes to event payloads affect CI consumers. Mitigation: event contracts are already versioned (see event-catalog.md).
Preparation (Phase 1β2) β
While the full CI context is deferred, the following actions during Phases 1β2 lay the groundwork:
- Ensure all events listed above are emitted by their source contexts (most already exist in the event catalog).
- Add
marketing_consentandlocaletopassenger_profilesβ these are identity-level fields that belong on the profile regardless of CI. - Document the Contact β PassengerProfile merge strategy β ensure Communications auto-links new Contacts to existing profiles by email/phone match.
- Keep PassengerProfile lean β resist the temptation to add aggregated fields (lifetime_value, booking_count) directly to the profile. These belong in CI.