Action-Oriented Architecture

الكود
— هو الرسم البياني.

AOA هو إطار عمل Python تكون فيه عملية العمل هي العمود الفقري للمعمارية كلها. العملية نفسها تُعلن من يحق له تنفيذها، وعلى ماذا تعتمد، وماذا يحدث عند الفشل؛ ومن فهرس العمليات يُبنى رسم بياني يتحقق من نفسه ويمنع اختلاط البنية التحتية بمنطق العمل. المخالفة تُلتقط عند الإقلاع، لا في الإنتاج بعد ثلاثة أسابيع.

pip install aoa-action-machine
كيف تبدأ
python 3.12+ترخيص Apache 2.0CI ناجحاختبارات 2 555aoa-action-machine 1.0.1a2
orders/actions.py
@meta(domain=OrderDomain)@check_roles(ManagerRole)@depends(PaymentGateway)@compensate(refund_payment)class ChargeOrderAction(BaseAction[Params, Result]):    @result_state(OrderStatus.CONFIRMED)    async def charge_aspect(self, params, state, box):        await self.gateway.charge(params.amount)        return {"status": OrderStatus.CONFIRMED}
يجتازه إطار العملمباشرةً، عند الاستيراد
DomainRoleActionGateway

01 — نظرة عامة

المعمارية تعيش في الكود.
لا في الرؤوس ولا في المستندات.

لا تموت الأنظمة بسبب الأخطاء البرمجية — بل لأن الناس يتوقفون مع الوقت عن فهمها، بينما يتغيّر الفريق ويزداد التعقيد. نتعلّم كتابة الكود، وتطبيق الأنماط، واتّباع الأساليب — لكن لا يعلّمنا أحد كيف نُدير التعقيد ونُبقي النظام قابلًا للقراءة بعد سنة أو سنتين أو خمس سنوات. كل دقيقة تُنفَق في معرفة «ما الذي يجري هنا» هي دقيقة مسروقة من التقدّم.

يتبنى AOA نهجًا مختلفًا: فهو ينقل المعرفة بالمعمارية والنظام من أذهان الأشخاص والوثائق المتقادمة — إلى الكود، بوصفه قصدًا قابلًا للقراءة آليًا: قابلًا للتنفيذ، وقابلًا للتحقق، وقابلًا للمراقبة.

خمسة مستويات من التفصيل

كيف تقطع الطريق من فهم النظام ككل إلى الكود نفسه

كل مستوى نقطة ارتكاز: يجيب إجابة كاملة عن سؤاله الخاص عن ماهية النظام، دون أن يشترط معرفة ما هو أعمق.

استعراض المستويات الخمس ↗
01

Domain

أين تكمن المسؤولية؟

02

Action

ما الذي يستطيعه النظام؟

03

Contract

ماذا تتطلب العملية وبماذا تعد؟

04

Pipeline

كيف يتطور السيناريو؟

05

Code

أين يقع السلوك الفعلي؟

● مُستخرَج من الرسم البياني
Design-first

صمِّم النموذج، ثم الكود.

الكيانات وعلاقاتها ودورة حياتها تُعلَن كنموذج نطاق خالص — غير مرتبط بـORM ولا بقاعدة بيانات بعينها. وسلامة النموذج كله يجري التحقق منها عند الإقلاع.

صمِّم النموذج →
ResourceEntityRelationsLifecyclethe domain, understoodthencode
Params → Result

صنف واحد، العملية كاملة.

الأدوار والخطوات والتعويضات والأخطاء والذاكرة المؤقتة والتبعيات مُعلَنة في مكان واحد: Params دخولًا وResult خروجًا، وبلا أي باب جانبي بينهما.

transportrolesIoCrollbackcontextconnectionActionParamsResultrolesstepsrollbackcontext
تصحيح مباشر

Action X-Ray.

يُضمِّن رؤية على مستوى المُصحِّح داخل المعمارية نفسها: يمكن مراقبة سير العملية وحالتها في كل خطوة مباشرةً حتى في بيئة الإنتاج — دون إيقاف العملية.

