update DOC
This commit is contained in:
205
AGENTS.md
205
AGENTS.md
@@ -3,19 +3,25 @@
|
||||
> **Trước khi làm việc, đọc các file quan trọng:**
|
||||
> - `CODEBASE_SNAPSHOT.md` — Toàn bộ cấu trúc codebase (thay vì scan lại code)
|
||||
> - `TASKS_ROADMAP.md` — Roadmap: đã làm, đang làm, sẽ làm
|
||||
> - `PROGRESS.md` — Lịch sử tiến độ hoàn thành
|
||||
> - `docs/I18N_GUIDE.md` — Hướng dẫn đa ngôn ngữ
|
||||
> - `docs/ENUM_GUIDE.md` — Hướng dẫn thêm Enum mới
|
||||
> - `luutru/` — Archive các file đã lỗi thời (tham khảo nếu cần)
|
||||
>
|
||||
> **File đã lỗi thời trong luutru/:** PROGRESS.md, SOP_des.md, AI_01/02/03, CHANGELOG.md, README.md gốc, SYSTEM_ASSESSMENT_PROPOSALS.md
|
||||
|
||||
## Overview
|
||||
AfterSales CRM is a real-estate after-sales customer care system built with **Laravel 13.6** + **Filament 5.6**.
|
||||
Hệ thống có **2 Filament Panel**:
|
||||
- `/admin` — Admin Panel: đầy đủ tất cả modules (Contract, Handover, Service, User/Role...)
|
||||
- `/support` — Support Panel: rút gọn, tập trung Feedback (Feedback, Customer, Product, Channel, Tag, ActivityLog)
|
||||
|
||||
## How to Run
|
||||
```bash
|
||||
cd /home/phuongtc/vibecode/minicrm
|
||||
php artisan migrate:fresh --seed
|
||||
php artisan serve
|
||||
# Open http://localhost:8000/admin
|
||||
# Admin panel: http://localhost:8000/admin
|
||||
# Support panel: http://localhost:8000/support
|
||||
```
|
||||
|
||||
### Test Accounts (seeded)
|
||||
@@ -51,8 +57,30 @@ php artisan test # run pest tests
|
||||
php artisan app:export-backup
|
||||
php artisan app:export-backup --path=/custom/path --pretty
|
||||
php artisan app:export-backup --tables=feedback,customers,products
|
||||
|
||||
# Import data from Excel
|
||||
php artisan app:import-cskh ai_instructions/CSKH.xlsx --dry-run
|
||||
php artisan app:import-cskh ai_instructions/CSKH.xlsx
|
||||
```
|
||||
|
||||
## Dual Panel Architecture
|
||||
|
||||
Hệ thống có 2 Filament Panel độc lập:
|
||||
|
||||
### Admin Panel (`/admin`) — `AdminPanelProvider.php`
|
||||
Đầy đủ tất cả modules, bao gồm:
|
||||
- Feedback, Customer, Product, Contract, FeedbackChannel, FeedbackTag
|
||||
- User, Role (admin-only)
|
||||
- 3 Dashboard widgets: ResolvedTicketsWidget, AvgProcessingTimeWidget, HandlerPerformanceWidget
|
||||
|
||||
### Support Panel (`/support`) — `SupportPanelProvider.php`
|
||||
Rút gọn, chỉ tập trung vào quy trình xử lý feedback:
|
||||
- Feedback, Customer, Product, FeedbackChannel, FeedbackTag, ActivityLog
|
||||
- 3 Dashboard widgets giống Admin panel
|
||||
- Không có: Contracts, Users, Roles, Handovers, ProductServices
|
||||
|
||||
Cả 2 panel dùng chung: Models, Services, Policies, Database, Translations.
|
||||
|
||||
## Directory Structure
|
||||
|
||||
```
|
||||
@@ -60,6 +88,9 @@ minicrm/
|
||||
├── app/
|
||||
│ ├── Filament/
|
||||
│ │ ├── Resources/
|
||||
│ │ │ ├── ActivityLogs/ # NEW: Audit trail (read-only)
|
||||
│ │ │ │ ├── ActivityLogResource.php
|
||||
│ │ │ │ └── Pages/ListActivityLogs.php
|
||||
│ │ │ ├── Feedback/
|
||||
│ │ │ │ ├── FeedbackResource.php
|
||||
│ │ │ │ ├── Schemas/FeedbackForm.php
|
||||
@@ -67,79 +98,101 @@ minicrm/
|
||||
│ │ │ │ ├── Pages/{Create,Edit,List}Feedback.php
|
||||
│ │ │ │ └── RelationManagers/InteractionsRelationManager.php
|
||||
│ │ │ ├── Products/
|
||||
│ │ │ │ └── RelationManagers/{Contracts,Handovers,ProductServices}RelationManager.php
|
||||
│ │ │ ├── Customers/
|
||||
│ │ │ │ └── RelationManagers/FeedbacksRelationManager.php
|
||||
│ │ │ ├── Contracts/
|
||||
│ │ │ ├── FeedbackChannels/
|
||||
│ │ │ ├── FeedbackTags/
|
||||
│ │ │ ├── Contracts/
|
||||
│ │ │ ├── Users/
|
||||
│ │ │ └── Roles/
|
||||
│ │ └── Widgets/
|
||||
│ │ ├── ResolvedTicketsWidget.php # Dashboard: resolved tickets table
|
||||
│ │ ├── AvgProcessingTimeWidget.php # Dashboard: stats overview
|
||||
│ │ └── HandlerPerformanceWidget.php # Dashboard: bar chart per handler
|
||||
│ ├── Console/Commands/
|
||||
│ │ ├── ImportCskh.php # app:import-cskh
|
||||
│ │ └── ExportBackup.php # app:export-backup
|
||||
│ ├── Enums/
|
||||
│ │ ├── ContractType.php
|
||||
│ │ ├── ContractStatus.php
|
||||
│ │ ├── HandoverStatus.php
|
||||
│ │ └── ServiceType.php
|
||||
│ ├── Http/
|
||||
│ │ ├── Controllers/Controller.php
|
||||
│ │ └── Middleware/HandleUploadErrors.php
|
||||
│ ├── Models/
|
||||
│ │ ├── User.php # HasRoles (Spatie), isAdmin(), isManager()
|
||||
│ │ ├── Department.php # NEW: name, manager_id → User
|
||||
│ │ ├── Product.php
|
||||
│ │ ├── ActivityLog.php # NEW: Audit trail model
|
||||
│ │ ├── Contract.php
|
||||
│ │ ├── Customer.php
|
||||
│ │ ├── CustomerProduct.php
|
||||
│ │ ├── Feedback.php # added: current_department_id, is_escalated, transferLogs
|
||||
│ │ ├── Department.php
|
||||
│ │ ├── Feedback.php
|
||||
│ │ ├── FeedbackAttachment.php
|
||||
│ │ ├── FeedbackChannel.php
|
||||
│ │ ├── FeedbackTag.php
|
||||
│ │ ├── FeedbackInteraction.php
|
||||
│ │ ├── FeedbackAttachment.php # added: uuid, disk, collection
|
||||
│ │ └── TicketTransferLog.php # NEW: department-to-department transfer history
|
||||
│ │ ├── FeedbackTag.php
|
||||
│ │ ├── Handover.php
|
||||
│ │ ├── Product.php
|
||||
│ │ ├── ProductService.php
|
||||
│ │ ├── TicketTransferLog.php
|
||||
│ │ └── User.php # HasRoles (Spatie), isAdmin(), isManager()
|
||||
│ ├── Policies/
|
||||
│ │ ├── FeedbackPolicy.php # Spatie hasRole() checks
|
||||
│ │ ├── ProductPolicy.php
|
||||
│ │ ├── ActivityLogPolicy.php # NEW
|
||||
│ │ ├── ContractPolicy.php
|
||||
│ │ ├── CustomerPolicy.php
|
||||
│ │ └── FeedbackChannelPolicy.php
|
||||
│ ├── Services/
|
||||
│ │ ├── FileService.php # Upload, validation, temp URLs, collections
|
||||
│ │ ├── TransferService.php # Cross-dept transfer + notification
|
||||
│ │ └── ClosingService.php # Role-gated closing + evidence check
|
||||
│ ├── Rules/
|
||||
│ │ └── RequireProofOfResolution.php # Custom validation: proof_of_resolution required for close
|
||||
│ │ ├── FeedbackChannelPolicy.php
|
||||
│ │ ├── FeedbackPolicy.php
|
||||
│ │ ├── ProductPolicy.php
|
||||
│ │ ├── RolePolicy.php
|
||||
│ │ └── UserPolicy.php
|
||||
│ ├── Notifications/
|
||||
│ │ ├── TicketTransferred.php # DB + Mail for department transfer
|
||||
│ │ └── TicketClosed.php # DB + Mail for ticket closure
|
||||
│ └── Providers/Filament/
|
||||
│ └── AdminPanelProvider.php
|
||||
├── lang/ # i18n translation files
|
||||
│ ├── en/
|
||||
│ │ ├── app.php # General UI labels, navigation, status, widgets
|
||||
│ │ ├── feedback.php # Feedback domain: services, notifications, interactions
|
||||
│ │ └── enums.php # Enum labels
|
||||
│ └── vi/
|
||||
│ ├── app.php
|
||||
│ ├── feedback.php
|
||||
│ └── enums.php
|
||||
│ │ ├── TicketTransferred.php
|
||||
│ │ └── TicketClosed.php
|
||||
│ ├── Providers/Filament/
|
||||
│ │ ├── AdminPanelProvider.php # Panel đầy đủ (/admin)
|
||||
│ │ └── SupportPanelProvider.php # Panel rút gọn (/support)
|
||||
│ ├── Rules/
|
||||
│ │ └── RequireProofOfResolution.php
|
||||
│ └── Services/
|
||||
│ ├── ActivityLogger.php # NEW: static log() cho audit trail
|
||||
│ ├── ClosingService.php
|
||||
│ ├── FileService.php
|
||||
│ └── TransferService.php
|
||||
├── lang/ # i18n translation files
|
||||
│ ├── en/{app.php, feedback.php, enums.php}
|
||||
│ └── vi/{app.php, feedback.php, enums.php}
|
||||
├── resources/views/filament/resources/feedback/
|
||||
│ ├── similar-cases.blade.php
|
||||
│ └── attachment-links.blade.php # Modal listing attachments with signed download URLs
|
||||
│ └── attachment-links.blade.php
|
||||
├── webappUI/aftersales_crm_core/ # Design tokens & system
|
||||
│ └── DESIGN.md
|
||||
├── database/
|
||||
│ ├── migrations/
|
||||
│ └── seeders/AfterSalesSeeder.php # includes departments, logs, attachments
|
||||
├── tests/
|
||||
│ ├── Feature/
|
||||
│ │ ├── ClosingPermissionTest.php # 4 tests: staff forbid, no-evidence, with-evidence, cross-dept
|
||||
│ │ └── TransferFlowTest.php # 2 tests: successful + missing reason
|
||||
│ └── Pest.php
|
||||
├── storage/app/private/feedback-attachments/ # Private disk upload directory
|
||||
├── composer.json
|
||||
├── PROGRESS.md
|
||||
└── AGENTS.md
|
||||
│ ├── migrations/ # 25 migrations
|
||||
│ └── seeders/{AfterSalesSeeder,PermissionSeeder}.php
|
||||
├── tests/Feature/
|
||||
│ ├── ClosingPermissionTest.php
|
||||
│ └── TransferFlowTest.php
|
||||
├── luutru/ # Archive các file đã lỗi thời
|
||||
├── UI_DESIGN_BRIEF.md # Thiết kế UI chi tiết
|
||||
└── TASKS_ROADMAP.md
|
||||
```
|
||||
|
||||
## Database Schema
|
||||
|
||||
### departments (NEW)
|
||||
### activity_logs (NEW)
|
||||
| Column | Type | Notes |
|
||||
|--------|------|-------|
|
||||
| id | bigint PK | |
|
||||
| user_id | fk -> users nullable | Who performed action |
|
||||
| action | string | import, export, transfer, close, create, update, delete |
|
||||
| description | text | Human-readable description |
|
||||
| subject_type | string nullable | Related model class |
|
||||
| subject_id | bigint nullable | Related model ID |
|
||||
| metadata | json nullable | Extra data |
|
||||
| created_at | timestamp | |
|
||||
|
||||
### departments
|
||||
| Column | Type | Notes |
|
||||
|--------|------|-------|
|
||||
| id | bigint PK | |
|
||||
@@ -147,7 +200,7 @@ minicrm/
|
||||
| manager_id | fk -> users nullable | Department head |
|
||||
| created_at, updated_at | timestamp | |
|
||||
|
||||
### ticket_transfer_logs (NEW)
|
||||
### ticket_transfer_logs
|
||||
| Column | Type | Notes |
|
||||
|--------|------|-------|
|
||||
| id | bigint PK | |
|
||||
@@ -164,10 +217,11 @@ minicrm/
|
||||
| id | bigint PK | |
|
||||
| customer_id | fk -> customers | cascadeOnDelete |
|
||||
| customer_product_id | fk -> customer_product nullable | null = general feedback |
|
||||
| contract_id | fk -> contracts nullable | **(NEW)** Snapshot contract |
|
||||
| feedback_channel_id | fk -> feedback_channels | |
|
||||
| assigned_to | fk -> users nullable | Current handler |
|
||||
| current_department_id | fk -> departments nullable | **(NEW)** Current department |
|
||||
| is_escalated | boolean default false | **(NEW)** |
|
||||
| current_department_id | fk -> departments nullable | Current department |
|
||||
| is_escalated | boolean default false | |
|
||||
| title | string | |
|
||||
| content | text | |
|
||||
| status | string | pending, processing, resolved, closed |
|
||||
@@ -177,20 +231,20 @@ minicrm/
|
||||
| Column | Type | Notes |
|
||||
|--------|------|-------|
|
||||
| id | bigint PK | |
|
||||
| uuid | string nullable unique | **(NEW)** |
|
||||
| uuid | string nullable unique | |
|
||||
| feedback_id | fk -> feedback | |
|
||||
| feedback_interaction_id | fk -> feedback_interactions nullable | |
|
||||
| user_id | fk -> users | |
|
||||
| name | string | |
|
||||
| path | string | |
|
||||
| disk | string default 'local' | **(NEW)** |
|
||||
| collection | string default 'general' | **(NEW)** proof_of_resolution, customer_evidence, general |
|
||||
| disk | string default 'local' | |
|
||||
| collection | string default 'general' | proof_of_resolution, customer_evidence, general |
|
||||
| mime_type | string nullable | |
|
||||
| size | bigint nullable | |
|
||||
| created_at, updated_at | timestamp | |
|
||||
|
||||
### Other tables
|
||||
feedback_interactions, feedback_tags, feedback_feedback_tag, products, customers, customer_product, feedback_channels, users (Spatie permission tables: roles, permissions, model_has_roles, etc.)
|
||||
feedback_interactions, feedback_tags, feedback_feedback_tag, products, customers, customer_product, feedback_channels, users, contracts, handovers, product_services, roles, permissions, model_has_roles (Spatie), notifications, sessions, cache
|
||||
|
||||
## Workflow
|
||||
|
||||
@@ -205,14 +259,24 @@ feedback_interactions, feedback_tags, feedback_feedback_tag, products, customers
|
||||
|
||||
## Key Features
|
||||
|
||||
### Transfer Department (NEW - SOP compliant)
|
||||
- Action on EditFeedback page: TransferDepartment
|
||||
### Dual Panel System (NEW)
|
||||
- **Admin Panel** (`/admin`): Đầy đủ modules, User/Role management
|
||||
- **Support Panel** (`/support`): Rút gọn, tập trung Feedback. Dùng cho đội support không cần quản lý hệ thống
|
||||
|
||||
### ActivityLog — Audit Trail (NEW)
|
||||
- Tự động ghi log các hành động: import, export, transfer, close, create, update, delete
|
||||
- `ActivityLogger::log(action, description, subject, metadata, userId)`
|
||||
- Xem tại `/admin/activity-logs` hoặc `/support/activity-logs`
|
||||
- Admin-only access (ActivityLogPolicy)
|
||||
|
||||
### Transfer Department (SOP compliant)
|
||||
- Action trên EditFeedback: TransferDepartment
|
||||
- Modal: select target department + reason (required) + optional attachments
|
||||
- Calls TransferService: creates TicketTransferLog, updates current_department_id, resets handler to dept manager
|
||||
- Sends TicketTransferred notification to target department manager
|
||||
|
||||
### Close Ticket (NEW - SOP compliant)
|
||||
- Action on EditFeedback page: CloseTicket
|
||||
### Close Ticket (SOP compliant)
|
||||
- Action trên EditFeedback: CloseTicket
|
||||
- Visible only to admin/manager, only when status != 'closed'
|
||||
- Requires confirmation
|
||||
- Staff (403) if tries to close
|
||||
@@ -224,14 +288,14 @@ feedback_interactions, feedback_tags, feedback_feedback_tag, products, customers
|
||||
- Manager/Admin: all options including "closed"
|
||||
- When "closed" selected: calls ClosingService which validates evidence
|
||||
|
||||
### File Management (Updated - SOP compliant)
|
||||
- Files stored on private `local` disk (storage/app/private/feedback-attachments/)
|
||||
### File Management (SOP compliant)
|
||||
- Files stored on `public` disk (`storage/app/public/feedback-attachments/`)
|
||||
- Collection system: `proof_of_resolution`, `customer_evidence`, `general`
|
||||
- FileService validates: jpg, png, pdf, mp4, mov, max 20MB
|
||||
- Temporary signed URLs for private file access
|
||||
- FileService::hasCollection() checks existence of required evidence
|
||||
|
||||
### Dashboard Widgets (NEW)
|
||||
### Dashboard Widgets
|
||||
- ResolvedTicketsWidget: table of resolved tickets awaiting closure (manager: filtered to own department)
|
||||
- AvgProcessingTimeWidget: 4 stats (resolved count, avg time, pending count, escalated count)
|
||||
- HandlerPerformanceWidget: bar chart of avg processing time per handler
|
||||
@@ -303,19 +367,35 @@ public function getHeading(): string | Htmlable | null
|
||||
|
||||
## Navigation Structure
|
||||
|
||||
### Admin Panel (`/admin`)
|
||||
```
|
||||
Dashboard
|
||||
Dashboard (AccountWidget + 3 custom widgets)
|
||||
├── Customer Care / Chăm sóc khách hàng (group)
|
||||
│ └── Feedbacks / Phản ánh (chat-bubble-left-right, sort=1)
|
||||
└── Management / Quản lý (group)
|
||||
├── Products / Sản phẩm (building-storefront, sort=1)
|
||||
├── Customers / Khách hàng (user-group, sort=2)
|
||||
├── Channels / Kênh phản ánh (inbox-stack, sort=3)
|
||||
├── Contracts / Hợp đồng (document-text, sort=4)
|
||||
├── Tags / Thẻ (tag, sort=default)
|
||||
├── Activity Logs (clock, sort=7) — admin only
|
||||
├── Users / Người dùng (users, sort=5) — admin only
|
||||
└── Roles / Vai trò (shield-check, sort=6) — admin only
|
||||
```
|
||||
|
||||
### Support Panel (`/support`)
|
||||
```
|
||||
Dashboard (3 custom widgets)
|
||||
├── Customer Care / Chăm sóc khách hàng (group)
|
||||
│ └── Feedbacks
|
||||
└── Management / Quản lý (group)
|
||||
├── Products
|
||||
├── Customers
|
||||
├── Channels
|
||||
├── Tags
|
||||
└── Activity Logs
|
||||
```
|
||||
|
||||
Dashboard widgets: ResolvedTicketsWidget, AvgProcessingTimeWidget, HandlerPerformanceWidget (admin/manager only)
|
||||
|
||||
## RBAC (Role-Based Access Control) - Spatie
|
||||
@@ -400,6 +480,9 @@ use Filament\Schemas\Schema;
|
||||
```php
|
||||
use Illuminate\Support\Facades\App;
|
||||
$service = App::make(FileService::class);
|
||||
|
||||
// ActivityLogger (static)
|
||||
\App\Services\ActivityLogger::log('transfer', '...', $feedback, ['dept' => 'CSKH']);
|
||||
```
|
||||
|
||||
### Spatie role check
|
||||
@@ -432,6 +515,7 @@ $user->assignRole('manager');
|
||||
19. **FileUpload in Actions**: When handling file uploads in Action callbacks (e.g., transfer attachments), file paths are strings (not UploadedFile). Create records directly instead of using FileService::upload().
|
||||
20. **Tailwind CSS in Filament**: Custom blade views render inside Filament layout which does NOT include full Tailwind CSS build. Must add needed utilities to `public/css/filament-custom.css` with `!important`.
|
||||
21. **SVG icon sizing**: Use inline `width`/`height` attributes on SVG icons (e.g., `<svg width="14" height="14">`) instead of Tailwind classes (`w-3.5 h-3.5`) — prevents Filament CSS from overriding sizes.
|
||||
22. **Dual Panel**: Support panel at `/support` is separate from Admin panel at `/admin`. Both share the same models/services/policies/database.
|
||||
|
||||
## File Upload Architecture
|
||||
|
||||
@@ -501,3 +585,4 @@ protected function afterSave(): void
|
||||
// For SVG icons, use inline attributes:
|
||||
<svg width="14" height="14" class="text-blue-600">...</svg>
|
||||
// NOT: <svg class="w-3.5 h-3.5 text-blue-600">...</svg>
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user