01
Behavioral
Strategy
Define a family of algorithms, encapsulate each one, and make them interchangeable at runtime.
+ score(profile): RiskScore
byld-advisory → RiskScoringStrategy
byld-mia → PersonaStrategy
Swap risk models per tier without changing use case logic
Strategy — Full Hierarchy
RiskScoringStrategy «interface»
└─ ConservativeScorer
└─ BalancedScorer
└─ AggressiveScorer
PersonaStrategy «interface»
└─ WealthPersona (warm, advisory)
└─ MarketsPersona (sharp, data)
FeeCalculationStrategy «interface»
└─ FlatFeeCalculation
└─ AumBasedFeeCalculation
└─ TieredFeeCalculation
02
Structural
Repository
Mediate between domain and data mapping layers using a collection-like interface for domain objects.
+ findById(id): Portfolio?
+ save(p: Portfolio)
+ findByClient(c): List
- entityManager: EM
+ findById() + save()
byld-portfolio → PortfolioRepository
byld-identity → ClientRepository
Domain stays pure; JPA is a swappable plugin
Repository — Full Hierarchy
PortfolioRepository (domain.port)
└─ JpaPortfolioRepository (infra.persistence)
└─ InMemoryPortfolioRepo (test)
ClientRepository (domain.port)
└─ JpaClientRepository
GoalRepository (domain.port)
└─ JpaGoalRepository
ChatSessionRepository (domain.port)
└─ RedisSessionRepository
└─ JpaSessionRepository
03
Creational
Factory
Encapsulate complex object creation logic, ensuring aggregates are always created in a valid state.
+ createForClient(cmd)
+ reconstitute(snapshot)
byld-portfolio → PortfolioFactory
byld-identity → ClientFactory
Aggregates born valid; creation rules in one place
Factory — Full Hierarchy
PortfolioFactory
└─ creates Portfolio aggregate
└─ with Holdings[], Money totalValue
└─ emits PortfolioCreated event
ClientFactory
└─ creates Client aggregate
└─ with RiskProfile, KycStatus
GoalFactory
└─ creates Goal (retirement/education/...)
└─ calculates required SIP via FV formula
04
Behavioral
Observer
Domain events notify interested parties without the aggregate knowing who listens.
+ addHolding()
→ raises HoldingAdded
All services → EventPublisherPort
byld-notification → EventConsumer
Loose coupling via domain events over Kafka
Observer — Domain Events
Portfolio raises:
HoldingAdded, TransactionRecorded
PortfolioRebalanced
Client raises:
ClientOnboarded, KycCompleted
TierUpgraded
EventPublisherPort
└─ KafkaEventPublisher
└─ InMemoryEventBus (test)
05
Architectural
Saga
Coordinate distributed transactions across microservices with compensation on failure.
+ start(cmd)
+ onPaymentConfirmed()
+ compensate()
byld-distribution → MFOrderSaga
byld-payments → PaymentSaga
No 2PC; eventual consistency with compensating txns
Saga — Orchestrated Steps
MFOrderSaga
Step 1: CreateOrder in byld-distribution
Step 2: DebitPayment in byld-payments
Step 3: SubmitToBSE via MFU Central
Compensate: RefundPayment → CancelOrder
KycOnboardingSaga
Step 1: VerifyAadhaar (UIDAI)
Step 2: VerifyPAN (NSDL)
Step 3: CreateCKYC (KRA)
Compensate: RollbackKRA → NotifyClient
06
Architectural
Anti-Corruption Layer
Translate between external system models and our domain model, preventing foreign concepts from leaking in.
+ translate(ext)
+ toFundData()
byld-portfolio → MorningstarACL
byld-identity → AadhaarACL, NSDLACL
External API changes never ripple into domain
ACL — Translation Boundaries
MorningstarACL
Morningstar FundDTO → FundData VO
Morningstar NAVDTO → NAV VO
AadhaarACL
UIDAI eKYC XML → AadhaarIdentity VO
FinvuACL
AA FI Data JSON → AccountAggregate VO
BSE/MFU ACL
MFU OrderResponse → OrderConfirmation
07
Structural
Decorator
Attach additional responsibilities dynamically without altering the original class.
byld-mia → CachingLlmDecorator
byld-mia → AuditingLlmDecorator
Layer caching + SEBI audit without touching core LLM adapter
Decorator — Layered Wrappers
LlmPort
└─ ClaudeApiAdapter (base)
└─ CachingLlmDecorator wraps above
└─ AuditingLlmDecorator wraps above
└─ RateLimitingDecorator wraps above
Call chain:
RateLimit → Audit → Cache → Claude API
08
Behavioral
Chain of Responsibility
Pass requests along a chain of handlers; each handler decides to process or pass along.
+ handle(req): Response
+ setNext(h): Handler
byld-gateway → API filter chain
byld-mia → MessageValidationChain
Security, rate-limiting, compliance checks without if-else soup
Chain of Responsibility — Pipeline
Gateway Filter Chain:
JwtAuthHandler
↓
RateLimitHandler (tier-based)
↓
ComplianceHandler (SEBI check)
↓
AuditLogHandler
↓
RouteToService
09
Architectural
CQRS
Separate read and write models to optimize each independently for scale and complexity.
+ addHolding()
+ recordTxn()
+ getSummary()
+ getXIRR()
byld-portfolio → write/read split
byld-markets → quote projections
Reads scale independently; sub-100ms dashboard loads
CQRS — Separate Models
WRITE SIDE (Commands):
AddHoldingCommand → Aggregate
RecordTransactionCmd → Aggregate
Store: Aurora PostgreSQL (normalized)
READ SIDE (Queries):
GetPortfolioSummaryQuery
GetXIRRQuery
Store: Redis (denormalized projections)
Sync: Kafka event → projection handler
10
Creational
Builder
Construct complex objects step by step, separating construction from representation.
+ withSummary(s)
+ withRiskAnalysis(r)
+ withRecommendations(r)
+ build(): Report
- sections: List<Section>
- generatedAt: Instant
byld-advisory → AdvisoryReportBuilder
byld-mia → PromptBuilder
Complex reports built fluently; immutable once built
Builder — Fluent Construction
AdvisoryReportBuilder
.withClientProfile(profile)
.withRiskAnalysis(analysis)
.withAssetAllocation(alloc)
.withRecommendations(recs)
.withDisclaimer(sebiDisclaimer)
.build() → AdvisoryReport (immutable)
PromptBuilder
.withSystemPrompt(persona)
.withContext(portfolio, goals)
.withHistory(messages[])
.build() → MiaPrompt
11
Behavioral
Template Method
Define the skeleton of an algorithm in a base class, deferring specific steps to subclasses.
+ verify() {template}
# extractData()
# validateRules()
# submitToKRA()
# extractData()
# validateRules()
# extractData()
# validateRules()
byld-identity → AbstractKycVerifier
byld-advisory → AbstractRiskProfiler
KYC flow is standard; only extraction details differ per doc type
Template Method — KYC Flow
AbstractKycVerifier
1. extractData() {abstract}
2. validateRules() {abstract}
3. checkAML() {final}
4. submitToKRA() {abstract}
5. notifyClient() {final}
Implementations:
AadhaarKycVerifier (UIDAI eKYC)
PanKycVerifier (NSDL/UTI)
DigilockerKycVerifier
12
Architectural
Ports & Adapters
The application talks to the outside world through ports; adapters plug in to implement them.
All services → Hexagonal Architecture
Domain has zero framework imports
The foundational pattern; all others compose within it
Ports & Adapters — Hexagonal
DRIVING PORTS (left side):
SendMessagePort ← REST
GetPortfolioPort ← REST
OnboardClientPort ← REST
DRIVEN PORTS (right side):
LlmPort → Claude API
PortfolioRepository → JPA
EventPublisherPort → Kafka
VectorStorePort → Pinecone