Overview
The Domain layer represents the core business logic and entities of PriceSignal. It contains domain models, value objects, and domain events following Domain-Driven Design (DDD) principles. This layer has no dependencies on other layers and defines the business rules.Base Entities
EventEntity
The foundation for domain events, allowing entities to raise and manage events.BaseEntity
Provides identity tracking for all domain entities.BaseAuditableEntity
Extends BaseEntity with audit timestamps for tracking creation, modification, and soft deletion.Core Domain Models
Exchange
Represents a cryptocurrency exchange (e.g., Binance, Coinbase).Instrument
Represents a tradable cryptocurrency pair (e.g., BTC/USDT).InstrumentPrice
Captures real-time price data for an instrument.User
Represents a PriceSignal user with their subscriptions and notification preferences.Price Rules Aggregate
PriceRule
The core aggregate root for user-defined price alerts and conditions.- Supports multiple conditions that must all be met
- Tracks trigger history with snapshots
- Raises domain events when triggered
- Supports cooldown periods to prevent spam
PriceCondition
Defines specific conditions for price rule evaluation.- Price: Trigger when price crosses a threshold
- PricePercentage: Trigger on percentage change
- PriceCrossover: Trigger when price crosses above/below a level
- TechnicalIndicator: Trigger based on RSI, SMA, EMA
PriceRuleTriggerLog
Immutable audit log of price rule activations.Domain Events
BaseEvent
Base class for all domain events, integrated with MediatR.PriceRuleTriggeredEvent
Raised when a price rule’s conditions are met.- Notification delivery to users
- Trigger log creation
- Analytics tracking
Design Patterns
Aggregate Pattern
PriceRule acts as an aggregate root, ensuring consistency:- Controls access to PriceCondition entities
- Manages its own state transitions
- Raises domain events at aggregate boundaries
Rich Domain Model
Entities contain business logic, not just data:PriceRule.Trigger()encapsulates triggering logicInstrument.SetExchange()maintains invariants
Event Sourcing (Partial)
While not full event sourcing, the system:- Captures all state changes as events
- Maintains immutable trigger logs
- Uses snapshots for historical queries
Validation Rules
- Instruments must have valid base and quote assets
- Price rules require at least one condition
- Soft deletes prevent data loss (DeletedAt pattern)
- EntityId (GUID) used for external references, Id (long) for internal performance
Next Steps
- Learn how the Application Layer orchestrates these domain models
- Explore Infrastructure Layer for persistence with EF Core
- See GraphQL Layer for API exposure