Files
minicrm/TASKS_ROADMAP.md
2026-05-12 09:23:05 +00:00

13 KiB

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)
  • V2 Restructure: 100% hoàn thành (Contract category, bỏ pivot, đại diện)
  • 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

  • Bảng departments (id, name, manager_id → users)
  • Bổ sung feedback: current_department_id, is_escalated
  • Bảng ticket_transfer_logs (feedback_id, from/to department, sender, reason)
  • Nâng cấp feedback_attachments: uuid, disk, collection
  • Cài Spatie laravel-permission

Giai đoạn 2: Services & Logic

  • FileService: upload, validation (jpg/png/pdf/mp4/mov ≤20MB), collection query, temporary URL
  • TransferService: transfer department + reason required + notification
  • ClosingService: role-gated close + proof_of_resolution check
  • Policies dùng Spatie hasRole()
  • Custom Rule RequireProofOfResolution

Giai đoạn 3: Notifications

  • TicketTransferred (Database + Mail)
  • TicketClosed (Database + Mail)

Giai đoạn 4: Filament UI

  • TransferDepartment Action trên Edit Feedback (modal: department + reason + attachment)
  • CloseTicket Action (visible: admin/manager, status ≠ closed, requires confirmation)
  • InteractionsRelationManager: role-aware status options (staff: no "closed"), department field
  • FeedbackForm: current_department_id, is_escalated, attachment_collection

Giai đoạn 5: Dashboard Widgets

  • ResolvedTicketsWidget: bảng ticket resolved chờ đóng (manager lọc theo phòng quản lý)
  • AvgProcessingTimeWidget: 4 stats (resolved count, avg time, pending, escalated)
  • HandlerPerformanceWidget: bar chart thời gian xử lý trung bình theo nhân viên

Giai đoạn 6: Testing

  • Pest cài đặt + 8 test scenarios
  • ClosingPermissionTest: 4 tests (staff 403, no evidence 422, with evidence OK, cross-department 403)
  • TransferFlowTest: 2 tests (success + missing reason)

Giai đoạn 7: Seeder

  • 4 departments (CSKH, Kỹ thuật, Kế toán, Pháp lý)
  • 1 ticket_transfer_log mẫu
  • 3 feedback_attachments (2 proof_of_resolution, 1 customer_evidence)

Giai đoạn 8: Polish & Bug Fix

  • Dashboard widget filter Manager theo department
  • Migration disk default fix (private → local)
  • File upload pattern fix
  • Department + Escalated columns trên FeedbackTable + Department filter
  • Validation proof_of_resolution khi close từ form
  • Manager chỉ đóng ticket phòng mình
  • View Attachments trong Interaction History (temporary signed URL)
  • Docker deployment (Dockerfile, docker-compose, entrypoint)
  • Migration notifications table

Giai đoạn 9: Granular Permissions + Export Backup + User/Role Management

  • PermissionSeeder: 29 granular permissions (view/create/update/delete per module + close-ticket, transfer-department, export-data)
  • Role → Permission mapping: admin (all), manager (no delete/export), staff (view + limited write)
  • Policies updated to hasPermissionTo() (5 policies)
  • ExportBackup command: app:export-backup (JSON, per-table, chunk 500, manifest.json)
  • UserResource: admin-only CRUD users + assign role
  • RoleResource: admin-only CRUD roles + assign permissions via CheckboxList
  • UserPolicy + RolePolicy (admin-only access)

A: Module Hợp đồng (Contract)

  • Migration contracts: product_id, customer_id, type (sale/lease/bcc), dates, status, signed_status
  • Enum ContractType (SALE/LEASE/BCC) + ContractStatus (ACTIVE/EXPIRED/LIQUIDATED)
  • Model Contract: relationships product(), customer(), feedbacks()
  • Filament Resource Contracts (CRUD) + ContractPolicy
  • RelationManager ContractsRelationManager trên ProductResource
  • Model Product thêm contracts() HasMany
  • Seeder: 5 contracts mẫu

B: Cơ chế Snapshot Hợp đồng

  • Migration thêm contract_id (FK->contracts, nullable) vào bảng feedback
  • Model Feedback: thêm contract_id fillable + contract() BelongsTo
  • FeedbackForm: auto-select active contract khi chọn sản phẩm, cho phép chọn lại thủ công
  • FeedbackTable: cột "Contract" hiển thị loại HĐ dạng badge
  • Seeder: gán contract_id cho 5 feedback mẫu

