## Status

- [x] step-1-prisma: schema + migration files (product.prisma, bom.prisma, prisma:generate OK)
- [x] step-2-domain: interface, model, repository, exceptions, token
- [x] step-3-usecases: 5 use case files + component.repository.ts updated
- [x] step-4-infra: mapper, repository impl, provider (build 0 TS errors)
- [x] step-5-presentation: DTOs, controller, admin.module wiring (build clean)
- [x] step-6-migration-api: MigrateProductStructureUsecase + POST /migration/product-structure (⚠️ TEMPORARY endpoint)

## Build

✅ `bun run build:app` exit 0 — no TypeScript errors

## Files changed (api-kingston)

### Prisma Schema
- `prisma/providers/mysql/prisma-models/product.prisma` — model ProductStructure, alter Component (structureId), Product relations (modified)
- `prisma/providers/mysql/prisma-models/bom.prisma` — alter Bom (structureId) (modified)

### Domain Layer
- `src/core/domain/model/product-structure/product-structure.interface.ts` (created)
- `src/core/domain/model/product-structure/product-structure.model.ts` (created)
- `src/core/domain/model/product-structure/index.ts` (created)
- `src/core/domain/model/product-structure/` — barrel added to `model/index.ts` (modified)
- `src/core/domain/repository/product-structure.repository.ts` (created)
- `src/core/domain/repository/repository.token.ts` — PRODUCT_STRUCTURE_REPOSITORY (modified)
- `src/core/domain/repository/index.ts` — export product-structure (modified)
- `src/core/exception/product-structure.exception.ts` (created)
- `src/core/exception/index.ts` — export product-structure exceptions (modified)
- `src/core/domain/model/component/component.interface.ts` — structureId (modified)
- `src/core/domain/model/component/component.model.ts` — structureId property (modified)
- `src/core/domain/model/bom/bom.interface.ts` — structureId (modified)
- `src/core/domain/model/bom/bom.model.ts` — structureId property (modified)

### Application Layer
- `src/application/usecases/product-structure/create-product-structure.usecase.ts` (created)
- `src/application/usecases/product-structure/get-product-structures.usecase.ts` (created)
- `src/application/usecases/product-structure/update-product-structure.usecase.ts` (created)
- `src/application/usecases/product-structure/deactivate-product-structure.usecase.ts` (created)
- `src/application/usecases/product-structure/get-structure-tree.usecase.ts` (created)
- `src/application/usecases/product-structure/index.ts` (created)
- `src/application/usecases/index.ts` — export product-structure (modified)
- `src/application/application.module.ts` — 5 use cases registered (modified)
- `src/core/domain/repository/component.repository.ts` — structureId in getList option (modified)

### Infrastructure Layer
- `src/infrastructure/database/mysql/mapper/product-structure.mapper.ts` (created)
- `src/infrastructure/database/mysql/repository/product-structure-repository.implement.ts` (created)
- `src/infrastructure/database/mysql/mapper/index.ts` — export (modified)
- `src/infrastructure/database/mysql/repository/index.ts` — export (modified)
- `src/infrastructure/providers/repository.provider.ts` — PRODUCT_STRUCTURE_REPOSITORY binding (modified)
- `src/infrastructure/database/mysql/mapper/component.mapper.ts` — structureId in fromDomain + modelBasicBuilder (modified)
- `src/infrastructure/database/mysql/repository/component-repository.implement.ts` — structureId in getList filter (modified)
- `src/infrastructure/database/mysql/mapper/bom.mapper.ts` — structureId in fromDomain + modelBasicBuilder (modified)

### Presentation Layer
- `src/presentation/ports/http/controllers/product-structure/structure.dto.ts` (created)
- `src/presentation/ports/http/controllers/product-structure/product-structure.controller.ts` (created)
- `src/presentation/ports/http/controllers/product-structure/index.ts` (created)
- `src/presentation/ports/http/controllers/index.ts` — export product-structure (modified)
- `src/presentation/ports/http/modules/admin.module.ts` — ProductStructureController registered (modified)

### Migration API (⚠️ TEMPORARY)
- `src/application/usecases/product-structure/migrate-product-structure.usecase.ts` (created)
- `src/presentation/ports/http/controllers/migration/migration.controller.ts` (created) ⚠️ **TEMPORARY**
- `src/presentation/ports/http/controllers/migration/index.ts` (created) ⚠️ **TEMPORARY**
- `src/presentation/ports/http/controllers/index.ts` — export migration (modified)
- `src/presentation/ports/http/modules/admin.module.ts` — MigrationController registered (modified)

Endpoint: `POST /migration/product-structure` — idempotent, requires `product:update` permission.

## Cleanup After Migration

> Sau khi gọi `POST /migration/product-structure` trên production và verify `orphanComponents = 0 && orphanBoms = 0`, xóa:

- [ ] `src/application/usecases/product-structure/migrate-product-structure.usecase.ts`
- [ ] Xóa export trong `src/application/usecases/product-structure/index.ts`
- [ ] Xóa `MigrateProductStructureUsecase` khỏi `application.module.ts`
- [ ] `src/presentation/ports/http/controllers/migration/` (toàn bộ folder)
- [ ] Xóa export trong `src/presentation/ports/http/controllers/index.ts`
- [ ] Xóa `MigrationController` khỏi `admin.module.ts`