افتح Action X-Ray ↗
ONLINE DEBUG · RUN #A84FLIVE · PRODUCTIONACTION · ONE EXECUTIONParamsvalidatereservechargeResultSTATE IN{ validated_items: 3 }STATE OUTreservation_id · 18.6 msinput · output · error · duration at every boundarydevelopment · tests · production — the same projection
@depends / @connection / @context_requires

منافذ المعمارية السداسية، لا تبعيات.

@depends / @connection / @context_requires تُعلن منافذ Action — وتتصل المُهايئات من الخارج. box.resolve(T) لا يُعيد إلا ما هو مُعلَن.

PaymentGatewayEmailServiceInventoryServiceenv.* · runtime.*request.* · user.*@depends@connection@depends@context_requiresActionbox.resolve(T) — только объявленное
TestBench

استبدل العالم، لا الكود.

يعمل الـPipeline الحقيقي دون أي تعديل — لكن على عالم مُستبدَل: المستخدم، والكائنات الوهمية، والسياق. ما ينجح هنا هو ما يعمل في بيئة الإنتاج.

Test worldmocked gatewayProd worldreal gatewayActionResultsame pipeline — different world

02 — Maxitor

الرسم البياني أعلاه — حقيقي.
وهذه هي الأداة التي ترسمه.

كل Domain وRole وتبعية يصبح عقدة لحظة الاستيراد — أربعة تمثيلات مختلفة لنفس النظام قيد التشغيل، وجميعها تصديرات غير مُعدَّلة.

الرسم البياني الكامل

كل Domain وRole وتبعية — رسم بياني واحد.

جرّب Maxitor ↗

Domain ERD

الكيانات وعلاقاتها.

جرّب Maxitor ↗

مخطط Use-case

Role، وAction يمكنها الوصول إليها.

جرّب Maxitor ↗

Lifecycle FSM

كل الانتقالات القابلة للوصول بين الحالات.

جرّب Maxitor ↗

03 — الإمكانيات

أكثر من مجرد Pipeline.

نفس الرسم البياني المُعلَن يغذّي التخزين المؤقت، والأحداث التجارية، وقابلية المراقبة، وأطر عمل الوكلاء — دون سطر واحد من كود الربط.

Actionmachinerolescacheeventsrollback

الآلة التي تُشغِّلها.

كل Action تُشغِّله آلة واحدة: الأدوار والذاكرة المؤقتة والأحداث والتراجعات من صنعها.

cache_key?cached valueaspectHITMISS

تخزين مؤقت، مُعلَن.

cache_key يقود مباشرةً إلى النتيجة؛ وعند الإخفاق يُشغَّل الـAspect، بينما يحفظ on_cache_write القيمة.

ActionOrderCompletedMaxitorOCELDash

الأحداث حقائق، لا أسطر سجلّ.

box.info(Channel.business, …) يُصدر حقيقة مُحدَّدة النوع — يقرؤها كلٌّ من Maxitor وOCEL ولوحات المعلومات.

machineloggerotelocelone way — side-effects only

الـObserver لا يمكنه التدخل.

أزل كل الـObservers — لن يتغيّر السلوك. القياس عن بعد ضمانٌ، لا أمل.

aspectraiseson_errorResultone handler — end of pipeline

مكان واحد تتجمّع فيه كل الأخطاء.

معالج واحد فقط، في نهاية الـPipeline، يقرر ما ستُعيده العملية بعد الفشل.

reservereleasechargerefundpersistreverse order — automatic

الـSagas تتراجع من تلقاء نفسها.

الفشل يُفكِّك الخطوات المكتملة بترتيب عكسي، والتراجع مُعلَن بجوار خطوته.

check_rolesроль · RBACgrant/guardлёгкий ABACaccess_decide()глубокий ABACmachine.check() → AccessVerdict«могу ли я» — без вызовакаждый уровень может отказать раньше следующего

RBAC أولًا. ثم ABAC، بعمق أكبر فأكبر.

check_roles — RBAC خالص: هل الـRole موجود. grant.when / guard= — ABAC خفيف على مستوى الاستدعاء. access_decide() — ABAC معقّد: الكائن والحقيقة.

OrderDomainActionRoleManagerRoleissubclass = authorityaccess matrixdomain × role — вместе матрица доступа

Domain وRole — خريطة النظام.

