# 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. --- ## Trạng thái hiện tại - **SOP Phase 1-8:** 100% hoàn thành - **AI Instructions Core:** 85% (6/7, còn auto-suggest transfer) - **Test:** Pest 8/8 tests (21 assertions) pass - **Data import:** 3658 rows từ `ai_instructions/CSKH.xlsx` imported successfully - **Dual Panel:** Admin (đầy đủ) + Support (rút gọn, tập trung feedback) --- ## ✅ ĐÃ HOÀN THÀNH ### 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` (feedback_id, from/to department, sender, reason) - [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 Edit Feedback (modal: department + reason + attachment) - [x] `CloseTicket` Action (visible: admin/manager, status ≠ closed, requires confirmation) - [x] InteractionsRelationManager: role-aware status options (staff: no "closed"), department field - [x] FeedbackForm: current_department_id, is_escalated, attachment_collection ### Giai đoạn 5: Dashboard Widgets - [x] `ResolvedTicketsWidget`: bảng ticket resolved chờ đóng (manager lọc theo phòng quản lý) - [x] `AvgProcessingTimeWidget`: 4 stats (resolved count, avg time, pending, escalated) - [x] `HandlerPerformanceWidget`: bar chart thời gian xử lý trung bình theo nhân viên ### Giai đoạn 6: Testing - [x] Pest cài đặt + 8 test scenarios - [x] `ClosingPermissionTest`: 4 tests (staff 403, no evidence 422, with evidence OK, cross-department 403) - [x] `TransferFlowTest`: 2 tests (success + missing reason) ### Giai đoạn 7: Seeder - [x] 4 departments (CSKH, Kỹ thuật, Kế toán, Pháp lý) - [x] 1 ticket_transfer_log mẫu - [x] 3 feedback_attachments (2 proof_of_resolution, 1 customer_evidence) ### Giai đoạn 8: Polish & Bug Fix - [x] Dashboard widget filter Manager theo department - [x] Migration disk default fix (private → local) - [x] File upload pattern fix - [x] Department + Escalated columns trên FeedbackTable + Department filter - [x] Validation proof_of_resolution khi close từ form - [x] Manager chỉ đóng ticket phòng mình - [x] View Attachments trong Interaction History (temporary signed URL) - [x] Docker deployment (Dockerfile, docker-compose, entrypoint) - [x] Migration notifications table ### Giai đoạn 9: Granular Permissions + Export Backup + User/Role Management - [x] PermissionSeeder: 29 granular permissions (view/create/update/delete per module + close-ticket, transfer-department, export-data) - [x] Role → Permission mapping: admin (all), manager (no delete/export), staff (view + limited write) - [x] Policies updated to `hasPermissionTo()` (5 policies) - [x] ExportBackup command: `app:export-backup` (JSON, per-table, chunk 500, manifest.json) - [x] UserResource: admin-only CRUD users + assign role - [x] RoleResource: admin-only CRUD roles + assign permissions via CheckboxList - [x] UserPolicy + RolePolicy (admin-only access) ### A: Module Hợp đồng (Contract) - [x] Migration `contracts`: product_id, customer_id, type (sale/lease/bcc), dates, status, signed_status - [x] Enum `ContractType` (SALE/LEASE/BCC) + `ContractStatus` (ACTIVE/EXPIRED/LIQUIDATED) - [x] Model `Contract`: relationships product(), customer(), feedbacks() - [x] Filament Resource `Contracts` (CRUD) + `ContractPolicy` - [x] RelationManager `ContractsRelationManager` trên ProductResource - [x] Model `Product` thêm `contracts()` HasMany - [x] Seeder: 5 contracts mẫu ### B: Cơ chế Snapshot Hợp đồng - [x] Migration thêm `contract_id` (FK->contracts, nullable) vào bảng `feedback` - [x] Model `Feedback`: thêm `contract_id` fillable + `contract()` BelongsTo - [x] FeedbackForm: auto-select active contract khi chọn sản phẩm, cho phép chọn lại thủ công - [x] FeedbackTable: cột "Contract" hiển thị loại HĐ dạng badge - [x] Seeder: gán contract_id cho 5 feedback mẫu ### C: Module Bàn giao (Handover) - [x] Migration `handovers`: product_id, customer_id, handover_date, status, remark - [x] Enum `HandoverStatus` (NOT_READY/READY/SCHEDULED/HANDED_OVER) - [x] Model `Handover`: relationships product(), customer() - [x] RelationManager `HandoversRelationManager` trên ProductResource - [x] Model `Product` thêm `handovers()` HasMany - [x] Seeder: 5 handovers mẫu ### D: Module Dịch vụ phụ trợ (ProductService) - [x] Migration `product_services`: product_id, service_type, status, actual_collection_date, remark - [x] Enum `ServiceType` (MANAGEMENT_FEE/GRATITUDE/SELF_BUSINESS) - [x] Model `ProductService`: relationship product() - [x] RelationManager `ProductServicesRelationManager` trên ProductResource - [x] Model `Product` thêm `productServices()` HasMany - [x] Seeder: 5 services mẫu ### E: Enhancement ProductResource - [x] ProductResource có 3 tabs: Contracts + Handovers + Services (via getRelations()) ### G: Data Import Pipeline - [x] Cài `spatie/simple-excel` (Lazy Collection, chống OOM) - [x] Command `app:import-cskh {file_path} --dry-run` với ProgressBar, chunk 100 rows - [x] Pipeline per row: Product/Customer firstOrCreate → customer_product pivot → Contract → Handover → Service → Feedback + Interactions - [x] Xử lý DateTimeImmutable object từ Excel, skip header/meta rows - [x] Test thành công: 3658 rows → 3299 products, 2089 customers, 2637 contracts, 2077 handovers, 159 services, 71 feedbacks, 226 interactions ### Internationalization (i18n) — Vietnamese + English - [x] Config: `APP_LOCALE=vi`, `APP_FALLBACK_LOCALE=en` - [x] Created `lang/en/` and `lang/vi/` with 3 files each: `app.php`, `feedback.php`, `enums.php` - [x] ~120 translation keys: navigation, labels, status, widgets, services, notifications, enums - [x] All Resources: override `getPluralLabel()` + `getNavigationGroup()` with `__()` calls - [x] All Form fields: explicit `->label(__('key'))` - [x] All Table columns: explicit `->label(__('key'))` - [x] All RelationManagers: `$title` uses translation key - [x] All Widgets: `getHeading()`/`getDescription()` return translated strings - [x] Enums: `ContractType`, `ContractStatus`, `HandoverStatus`, `ServiceType` use `__()` in `label()` - [x] Filament vendor: 57 Vietnamese translation files auto-activated ### UI Polish & Bug Fixes - [x] File upload: Fixed `disk('local')` → `disk('public')` across all components - [x] File upload: Added `exists()` check before getting metadata - [x] File upload: Fixed `dehydrated(false)` issue — use property to store paths - [x] Tailwind CSS: Added ~200 utility classes to `public/css/filament-custom.css` - [x] SVG icons: Use inline `width`/`height` attributes instead of Tailwind classes - [x] GlobalSearch: Customized for all Resources with multi-field search - [x] RelationManager titles: Override `getTitle()` for proper translation - [x] Enum refactoring: Added `color()` method, static `options()`, developer comments - [x] Documentation: Created `docs/I18N_GUIDE.md` and `docs/ENUM_GUIDE.md` ### Support Panel (Dual Panel) - [x] `SupportPanelProvider`: panel thứ 2 tại path `/support`, rút gọn chỉ tập trung feedback - [x] Resources trong Support: Feedback, Customer, Product, FeedbackChannel, FeedbackTag, ActivityLog - [x] Widgets: ResolvedTicketsWidget, AvgProcessingTimeWidget, HandlerPerformanceWidget ### ActivityLog — Audit Trail - [x] Migration `activity_logs`: user_id, action, description, subject_type/id, metadata - [x] Model `ActivityLog` + Service `ActivityLogger` (static log method) - [x] Filament Resource `ActivityLogResource` (read-only, list view with filters) - [x] Policy `ActivityLogPolicy` (admin-only) - [x] Translation keys: `resource_activity_logs`, `action_*`, `details`, `system` --- ## 🔴 CHƯA LÀM ### F: Tự động gợi ý transfer (optional, nice-to-have) - [ ] Hiển thị badge gợi ý: "Ticket BCC → khuyến nghị chuyển Pháp lý" - [ ] Logic detect contract type → suggest department --- ## 📋 Ưu tiên phát triển | Ưu tiên | Task | Phụ thuộc | |---------|------|-----------| | 1 | F: Tự động gợi ý transfer (nice-to-have) | A | --- ## 📊 Tiến độ tổng quan ``` SOP Phase 1-9: ████████████████████████ 100% (Hoàn thành) AI Instructions Core: ███████████████████████░ 85% (6/7 — Còn: auto-suggest transfer) Support Panel: ████████████████████████ 100% (Hoàn thành) ActivityLog: ████████████████████████ 100% (Hoàn thành) i18n (vi/en): ████████████████████████ 100% (Hoàn thành) Data Import: ████████████████████████ 100% (3658 rows imported) Tests: ████████████████████████ 100% (8 tests, 21 assertions) ``` --- ## Cách chạy Local Dev ```bash cd /home/phuongtc/vibecode/minicrm php artisan migrate:fresh --seed php artisan serve # Admin panel: http://localhost:8000/admin # Support panel: http://localhost:8000/support php artisan test # 8 tests (21 assertions) ``` ### Data Import ```bash php artisan app:import-cskh ai_instructions/CSKH.xlsx --dry-run # phân tích php artisan app:import-cskh ai_instructions/CSKH.xlsx # import thật ``` ### Export Backup ```bash php artisan app:export-backup php artisan app:export-backup --path=/custom/path --pretty php artisan app:export-backup --tables=feedback,customers,products ``` --- ## Tài khoản test (seeded) | Role | Email | Password | |------|-------|----------| | Admin | admin@minicrm.local | password | | Manager | manager@minicrm.local | password | | Staff | staff@minicrm.local | password | --- ## Tech Stack - PHP 8.3, Laravel 13.6.0, Filament 5.6.1 - Database: SQLite (`database/database.sqlite`) - Composer: `/home/phuongtc/composer` - Spatie: laravel-permission (RBAC) - Testing: Pest PHP --- ## File hướng dẫn cho AI Agent | File | Nội dung | |------|----------| | `AGENTS.md` | Hướng dẫn toàn diện: chạy, cấu trúc, workflow, RBAC, gotchas, patterns | | `CODEBASE_SNAPSHOT.md` | Snapshot cấu trúc codebase (đọc thay vì scan code) | | `TASKS_ROADMAP.md` | File này — roadmap + tiến độ | | `docs/I18N_GUIDE.md` | Hướng dẫn đa ngôn ngữ chi tiết | | `docs/ENUM_GUIDE.md` | Hướng dẫn thêm Enum mới | | `UI_DESIGN_BRIEF.md` | Thiết kế UI chi tiết (horizontal top bar) | | `webappUI/aftersales_crm_core/DESIGN.md` | Design tokens (colors, typography, spacing) | | `luutru/` | Archive các file đã lỗi thời (AI_01-03 specs, SOP_des, PROGRESS cũ...) |