# TASKS_ROADMAP.md — AfterSales CRM > **Mục đích:** Theo dõi tất cả các công việc: đã hoàn thành, đang làm, sẽ làm. > **Cập nhật:** Mỗi khi hoàn thành hoặc thêm task mới. --- ## ✅ ĐÃ HOÀN THÀNH (SOP Phase 1–8) ### Giai đoạn 1: Mở rộng CSDL - [x] Bảng `departments` (id, name, manager_id → users) - [x] Bổ sung `feedback`: current_department_id, is_escalated - [x] Bảng `ticket_transfer_logs` - [x] Nâng cấp `feedback_attachments`: uuid, disk, collection - [x] Cài Spatie laravel-permission ### Giai đoạn 2: Services & Logic - [x] `FileService`: upload, validation (jpg/png/pdf/mp4/mov ≤20MB), collection query, temporary URL - [x] `TransferService`: transfer department + reason required + notification - [x] `ClosingService`: role-gated close + proof_of_resolution check - [x] Policies dùng Spatie `hasRole()` - [x] Custom Rule `RequireProofOfResolution` ### Giai đoạn 3: Notifications - [x] `TicketTransferred` (Database + Mail) - [x] `TicketClosed` (Database + Mail) ### Giai đoạn 4: Filament UI - [x] `TransferDepartment` Action trên EditFeedback - [x] `CloseTicket` Action - [x] InteractionsRelationManager: role-aware status options - [x] FeedbackForm: current_department_id, is_escalated ### Giai đoạn 5: Dashboard Widgets - [x] `ResolvedTicketsWidget` - [x] `AvgProcessingTimeWidget` - [x] `HandlerPerformanceWidget` ### Giai đoạn 6: Testing - [x] Pest: 8 tests (21 assertions) ### Giai đoạn 7: Seeder - [x] 4 departments, 5 channels, 5 products, 4 customers, 5 feedbacks, 5 tags, 5 interactions, 1 transfer log, 3 attachments ### Giai đoạn 8: Polish & Bug Fix - [x] Dashboard widget filter Manager theo department - [x] Migration disk default fix - [x] File upload pattern fix - [x] Department + Escalated columns trên FeedbackTable - [x] Validation proof_of_resolution khi close từ form - [x] Manager chỉ đóng ticket phòng mình - [x] View Attachments trong Interaction History - [x] Docker deployment - [x] Migration notifications table ### Giai đoạn 9: Granular Permissions + Export Backup + User/Role Management - [x] PermissionSeeder: 29 granular permissions (admin/manager/staff mapping) - [x] Policies updated to `hasPermissionTo()` (5 policies) - [x] ExportBackup command: `app:export-backup` (JSON, per-table, chunk 500) - [x] UserResource: CRUD users + assign role (admin only) - [x] RoleResource: CRUD roles + assign permissions via CheckboxList (admin only) - [x] UserPolicy + RolePolicy (admin-only access) --- ## 🔴 CHƯA LÀM — Theo AI Instructions ### A: Module Hợp đồng (Contract) — từ `AI_01`, `AI_02` - [x] Tạo migration bảng `contracts`: - `product_id` FK, `customer_id` FK - `type` (LEASE/BCC/SALE) - `start_date`, `end_date` - `status` (Active/Expired/Liquidated) - `printed_at`, `signed_status` - [x] Tạo Model `Contract` + Enum `ContractType` - [x] Relationships: `product()`, `customer()`, `feedbacks()` - [x] Tạo ContractResource Filament + ContractPolicy - [x] Tạo ContractsRelationManager trên ProductResource ### B: Cơ chế Snapshot Hợp đồng — từ `AI_01` - [x] Tạo migration thêm `contract_id` (FK->contracts, nullable) vào bảng `feedback` - [x] Cập nhật Model `Feedback`: fillable + relationship `contract()` - [x] Logic auto-select active contract khi tạo Feedback mới (FeedbackForm) - [x] Hiển thị contract info trên Feedback list (FeedbackTable column) - [x] Gán contract_id cho feedback mẫu trong Seeder ### C: Module Bàn giao (Handover) — từ `AI_01`, `AI_02` - [x] Tạo migration bảng `handovers`: - `product_id` FK, `customer_id` FK - `handover_date` (date) - `status` (Chưa đủ điều kiện/Đủ ĐK/Đã lên lịch/Đã BG) - `remark` (text nullable) - [x] Tạo Model `Handover` + Enum `HandoverStatus` - [x] Relationships: `product()`, `customer()` - [x] Tạo `HandoversRelationManager` gắn vào `ProductResource` - [x] Cập nhật Product model: thêm `handovers()` HasMany ### D: Module Dịch vụ phụ trợ (ProductService) — từ `AI_02` - [x] Tạo migration bảng `product_services`: - `product_id` FK - `service_type` (MANAGEMENT_FEE/GRATITUDE/SELF_BUSINESS) - `status` - `actual_collection_date` (date nullable) - `remark` (text nullable) - [x] Tạo Model `ProductService` + Enum `ServiceType` - [x] Relationship: `product()` - [x] Tạo `ProductServicesRelationManager` gắn vào `ProductResource` - [x] Cập nhật Product model: thêm `productServices()` HasMany ### E: Enhancement ProductResource — từ `AI_02` - [x] Thêm RelationManagers vào `ProductResource::getRelations()` - ContractsRelationManager ✅ - HandoversRelationManager ✅ - ProductServicesRelationManager ✅ - [x] Product detail page có 3 tabs: Contracts + Handovers + Services ### F: Tự động gợi ý transfer — từ `AI_01` (optional) - [ ] Hiển thị badge gợi ý: "Ticket BCC → khuyến nghị chuyển Pháp lý" - [ ] Logic detect contract type → suggest department ### G: Data Import Pipeline — từ `AI_03` - [x] Cài package `spatie/simple-excel` - [x] Tạo Command `app:import-cskh {file_path} --dry-run` - [x] Logic: Lazy Collection, chunk 100 rows, DB::transaction, ProgressBar - [x] Pipeline per row: Product/Customer firstOrCreate → Contract/Handover/Service → Feedback + Interactions - [x] Tạo customer_product pivot record - [x] Xử lý DateTimeImmutable từ Excel - [x] Skip header/meta rows - [x] Đã test thành công với CSKH.xlsx (3658 rows → 3299 products, 2089 customers, 2637 contracts, 2077 handovers, 159 services, 71 feedbacks, 226 interactions) --- ## 📋 Ưu tiên phát triển | Ưu tiên | Task | Phụ thuộc | |---------|------|-----------| | 1 | ~~A: Module Hợp đồng (Migration + Model)~~ ✅ | Không | | 2 | ~~B: contract_id trên feedback (Snapshot)~~ ✅ | A | | 3 | ~~C: Module Bàn giao (Migration + Model + RelationManager)~~ ✅ | Không | | 4 | ~~D: Module Dịch vụ (Migration + Model + RelationManager)~~ ✅ | Không | | 5 | ~~E: Enhancement ProductResource~~ ✅ | A, C, D | | 6 | ~~G: Data Import Pipeline~~ ✅ | A, B, C, D | | 7 | F: Tự động gợi ý transfer (nice-to-have) | A | --- ## 📊 Tiến độ tổng quan ``` SOP Phase 1-8: ████████████████████████ 100% (Hoàn thành) AI Instructions Core: ███████████████████████░ 85% (6/7 — Còn: auto-suggest transfer) Data Import Tested: ████████████████████████ 100% (3658 rows real data imported successfully) ```