معماری چندکسبوکاری، تجاری و تجارت الکترونیک · فصل ۵ — Editorial Cell، SEO، QA، Approval و Onboarding · 259
Client Approval States و Revision Branching
workflow تجاری را به UI یا integration منفرد تقلیل میدهد و state، rights، approval و measurement را یکپارچه نمیکند. موضوع جاری: «Client Approval States و Revision Branching». میتواند «Client Approval States و Revision Branching» را برای یک workflow محدود با state/contract/approval و verification مناسب طراحی کند.
خلاصهٔ درس
workflow تجاری را به UI یا integration منفرد تقلیل میدهد و state، rights، approval و measurement را یکپارچه نمیکند. موضوع جاری: «Client Approval States و Revision Branching».
میتواند «Client Approval States و Revision Branching» را برای یک workflow محدود با state/contract/approval و verification مناسب طراحی کند.
خروجی این درس
میتواند «Client Approval States و Revision Branching» را برای یک workflow محدود با state/contract/approval و verification مناسب طراحی کند.
1) چرا یک فیلد «Approved» کافی نیست؟
در پروژههای واقعی، بازخورد مشتری از چند کانال میرسد: کامنت، ایمیل، پیامرسان، review tool یا جلسه. اگر نتیجهی همهی اینها در یک فیلد mutable مثل Approved=true خلاصه شود، خیلی زود معلوم نیست چه کسی، دقیقاً کدام revision، با چه scope و چه اختیاری را تأیید کرده است. بعد یک ویرایش کوچک انجام میشود و همان approval قبلی ظاهراً روی نسخهی جدید باقی میماند؛ در حالی که مشتری هرگز نسخهی جدید را ندیده است.
در این درس Client Approval Revision Branch Ledger v1 را میسازیم: یک ledger محدود و قابلممیزی که approval، rejection و request-changes را به revision دقیق، branch lineage، reviewer role، authority و rationale متصل میکند.
قانون مرکزی: approval یک ویژگی شناور روی «آیتم» نیست؛ یک decision record روی revision مشخص است.
2) مرز درس
COM-018 مالک Client Approval States و Revision Branching است. COM-017 مالک Content Workflow States و COM-019 مالک Safe Workflow Lab است. این درس workflow کلی را از نو طراحی نمیکند و آزمایشگاه safety هم نمیسازد؛ تمرکز فقط روی این است که تصمیم مشتری در برابر revision و branch چگونه معتبر یا نامعتبر میشود.
همچنین این درس authority واقعی مشتری، قرارداد حقوقی، انتشار production، billing یا دسترسی tenant را ایجاد نمیکند. ما فقط یک مدل evidence-backed برای تصمیمگیری میسازیم.
3) مدل ذهنی: Case → Revision → Authority → Decision → Branch → Fresh Review
هر approval case باید حداقل این زنجیره را داشته باشد:
approval_case_id؛content_item_id؛- baseline و branch مشخص؛
revision_idوrevision_digest؛- reviewer و role؛
decision_authority؛- state تصمیم؛
- scope و rationale؛
- requested changes؛
- supersession relation؛
- conflict/reopen state؛
- audit event و evidence ref.
| approval_case_id | content_item_id | baseline_version | branch_id | branch_parent | revision_id | revision_digest | reviewer_id | reviewer_role | decision_authority | approval_state | decision_scope | decision_rationale | requested_change_ids | supersedes_decision_id | merge_target | conflict_state | reopen_reason | timestamp | audit_event_id | evidence_ref |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| CASE-018-A | item-campaign-7 | v16 | branch-main | root | r17 | sha-r17-a | client-01 | CLIENT_APPROVER | CLIENT_FINAL | APPROVED | FULL_CAMPAIGN | All approved on r17 | [] | DEC-016 | branch-main | NONE | 2026-09-15T10:00:00Z | AUD-018-A | EV-018-A | |
| CASE-018-B | item-campaign-7 | v16 | branch-main | root | r18 | sha-r18-b | client-01 | CLIENT_APPROVER | CLIENT_FINAL | APPROVED | FULL_CAMPAIGN | Old approval copied after edit | [] | DEC-017 | branch-main | NONE | edited after approval | 2026-09-15T11:00:00Z | AUD-018-B | EV-018-B |
| CASE-018-C | item-campaign-7 | v16 | branch-legal | branch-main | r17-legal | sha-r17-l | client-01 | CLIENT_APPROVER | CLIENT_FINAL | APPROVED | LEGAL_CLAUSE | Sibling approval reused | [CHG-LEGAL-1] | DEC-017 | branch-main | OPEN | legal clause reopened | 2026-09-15T12:00:00Z | AUD-018-C | EV-018-C |
اگر یکی از اجزای حیاتی گم باشد، تصمیم نباید بهزور «Approved» شود. stateهای محدود مثل HOLD، DISPUTED یا BLOCKED بخشی از طراحی درستاند.
4) Fact بیرونی را از طراحی MAKNOW جدا کن
مستندات فعلی Contentful نشان میدهد workflow stepها میتوانند مشخص کنند چه کاربران یا تیمهایی حق edit، publish یا تغییر step را دارند. همچنین workflow میتواند حرکت رو به جلو یا عقب برای revision بیشتر داشته باشد. اینها FACT دربارهی رفتار پلتفرم هستند.
اما این نتیجه از Contentful درنمیآید که approval باید دقیقاً با چه branch naming، چه state vocabulary یا چه merge rule ذخیره شود. binding تصمیم به revision و branch، و اینکه edit بعد از approval نیازمند fresh review است، DESIGN داخلی MAKNOW است.
5) approval باید به revision identity متصل باشد
دو شناسه را از هم جدا کن:
revision_id: شناسهی منطقی نسخه؛revision_digest: fingerprint محتوای همان نسخه.
اگر مشتری revision r17 با digest مشخص را approve کرده و بعد محتوای همان item تغییر کرده، تصمیم قدیمی نباید روی r18 یا digest جدید حمل شود. حتی اگر عنوان آیتم و URL ثابت باشند، evidence عوض شده است.
در ledger، یک approval فقط وقتی معتبر است که revision تصمیم با revision فعال برابر باشد و lineage آن قابلردیابی باشد. mismatch باید state را به BLOCKED_STALE_APPROVAL ببرد، نه اینکه «تقریباً approved» فرض شود.
6) branch lineage جلوی approvalِ اشتباه را میگیرد
فرض کن از baseline یک branch برای طراحی و یک sibling branch برای اصلاح حقوقی ساخته شده است. approval روی branch طراحی، خودکار روی sibling حقوقی معتبر نیست. ممکن است diff کوچک باشد، اما evidence مستقل است.
بنابراین branch_id، branch_parent و merge_target باید قابلردیابی باشند. اگر approval از branch دیگری reuse شود، نتیجه باید BLOCKED_CROSS_BRANCH_APPROVAL باشد تا یک تصمیم تازه ثبت شود.
7) authority با role یکی نیست
داشتن role مثل Editor یا Designer لزوماً به معنی حق نهایی تأیید مشتری نیست. reviewer_role توصیف میکند فرد چه نقشی دارد؛ decision_authority میگوید آیا همان فرد میتواند این نوع decision را صادر یا supersede کند.
اگر یک reviewer بدون authority تصمیم client approver را supersede کند، ledger باید آن را مسدود کند. نام کاربر، seniority یا دسترسی UI جای authority evidence را نمیگیرد.
8) state vocabulary باید معنی عملی داشته باشد
برای این درس stateهای اصلی چنیناند:
APPROVED_REVISION_BOUND: revision دقیق با authority معتبر تأیید شده؛CHANGES_REQUESTED: تغییرات مشخص درخواست شدهاند؛REJECTED: تصمیم رد با rationale ثبت شده؛HOLD_MISSING_EVIDENCE: evidence حیاتی ناقص است؛BLOCKED_STALE_APPROVAL: approval مربوط به revision قدیمی است؛BLOCKED_CROSS_BRANCH_APPROVAL: تصمیم از branch دیگری reuse شده؛BLOCKED_UNAUTHORIZED_SUPERSESSION: actor حق override ندارد؛DISPUTED_CONFLICT: تصمیمهای متعارض بدون resolution وجود دارد؛PARTIAL_SCOPE_REOPENED: فقط scope مشخصی دوباره برای review باز شده است.
این vocabulary قرار نیست تمام سیستم workflow را مالک شود؛ فقط outcome محدود این درس را پوشش میدهد.
9) conflict و supersession را پاک نکن
وقتی دو reviewer تصمیم متفاوت میدهند، overwrite کردن رکورد قبلی audit trail را خراب میکند. تصمیم جدید باید supersedes_decision_id داشته باشد، و conflict قبلی باید قابلردیابی بماند.
اگر conflict هنوز باز است، merge نباید نتیجهی نهایی بسازد. conflict_state=OPEN باید یک state مثل DISPUTED_CONFLICT ایجاد کند. فقط بعد از resolution مستند، branch میتواند به merge candidate تبدیل شود.
10) درخواست تغییر هم باید evidence داشته باشد
requested_change_ids نباید متن مبهمی مثل «یه کم بهترش کن» باشد. هر change بهتر است شناسه، scope و rationale داشته باشد تا معلوم شود کدام بخش approval قبلی را invalidate کرده است.
اگر تغییر فقط بخشی از محتوا را تحتتأثیر قرار داده، میتوان accepted scope را حفظ کرد و فقط همان scope را reopen کرد. این دقیقاً جایی است که revision branching از دوبارهکاری کامل جلوگیری میکند.
11) Lab: هشت fixture برای failure path واقعی
Lab این درس آفلاین، synthetic و بدون credential است. هشت fixture داریم و برای هر fixture شش invariant deterministic بررسی میشود؛ در مجموع 48 assertion.
Failureها شامل این موارداند:
- edit بعد از approval بدون fresh revision review؛
- reuse approval روی sibling branch؛
- supersession توسط reviewer بدون authority؛
- missing evidence؛
- conflict unresolved؛
- merge قبل از resolution؛
- transfer case که یک clause حقوقی بعداً reopen میشود.
هدف این نیست که فقط baseline را سبز کنیم؛ باید دقیقاً ببینیم چرا shortcutها blocked یا disputed میشوند.
12) تمرین انتقال: فقط scope آسیبدیده را دوباره باز کن
سناریوی انتقال: مشتری کل campaign bundle را approve کرده، اما legal reviewer بعداً فقط یک clause را reopen میکند. طراحی ضعیف یا approval کل bundle را معتبر نگه میدارد، یا برعکس همهچیز را از صفر وارد review میکند.
طراحی درست این است:
- accepted scopeهای دستنخورده حفظ شوند؛
- clause بازشده در revision branch جدید قرار گیرد؛
reopen_reasonو requested change ثبت شوند؛- فقط همان scope نیازمند fresh approval باشد؛
- merge نهایی تا resolution همان scope متوقف بماند.
این fixture باید به PARTIAL_SCOPE_REOPENED برسد، نه approval کامل و نه reset کامل.
13) جمعبندی و معیار عبور
Client Approval States زمانی قابلاعتمادند که تصمیم را از یک flag mutable به رکورد نسخهدار و authority-bound تبدیل کنیم. برای عبور از این درس باید بتوانی ثابت کنی: revision و digest دقیقاند، branch lineage روشن است، reviewer authority معتبر است، conflict overwrite نشده، requested changes قابلردیابیاند و edit بعد از approval به fresh review منجر میشود.
Artifact نهایی این درس Client Approval Revision Branch Ledger v1 است؛ publication یا release authority نیست.
منابع و تازگی
- Contentful Help Center, Workflows — rechecked 2026-09-15.
- Contentful Help Center, Workflow rules: editing and publishing permissions — rechecked 2026-09-15.
- Contentful Help Center, Workflow step change permissions — rechecked 2026-09-15.
- revision binding، branch semantics، supersession و partial-scope reopen در این درس DESIGNهای MAKNOW هستند و به vendor نسبت داده نمیشوند.
ارزیابی
پاسخنامهی این درس در بستهی آموزش وجود ندارد؛ خودت جواب بده و صادقانه علامت بزن. «نیاز به مرور» درس را به صف تکرار میفرستد.
Q1 retrieval
Why is an item-level Approved flag insufficient after a content edit?
Q2 diagnosis
An approval from branch-design is copied to branch-legal. Which evidence dimensions invalidate the shortcut and what bounded state should result?
Q3 transfer
A legal reviewer reopens one clause after a client approved the rest. Preserve unaffected scope and require fresh approval only where evidence was invalidated.
ملاکهای ارزیابی (rubric)
Pass requires: explicit COM-018 boundary; exact revision id/digest binding; branch lineage; explicit decision authority; preserved supersession and conflict history; traceable requested changes; typed non-success states when evidence is missing or invalid; and a transfer solution that reopens only the invalidated scope.
منابع و تازگی
مطالعهٔ موارد (case studies)
فایلهای آزمایشگاه
دستور python run_checks.py را اجرا کنید. اعتبار approval را از revision، branch، authority، conflict و evidence تشخیص دهید. فقط از دادههای مصنوعی استفاده کنید.