DDD Map
A snapshot inventory of every bounded context under src/Domain/ on master, paired with two heuristic scores. Use the table to spot exemplary templates worth copying from and the domains that still drag a long legacy tail behind them.
What this map is (and isn't)
This is a snapshot estimate, not an authoritative scorecard. Both percentages are computed from the file tree, not from reading the code. A domain with 90% DDD adherence can still have ugly internals; a domain with 30% legacy can still be the most-loved part of the system. Treat the numbers as a starting point for a conversation, not a final verdict.
Legacy code % — proxy for "how much of this domain still lives outside the DDD layout". Computed by looking for files that name-match the domain in the legacy locations (app/Http/Controllers/, app/Http/Controllers/Cp/, app/Models/ — which in this repo actually live directly under app/ — and matching database/migrations/), then comparing that count to the file count inside src/Domain/{Name}/. Where exact counting was impractical (rate limits, ambiguous matches), the value is bucketed and marked with ≈.
DDD adherence % — heuristic based on the canonical subfolder layout. Each domain earns points for presence of Actions/ (+20), Services/ (+15), Contracts/ (+15), DataTransferObjects/ (+10), Models/ (+10), Providers/ (+10), plus up to +10 for any combination of Jobs/, Observers/, Notifications/, Mails/, Events/. A registered service provider in Providers/ is assumed when the folder exists. Note: this repo uses DataTransferObjects/ (not DataObjects/) — the points still apply.
The team should refine these numbers over time. When you do a refactor sweep on a domain, update its row.
The map
All 43 domains under src/Domain/ on master are listed. Sorted alphabetically.
- Domains
- 43
- Avg DDD
- 81%
- DDD ≥ 85
- 14
- Clean (legacy ≤ 10%)
- 27
- Heavy legacy (> 30%)
- 6
| Purpose | Notes | |||
|---|---|---|---|---|
Accounting The ledger: recorded transactions for orders, rentals, transfers, and adjustments. | The ledger: recorded transactions for orders, rentals, transfers, and adjustments. | ≈30-60% | 90% | Full layout including Observers/, Jobs/, Traits/. Legacy footprint mostly PDF controllers. Strong template candidate. |
Activity Activity-log entries describing what changed and who changed it. | Activity-log entries describing what changed and who changed it. | ≈30-60% | 50% | Outlier: no Actions/, no DataTransferObjects/, no Enums/. Legacy app/Activity.php model and Cp/ActivitiesController still outside the domain. Mid-refactor — do not use as a template. |
AddDataRequest Requests to add new reference data that route through an approval workflow. | Requests to add new reference data that route through an approval workflow. | <10% | 80% | New domain, born inside the DDD layout. Pairs with Approval. |
Ai AI-assisted features in the product. | AI-assisted features in the product. | <10% | 60% | Skeleton only — Actions/, Contracts/, Providers/, Services/. No Models/, DataTransferObjects/, or Enums/ yet. Expect rapid evolution. |
Approval Multi-step approval flow for request types that need supervisor sign-off. | Multi-step approval flow for request types that need supervisor sign-off. | <10% | 80% | New domain (May 2026 migrations). Full canonical layout. Used by AddDataRequest, ChangeDataRequest. |
Attachment Polymorphic file attachments — any entity can | Polymorphic file attachments — any entity can morphMany(Attachment::class, "attachable"). | ≈30-60% | 80% | Legacy AttachmentsTypesController, AdministrativeAttachmentsController, DocumentFor.php, DocumentType.php, DocumentTypesController still in app/. Heavily used cross-domain, so legacy callers are everywhere. |
AttemptProcess Process / attempt tracking for operations that retry. | Process / attempt tracking for operations that retry. | <10% | 80% | Scope confirmation pending. |
Bank Bank account records and transfer destinations. | Bank account records and transfer destinations. | <10% | 80% | Clean. Backfill migration moved bank data into predefined_assets, so some overlap with PredefinedAsset. |
Banner Promotional banners shown in the customer-facing apps. | Promotional banners shown in the customer-facing apps. | <10% | 80% | Clean. Small surface. |
Category Generic category taxonomy used across multiple domains. | Generic category taxonomy used across multiple domains. | <10% | 80% | Polymorphic. Recent migration consolidated category types. |
ChangeDataRequest Requests to amend existing reference data that route through an approval workflow. | Requests to amend existing reference data that route through an approval workflow. | <10% | 80% | Mirror of AddDataRequest. Same shape, same maturity. |
Comment Comments attached polymorphically to other entities. | Comments attached polymorphically to other entities. | 10-30% | 85% | Legacy app/Packages/Comments.php helper still around. Otherwise canonical. |
Company Corporate customer records. | Corporate customer records. | <10% | 90% | Full layout with Observers/, Jobs/. Glossary flags overlap with Establishment and Customer as a TODO. |
Core Shared abstracts, traits, base classes ( | Shared abstracts, traits, base classes (FilterData, GetDataAbstract, Arrayable, ProjectFlavor, FeatureFlag). | 0% | 80% | Foundational — not a business domain. Has Abstracts/, Casts/, Helpers/, Scopes/, Traits/ that other domains don't need. First place to look before adding a new utility. |
Employee Staff records, including admin and back-office personnel. | Staff records, including admin and back-office personnel. | 10-30% | 85% | Legacy app/Position.php and Cp/PositionController still around. Recent migrations added employment-type, work-mode, and line-manager fields. |
Establishment Establishment / company records used in user onboarding. | Establishment / company records used in user onboarding. | <10% | 80% | Renamed from offices table in May 2026 — recent migration rename_offices_to_establishments. |
Exporter Orchestrates large CSV / Excel exports across multiple domains. | Orchestrates large CSV / Excel exports across multiple domains. | <10% | 90% | Full layout with Abstracts/, Jobs/, Exports/. Exemplary template for orchestration domains. |
FavoritePage User-bookmarked pages in the admin panel. | User-bookmarked pages in the admin panel. | 0% | 80% | Small, clean, single-purpose. |
FileArchive Long-term archival of files. | Long-term archival of files. | <10% | 80% | Retention policy and relationship to Attachment still TODO in glossary. |
FixedPrice Fixed-price catalogue entries used in quotations and orders. | Fixed-price catalogue entries used in quotations and orders. | <10% | 85% | Has Exports/. Clean. |
FleetManagement Fleet-level operations: vehicles, drivers, maintenance scheduling. | Fleet-level operations: vehicles, drivers, maintenance scheduling. | ≈30-60% | 90% | Full layout (Observers/, Jobs/, Exceptions/). Legacy app/Driver.php, VehicleDocumentsSummaryController, AssignRequestPdfController still outside. Many recent migrations land here. High activity, partial legacy. |
Integration Third-party integration glue (external APIs, webhooks). | Third-party integration glue (external APIs, webhooks). | <10% | 70% | No Models/, no Enums/. Likely intentional — a thin orchestration layer. |
InternalOrder Internal-only orders that don't surface to the customer-facing flow. | Internal-only orders that don't surface to the customer-facing flow. | <10% | 80% | Minimal layout — no Enums/, no Jobs/. Smaller surface than Order. |
Leave Employee leave management. | Employee leave management. | <10% | 80% | New domain (May 2026 migrations: create_leave_types_table, create_annual_leave_tables, create_leaves_table). |
Location Geographic locations (cities, regions, addresses). | Geographic locations (cities, regions, addresses). | >60% | 85% | Heaviest legacy tail. app/Address.php, app/City.php, app/Country.php, app/Region.php, plus Cp/CitiesController, CountriesController, RegionController, WinchCitiesController. Domain layout is solid, but the migration from legacy is far from complete. |
Message In-app messages between users. | In-app messages between users. | <10% | 90% | Full layout including Mails/ and Jobs/. Solid template for communication domains. |
Module Application module / feature toggles tied to the menu. | Application module / feature toggles tied to the menu. | <10% | 80% | Glossary TODO: relationship to Pennant flags and ProjectFlavor is unclear. |
MoneyTransfer Transfers between accounts. | Transfers between accounts. | <10% | 80% | Clean. |
Nationality Nationality lookup data. | Nationality lookup data. | <10% | 80% | Small reference-data domain. |
Order Customer-placed orders — the central transaction the rest of the operational flow revolves around. | Customer-placed orders — the central transaction the rest of the operational flow revolves around. | 10-30% | 85% | 17 actions, full layout with Jobs/ and Exceptions/. Some legacy: OrderDocumentPdfController, Coupon.php, CouponHistory.php. Recent migration make_order_provider_morphable. The flagship domain — good template, but big. |
Owner Vehicle and asset owners that providers represent. | Vehicle and asset owners that providers represent. | <10% | 85% | Full layout with Observers/. Recent migration changed default payment method to postpaid. |
PredefinedAsset Catalogue of predefined assets that can be assigned into a fleet. | Catalogue of predefined assets that can be assigned into a fleet. | <10% | 70% | No DataTransferObjects/. New domain (May 2026 migration: create_predefined_assets_table). Backfilled from Bank assets. |
Provider Third-party service providers that fulfil orders. | Third-party service providers that fulfil orders. | 10-30% | 85% | Full layout with Observers/. Legacy app/ProviderStatusHistory.php, Cp/ProviderDocumentsSummaryController, ProvidersCreditLimitController still outside. |
Quotation Quotations issued to customers, often the predecessor of an Order. | Quotations issued to customers, often the predecessor of an Order. | 10-30% | 80% | Has Exports/. Legacy QuotationPdfController and root QuotationRequestController outside the domain. Recent migration add_visible_to_customer_to_quotations_table. |
Rental Rental contracts and the state machine around active and returned rentals. | Rental contracts and the state machine around active and returned rentals. | <10% | 85% | Full layout with Exports/. Clean. |
Role Role definitions used by the permission system. | Role definitions used by the permission system. | 10-30% | 80% | Legacy app/Role.php, app/Permission.php, Cp/RolesController, Cp/BulkPermissionsController all outside. Recent migration create_winch_branch_roles_table plus migrate_role_description_to_translations. |
Security Login, OTP, account locking, audit. | Login, OTP, account locking, audit. | 10-30% | 80% | Has Traits/. Legacy LoginController, RemoteLoginController still in Cp/. Glossary TODO flags overlap with UserCore. |
Setting Application-wide settings stored in the database. | Application-wide settings stored in the database. | 10-30% | 80% | Legacy Cp/SettingsController still outside. |
Supply Supply / supplier records. | Supply / supplier records. | <10% | 80% | Glossary TODO: describe responsibilities. |
UserContract User-facing legal contracts (terms of service, privacy policy versions, signed agreements). | User-facing legal contracts (terms of service, privacy policy versions, signed agreements). | <10% | 80% | Clean. |
UserCore Base user identity and shared user-account behaviour underneath the user-type panels. | Base user identity and shared user-account behaviour underneath the user-type panels. | >60% | 80% | Second-heaviest legacy tail. Legacy app/User.php, app/ChangeAvatarRequest.php, app/ChangeMeRequest.php, app/Verification.php, app/VerifyRequest.php, plus Cp/UsersController, UserActionController, VerifyRequestsController. The user model itself still lives in app/. |
Waybill Issued waybills attached to orders, used as the physical record for transport. | Issued waybills attached to orders, used as the physical record for transport. | 10-30% | 85% | Legacy WaybillPdfController outside. Recent migration add_driver_columns_to_orders_and_waybills. |
WinchBranch WINCH operational branches; the | WINCH operational branches; the winch_branches feature is gated behind a Pennant flag. | 10-30% | 80% | Legacy Cp/WinchCitiesController outside. Heavy migration churn (branch cities, balances, codes). |
- Accounting (90) — full layout,
Jobs/,Observers/,Traits/. Reach for it when you need a domain with money, audit trails, and side effects. - FleetManagement (90) — full layout plus
Observers/,Jobs/,Exceptions/. Good template when the domain has many models and state transitions. - Message (90) — full layout including
Mails/andJobs/. The template for any communication-shaped domain. - Exporter (90) — full layout including
Abstracts/,Jobs/,Exports/. Good template for orchestration domains. - Company (90) — full layout including
Observers/andJobs/. Solid mid-sized template. - Order (85, 17 actions) — biggest action surface; copy patterns from here when you need a transaction-heavy domain.
- Location — Address, City, Country, Region all still in
app/. MultipleCp/controllers. Touched by almost every order — refactoring here unlocks downstream cleanup. - UserCore —
app/User.phpstill lives in the legacy tree, along with verification, change-avatar, change-me, and the matchingCp/controllers. The most foundational migration left. - Attachment — polymorphic and used everywhere, with several attachment-type controllers and document-type models still in
app/. Hard to refactor in isolation. - Role —
app/Role.php,app/Permission.php, and the role / bulk-permission controllers still outside. Permission system rework is a prerequisite. - Activity — DDD adherence is also low (50) — missing
Actions/,DataTransferObjects/,Enums/. Both legacy and incomplete on the DDD side.
When to update this map
- After any refactor that moves a class out of
app/intosrc/Domain/{Name}/. - When a new domain is added to
src/Domain/(also update the domain glossary). - When a domain's subfolder layout changes meaningfully (e.g.
Actions/added,Observers/introduced). - At least once a quarter, run a quick pass and re-score the rows that have seen significant change.
Before claiming a domain is "fully migrated"
- No files matching the domain name remain in
app/Http/Controllers/orapp/Http/Controllers/Cp/. - No Eloquent model files for the domain remain directly in
app/. - No helper / trait / package for the domain remains in
app/Packages/,app/Traits/, orapp/Constants/. - All routes for the domain are wired through the domain's own service provider (registered in
bootstrap/providers.php). - Migrations created since the move follow the domain's table naming convention.
- The domain glossary and this map have been updated to reflect the new state.
API Resource
Step-by-step recipe for a full CRUD JSON endpoint on any API panel — Business, Customer, Owner, Provider — backed by an existing domain Contract.
Learning Resources
A curated path into the ideas behind the WINCH backend — watch the talk, skim the slides, explore the sample app, then apply it. Plus deep-dive talks on Domain-Driven Design and the move into software architecture.