┌─────────────────┐
│ TYPR DOMAIN │
│ │
│ Person │
│ Address │
│ Order │
│ ... │
└────────┬────────┘
│
┌─────────────────┼─────────────────┐
│ │ │
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Database │ │ APIs │ │ Events │
│ │ │ │ │ │
│ PersonRow│ │PersonDto │ │PersonAvro│
│.toDomain │ │.toDomain │ │.toDomain │
│.fromDom │ │.fromDom │ │.fromDom │
└──────────┘ └──────────┘ └──────────┘
Domain is the hub. Boundaries are spokes.
- Domain type DSL (Bridge core)
- Name alignment engine
- Matching rules engine
- toDomain/fromDomain generation
- Field coverage checks
- Type compatibility checks
- Missing value analysis
- Nested type resolution
- Domain-centric repositories (return domain, not rows)
- Domain-centric services
- CRUD endpoints
- Event publishers/consumers
- gRPC services
- PostgreSQL
- MariaDB/MySQL
- Oracle
- SQL Server
- DuckDB
- DB2
- Schema parsing
- Type extraction
- Field alignment
- Mapper generation
- TUI browsing
- Schema parsing (AvroParser)
- Type extraction (AvroTypes)
- TUI source loading (SourceLoader)
- TUI field extraction (ProjectionFieldExtractor)
- TUI schema browser (AvroBrowser)
- Type narrowing/compatibility (TypeNarrower)
- Mapper generation (FileBridgeProjectionMapper with ExternalRecord)
- Validation (FlowValidator with SourceEntityType.Record)
- Protobuf parsing (existing in typr/grpc/)
- TUI source loading
- TUI field extraction
- TUI schema browser (ProtoBrowser)
- Type narrowing/compatibility
- Mapper generation
- Validation
- Missing value analysis (detect fields that need defaults)
- Nested type resolution (domain types referencing other domain types)
- External contract ownership model (see below)
Key Insight: Some contracts are external (we consume but can't change), some are ours (we define).
| Direction | Ownership | Generated Code | Validation |
|---|---|---|---|
In |
External | toDomain() only |
Warning if missing |
Out |
Ours | fromDomain() only |
Error if missing |
InOut |
Ours | Both | Error if missing |
Automatic Direction Detection:
APIs are functions with inputs and outputs - we can detect direction automatically:
POST /customers
requestBody: CustomerCreate → In (we receive)
response: CustomerResponse → Out (we send)
External API call (reversed):
request: we send → Out from domain
response: we receive → In to domain
| Source | Detection Method |
|---|---|
| OpenAPI | Schema position in request vs response |
| gRPC | Message position in service method |
| Avro | Producer vs consumer role |
| Database | Always InOut |
Tasks:
- Auto-detect In/Out from OpenAPI schema positions
- Auto-detect In/Out from gRPC service definitions
- Add
ownership: external | internalflag to SourceDeclaration - Suppress
toSource()generation for external contracts - Different validation severity based on ownership
- Contract versioning for external schemas
- Adapter generation for external → internal mapping
Use Cases:
- Partner API webhooks (In, external) - adapt to their schema
- Your public API (Out, internal) - you define the contract
- Calling external API (Out=request, In=response)
- Third-party event streams (In, external) - consume but can't change
- Your database (InOut, internal) - full control
- Domain-centric repositories (return domain types, not rows)
- Domain-centric services (orchestrate across boundaries)
- CRUD endpoints (REST from domain types)
- Event publishers/consumers (Kafka from domain types)
- gRPC services (from domain types)
- Added SourceStatus.ReadyProto to TuiState
- Implemented loadProtoSource() in SourceLoader
- Added extractFromProto() and formatProtoType() to ProjectionFieldExtractor
- Added ExtractedSourceType.Message and SourceEntityType.Message
- Updated getAvailableEntities() for Proto sources
- Updated allReadySources/allReady extension methods
- Created ProtoBrowser.scala screen with full navigation
- Added ProtoMessageInfo, ProtoFieldInfo, ProtoBrowserState types
- Added AppScreen.ProtoBrowser and Location.ProtoBrowser
- Extended TypeNarrower with normalizeProtoType(), mapProtoTypeToCanonical(), isProtoTypeCompatible()
- Created BridgeProtoAdapter.scala for Proto→ExternalRecord conversion
- Extended normalizeDbType() to handle Proto scalar and well-known types
- FlowValidator now works with Proto sources via generic SourceEntity abstraction
- Added SpecSourceType.Avro and SourceStatus.ReadyAvro
- Added Avro source loading to SourceLoader
- Added Avro field extraction to ProjectionFieldExtractor
- Created AvroBrowser TUI screen
- Extended TypeNarrower for Avro type compatibility
- Added ExternalRecord abstraction to FileBridgeProjectionMapper
- Created BridgeAvroAdapter for Avro→ExternalRecord conversion
- Extended FlowValidator with proper source type tracking