Domain هو نقطة تجميع العملية: الرسم البياني، ومصفوفة الوصول، والتصور المرئي. ويحمل Role الصلاحيات عبر الوراثة. ومعًا يُشكِّلان هذه المصفوفة.


04 — الامتداد

النواة صغيرة.
أما النظام البيئي، فلا.

نفس الرسم البياني المُعلَن يصل العملية بالعالم الخارجي: أطر عمل الوكلاء، والطوابير، والواجهات، وقابلية المراقبة. النواة لا تنمو — بل ينمو ما حولها.

startplanActionrespondagent loop

عقدة مُحدَّدة النوع في LangGraph.

يُضمِّن LangGraphController الـAction داخل رسم بياني للوكيل — نفس العقود، ونفس التراجع.

KafkaplannedFastAPIHTTPMCPAI toolsActionthe adapters translate — the Action doesn't change

Action واحد. أي واجهة أمامية.

مسار HTTP واستدعاء أداة AI هما نفس العملية، بنفس الضمانات.

many runsOCELobject-centric logOrderthe real process, discovered from what actually ran

OCEL/OCPM — العملية الحقيقية، لا مخطط.

كل تشغيل يُنتج بالفعل lifecycle events. يرى Process mining من خلالها العملية الحقيقية والكيانات المعنية — لا مخططًا رُسم مرة واحدة.

ActionlifecycleeventsX-RayOTel spansone source of events — two live projections

OTel — نفس الأحداث، في هيئة تتبع.

نفس الإضافة التي تبني الإسقاط المباشر لـAction X-Ray، تُصدر الأحداث إلى OpenTelemetry: مصدر واحد — تتبعات وتشغيل مباشر في آنٍ معًا.

route→ capabilityVerdictallowedreasonexpiresReactmobileFletsame verdict — any UI

Intent-Based UI — ليست قيمة منطقية، بل حكمًا.

المسار → إمكانية مُحدَّدة النوع: verdict() يشرح الرفض، وcall() يستدعي. عقد واحد — React، وmobile، وFlet.

EntityModelAgentActomdigital twinentity + behavior + agent — one declaration

Digital twin

يجمع Actom بين الكيان والسلوك والوكيل في إعلان واحد — فاعل ذو حالة، يمكن مراقبته عبر Action X-Ray. تصبح الملفات توأمًا بيانيًا للنظام.


05 — المفاهيم

خمسة مواضيع.
كل واحد سيصبح صفحة مستقلة.

خمس زوايا مستقلة لنفس النظام — من قواعد الإعلانات إلى موقع AOA بين الأطر الأخرى.

01

قواعد إلزامية

تُحوِّل القواعد كل قاعدة إلى إعلان (@check_roles، @depends، مُدققات، قواعد تسمية)؛ وعند الاستيراد تندمج هذه الإعلانات في رسم بياني — وهكذا يكون الكود هو المواصفة، والرسم البياني هو صورته القابلة للقراءة آليًا: يُتحقَّق منه عند التشغيل، ويُرسَم في Maxitor، ويتتبعه Action X-Ray — لا وثيقة تطفو في مكانٍ ما بجوار الكود.

02

دستور AOA

ثمانية عناصر أساسية ومجموعة من الإعلانات الإلزامية — ليست اصطلاح تنسيق، بل قانون تتحقق منه الآلة عند كل استيراد. لا يمكن انتهاكه بصمت: عدم التوافق يوقف التشغيل، ولا يظهر لاحقًا في بيئة الإنتاج.

03

الفصل بين منطق الأعمال والبنية التحتية

يعرف Action الـDomain والقواعد؛ أما كيفية الوصول إلى Postgres أو Kafka أو API خارجي، فيعرفها المُهايئ الكائن خلف واجهة Gateway أو Resource. الكود الخاص بمنطق الأعمال لا يستورد المشغِّلات مباشرةً — يمر الحدّ عبر الإعلان، لا عبر اتفاق بين المطورين.

04

مبادئ البرمجة الموجهة بالقصد

يُعلن الكود القصد — ما الذي ينبغي أن يحدث وتحت أي شروط — لا تسلسلًا من استدعاءات مكتبات مُحدَّدة. يُحقن التنفيذ عبر منافذ (@depends، @connection) ويمكن أن يتغيّر ما دام القصد ثابتًا.

05

