# TorbatYar Frontend — Dependency Report

**Date:** 2026-07-26  
**Scope:** npm packages, internal module dependencies, API clients, dead code

---

## 1. npm Dependencies

### Production (`package.json`)

| Package | Version | Used in source? | Notes |
|---------|---------|:---------------:|-------|
| `next` | 15.5.18 | ✅ | App Router framework |
| `react` / `react-dom` | ^19.0.0 | ✅ | UI runtime |
| `@tanstack/react-query` | ^5.101.4 | ✅ | Primary async state (~70+ files) |
| `@tanstack/react-table` | ^8.21.3 | ❌ | **Zero imports — unused** |
| `react-hook-form` | ^7.82.0 | ✅ | Forms (~29 files) |
| `@hookform/resolvers` | ^5.4.0 | ✅ | Zod resolver |
| `zod` | ^4.4.3 | ✅ | Schema validation |
| `recharts` | ^3.10.0 | ❌ | **Zero imports — unused** |
| `class-variance-authority` | ^0.7.1 | ✅ | DS Button/Badge variants |
| `clsx` | ^2.1.1 | ✅ | Via `cn()` in utils |
| `tailwind-merge` | ^3.6.0 | ✅ | Via `cn()` in utils |
| `dayjs` | ^1.11.21 | ✅ | Date utilities |
| `jalaali-js` | ^2.0.0 | ✅ | Jalali calendar (DatePicker) |
| `lucide-react` | ^1.26.0 | ✅ | Icons throughout |
| `framer-motion` | ^12.42.2 | ⚠️ | Limited usage (check before removing) |
| `sonner` | ^2.0.7 | ✅ | Toast notifications |

### Dev dependencies

| Package | Version | Purpose |
|---------|---------|---------|
| `typescript` | ^5.4.0 | Type checking |
| `tailwindcss` | ^3.4.0 | Styling |
| `autoprefixer` | ^10.4.0 | CSS post-processing |
| `postcss` | ^8.4.0 | CSS pipeline |
| `@types/*` | various | Type definitions |

### Unused dependency impact

| Package | Bundle impact | Recommendation |
|---------|---------------|----------------|
| `@tanstack/react-table` | Tree-shaken if unused, but adds install size | Remove unless table upgrade planned |
| `recharts` | Same | Remove until analytics charts implemented |

---

## 2. Internal Dependency Graph

### Layer model (verified acyclic)

```
Layer 0: styles/, public/
Layer 1: lib/utils.ts, lib/auth.ts
Layer 2: lib/api.ts, lib/theme.ts, lib/identity.ts
Layer 3: lib/{module}-api.ts, lib/{module}-portals.ts
Layer 4: hooks/
Layer 5: components/ds/
Layer 6: components/{module}/
Layer 7: app/
```

**Circular dependencies detected:** 0

### Internal dependency hotspots

| File | Inbound refs | Outbound deps | Role |
|------|-------------|---------------|------|
| `lib/utils.ts` | ~47 | clsx, tailwind-merge | Utility hub |
| `lib/auth.ts` | ~15 | — | Token/session management |
| `hooks/useTenantId.ts` | ~67 | useMe, lib/auth | Most-referenced hook |
| `components/ds/index.ts` | ~90+ | ds internals, lib/utils | DS barrel |
| `lib/accounting-api.ts` | ~30 | lib/auth | Accounting API monolith |
| `lib/beauty-business-api.ts` | ~28 | lib/auth | Beauty API monolith |
| `lib/healthcare-api.ts` | ~14 | lib/auth | Healthcare API monolith |

---

## 3. API Client Monoliths

### Structure (common pattern)

All three module API clients follow identical architecture:

```typescript
import { getValidAccessToken, refreshSession } from "@/lib/auth";

const BASE = typeof window !== "undefined"
  ? "/api/{service}"                    // browser → BFF
  : process.env.NEXT_PUBLIC_*_API_URL;  // SSR → direct

export class {Module}ApiError extends Error { status, body }

async function request<T>(path, options): Promise<T> {
  // token refresh, x-tenant-id header, error mapping
}

export const {module}Api = {
  // 100–200+ methods
};
```

### Size comparison

| Client | Lines | Import sites | Exported methods (est.) |
|--------|------:|-------------:|------------------------:|
| `lib/accounting-api.ts` | 1,856 | 30 | 200+ |
| `lib/beauty-business-api.ts` | 1,446 | 28 | 150+ |
| `lib/healthcare-api.ts` | 1,322 | 14 | 120+ |
| `lib/api.ts` (platform) | 502 | ~15 | 40+ |

### Duplication within API layer

Each monolith reimplements:
- Token refresh on 401
- `x-tenant-id` header injection
- Error class with status code
- JSON parse/error handling
- Query string building

**Estimated duplicated code:** ~80 lines × 3 = ~240 lines of identical fetch wrapper logic.

### Superseded / dead API files

| File | Lines | Imports | Status |
|------|------:|--------:|--------|
| `lib/api-client.ts` | 62 | 0 | **Dead** — duplicate of `lib/api.ts` |
| `lib/optional-sso.ts` | ~50 | 0 | **Dead** — SSO helpers never wired |
| `lib/beauty-business-nav.ts` | ~100 | 0 | **Dead** — superseded by `lib/beauty-portals.ts` |

---

## 4. Platform API Dependencies

### Direct backend calls (no BFF)

| Client | Target | Used by |
|--------|--------|---------|
| `lib/api.ts` | `NEXT_PUBLIC_BACKEND_URL` (:8000) | Admin, dashboard, onboarding |
| `lib/identity.ts` | `NEXT_PUBLIC_IDENTITY_API_URL` (:8001) | Auth flows |
| `lib/auth.ts` | Keycloak + identity | All authenticated modules |

