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>
241 lines
7.9 KiB
Markdown
241 lines
7.9 KiB
Markdown
# Beauty Module Migration Report
|
|
|
|
**Date:** 2026-07-26
|
|
**Scope:** Migrate Beauty business logic to `frontend/modules/beauty`
|
|
**Routes:** Unchanged — all URLs remain under `/beauty/*` via `app/beauty/`
|
|
|
|
---
|
|
|
|
## Executive Summary
|
|
|
|
The Beauty Business module is the **first completed migration** from legacy `components/beauty/` + scattered `lib/`/`hooks/` files into the formal `modules/beauty/` package. All **98 route pages** and **8 layouts** remain in `app/beauty/` as thin adapters; business logic now lives in the module.
|
|
|
|
| Validation | Result |
|
|
|------------|--------|
|
|
| Typecheck | ✅ Pass |
|
|
| Lint | ✅ Pass (3 pre-existing accounting warnings) |
|
|
| Build | ✅ Pass |
|
|
| Import validation | ✅ Pass |
|
|
| Route validation | ✅ Pass |
|
|
| Architecture validation | ✅ Pass |
|
|
| Bundle validation | ✅ Pass (196 compiled beauty segments) |
|
|
|
|
---
|
|
|
|
## 1. What Moved
|
|
|
|
### From → To
|
|
|
|
| Legacy path | New path | Files |
|
|
|-------------|----------|------:|
|
|
| `components/beauty/*.tsx` | `modules/beauty/components/` | 4 |
|
|
| `components/beauty/pages/*.tsx` | `modules/beauty/pages/` | 9 |
|
|
| `components/beauty/design-system/*` | `modules/beauty/design-system/` | 6 |
|
|
| `lib/beauty-business-api.ts` | `modules/beauty/services/beauty-business-api.ts` | 1 |
|
|
| `lib/beauty-portals.ts` | `modules/beauty/constants/portals.ts` | 1 |
|
|
| `hooks/useBeautyLookups.ts` | `modules/beauty/hooks/useBeautyLookups.ts` | 1 |
|
|
| `app/beauty/(owner)/**/page.tsx` (inline CRUD) | `modules/beauty/features/owner/*.tsx` | 18 |
|
|
|
|
**Total module files:** 43 (including README, index barrels)
|
|
|
|
### Deleted / emptied
|
|
|
|
- `components/beauty/` — fully removed (0 files remain)
|
|
|
|
---
|
|
|
|
## 2. What Stayed in `app/beauty/`
|
|
|
|
Per migration rules, only Next.js routing artifacts remain:
|
|
|
|
| Artifact | Count | Role |
|
|
|----------|------:|------|
|
|
| `page.tsx` | 98 | Thin re-exports to `@/modules/beauty/*` |
|
|
| `layout.tsx` | 8 | Portal layouts calling `createPortalLayout()` |
|
|
| `loading.tsx` | 0 | (none existed) |
|
|
| `error.tsx` | 0 | (none existed) |
|
|
| `not-found.tsx` | 0 | (none existed) |
|
|
|
|
### Layout files (unchanged URLs)
|
|
|
|
```
|
|
app/beauty/layout.tsx
|
|
app/beauty/(owner)/layout.tsx
|
|
app/beauty/owner/layout.tsx
|
|
app/beauty/admin/layout.tsx
|
|
app/beauty/customer/layout.tsx
|
|
app/beauty/reception/layout.tsx
|
|
app/beauty/staff-portal/layout.tsx
|
|
app/beauty/site/layout.tsx
|
|
```
|
|
|
|
### Route adapter pattern
|
|
|
|
**Portal pages (unchanged pattern):**
|
|
```tsx
|
|
export { CustomerWallet as default } from "@/modules/beauty/pages/customer";
|
|
```
|
|
|
|
**Owner CRUD pages (new thin adapters):**
|
|
```tsx
|
|
export { default } from "@/modules/beauty/features/owner/organizations";
|
|
```
|
|
|
|
---
|
|
|
|
## 3. Module Structure
|
|
|
|
```
|
|
modules/beauty/
|
|
├── README.md
|
|
├── index.ts # Public barrel
|
|
├── components/
|
|
│ ├── BeautyPortalShell.tsx
|
|
│ ├── PublicBeautyLayout.tsx
|
|
│ ├── createPortalLayout.tsx
|
|
│ └── BeautyBusinessShell.tsx (@deprecated)
|
|
├── pages/
|
|
│ ├── admin.tsx, customer.tsx, owner.tsx, reception.tsx
|
|
│ ├── staff-portal.tsx, public.tsx, hub.tsx, shared.tsx
|
|
│ └── mobile.tsx
|
|
├── features/owner/ # 18 CRUD screens
|
|
│ ├── organizations.tsx
|
|
│ ├── customers.tsx, branches.tsx, appointments.tsx
|
|
│ ├── catalog-services.tsx, catalog-categories.tsx
|
|
│ ├── staff.tsx, staff-commissions.tsx
|
|
│ ├── packages.tsx, packages-memberships.tsx
|
|
│ ├── salon-*.tsx, booking-*.tsx
|
|
│ ├── marketing-*.tsx, settings.tsx
|
|
├── design-system/
|
|
│ ├── tokens.ts, BeautyStatusChip.tsx, BeautyCards.tsx
|
|
│ ├── BeautyPrimitives.tsx, BeautyTablePage.tsx
|
|
│ └── index.ts
|
|
├── hooks/
|
|
│ └── useBeautyLookups.ts
|
|
├── services/
|
|
│ └── beauty-business-api.ts # 1,446 lines
|
|
├── constants/
|
|
│ └── portals.ts
|
|
├── types/
|
|
│ └── index.ts
|
|
├── forms/ # Reserved (README scaffold)
|
|
├── tables/ # Reserved — BeautyTablePage in design-system/
|
|
├── calendar/ # Reserved
|
|
├── charts/ # Reserved
|
|
└── utils/ # Reserved
|
|
```
|
|
|
|
---
|
|
|
|
## 4. Import Migration
|
|
|
|
### New canonical imports
|
|
|
|
```typescript
|
|
import { beautyBusinessApi } from "@/modules/beauty/services/beauty-business-api";
|
|
import { createPortalLayout } from "@/modules/beauty/components/createPortalLayout";
|
|
import { useBeautyLookups } from "@/modules/beauty/hooks/useBeautyLookups";
|
|
import { BEAUTY_PORTALS } from "@/modules/beauty/constants/portals";
|
|
import { CustomerDashboard } from "@/modules/beauty/pages/customer";
|
|
```
|
|
|
|
### Deprecated shims (backward compatible)
|
|
|
|
| Shim | Re-exports |
|
|
|------|------------|
|
|
| `lib/beauty-business-api.ts` | `@/modules/beauty/services/beauty-business-api` |
|
|
| `lib/beauty-portals.ts` | `@/modules/beauty/constants/portals` |
|
|
| `hooks/useBeautyLookups.ts` | `@/modules/beauty/hooks/useBeautyLookups` |
|
|
|
|
**119 files** updated by `scripts/migrate-beauty-imports.mjs`. Zero remaining `@/components/beauty/*` imports in source.
|
|
|
|
---
|
|
|
|
## 5. URL Preservation
|
|
|
|
All beauty URLs are unchanged. Examples:
|
|
|
|
| URL | Route file | Module export |
|
|
|-----|------------|---------------|
|
|
| `/beauty/hub` | `app/beauty/hub/page.tsx` | `pages/hub` |
|
|
| `/beauty/customer/wallet` | `app/beauty/customer/wallet/page.tsx` | `pages/customer` |
|
|
| `/beauty/organizations` | `app/beauty/(owner)/organizations/page.tsx` | `features/owner/organizations` |
|
|
| `/beauty/site/book` | `app/beauty/site/book/page.tsx` | `pages/public` |
|
|
| `/beauty/admin/analytics` | `app/beauty/admin/analytics/page.tsx` | `pages/admin` |
|
|
|
|
No `next.config.mjs` redirect changes. No backend modifications.
|
|
|
|
---
|
|
|
|
## 6. Tooling Updates
|
|
|
|
| File | Change |
|
|
|------|--------|
|
|
| `tsconfig.json` | `@/modules/*` alias (already present) |
|
|
| `tailwind.config.ts` | Added `./modules/**/*.{ts,tsx}` to content |
|
|
| `.eslintrc.json` | Beauty rules apply to `modules/beauty/**/*` |
|
|
| `scripts/validate-architecture.mjs` | Beauty domain = `modules/beauty` |
|
|
| `scripts/validate-beauty-imports.mjs` | **New** |
|
|
| `scripts/validate-beauty-routes.mjs` | **New** |
|
|
| `scripts/validate-beauty-bundle.mjs` | **New** |
|
|
| `package.json` | Added `validate:beauty*` scripts |
|
|
| `components/ds/Button.tsx` | Added `loading` prop (unblocks build) |
|
|
|
|
### Validation commands
|
|
|
|
```bash
|
|
npm run typecheck
|
|
npm run lint
|
|
npm run validate:beauty-imports
|
|
npm run validate:beauty-routes
|
|
npm run validate:architecture
|
|
npm run build
|
|
npm run validate:beauty-bundle
|
|
# Or all beauty checks:
|
|
npm run validate:beauty
|
|
```
|
|
|
|
---
|
|
|
|
## 7. Boundaries
|
|
|
|
| Rule | Status |
|
|
|------|--------|
|
|
| Beauty must not import healthcare/accounting | ✅ Enforced |
|
|
| Shared/ds must not import modules/beauty | ✅ Enforced |
|
|
| Healthcare/accounting unchanged | ✅ |
|
|
| Backend unchanged | ✅ |
|
|
| CRM not present | N/A |
|
|
|
|
---
|
|
|
|
## 8. Not Migrated (by design)
|
|
|
|
| Item | Reason |
|
|
|------|--------|
|
|
| Healthcare | Explicitly out of scope |
|
|
| Accounting | Explicitly out of scope |
|
|
| `shared/` code | Platform layer — Phase 2 |
|
|
| `components/ds/` | Shared design system |
|
|
| `lib/beauty-business-nav.ts` | Dead file (0 imports pre-migration) |
|
|
| Auth guards, SiteHeader | Platform components |
|
|
|
|
---
|
|
|
|
## 9. Follow-up Recommendations
|
|
|
|
1. **Remove deprecated shims** after confirming no external consumers of `lib/beauty-*` paths
|
|
2. **Move BeautyTablePage** to `modules/beauty/tables/` when table abstraction is extracted
|
|
3. **Extract owner forms** into `modules/beauty/forms/` if CRUD forms grow further
|
|
4. **Apply same pattern to Healthcare** as next module migration
|
|
5. **Delete `BeautyBusinessShell.tsx`** after confirming zero imports
|
|
|
|
---
|
|
|
|
## 10. Related Documents
|
|
|
|
- [frontend-architecture.md](./frontend-architecture.md)
|
|
- [frontend-migration-plan.md](./frontend-migration-plan.md)
|
|
- [module-boundaries.md](./module-boundaries.md)
|
|
- [../modules/beauty/README.md](../modules/beauty/README.md)
|