المقارنة مع الأطر الأخرى

يمنحك FastAPI وDjango التوجيه وORM، لكنهما لا يتحققان من الـRole والتبعيات وانتقالات الحالة عند الاستيراد. يبني LangGraph رسمًا بيانيًا بشكل صريح، لكن لتنسيق خطوات LLM، لا عمليات الأعمال. تقف AOA أقرب إلى الاثنين معًا — رسم بياني قابل للتنفيذ لمعمارية التطبيق، لا مجرد نقل أو Pipeline نموذج.


06 — وصفات عملية

مهمة واحدة.
وصفة واحدة.

مُوجَّهة نحو المهمة، لا نحو التعليم — أنت تعرف مسبقًا ما تبنيه. وهذه الوصفات تخبرك كيف.

how-to/authoring-action

هيكل Action: Params، وPipeline الـAspects، وcheckers، والاتصالات.

how-to/choosing-primitive

دليل لاختيار العنصر الأساسي الذي يناسب مهمتك فعلًا.

how-to/authoring-resource

غلِّف قاعدة بيانات أو طابورًا أو SDK في تبعية مُدارة وقابلة للحقن.

how-to/authoring-adapter

افتح الوصول إلى Action الموجودة عبر بروتوكول جديد، دون المساس بها.

how-to/authoring-cache-adapter

وصِّل backend مختلفًا للتخزين المؤقت بـcache_key / on_cache_write.

how-to/authoring-plugin

راقب أحداث الـLifecycle الخاصة بالآلة، دون أي حق في التدخل.

how-to/authoring-auth-coordinator

اربط مخطط مصادقة مخصصًا بـ@check_roles.

how-to/authoring-logger

وجِّه box.info / box.warning إلى حيث تعيش سجلاتك فعليًا.

how-to/authoring-intent

أعلن عن قواعد مشاركة جديدة يمكن لعناصر أساسية أخرى الانضمام إليها.

how-to/extending-context

أضف شريحتك الخاصة إلى ما يمكن لـAction رؤيته عن الاستدعاء.

how-to/migrating-legacy

انقل قاعدة الكود الحالية تدريجيًا، Action تلو الآخر.


07 — faq

أسئلة — أجوبة.

أليست هذه مجرد Clean Architecture مع حفنة من المُزخرِفات؟

الفرق يكمن في آلية الإنفاذ. فـClean Architecture مجموعة من الاصطلاحات التي يتحقق منها المُراجِع يدويًا. أما عقود AOA — @check_roles، @depends، وcheckers الحالة — فتتحقق منها الآلة قبل تشغيل العملية، لا مَن تذكّر أن ينظر.

هل يلزم إعادة كتابة تطبيق قائم على FastAPI أو Django؟

لا. يعرض aoa-fastapi-adapter الـAction الموجودة كمسارات عادية. أنت تتبنى AOA Action تلو الآخر، لا إطار عمل تلو الآخر.

كم تكلفة Pipeline الـAspects أثناء التشغيل؟

كل Aspect هو مجرد استدعاء async عادي: دون تسلسل، ودون حدود عملية. التكلفة هي عمليات التحقق التي طلبتها أنت بنفسك، لا الإطار المحيط بها.

هل يلزم Maxitor لاستخدام AOA؟

لا. يقرأ Maxitor نفس الـDomain وRole وAction التي أعلنتها بالفعل — فهو أداة عرض، لا تبعية. تعمل AOA حتى بدونه.

ما الفرق بين @compensate ومعاملة قاعدة البيانات؟

المعاملة تتراجع عن مخزن بيانات واحد. أما @compensate فيتراجع عن عملية أعمال قد تكون لامست Gateway للدفع، وخدمة بريد إلكتروني، وقاعدة بيانات — وهذه الأنظمة لا تتشارك حدود معاملة واحدة.

متى تكون AOA الأداة غير المناسبة؟

بالنسبة لسكربت، أو أداة CLI لمرة واحدة، أو خدمة بعملية واحدة ودون متطلبات امتثال — فإن الدوال العادية هي الخيار الصحيح.

⭐ إذا أعجبتك AOA، ضع نجمة على GitHub وانضم إلى النقاش في GitHub Discussions.

AOA — الكود — هو الرسم البياني. · aoa.run