Assist_Design/docs/development/domain/import-hygiene.md
barsa 3030d12138 Update Domain Import Practices and Enhance Documentation
- Added a new script to check domain imports, promoting better import hygiene across the codebase.
- Refactored multiple domain index files to remove unnecessary type re-exports, streamlining the module structure.
- Expanded documentation on import patterns and validation processes to provide clearer guidance for developers.
- Included an architecture diagram to illustrate the relationships between the Portal, BFF, and Domain packages.
2025-12-26 15:07:47 +09:00

3.5 KiB
Raw Blame History

Import Hygiene Guide (Domain)

Principles

  • No deep imports: internal file layout is not part of the contract.
  • Barrels define the public API: if its not exported from the entrypoint, its not public.
  • Providers are integration-only: Portal must never import provider adapters/types.

Allowed import levels

  • Default (Portal + BFF):
    • @customer-portal/domain/<module>
    • @customer-portal/domain/toolkit
  • BFF-only (integration/infrastructure):
    • @customer-portal/domain/<module>/providers

Quick Reference

Context Import Pattern Example
Portal/BFF domain types @customer-portal/domain/<module> import { Invoice } from "@customer-portal/domain/billing"
BFF provider adapters .../<module>/providers import { Whmcs } from "@customer-portal/domain/billing/providers"
Toolkit utilities @customer-portal/domain/toolkit import { Formatting } from "@customer-portal/domain/toolkit"

Architecture Diagram

graph TD
    subgraph Portal [Portal App]
        PC[PortalComponents]
    end

    subgraph BFF [BFF App]
        BC[BFFControllers]
        BI[BFFIntegrations]
    end

    subgraph Domain [Domain Package]
        DM[ModuleEntrypoints]
        DP[ProviderEntrypoints]
        DT[Toolkit]
    end

    PC -->|allowed| DM
    PC -->|allowed| DT
    PC -.->|BLOCKED| DP

    BC -->|allowed| DM
    BC -->|allowed| DT
    BI -->|allowed| DM
    BI -->|allowed| DP
    BI -->|allowed| DT

Never

  • @customer-portal/domain/<module>/** (anything deeper than the module entrypoint)
  • @customer-portal/domain/<module>/providers/** (anything deeper than /providers)
  • apps/portal/** importing any @customer-portal/domain/*/providers

Rule of thumb

Import from the highest stable entrypoint that contains what you need.

  • If it exists in @customer-portal/domain/<module>, dont import a deeper file.
  • If its provider-specific, use @customer-portal/domain/<module>/providers (BFF-only).
  • If its cross-domain utility, use @customer-portal/domain/toolkit.

When to create a new explicit entrypoint (instead of deep-importing)

Create/adjust exports when:

  • The symbol is used in 2+ apps (Portal + BFF), or many call sites.
  • The symbol is part of a workflow that should remain stable (pagination, formatting, shared validation helpers).

Where to export it:

  • Module root (@customer-portal/domain/<module>): normalized domain types/models, schemas, provider-agnostic helpers.
  • Providers entrypoint (.../<module>/providers): provider adapters, mapper/query builder logic, raw provider shapes (if truly needed).
  • Toolkit (@customer-portal/domain/toolkit): shared utilities (Formatting, Validation, Typing namespaces).

Naming conventions

  • Module root: Invoice, invoiceSchema, validateOrderBusinessRules
  • Providers: Whmcs, Salesforce, Freebit namespaces; raw shapes should be obviously integration-only.

PR checklist

  • No @customer-portal/domain/*/* imports (except exact .../<module>/providers in BFF).
  • Portal has zero .../providers imports.
  • No wildcard subpath exports added to packages/domain/package.json#exports.

Validation

After changes:

  1. Run pnpm lint
  2. Run pnpm type-check
  3. Run pnpm build