ATP - زیرمراحل یک مرحله گردشکار (GET /api/v1/invention-cases/{invention_case_id}/workflow/steps/{step_key}/substeps/)
Endpoint
GET /api/v1/invention-cases/{invention_case_id}/workflow/steps/{step_key}/substeps/
هدف آزمون
دریافت projection زیرمراحل یک step از طریق trusted substep provider (ADR-0012).
شرایط آزمون
- سرویس core-api در حال اجرا باشد
- هدر Authorization با access token معتبر
- کاربر عضو workspace پرونده باشد
- step_key در workflow definition پرونده وجود داشته باشد
فرآیند آزمون
- GET workspace-navigation و انتخاب step_key
- GET .../workflow/steps/{step_key}/substeps/
- بررسی step و آرایه substeps
- اختیاری: ارسال ?run_id برای scope کردن prior-art به یک run
- پس از تغییر دامنه، با revision جدید دوباره fetch کنید
معرفی ویژگی
زیرمراحل پویا از مدلهای دامنه (source upload، extraction، prior-art search/report، draft sections، …) توسط providerهای ثبتشده در کد پروژه میشوند. جدول عمومی CaseSubstepInstance وجود ندارد.
- step: همان قرارداد WorkflowStepProjection
- substeps[]: key، renderer_key، availability، status، route، actions، badges
- route: دیکشنری ناوبری (مثلاً step_key + substep_key)
- run_id (Query): اختیاری؛ UUID اجرای prior-art برای projection scoped
- بدون محتوای draft: فقط metadata؛ ProseMirror برنمیگردد
سناریوی آزمون
سناریو 1: زیرمراحل prior_art
- ایجاد case با عضویت
- GET .../workflow/steps/prior_art/substeps/
- بررسی 200 و step.key=prior_art
- بررسی len(substeps) برابر bindingهای prior_art
- بررسی هر substep دارای route و status.execution
سناریو 2: خطا — step_key ناموجود
- GET با step_key=not_a_step
- دریافت 404
- بررسی error.code برابر WORKFLOW_STEP_NOT_FOUND یا NOT_FOUND
سناریو 3: run_id نامعتبر
- GET با ?run_id=abc
- دریافت 400
- بررسی error.code="VALIDATION_ERROR"
سناریو 4: step patent_drafting
- GET .../workflow/steps/patent_drafting/substeps/
- بررسی 200
- بررسی substeps مربوط به بخشهای draft (بدون content)
قالب API
| مولفه | نوع | نوع داده | اجباری | توضیحات |
|---|---|---|---|---|
| run_id | Query | uuid | خیر | محدود کردن projection به یک prior-art run |
| invention_case_id | Path | uuid | بله | شناسه پرونده اختراع |
| step_key | Path | string | بله | کلید مرحله گردشکار (مثلاً prior_art) |
Swagger
get:
summary: زیرمراحل یک مرحله گردشکار
responses:
200:
description: عملیات موفق
401:
description: احراز هویت نامعتبر یا ناقص
نمونه ورودی
curl -X GET "http://localhost:8000/api/v1/invention-cases/{invention_case_id}/workflow/steps/prior_art/substeps/" \
-H "Authorization: Bearer <access>"
نمونه خروجی
{
"success": true,
"data": {
"case_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"revision": 3,
"step": {
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"key": "prior_art",
"title": "Prior art",
"renderer_key": "prior-art",
"order_index": 0,
"required": true,
"availability": { "visible": true, "available": true, "read_only": false },
"status": { "execution": "not_started", "attention": "none" },
"feature": { "key": "prior_art", "version": 1 },
"actions": [],
"badges": []
},
"substeps": [
{
"id": "m1:source_upload",
"key": "source_upload",
"title": "Upload",
"renderer_key": "source-upload",
"order_index": 0,
"required": true,
"availability": { "visible": true, "available": true, "read_only": false },
"status": { "execution": "not_started", "attention": "none" },
"progress": null,
"domain_reference": null,
"route": { "step_key": "prior_art", "substep_key": "source_upload" },
"actions": [],
"badges": []
}
]
}
}
Status Codes
- 200: projection زیرمراحل برگردانده شد
- 400: run_id نامعتبر
- 401: احراز هویت نامعتبر
- 403: بدون دسترسی
- 404: پرونده یا step یافت نشد
نتیجه مورد انتظار
پاسخ شامل step و substeps[] نرمالشده. step_key ناموجود → 404 با کد پایدار. run_id بدفرمت → 400 VALIDATION_ERROR.
روال صحتسنجی
- بررسی 200 برای prior_art
- بررسی step.feature.key و تعداد substeps
- بررسی route.step_key و route.substep_key در هر آیتم
- بررسی 404 برای step_key ناموجود
- ارسال ?run_id=not-a-uuid و بررسی 400 با code="VALIDATION_ERROR"
- بررسی عدم وجود محتوای ProseMirror در پاسخ
توضیحات
- ADR-0012: providerها فقط با کلید trusted در کد ثبت میشوند
- unknown provider → خطای configuration پایدار
- محتوای draft و dirty state در frontend میماند؛ Core فقط metadata میدهد