Odyssey-Api Architecture Diagrams
#1. High-Level System Architecture
#2. Module Dependency Graph
#3. EDS Vehicle Import Flow (Cron - Every 30 Minutes)
#4. GraphQL Search Query Flow
#5. Azure Service Bus Message Flows
#6. REST API & Mutation Flows (routes module)
#7. Vehicle Image & 360 Spin Flow
#8. Cron Scheduled Jobs Overview
| Job | Schedule | Method | Purpose |
|---|---|---|---|
| EDS Vehicle Import | 0 0,30 * * * * | runVehicleReaderImport() | Import inventory from Azure Blob, apply lease expiries |
| Postal Code Sync | 0 45 0,6,12,18 * * * | runRegionSync() | Sync OEM region mappings |
| Stale Cleanup | 0 15 * * * * | runStaleRecordCleanup() | Delete DELETED vehicles |
| Temp Cleanup | 0 10 8 * * * | runStaleTempCollectionCleanup() | Drop temp collections > 28 days |
| Spin Metric | 30 */5 * * * * | updateSpinCountMetric() | Update 360 spin count metric |
#9. CI/CD Pipeline Flow
#10. MongoDB Collection Relationships
#11. Data Flow: Vehicle Lifecycle
#12. Spring Profile Configuration
Part B — The Wider Driveway Service Ecosystem
Odyssey is one service in a larger platform. This section answers: what does every backend service do, what is it responsible for, how do they communicate, and how would you add a new one? Informative only — no infrastructure identifiers.
#13. The Whole Platform at a Glance
#14. What Each Service Is Responsible For
| Service | One-line responsibility | Stack | Talks to |
|---|---|---|---|
| Odyssey API | Vehicle inventory + Atlas search + availability | Kotlin / Spring, MongoDB, DGS GraphQL | reads Admin; publishes inventory deltas |
| Cart Service | Shopping cart, order lifecycle, the order tracker | Kotlin / Spring, MongoDB, REST + GraphQL | reads Incentives/Taxes/Products/Valuation/Admin; receives Salesforce milestones |
| Offer API | Vehicle offers + pricing strategy + markups | Kotlin, MongoDB | called by Cart, Odyssey |
| Incentives API | OEM rebates + leasing programs | Kotlin / Spring, Postgres | consumes inventory deltas; publishes leasing/incentives |
| Taxes & Fees API | Tax, fee, and shipping estimation | Kotlin / Spring | called by Cart, Prequalification, Backpack |
| Products API | Finance & Insurance (F&I) product catalog + rates | Kotlin / Spring, MongoDB | consumes inventory deltas; called by Cart |
| Prequalification API | Loan prequalification applications | Kotlin / Spring, MongoDB | reads Admin/Vehicle/Incentives/Taxes; publishes finance intents |
| Valuation API | Trade-in valuation + vehicle detail lookups | Kotlin / Spring, Postgres | called by Cart, Backpack, Prequalification |
| Vehicle Service | Vehicle specification data (not inventory) | Kotlin / Spring, Postgres | called by Backpack, Prequalification |
| Backpack | Sell/trade-in flow: appraisals + inspections | Kotlin / Spring, MongoDB | reads Vehicle/Valuation/Admin |
| Admin API | Dealership + zone + config hub | Kotlin / Spring | read by Odyssey, Cart, Prequalification, Backpack |
| Account Center API | User accounts, saved searches, favorites | Kotlin / Spring, Postgres + Auth0 | identity provider integration |
| Salesforce Integration API | Subscribes to Salesforce events, forwards to Cart | Kotlin / Spring (coroutines), MongoDB | Salesforce Pub/Sub in, Cart REST out |
| Ecommerce Intent Service | Reliable intent submission into Salesforce | Kotlin / Spring, MongoDB | consumes intents topic, calls Salesforce |
| Salesforce (FreewayCRM) | System of record for the deal | Apex + Flows | publishes order events; receives intents |
#15. How They Communicate
| Mechanism | When it's used | Example |
|---|---|---|
| REST | a service needs data right now | Cart asks Taxes & Fees for an estimate |
| GraphQL | a client needs a rich, selectable graph | Web app reads the cart + order details |
| Service Bus topics | one event, many independent consumers | Odyssey publishes an inventory delta; Incentives and Products both react |
| Salesforce Pub/Sub | order milestones leave Salesforce | a Case status change becomes an order event |
| Intents topic | shopping/finance interest enters Salesforce | a prequalification becomes a CRM lead |
| Data pipeline / cron | bulk external data import | nightly vehicle files become catalog rows |
#16. The Two Salesforce Directions
#17. How To Add a New Service (checklist)
Rules of thumb when introducing a service:
- One domain, one database. If it doesn't own new data, extend an existing service instead of creating one.
- Never duplicate config. Dealerships, zones, and regional rules come from Admin API — read them, don't copy them.
- Prefer async for cross-service reactions. If service X must react when Y changes, publish/consume a Service Bus topic rather than a synchronous call chain.
- Salesforce is integrated, not called inline. Consume milestones through the integration bridge; submit intents to the intents topic. Never block a customer request on a direct Salesforce call.
- Be idempotent + replayable. Any event consumer should de-duplicate and bookmark its position so restarts never lose or double-count.
- Ship the operational basics. Each service owns its own database, its own import/cron if needed, health checks, and dashboards.
#18. Responsibility Boundaries (who must NOT do what)
| Concern | Owner | Everyone else |
|---|---|---|
| Vehicle catalog & search | Odyssey API | read via Odyssey, never store their own copy |
| Dealership / zone config | Admin API | read-only; no writes |
| Order lifecycle & tracker | Cart Service | send milestones via the bridge; don't write orders directly |
| The deal record | Salesforce | integrate through events/intents; don't mutate Cases ad-hoc |
| Customer identity | Account Center + Auth0 | trust the validated token; don't re-implement auth |
| Pricing / incentives / taxes | their respective services | Cart composes them; doesn't recompute them |