### BFF-proxied calls

| Client | BFF route | Upstream |
|--------|-----------|----------|
| `lib/accounting-api.ts` | `/api/accounting/*` | :8002 |
| `lib/beauty-business-api.ts` | `/api/beauty-business/*` | :8011 |
| `lib/healthcare-api.ts` | `/api/healthcare/*` | :8010 |

### Missing BFF routes

| Backend service | Frontend client | Gap |
|-----------------|-------------------|-----|
| Delivery | None | No frontend module |
| Communication | None | Not implemented |
| Core (admin) | Direct call | CORS risk in some deployments |

---

## 5. Hook Dependencies

| Hook | Depends on | Depended on by |
|------|------------|----------------|
| `useMe` | `lib/api.ts`, TanStack Query | useTenantId, useAuth, all portal layouts |
| `useTenantId` | useMe | ~67 component/page files |
| `useAuth` | lib/auth.ts | Auth pages, guards |
| `useTheme` | lib/theme.ts | ThemeProvider |
| `useBeautyLookups` | beauty-business-api | Beauty owner CRUD pages |
| `useHealthcareLookups` | healthcare-api | Healthcare portal pages |
| `useHealthcarePatientContext` | healthcare-api, useMe | Patient portal |
| `useHealthcareDoctorContext` | healthcare-api, useMe | Doctor portal |
| `useHeaderSession` | useMe | SiteHeader |
| `useTenantHost` | lib/api.ts | Platform home |

No hook imports from wrong domain API client. ✅

---

## 6. Dead Code Inventory

### Confirmed dead files (zero imports)

| File | Lines | Reason |
|------|------:|--------|
| `lib/api-client.ts` | 62 | Superseded by `lib/api.ts` |
| `lib/optional-sso.ts` | ~50 | SSO flow never integrated |
| `lib/beauty-business-nav.ts` | ~100 | Superseded by `lib/beauty-portals.ts` |
| `components/HealthStatus.tsx` | ~80 | Component never mounted |
| `components/beauty/pages/mobile.tsx` | ~60 | MobilePortalFrame unused |

**Total dead code:** ~350 lines across 5 files

### Likely-unused exports (requires ts-prune)

The three API monoliths export hundreds of methods and types. Many correspond to routes not yet wired or features in development. Static analysis without runtime profiling cannot enumerate all unused exports.

**High-confidence unused npm packages:** 2  
**High-confidence dead files:** 5  
**Estimated unused API exports:** Unknown (likely 20–40% of monolith surface)

### Deprecated but present

| File | Marker | Imports |
|------|--------|--------:|
| `components/beauty/BeautyBusinessShell.tsx` | `@deprecated` comment | 0 (verify) |

---

## 7. Cross-Module Dependency Matrix

|  | platform lib | accounting lib | beauty lib | healthcare lib |
|--|:------------:|:--------------:|:----------:|:----------------:|
| **platform lib** | ✅ | ❌ | ❌ | ❌ |
| **accounting lib** | ✅ | ✅ | ❌ | ❌ |
| **beauty lib** | ✅ | ❌ | ✅ | ❌ |
| **healthcare lib** | ✅ | ❌ | ❌ | ✅ |

**Cross-module component imports:** 0  
**Cross-module hook imports:** 0  
**Circular dependencies:** 0

---

## 8. Environment Variable Dependencies

From `next.config.mjs`:

| Variable | Default | Consumer |
|----------|---------|----------|
| `NEXT_PUBLIC_BACKEND_URL` | localhost:8000 | lib/api.ts |
| `NEXT_PUBLIC_API_BASE_URL` | localhost:8000 | Legacy alias |
| `NEXT_PUBLIC_IDENTITY_API_URL` | localhost:8001 | lib/identity.ts |
| `NEXT_PUBLIC_KEYCLOAK_URL` | localhost:8080 | lib/auth.ts |
| `NEXT_PUBLIC_KEYCLOAK_REALM` | superapp | lib/auth.ts |
| `NEXT_PUBLIC_KEYCLOAK_CLIENT_ID` | superapp-frontend | lib/auth.ts |
| `NEXT_PUBLIC_ACCOUNTING_API_URL` | localhost:8002 | accounting-api SSR |
| `NEXT_PUBLIC_HEALTHCARE_API_URL` | localhost:8010 | healthcare-api SSR |

**Missing from next.config.mjs env block:**
- `NEXT_PUBLIC_BEAUTY_BUSINESS_API_URL` (used in beauty-business-api.ts via process.env directly)
- `BEAUTY_BUSINESS_SERVICE_URL` (BFF server-side)
- `ACCOUNTING_SERVICE_URL` (BFF server-side)
- `HEALTHCARE_SERVICE_URL` (BFF server-side)

---

## 9. Build Dependency Health

| Check | Result |
|-------|--------|
| `npm run build` compile | ✅ ~55s |
| TypeScript check | ❌ Fails (Button `loading` prop) |
| ESLint | Not reached |
| Circular deps | ✅ None |
| Unused npm (confirmed) | ⚠️ 2 packages |

---

## 10. Recommendations

### Immediate (Phase 0)

1. Remove `@tanstack/react-table` and `recharts` OR implement usage
2. Delete 5 confirmed dead files
3. Fix Button type error to unblock build

### Short-term (Phase 3)

1. Extract shared `createApiClient()` from three monoliths
2. Split API clients by domain subdomain
3. Run `ts-prune` to identify unused exports

### Medium-term

1. Add `@next/bundle-analyzer` to CI
2. Add `depcheck` to CI for npm hygiene
3. Add import graph validation script

---

## Related Documents

- [import-report.md](./import-report.md)
- [module-boundaries.md](./module-boundaries.md)
- [refactor-risk-analysis.md](./refactor-risk-analysis.md)
