Files
ERP/API_CONTRACT.md
T
MMD 934b74ebbd Squashed 'pm/' content from commit 91f3271
git-subtree-dir: pm
git-subtree-split: 91f3271d866fa8ee471cfb6793e334b83e6d2b6e
2026-10-07 15:14:20 +03:30

103 lines
6.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# PM API Contract (v3) — Standalone Native Platform — پایه: /api/v1
پلتفرم مدیریت پروژه ساختمانی بومی (Standalone)، مستقل و بدون وابستگی به هیچ سیستم خارجی.
## Auth
- `POST /auth/login` `{username, password}` → `{data:{token, user:{id, username, display_name, role}}}`
- `GET /auth/dev-roles` (در حالت توسعه) → لیست نقش‌های آماده جهت ورود سریع
- `POST /auth/dev-login` `{role}` (در حالت توسعه) → دریافت سریع توکن نقش انتخابی
- همه endpointها (جز لاگین و فایل‌های عمومی) هدر `Authorization: Bearer <token>` می‌خواهند.
- خطاها: `{"error": {"code", "message", "field"?}}` — کدها: `VALIDATION_ERROR` (400)،
`UNAUTHORIZED` (401)، `FORBIDDEN` (403)، `NOT_FOUND` (404)، `CONFLICT` (409)،
`UPSTREAM_UNAVAILABLE` (503).
## تاریخ جلالی
- **همه تاریخ‌های قابل مشاهده در UI شمسی‌اند.** API هم ISO می‌پذیرد/می‌دهد و هم شمسی.
- هر تسک علاوه بر `start_date`/`due_date` (ISO) فیلدهای `start_date_jalali`/
`due_date_jalali` را هم برمی‌گرداند («1405/06/23»).
- `PATCH /tasks/{id}/dates` هر دو قالب را می‌پذیرد: `1405/06/23` یا `2026-09-14`
(سال ≥ 1700 میلادی، کمتر از آن شمسی تفسیر می‌شود). روز نامعتبر → 400.
- تبدیل‌ها در `backend/app/utils/jalali.py` و `frontend/src/lib/jalali.ts` انجام می‌شوند.
## Dashboard
- `GET /dashboard/today` → `{data:{summary:{problems,warnings,ok}, sections:{overdue,due_today,awaiting_qc,failed_qc,blocked,upcoming}}}`
- `awaiting_qc` = وضعیت‌های `pre_qc_pending|exec_qc_pending|ready`
- `failed_qc` = وضعیت‌های `pre_qc_failed|qc_failed_rework`
## Projects
- `GET /projects` → `[...{id, name, identifier, description, active, erp_project_id, created_at, stats:{total, awaiting_qc, failed_qc, overdue}}]`
- `POST /projects` → ساخت پروژه جدید
- `GET /projects/{id}` → جزئیات پروژه به همراه آمارهای تسک‌ها
- `PUT /projects/{id}` | `DELETE /projects/{id}`
- `GET /projects/{id}/gantt` → داده‌های گانت چارت پروژه
- `PATCH /projects/{id}/erp-mapping {erp_project_id}`
## Tasks
- `GET /tasks?project_id=&search=&qc_status=&status=&page=&page_size=`
- `POST /tasks` → ثبت فعالیت/تسک جدید
- `GET /tasks/{id}` → تسک + `relations` + `children` + **`qc`** + **`qc_definitions`** + `defects` + `open_defects`
- `PUT /tasks/{id}` → ویرایش اطلاعات تسک
- `DELETE /tasks/{id}` → حذف تسک
- `PATCH /tasks/{id}/progress {percentage: 0..100}`
- **قاعده ۱:** اگر `percentage > 0` و بازرسی پیش از اجرا تأیید نشده باشد → 400
«بازرسی پیش از اجرا تأیید نشده است (N سؤال باقی‌مانده)»
- **قاعده ۲:** اگر `percentage >= 100` و هر سؤال الزامی تأییدنشده/مردود باشد → 400
«تا زمانی که همه بازرسی‌های الزامی تأیید نشوند پیشرفت ۱۰۰٪ مجاز نیست (…)»
- `PATCH /tasks/{id}/dates {start_date?, due_date?}` (ISO یا شمسی)
- `POST /tasks/relations` | `DELETE /tasks/relations/{id}` → مدیریت روابط وابستگی تسک‌ها (FS, SS, FF, SF)
### شکل بلوک `qc` در جزئیات تسک
```json
{"pre": {"total":3,"passed":3,"failed":0,"pending":0,"na":0,"required_unresolved":0,"status":"passed"},
"exec": {"total":6,"passed":2,"failed":1,"pending":3,"na":0,"required_unresolved":4,"status":"pending"},
"all": { /* مجموع */ },
"status": "exec_qc_pending",
"can_start": true, "can_complete": false,
"block_reasons": ["تا زمانی که همه بازرسی‌های الزامی تأیید نشوند پیشرفت ۱۰۰٪ مجاز نیست (۴ سؤال باقی‌مانده، ۱ مورد مردود)"]}
```
### وضعیت‌های `qc_status` روی تسک
`none` · `pre_qc_pending` · `pre_qc_failed` · `ready` · `exec_qc_pending` ·
`in_progress` · `qc_failed_rework` · `final_passed`
## QC — تعریف (Definition)
### قالب‌های سراسری (قابل استفاده مجدد)
- `GET /qc/templates` → `[{id,name,activity_type,description,questions:[{id,phase,text,sort_order,required}]}]`
- `POST /qc/templates {name, activity_type?, description?, questions?:[…]}` → `{data:{id}}`
- `PATCH /qc/templates/{id} {name?,activity_type?,description?}`
- `DELETE /qc/templates/{id}`
- `POST /qc/templates/{id}/questions {phase,text,required?,sort_order?}`
- `PATCH /qc/questions/{qid} {text?,phase?,required?,sort_order?}`
- `DELETE /qc/questions/{qid}`
- `PUT /qc/templates/{id}/questions {questions:[…]}` — جایگزینی گروهی (برای ادیتور)
`phase` ∈ `"pre"` (پیش از اجرا) · `"during"` (هنگام اجرا) · `"after"` (پس از اجرا)
### تعریف مخصوص تسک (کپی مستقل — ویرایش آن قالب سراسری را تغییر نمی‌دهد)
- `GET /qc/tasks/{task_id}` → `{data:{task, definitions:[{id,name,source_template_id,created_at,questions:[{…,result,history_count}],summary}], readiness}}`
- `POST /qc/tasks/{task_id}/definition {name?, template_id?}` → **کپی عمیق** سؤالات قالب
- `PATCH /qc/definitions/{id} {name}` | `DELETE /qc/definitions/{id}`
- `POST /qc/definitions/{id}/questions {text,phase,required?,sort_order?}`
- `PATCH /qc/task-questions/{qid} {text?,phase?,required?,sort_order?}`
- `DELETE /qc/task-questions/{qid}`
## QC — اجرا (Execution)
- `PUT /qc/task-questions/{qid}/result {answer:"pass"|"fail"|"na", comment?}`
→ `{data:{question_id, answer, task_qc_status, readiness}}`
- پاسخ‌ها **append-only** هستند (تاریخچه می‌ماند؛ بازرسی مجدد پس از رفع عیب ممکن است)
- تعریف و اجرا کاملاً جدا هستند: هنگام ساخت/کپی سؤال هیچ پاس/ردی ثبت نمی‌شود.
- عیب‌ها:
- `POST /qc/defects {task_id, question_id?, title, description?, severity?, corrective_action?, photo_id?}`
- `POST /qc/defects/{id}/resolve {resolution_notes?}`
- عکس عیب: `POST /files` (multipart) → `{data:{id, url}}` سپس `photo_id`
## فایل‌ها
- `POST /files` multipart (jpg/png/webp تا ۱۰MB) → `{data:{id,url,filename}}`
- `GET /files/{id}`
## Materials / Resources (یکپارچگی ERP)
- `GET/POST /tasks/{task_id}/materials` · `PATCH/DELETE /materials/{req_id}`
- `GET /erp/materials?search=` · `GET /erp/projects`
- `POST /materials/{req_id}/reserve|purchase-request` · `GET /reservations` · `POST /reservations/{id}/release`
- `GET/PATCH /purchase-requests` · `POST /projects/{project_id}/erp-mapping`