# راهنمای فنی P1: Task و تاریخچه یادداشت تماس ## دامنه پیاده‌سازی P1 یک Task عمومی و polymorphic برای `lead`، `contact`، `company`، `deal`، `call` و `campaign` اضافه می‌کند. نام کلاس PHP هیچ‌وقت از ورودی API پذیرفته نمی‌شود و alias امن در سرور resolve می‌شود. این فاز همچنین یادداشت چندتایی تماس، reminderهای idempotent، notification دارای `read_at`، audit قبل/بعد و حفظ تاریخی شماره تماس را پوشش می‌دهد. ## مدل داده - `tasks`: موضوع، توضیحات، `taskable_type/id`، مسئول/تخصیص‌دهنده/سازنده، اولویت، وضعیت، موعد، شروع/تکمیل/یادآوری، parent، تخمین، visibility، version و soft delete. - `notes`: تاریخچه polymorphic با type، visibility، pin، زمان ویرایش، `source_key` یکتا و soft delete. `user_id` برای حفظ تاریخچه پس از حذف کاربر nullable و `nullOnDelete` است. - `internal_notifications`: زمان خواندن و کلید idempotency یکتا. - `activity_logs`: snapshotهای redacted قبل/بعد و request ID. - `contact_phones`: soft delete؛ تماس‌های تاریخی شماره حذف‌شده را با `withTrashed` بازیابی می‌کنند. وضعیت‌های Task عبارت‌اند از `open`، `in_progress`، `done` و `cancelled`. مسیرهای مجاز lifecycle در سرویس دامنه کنترل می‌شوند و تمام mutationها `version` را افزایش می‌دهند. ویرایش با version قدیمی پاسخ استاندارد `409 VERSION_CONFLICT` می‌دهد. ## API اصلی - `GET/POST /api/tasks` و `GET/PATCH/DELETE /api/tasks/{id}` - `POST /api/tasks/{id}/assign|start|complete|reopen|cancel` - `POST /api/tasks/bulk-assign` و `POST /api/tasks/bulk-complete` (اتمیک) - `GET /api/users/assignable?context=task&search=...` (فقط کاربران active و مجاز؛ حداکثر ۲۰ نتیجه) - `GET/POST /api/calls/{call}/notes` - `PATCH/DELETE /api/notes/{note}` و `POST /api/notes/{note}/pin|unpin` - `GET /api/notifications`، `PATCH /api/notifications/read-all` و `PATCH /api/notifications/{id}/read` فهرست Task فیلترهای status، priority، assignee، creator، بازه موعد، overdue، entity، search، sort و pagination را می‌پذیرد. پاسخ‌های جدید envelope استاندارد `data/meta/links/message` دارند. ## مجوز و scope مجوزهای مستقل view own/team/all، create، assign/reassign، edit own/team، delete، complete، bulk، مدیریت note و pin تعریف شده‌اند. Policy و scope سرور منبع حقیقت‌اند: - Admin تمام Taskهای سازمان و کاربران فعال را می‌بیند. - Supervisor فقط Task و کاربران تیم خودش (به‌علاوه خودش) را مدیریت می‌کند. - Agent فقط Taskهای خود را می‌بیند و نمی‌تواند Task را به کاربر دیگر تخصیص دهد. - visibility خصوصی فقط برای مشارکت‌کننده مجاز است و IDOR با `403` بسته می‌شود. ## مهاجرت و backfill قبل از استقرار backup بگیرید، سپس: ```powershell cd backend php artisan migrate --force php artisan permissions:sync-defaults php artisan call-notes:backfill ``` migration و فرمان backfill از `source_key=legacy_call:{id}` استفاده می‌کنند؛ اجرای تکراری Note دوم نمی‌سازد. `calls.notes` حذف یا بازنویسی نمی‌شود و فقط به‌عنوان legacy read-only باقی می‌ماند. Noteهای نتیجه تماس جدید مستقیماً به تاریخچه افزوده می‌شوند. ## Scheduler و صف Scheduler هر ۱۵ دقیقه reminderهای Task و Follow-up را بررسی می‌کند. Taskهای done/cancelled اعلان نمی‌گیرند و idempotency key از تکرار reminder/overdue جلوگیری می‌کند. ```powershell php artisan schedule:work php artisan queue:work ``` در production این دو process را با Supervisor/systemd یا سرویس مشابه پایدار کنید. ## Rollback برای بازگشت سه migration P1 در آخرین batch: ```powershell php artisan migrate:rollback --step=3 --force ``` Rollback جدول Task و ستون‌های افزوده را حذف می‌کند و Noteهای backfillشده با کلید legacy پاک می‌شوند؛ متن اصلی در `calls.notes` باقی است. تغییر `notes.user_id` به nullable/`nullOnDelete` عمداً به cascade قدیمی برنمی‌گردد تا تاریخچه با حذف کاربر از بین نرود. در production rollback را فقط همراه backup و بررسی batch اجرا کنید. ## کنترل کیفیت ```powershell cd backend php artisan test cd ..\frontend npm run lint npm run test:run npm run build npm run test:e2e ``` تست‌های Feature، ماتریس نقش و IDOR، lifecycle و conflict، bulk transaction، note و visibility، backfill، notification/reminder و شماره تاریخی را پوشش می‌دهند. E2E مسیر ایجاد و تخصیص Task توسط Supervisor را در مرورگر پوشش می‌دهد.