Bounded Context: Shared Kernel (SK)
Responsibility: Hosts the small set of value types and enums that are co-owned by all five bounded contexts (Rider, Driver, Ride, Geolocation, Payment). Keeping these here — rather than duplicating them inside each context — makes their unit semantics, constraints, and invariants the single source of truth across the system.
Context Map
| Relation | Other Bounded Context | Position | Pattern | Description |
|---|---|---|---|---|
| Shared ↔ Rider, Driver, Ride, GEO, Payment | every other context | symmetric | Shared Kernel (SK) | All five contexts depend on Amount, Currency, Distance, Duration, and the Currencies enum. They are co-owned: no context modifies them unilaterally; any change requires coordinated agreement across the consumers. The kernel is intentionally small — only concepts that genuinely cut across contexts live here. |
The Shared Kernel pattern fits this set of types because:
- Money flows across contexts: a fare is computed in Payment, embedded in
RideRequestedfrom Ride, and pre-authorized back in Payment. Translating between bespoke per-context money types at every boundary would be needless ceremony. - Distance and Duration are physical quantities, not domain abstractions; their meaning (“meters”, “seconds”) is the same in every context that handles them. Defining them once removes the risk of a
decimalfield in one context being kilometers while another is meters.
Enums
Currencies
The closed set of ISO 4217 alphabetic currency codes (active list — ~178 entries). Lowercase to fit the DSL’s enum-value naming convention; the canonical ISO form is uppercase.
- Sample values:
usd,eur,gbp,jpy,chf,cny,inr,brl, … through tozwg. - Includes funds and precious-metal codes (
xau,xag,xpt,xpd,xdr,xof,xaf, …) per ISO 4217. - Realizes: REQ-PAY-014 (fare denomination), REQ-PAY-NFR-001 (multi-market support).
- Used as the
codefield of theCurrencyvalue type. The split between enum (the closed set of valid codes) and value type (the descriptor that bundles a code with its reference data) follows a common DDD pattern: the enum names the identity, the value type carries the attributes.
Value Types
Currency
ISO 4217 currency reference — alphabetic code, numeric code, and default minor-unit precision. Modeled on java.util.Currency.
- Fields:
code:Currencies— the ISO 4217 alphabetic code (e.g.usd,eur,jpy).numericCode: Integer —min(0),max(999). The ISO 4217 three-digit numeric identifier (e.g. 840 for USD, 978 for EUR, 392 for JPY).defaultFractionDigits: Integer —min(-1),max(4). The minor-unit precision (most currencies use 2; JPY/KRW/VND use 0; KWD/BHD/JOD use 3; CLF/UYW use 4; XAU/XAG/XDR and similar funds/metals use -1 to mean “not applicable”).
- Invariants:
numericCodeInRange:numericCode >= 0 and numericCode <= 999— enforcement: reject.fractionDigitsInRange:defaultFractionDigits >= -1 and defaultFractionDigits <= 4— enforcement: reject.
- Realizes: REQ-PAY-014 (fare denomination), REQ-PAY-NFR-001 (multi-market support), REQ-PAY-080 (receipt rendering — minor-unit precision drives the displayed digits).
- Note: Display name and currency symbol are locale-dependent derivations, not stored on the value type — exactly mirroring
java.util.Currency.getSymbol(Locale)andgetDisplayName(Locale). They belong in the rendering layer, not in the domain model.
Amount
A non-negative monetary value with explicit currency.
- Fields:
value: Decimal —min(0)currency:Currency
- Invariants:
nonNegative:value >= 0— enforcement: reject. The constructor refuses to produce a negativeAmount, so downstream code never has to defensively check.
- Realizes: REQ-PAY-014, REQ-PAY-020, REQ-PAY-022 (fare amounts), REQ-RIDE-003 (committed fare), REQ-RIDE-061 (cancellation fees).
- Replaces the prior
Moneyvalue type that lived inside Payment. Currency is carried insideAmountitself as aCurrencyvalue type, so consumers no longer pass(decimal, currency-code)pairs by convention — and they get the reference data (numeric code, fraction digits) for free wherever anAmountis in scope.
Distance
Distance expressed in meters.
- Fields:
meters: Decimal —min(0)
- Invariants:
nonNegative:meters >= 0— enforcement: reject.
- Realizes: REQ-GEO-012 (route distance), REQ-RIDE-040 (driver-to-pickup proximity), REQ-RIDE-048 (final-fare actual distance).
- Used by
Route,FareEstimate,FinalFare,SignalDriverArrival, theProximityService.findNearbyDriversquery, and theRideCompletedevent.
Duration
Duration expressed in seconds.
- Fields:
seconds: Integer —min(0)
- Invariants:
nonNegative:seconds >= 0— enforcement: reject.
- Realizes: REQ-GEO-011 (ETA), REQ-GEO-012 (route duration), REQ-RIDE-048 (final-fare actual duration), REQ-DRV-045 (suspension length).
- Used by
Route,ETA,FareEstimate,FinalFare,RideCompleted,SuspendDriver,DriverSuspended, theInstantPayoutNetwork.getEstimatedArrivalinfrastructure call, and the document-storage TTL.
Concrete syntax (.domain DSL)
The full DSL definition that the narrative above is rendered from:
context Shared :: "Cross-cutting value types co-owned by all ride-now bounded contexts (Shared Kernel)" {
// -----------------------------------------------------------------
// Enums
// -----------------------------------------------------------------
// ISO 4217 alphabetic currency codes (active list). Lowercase to fit DSL
// enum-value conventions; the canonical ISO form is uppercase.
enum Currencies {
aed, afn, all, amd, ang, aoa, ars, aud, awg, azn,
bam, bbd, bdt, bgn, bhd, bif, bmd, bnd, bob, bov, brl, bsd, btn, bwp, byn, bzd,
cad, cdf, che, chf, chw, clf, clp, cny, cop, cou, crc, cup, cve, czk,
djf, dkk, dop, dzd,
egp, ern, etb, eur,
fjd, fkp,
gbp, gel, ghs, gip, gmd, gnf, gtq, gyd,
hkd, hnl, htg, huf,
idr, ils, inr, iqd, irr, isk,
jmd, jod, jpy,
kes, kgs, khr, kmf, kpw, krw, kwd, kyd, kzt,
lak, lbp, lkr, lrd, lsl, lyd,
mad, mdl, mga, mkd, mmk, mnt, mop, mru, mur, mvr, mwk, mxn, mxv, myr, mzn,
nad, ngn, nio, nok, npr, nzd,
omr,
pab, pen, pgk, php, pkr, pln, pyg,
qar,
ron, rsd, rub, rwf,
sar, sbd, scr, sdg, sek, sgd, shp, sle, sos, srd, ssp, stn, svc, syp, szl,
thb, tjs, tmt, tnd, top, try, ttd, twd, tzs,
uah, ugx, usd, usn, uyi, uyu, uyw, uzs,
ved, ves, vnd, vuv,
wst,
xaf, xag, xau, xba, xbb, xbc, xbd, xcd, xdr, xof, xpd, xpf, xpt, xsu, xts, xua, xxx,
yer,
zar, zmw, zwg
}
// -----------------------------------------------------------------
// Value types
// -----------------------------------------------------------------
value Currency :: "ISO 4217 currency reference — alphabetic code, numeric code, and default minor-unit precision (modeled on java.util.Currency)" {
fields {
code : Currencies
numericCode : int min(0) max(999)
defaultFractionDigits : int min(-1) max(4)
}
invariants {
numericCodeInRange :: "ISO 4217 numeric codes are 3-digit identifiers" enforcement reject {
numericCode >= 0 and numericCode <= 999
}
fractionDigitsInRange :: "Minor-unit precision is between 0 and 4 (or -1 for funds/metals with no minor unit)" enforcement reject {
defaultFractionDigits >= -1 and defaultFractionDigits <= 4
}
}
}
value Amount :: "A non-negative monetary value with explicit currency" {
fields {
value : decimal min(0)
currency : Currency
}
invariants {
nonNegative :: "Amount is never negative" enforcement reject { value >= 0 }
}
}
value Distance :: "Distance expressed in meters" {
fields { meters : decimal min(0) }
invariants {
nonNegative :: "Distance is never negative" enforcement reject { meters >= 0 }
}
}
value Duration :: "Duration expressed in seconds" {
fields { seconds : int min(0) }
invariants {
nonNegative :: "Duration is never negative" enforcement reject { seconds >= 0 }
}
}
}