C: Module Bàn giao (Handover)

  • Migration handovers: product_id, customer_id, handover_date, status, remark
  • Enum HandoverStatus (NOT_READY/READY/SCHEDULED/HANDED_OVER)
  • Model Handover: relationships product(), customer()
  • RelationManager HandoversRelationManager trên ProductResource
  • Model Product thêm handovers() HasMany
  • Seeder: 5 handovers mẫu

D: Module Dịch vụ phụ trợ (ProductService)

  • Migration product_services: product_id, service_type, status, actual_collection_date, remark
  • Enum ServiceType (MANAGEMENT_FEE/GRATITUDE/SELF_BUSINESS)
  • Model ProductService: relationship product()
  • RelationManager ProductServicesRelationManager trên ProductResource
  • Model Product thêm productServices() HasMany
  • Seeder: 5 services mẫu

E: Enhancement ProductResource

  • ProductResource có 3 tabs: Contracts + Handovers + Services (via getRelations())

G: Data Import Pipeline

  • Cài spatie/simple-excel (Lazy Collection, chống OOM)
  • Command app:import-cskh {file_path} --dry-run với ProgressBar, chunk 100 rows
  • Pipeline per row: Product/Customer firstOrCreate → customer_product pivot → Contract → Handover → Service → Feedback + Interactions
  • Xử lý DateTimeImmutable object từ Excel, skip header/meta rows
  • 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

  • Config: APP_LOCALE=vi, APP_FALLBACK_LOCALE=en
  • Created lang/en/ and lang/vi/ with 3 files each: app.php, feedback.php, enums.php
  • ~120 translation keys: navigation, labels, status, widgets, services, notifications, enums
  • All Resources: override getPluralLabel() + getNavigationGroup() with __() calls
  • All Form fields: explicit ->label(__('key'))
  • All Table columns: explicit ->label(__('key'))
  • All RelationManagers: $title uses translation key
  • All Widgets: getHeading()/getDescription() return translated strings
  • Enums: ContractType, ContractStatus, HandoverStatus, ServiceType use __() in label()
  • Filament vendor: 57 Vietnamese translation files auto-activated

UI Polish & Bug Fixes

  • File upload: Fixed disk('local')disk('public') across all components
  • File upload: Added exists() check before getting metadata
  • File upload: Fixed dehydrated(false) issue — use property to store paths
  • Tailwind CSS: Added ~200 utility classes to public/css/filament-custom.css
  • SVG icons: Use inline width/height attributes instead of Tailwind classes
  • GlobalSearch: Customized for all Resources with multi-field search
  • RelationManager titles: Override getTitle() for proper translation
  • Enum refactoring: Added color() method, static options(), developer comments
  • Documentation: Created docs/I18N_GUIDE.md and docs/ENUM_GUIDE.md

Support Panel (Dual Panel)

  • SupportPanelProvider: panel thứ 2 tại path /support, rút gọn chỉ tập trung feedback
  • Resources trong Support: Feedback, Customer, Product, FeedbackChannel, FeedbackTag, ActivityLog
  • Widgets: ResolvedTicketsWidget, AvgProcessingTimeWidget, HandlerPerformanceWidget

V2: Contract Restructure — Category + Representative + Bỏ Pivot

  • Migration: thêm category (ownership/business), representative_* vào contracts, xóa customer_product
  • Enum: ContractCategory (ownership, business) + cập nhật ContractType (deposit, purchase, transfer, rental, self_business, bcc)
  • Model: Contract (+category, +representative), Customer (ownedProducts qua contracts), Feedback (-customer_product_id)
  • Xóa CustomerProduct model/pivot
  • Validation: ràng buộc 1 active/category/product (CreateContract/EditContract)
  • FeedbackForm: filter mới (Customer → Product qua Contract ownership + đại diện), case-insensitive search
  • ContractForm: select category → dynamic type options, representative form section
  • FeedbackTable: contract.product.name thay customerProduct.product.name
  • Seeder: 6 contracts V2 (ownership+business, có representative), feedback no customer_product_id
  • ImportCskh: cập nhật pipeline, không còn customer_product
  • i18n: vi/en cho category, type mới, representative, validation
  • Tests: 8/8 pass (21 assertions)

ActivityLog — Audit Trail

  • Migration activity_logs: user_id, action, description, subject_type/id, metadata
  • Model ActivityLog + Service ActivityLogger (static log method)
  • Filament Resource ActivityLogResource (read-only, list view with filters)
  • Policy ActivityLogPolicy (admin-only)
  • 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

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

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

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ũ...)