Topic exchange؛ صفهای durable؛ reject خطای مدیریتنشده به DLQ.
Redis / Celery
کش و jobهای async داخلی Core (نه مسیر اصلی workerهای AI)
CELERY_BROKER_URL
استخراج/context/prior-art از outbox/inbox عبور میکنند، نه Celery بهعنوان مسیر اصلی.
مرز سرویس در پلتفرم
core-api مالک پرونده، workspace، RBAC، projection وضعیت گردشکار و orchestration کارهای AI است. workerهای بیرونی فقط محاسبه میکنند و از RabbitMQ + Object Storage با Core یکپارچه میشوند.
Frontend از REST و SSE (workspace-navigation، workflow-state، workflow-events، conversation stream) با Core صحبت میکند.
Core هرگز مدل Django workerها را import نمیکند و workerها هرگز مستقیماً به PostgreSQL Core نمینویسند.
فایل اصلی در S3 ذخیره میشود؛ رویداد درخواست فقط metadata و کلید artifact را حمل میکند.
ناوبری سلسلهمراتبی UI از GET .../workspace-navigation/ و GET .../workflow/steps/{step_key}/substeps/ تغذیه میشود (ADR-0012).
workflow-state و workflow-events برای polling/SSE سازگار باقی میمانند؛ readiness endpointها برای tooling هستند.
ماژولهای آینده (stages، entitlements، packages، exports) فقط پس از vertical slice واقعی نصب میشوند.
هر Django app یک bounded context است: models برای schema، services برای mutation، selectors برای read، policies برای authorization. وابستگی بین appها یکطرفه است.
Mutation در transaction Django یک OutboxEvent میسازد. sidecar outbox-publisher به RabbitMQ publish میکند. inbox consumerها رویداد terminal worker را idempotent در PostgreSQL Core اعمال میکنند.
document.extraction.requested پس از آپلود SourceDocument؛ completed/failed در document-extraction-inbox-consumer.
context.extraction.requested با کلید artifact متن نرمالشده؛ questions_required برای Q&A تکمیلی.
prior_art.search.requested و prior_art.report.requested جداگانه؛ report پس از search.completed orchestrate میشود.
رویدادهای context ممکن است snapshot inline داشته باشند؛ prior-art فقط pointer + manifest برمیگرداند.
schema_version در envelope رویداد؛ consumer نامعتبر را reject و به DLQ میفرستد.
پس از inbox، CaseWorkflowEvent و revision ناوبری/workflow-state برای invalidate کردن کش frontend bump میشود.
flowchart LR
api["Django API<br/>service + transaction"]
outbox[("OutboxEvent")]
pub["outbox-publisher"]
ex[("patent_genie.events")]
worker["External worker"]
inbox[("InboxEvent")]
cons["inbox consumer"]
state["Product state<br/>summary · snapshot · executions"]
api --> outbox --> pub --> ex --> worker
worker --> ex --> inbox --> cons --> state
Case Workflow و SSE
CaseWorkflowStateService projection واحد UI را از intake، context و prior-art میسازد. CaseWorkflowEvent + SSE revision bump برای بهروزرسانی زنده frontend.
information_collection از SourceDocument + DocumentProcessingSummary تغذیه میشود.
context_completion از internal_context runs/snapshots/questions میآید.
prior_art_collection از PriorArtRun و search/report executions.
InventionCase.current_stage اشارهگر legacy مرحله است؛ پیشرفت محصول از CaseModuleInstance و capabilities مشتق میشود (ADR-0011).
POST transition-stage حذف شده است؛ tooling از GET progress و projectionها استفاده میکند.
WorkflowRun و Conversation لایه product shell هستند؛ source of truth دامنه در invention_cases / documents / prior_art میماند.
Frontend ناوبری پرونده را از projectionهای نرمالشده میگیرد، نه از اسمبلی سختکدشده. ProductFeature نسخهبندیشده substepها را تعریف میکند؛ trusted providers مدل دامنه را به DTO تبدیل میکنند (ADR-0012/0013).
GET .../workspace-navigation/ مراحل سطحبالا + feature {key, version} + revision را برمیگرداند.
GET .../workflow/steps/{step_key}/substeps/ زیرمراحل یک step را از FeatureSubstepBinding و providerها میسازد.
Providerها فقط با کلید trusted در کد ثبت میشوند؛ مسیر import پایتون در DB ذخیره نمیشود.
زیرمراحل پویا (مثلاً DraftDocumentSection) فقط metadata دارند؛ محتوای ProseMirror در projection نیست.
CaseModuleInstance تنها runtime instance برای step/feature است؛ جدول عمومی CaseSubstepInstance وجود ندارد.
SSE با event_type و revision کش navigation و substeps را هدفمند invalidate میکند.
flowchart TB
shell["Frontend case workspace"]
nav["GET .../workspace-navigation/"]
sub["GET .../steps/{step_key}/substeps/"]
proj["WorkflowNavigationProjectionService"]
reg["Trusted provider registry"]
feat["ProductFeatureVersion<br/>+ FeatureSubstepBinding"]
mod["CaseModuleInstance"]
domain["Domain models<br/>docs · context · prior_art · draft sections"]
shell --> nav & sub
nav & sub --> proj
proj --> feat & mod & reg
reg --> domain
proj -->|"normalized DTOs + revision"| shell
Clean Architecture عملگرا
بدون ceremony DDD: view نازک، service برای workflow، selector برای read، policy برای authorization. mutation حساس حتماً audit emit میکند.
accounts: JWT + UserSession؛ workspaces/access_control: RBAC و CaseAccessGrant.
capabilities: catalog، feature versions، workflow projection؛ بدون import مدل worker.
internal_context: opaque snapshot payload؛ Core schema worker را mirror نمیکند.
prior_art: staleness وقتی snapshot جدید ready شود؛ policies قبل از start/retry.
API responses UUID عمومی expose میکنند؛ workspace scoping در selectors پیشفرض است.
flowchart LR
req["HTTP request"]
view["View / Serializer"]
policy["Policy"]
service["Service"]
selector["Selector"]
model[("Django Model")]
audit["audit service"]
req --> view --> policy
view --> selector --> model
view --> service --> model
service --> audit
استقرار Docker Compose
Compose سرویس api، sidecarهای outbox/inbox، PostgreSQL و Redis را از یک image میسازد. RabbitMQ و S3 از stack infra روی شبکه patent-genie-local در دسترس هستند.