- PermissionSeeder: 29 permissions with role mapping (admin/manager/staff) - Policies updated to use hasPermissionTo() instead of hasRole() - ExportBackup command: JSON per-table backup with chunk processing - UserResource: CRUD users with role assignment (admin only) - RoleResource: CRUD roles with permission assignment (admin only) - UserPolicy + RolePolicy: admin-only access control - ImportCskh: detailed skip logging with color in dry-run mode - Widgets: permission-based visibility checks - Tests: 8/8 pass (21 assertions)
8.2 KiB
8.2 KiB
AfterSales CRM - Tiến độ
Trạng thái: Hoàn thành SOP + 6/7 AI Instructions (85%)
Đã test: Tất cả routes HTTP 200, Pest 8/8 tests (21 assertions) pass ✓
Tham chiếu: SOP_des.md — Bản đặc tả hệ thống After-Sale CRM
Data import: php artisan app:import-cskh ai_instructions/CSKH.xlsx — 3658 rows imported successfully
Công nghệ
- Laravel 13.6.0 + Filament 5.6.1 + SQLite
- PHP 8.3
- Spatie laravel-permission (RBAC)
- Pest PHP (testing)
Tài khoản test
| Role | Password | |
|---|---|---|
| admin | admin@minicrm.local | password |
| manager | manager@minicrm.local | password |
| staff | staff@minicrm.local | password |
ĐÃ 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 URLTransferService: transfer department + reason required + notificationClosingService: role-gated close + proof_of_resolution check- Policies cập nhật dùng Spatie
hasRole() - Custom Rule
RequireProofOfResolution
Giai đoạn 3: Notifications
TicketTransferred(Database + Mail)TicketClosed(Database + Mail)
Giai đoạn 4: Filament UI
TransferDepartmentAction trên Edit Feedback (modal: department + reason + attachment)CloseTicketAction (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)
Giai đoạn 6: Testing
- Pest cài đặt + 6 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
- AGENTS.md cập nhật đầy đủ
Bug Fix
- Dashboard widget lọc Manager dùng
Department::where('manager_id')thay vìauth()->id() - Migration default disk
private→local - File upload trong Interaction/Create/Edit dùng lưu thẳng FeedbackAttachment, không tạo UploadedFile giả
PM (Improvements)
- FeedbackTable: thêm cột Department, Escalated icon, Department filter
- EditFeedback: validation
proof_of_resolutionkhi đổi status sangclosedtừ form
PASS 3 — Hoàn thiện SOP
HandlerPerformanceWidget: biểu đồ bar chart thời gian xử lý trung bình theo từng nhân viên- Department_Head: Manager chỉ đóng được ticket phòng mình quản lý (kèm test)
- Temporary URL tích hợp vào UI: nút "View Attachments" trong Interaction History với download link
- Cho phép upload attachment trong status_change interaction
- Docker sẵn sàng production: Dockerfile, docker-compose, entrypoint
- Migration
notificationstable
AI Instructions — Phase 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
ContractsRelationManagertrên ProductResource - Model
Productthêmcontracts()HasMany - Seeder: 5 contracts mẫu
AI Instructions — Phase B: Snapshot Hợp đồng
- Migration thêm
contract_idFK nullable vàofeedback - Model
Feedback: thêmcontract_idfillable +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
AI Instructions — Phase 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
HandoversRelationManagertrên ProductResource - Model
Productthêmhandovers()HasMany - Seeder: 5 handovers mẫu
AI Instructions — Phase D: Module Dịch vụ (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
ProductServicesRelationManagertrên ProductResource - Model
ProductthêmproductServices()HasMany - Seeder: 5 services mẫu
AI Instructions — Phase E: Enhancement ProductResource
- ProductResource có 3 tabs: Contracts + Handovers + Services
AI Instructions — Phase G: Data Import Pipeline
- Cài
spatie/simple-excel(Lazy Collection, chống OOM) - Command
app:import-cskh {file_path} --dry-runvới ProgressBar - Pipeline: Product/Customer firstOrCreate → customer_product pivot → Contract → Handover → Service → Feedback + Interactions
- Xử lý DateTimeImmutable object từ Excel, skip meta rows
- Đã 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
Còn lại (Optional)
- Auto-suggest chuyển phòng ban dựa trên loại hợp đồng (Ticket BCC → gợi ý Pháp lý)
Granular Permissions + Export Backup + User/Role Management
- PermissionSeeder: 29 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 use
hasPermissionTo()instead ofhasRole() - Widgets/Filament updated to use permission-based checks
- ExportBackup command:
app:export-backup(JSON, per-table, chunk 500, manifest.json) - UserResource: admin can create/edit/delete users + assign roles
- RoleResource: admin can create/edit/delete roles + assign permissions
- UserPolicy + RolePolicy (admin-only)
- Tests updated: 8 tests, 21 assertions pass
Database Schema (final — 23 migrations)
products customers customer_product (pivot)
feedback_channels feedback feedback_interactions
feedback_attachments feedback_tags feedback_feedback_tag (pivot)
users departments ticket_transfer_logs
permissions roles model_has_roles (spatie)
notifications sessions cache
contracts handovers product_services
Data Import
# Dry-run (phân tích trước, an toàn)
php artisan app:import-cskh ai_instructions/CSKH.xlsx --dry-run
# Import thật
php artisan app:import-cskh ai_instructions/CSKH.xlsx
Local Dev
cd /home/phuongtc/vibecode/minicrm
php artisan migrate:fresh --seed
php artisan serve
# Mở http://localhost:8000/admin
php artisan test # 8 tests (21 assertions)
Hướng dẫn cho AI Agent khác
CODEBASE_SNAPSHOT.md— Toàn bộ cấu trúc codebase (đọc thay vì scan code)TASKS_ROADMAP.md— Roadmap: đã làm, đang làm, sẽ làmAGENTS.md— Hướng dẫn chạy, workflow, RBAC, gotchas