TorbatYar/frontend/docs/import-report.md
Mortezakoohjani 6f4a484051 Migrate Beauty, Healthcare, and Accounting frontend to modular src/modules architecture.
Move business logic out of App Router into module packages, add boundary validation scripts, and keep all routes as thin re-exports without changing URLs or API behavior.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-26 22:28:27 +03:30

378 lines
12 KiB
Markdown

# TorbatYar Frontend — Import Report
**Date:** 2026-07-26
**Scope:** Import patterns, alias usage, violations, and conventions
---
## 1. Summary Statistics
| Metric | Value |
|--------|------:|
| Total source files (`.ts`/`.tsx`) | ~481 |
| Total import statements | ~811 |
| `@/` alias imports | 756 (93%) |
| Relative imports (`./`, `../`) | 55 (7%) |
| Files using `@/` alias | 445 / 481 (92%) |
| Files using relative imports | 30 / 481 (6%) |
| Files using both patterns | 25 |
| Cross-domain imports | 0 |
| Circular import chains | 0 |
**Verdict:** Import conventions are strong and consistently applied.
---
## 2. Path Alias Configuration
### tsconfig.json
```json
{
"compilerOptions": {
"paths": { "@/*": ["./*"] }
}
}
```
Single alias `@/` maps to `frontend/` root. No scoped sub-aliases exist.
### Implications
| Aspect | Effect |
|--------|--------|
| Readability | ✅ Clean absolute-style paths |
| Refactoring | ⚠️ No enforced module scoping via alias |
| Tree-shaking | Neutral — bundler resolves same as relative |
| IDE navigation | ✅ Works well |
| Boundary enforcement | ❌ Cannot restrict by alias alone — needs ESLint |
---
## 3. Import Pattern Analysis
### Pattern A — Absolute `@/` (dominant, 93%)
Used for all cross-folder imports:
```typescript
// App route → component
export { CustomerWallet as default } from "@/components/beauty/pages/customer";
// Component → design system
import { Button, DataTable, PageHeader } from "@/components/ds";
// Component → API client
import { accountingApi } from "@/lib/accounting-api";
// Component → hook
import { useTenantId } from "@/hooks/useTenantId";
// Layout → guard
import { AuthGuard } from "@/components/AuthGuard";
```
### Pattern B — Relative `./` (local composition, 7%)
Used within co-located modules:
```typescript
// Page bundle → shared helpers
import { BeautyPageLoader, BeautyPageError } from "./shared";
// DS internal
import { Button } from "./Button";
// Design system barrel
export { BeautyStatusChip } from "./BeautyStatusChip";
export { CardShell } from "./BeautyCards";
// Portal layout → shell (same module)
import { BeautyPortalShell } from "@/components/beauty/BeautyPortalShell";
// Note: even same-module sometimes uses @/ — inconsistent but harmless
```
### Pattern C — Re-export routes (beauty/healthcare)
~175 routes use single-line re-exports:
```typescript
export { CustomerWallet as default } from "@/components/beauty/pages/customer";
```
This is the **canonical thin-route pattern** for the codebase.
---
## 4. Import Frequency by Target
### Most imported modules
| Target | Approx. imports | Category |
|--------|----------------:|----------|
| `@/components/ds` | 90+ | Design system |
| `@/hooks/useTenantId` | 67 | Shared hook |
| `@/lib/utils` | 47 | Utilities |
| `@/lib/accounting-api` | 30 | Domain API |
| `@/lib/beauty-business-api` | 28 | Domain API |
| `@/lib/auth` | 15 | Platform auth |
| `@/lib/healthcare-api` | 14 | Domain API |
| `@/components/AuthGuard` | 10+ | Platform guard |
| `@/hooks/useMe` | 7 | Shared hook |
| `@tanstack/react-query` | 70+ | External |
### Most imported DS exports
| Export | Typical consumers |
|--------|-------------------|
| `Button` | All modules |
| `PageHeader` | All modules |
| `DataTable` | All modules |
| `LoadingState`, `ErrorState` | Portal layouts, pages |
| `Dialog`, `ConfirmDialog` | CRUD pages |
| `FormField`, `MoneyInput` | Accounting, beauty owner |
| `DatePicker` | Accounting |
---
## 5. Domain Import Isolation
### Accounting imports
```
✅ @/components/ds
✅ @/components/accounting/*
✅ @/lib/accounting-api
✅ @/lib/accounting-nav
✅ @/hooks/useTenantId, useMe
✅ @/lib/auth, @/lib/utils
❌ @/components/beauty/* — NOT FOUND
❌ @/components/healthcare/* — NOT FOUND
❌ @/lib/beauty-business-api — NOT FOUND
❌ @/lib/healthcare-api — NOT FOUND
```
### Beauty imports
```
✅ @/components/ds
✅ @/components/beauty/*
✅ @/lib/beauty-business-api
✅ @/lib/beauty-portals
✅ @/hooks/useTenantId, useMe, useBeautyLookups
❌ @/components/accounting/* — NOT FOUND
❌ @/components/healthcare/* — NOT FOUND
```
### Healthcare imports
```
✅ @/components/ds
✅ @/components/healthcare/*
✅ @/lib/healthcare-api
✅ @/lib/healthcare-portals
✅ @/hooks/useTenantId, useMe, useHealthcareLookups, useHealthcarePatientContext
❌ @/components/accounting/* — NOT FOUND
❌ @/components/beauty/* — NOT FOUND
```
### Platform imports
```
✅ @/components/ui — Marketing surfaces
✅ @/components/ds — Some admin/settings
✅ @/lib/api — Core backend
✅ @/lib/auth, @/lib/identity
❌ Domain module components — NOT FOUND
```
**Compliance: 100%** — no cross-domain import violations detected.
---
## 6. Shared Layer Import Compliance
### `components/ds/` imports
The design system imports only:
- `@/lib/utils` (cn helper)
- Internal relative `./` imports
- External packages (cva, lucide-react, react)
**Does NOT import:** any domain module ✅
### `hooks/` imports
| Hook | Allowed imports | Violations |
|------|-----------------|------------|
| `useMe` | `@/lib/api` | None |
| `useTenantId` | `@/hooks/useMe` | None |
| `useBeautyLookups` | `@/lib/beauty-business-api` | None (domain hook) |
| `useHealthcareLookups` | `@/lib/healthcare-api` | None (domain hook) |
| `useAuth` | `@/lib/auth` | None |
Shared hooks (useMe, useTenantId, useAuth) do not import domain APIs. ✅
---
## 7. Improper Import Patterns
### 7.1 Legacy UI in new module code
| Issue | Severity | Details |
|-------|----------|---------|
| Module code importing `components/ui/` | 🟡 Low | Not found in beauty/healthcare/accounting — compliant |
| Platform code importing `components/ui/` | ✅ Expected | Login, dashboard, homepage |
### 7.2 Deep imports bypassing barrels
Some files import directly from DS sub-files instead of barrel:
```typescript
// Bypasses barrel — found occasionally
import { Button } from "@/components/ds/Button";
// Preferred
import { Button } from "@/components/ds";
```
**Impact:** Low — does not break boundaries, reduces barrel effectiveness.
### 7.3 Same-module `@/` vs relative inconsistency
Beauty and healthcare components sometimes use `@/components/beauty/...` for same-module imports where `./` would suffice.
**Impact:** None functional; stylistic inconsistency only.
### 7.4 Server/client boundary
Most app routes are `"use client"` — no widespread server component data fetching pattern. API clients check `typeof window` for BFF vs direct URL.
**Not a violation** but limits RSC benefits.
---
## 8. External Package Imports
| Package | Import count | Modules using |
|---------|-------------|---------------|
| `react` | All files | Universal |
| `next/navigation` | ~50+ | Client routes (useRouter, redirect) |
| `next/link` | ~30+ | Navigation |
| `next/image` | ~10 | Public sites |
| `@tanstack/react-query` | ~70+ | All modules |
| `react-hook-form` | ~29 | Accounting, beauty owner |
| `@hookform/resolvers/zod` | ~29 | With react-hook-form |
| `zod` | ~35+ | Form schemas |
| `lucide-react` | ~100+ | Icons everywhere |
| `sonner` | ~40+ | Toast via import or AppProviders |
| `class-variance-authority` | 2 | ds/Button, ds/Badge |
| `dayjs` | ~5 | Date formatting |
| `jalaali-js` | 1 | ds/DatePicker |
| `framer-motion` | ~3 | Limited animation |
| `@tanstack/react-table` | 0 | **Unused** |
| `recharts` | 0 | **Unused** |
---
## 9. Import Graph Layers
```
┌─────────────────────────────────────────────────────────┐
│ app/**/page.tsx │
│ (routes — import components, occasionally inline) │
└────────────────────────┬────────────────────────────────┘
┌────────────────────────▼────────────────────────────────┐
│ components/{module}/pages/*.tsx │
│ components/{module}/*Shell.tsx │
│ components/accounting/*.tsx │
└────────────────────────┬────────────────────────────────┘
┌────────────────┼────────────────┐
│ │ │
┌───────▼──────┐ ┌───────▼──────┐ ┌───────▼──────┐
│ components/ds│ │ hooks/ │ │ lib/*-api.ts │
└───────┬──────┘ └───────┬──────┘ └───────┬──────┘
│ │ │
└────────────────┼────────────────┘
┌────────▼────────┐
│ lib/auth.ts │
│ lib/utils.ts │
│ lib/api.ts │
└─────────────────┘
```
No back-edges detected. Graph is a DAG.
---
## 10. False-Positive Cross-Module Names
These filenames suggest cross-module coupling but are contained within their domain:
| Route/file | Looks like | Actually imports |
|------------|------------|------------------|
| `beauty/owner/accounting-integration/page.tsx` | Accounting | `@/components/beauty/pages/owner` |
| `beauty/owner/crm-integration/page.tsx` | CRM | `@/components/beauty/pages/owner` |
| `healthcare/clinic/accounting-integration/page.tsx` | Accounting | `@/components/healthcare/pages/clinic` |
Integration **pages** refer to external systems; they do not import other frontend modules.
---
## 11. Recommended Import Conventions
### For new code
```typescript
// 1. Design system — always from barrel
import { Button, DataTable } from "@/components/ds";
// 2. Domain code — absolute @/ within module
import { BeautyPortalShell } from "@/components/beauty/BeautyPortalShell";
// 3. Co-located helpers — relative
import { PageLoader } from "./shared";
// 4. Platform utilities
import { cn, formatMoney } from "@/lib/utils";
import { useTenantId } from "@/hooks/useTenantId";
// 5. Domain API — only in own module
import { beautyBusinessApi } from "@/lib/beauty-business-api";
// 6. NEVER cross-module
// import { AccountingShell } from "@/components/accounting/..."; // in beauty
```
### Route files
```typescript
// Preferred — thin re-export
export { MyPage as default } from "@/components/{module}/pages/{portal}";
// Acceptable — dynamic params wrapper
export { default } from "@/components/{module}/pages/public";
```
---
## 12. Enforcement Plan
| Mechanism | Purpose | Phase |
|-----------|---------|-------|
| ESLint `no-restricted-imports` | Block cross-domain paths | Phase 1 |
| ESLint `no-restricted-imports` | Block `components/ui/` in domain code | Phase 1 |
| Custom script: import graph | CI validation of DAG | Phase 1 |
| Path aliases `@accounting/*` | Make boundaries explicit | Phase 2 (optional) |
| `eslint-plugin-import` ordering | Consistent import sort | Phase 2 (optional) |
---
## Related Documents
- [module-boundaries.md](./module-boundaries.md)
- [dependency-report.md](./dependency-report.md)
- [frontend-architecture-audit.md](./frontend-architecture-audit.md)