diff --git a/docs/analysis/software-architecture.md b/docs/analysis/software-architecture.md
new file mode 100644
index 0000000..8188738
--- /dev/null
+++ b/docs/analysis/software-architecture.md
@@ -0,0 +1,369 @@
+# معماری نرمافزار (Software Architecture) – سامانه مدیریت و گزارش خرابی دانشگاهی
+
+**تهیهکننده:** امیرحسن عارف اصل
+**بازبین:** رضا آدوسی
+**آخرین بهروزرسانی:** ۱۴۰۵/۰۸/۱۴
+
+---
+
+## مقدمه
+
+این سند معماری نرمافزاری سامانهٔ مدیریت و گزارش خرابی دانشگاهی را در سطح **منطقی و مفهومی** تعریف میکند. چون پروژه هنوز وارد فاز پیادهسازی نشده است (طبق `README.md`)، این سند **تعهد به فناوری خاصی ندارد** و انتخابهای فناورانه در بخش «پرسشهای باز» علامتگذاری شدهاند.
+
+هدف این سند پاسخ به سه پرسش است:
+
+1. سامانه از چه **مؤلفههایی** تشکیل میشود و مرز مسئولیت هر کدام کجاست؟
+2. این مؤلفهها چگونه با هم **همکاری** میکنند تا جریانهای توصیفشده در `activity.md` محقق شوند؟
+3. کدام **نیروهای محرک معماری (Architectural Drivers)** این ساختار را توجیه میکنند؟
+
+## ۱. نیروهای محرک معماری
+
+### ۱.۱. نیازمندیهای غیرکارکردی
+
+| شناسه | نیازمندی | اثر معماری |
+|---|---|---|
+| `NFR-01` | امنیت اطلاعات | احراز هویت متمرکز، مجوزدهی سمت سرور، هش رمز، جلوگیری از دسترسی مستقیم به صفحات نقش دیگر |
+| `NFR-02` | حفظ حریم خصوصی | فیلتر داده بر اساس نقش در لایهٔ برنامه (نه فقط در رابط کاربری) |
+| `NFR-03` | کاربردپذیری | رابط RTL فارسی، اعتبارسنجی درجا، پیام خطای روشن |
+| `NFR-04` | زمان پاسخگویی | ایندکسگذاری هدفمند (طبق `data-model.md` §۷)، پرهیز از کوئریهای سنگین در داشبورد |
+| `NFR-05` | صحت و نگهداری اطلاعات | تاریخچهٔ append-only، قفل خوشبینانه، تراکنشهای اتمیک |
+| `NFR-06` | قابلیت نگهداری و توسعه | معماری لایهای و ماژولار، جداسازی دامنه از زیرساخت |
+
+### ۱.۲. محدودیتها
+
+| محدودیت | منبع | اثر |
+|---|---|---|
+| تیم سهنفره، پروژهٔ دانشگاهی | `README.md` | پرهیز از معماریهای توزیعشده و پیچیده |
+| هنوز فناوری انتخاب نشده | `README.md` («هنوز کدنویسی و پیادهسازی انجام نشده») | معماری باید فناوریمستقل بماند |
+| فهرست وضعیتها و اولویتها نهایی نیست | پرسشهای باز ۳ و ۴ در `activity.md` | اینها باید **داده** باشند، نه کد |
+| دامنهٔ فضاها مشخص نیست | ابهام `README.md` | مدل محل خرابی باید قابل گسترش بماند |
+
+## ۲. سبک معماری انتخابشده
+
+**سبک پیشنهادی: مونولیت ماژولار لایهای (Modular Layered Monolith)**
+
+### ۲.۱. مقایسهٔ گزینهها
+
+| گزینه | مزیت | عیب | تناسب با این پروژه |
+|---|---|---|---|
+| **مونولیت لایهای** | سادگی استقرار، دیباگ آسان، مناسب تیم کوچک | مقیاسپذیری مستقل ماژولها ندارد | ✅ **انتخاب شد** |
+| میکروسرویس | استقلال استقرار، مقیاسپذیری انتخابی | هزینهٔ عملیاتی بالا، نیاز به DevOps، پیچیدگی تراکنش توزیعشده | ❌ برای تیم سهنفره و پروژهٔ درسی توجیه ندارد |
+| بدون لایه (اسکریپتمحور) | سرعت شروع | نقض `NFR-06`، عدم قابلیت نگهداری | ❌ |
+
+### ۲.۲. توجیه
+
+- `NFR-06` قابلیت نگهداری را الزام میکند؛ لایهبندی این را تضمین میکند.
+- `NFR-05` صحت داده را الزام میکند؛ تراکنش در یک پایگاهدادهٔ واحد بسیار سادهتر از تراکنش توزیعشده است.
+- مرزهای دامنه (بخش ۳) از `domain-model.md` گرفته شدهاند تا در آیندهٔ دور اگر لازم شد، جداسازی به میکروسرویس **ممکن** باشد، بدون بازنویسی دامنه.
+
+## ۳. مرزهای ماژول (Bounded Contexts)
+
+مرزها از `domain-model.md` §۱ گرفته شدهاند:
+
+| ماژول | مسئولیت | مفاهیم اصلی | نیازمندیها |
+|---|---|---|---|
+| **M1 — هویت و دسترسی** | احراز هویت، تشخیص نقش، مجوزدهی | کاربر، نقش، نشست | `FR-01`، `FR-02`، `US-15` |
+| **M2 — گزارش خرابی** | ثبت، پیگیری، اطلاعات تکمیلی، بازخورد گزارشدهنده | گزارش، اطلاعات تکمیلی، بازخورد | `FR-03`–`FR-05`، `FR-14`، `US-01`–`US-05` |
+| **M3 — مدیریت تعمیر** | بررسی، اولویتبندی، تخصیص، ثبت نتیجه | اولویت، تخصیص، نتیجهٔ تعمیر | `FR-06`–`FR-13`، `US-06`–`US-14` |
+| **M4 — اطلاعرسانی** | واکنش به رویدادهای دامنه و ارسال اعلان | اعلان، کانال | `FR-15`، `US-16` |
+| **M5 — نظارت** | داشبورد و آمار تجمیعی | داشبورد (Read Model) | `FR-17`، `US-17` |
+
+> **نکته:** M2 و M3 در `data-model.md` روی یک جدول مرکزی (`fault_reports`) کار میکنند. جداسازی این دو **ماژول منطقی** است، نه فیزیکی. مزیت: هر ماژول فقط متدهای مجاز خودش را روی گزارش فراخوانی میکند و قانون «تغییر وضعیت فقط از مسیر مجاز» در یک نقطه کنترل میشود.
+
+## ۴. لایههای معماری
+
+```mermaid
+flowchart TB
+ subgraph P["لایهٔ نمایش (Presentation)"]
+ P1["رابط وب RTL
SCR-01 تا SCR-12"]
+ end
+ subgraph A["لایهٔ برنامه (Application)"]
+ A1["سرویسهای کاربردی
Use Cases"]
+ A2["اعتبارسنجی ورودی"]
+ A3["کنترل دسترسی"]
+ end
+ subgraph D["لایهٔ دامنه (Domain)"]
+ D1["موجودیتها و Value Objectها"]
+ D2["سیاستهای دامنه"]
+ D3["ماشین حالت گزارش"]
+ D4["رویدادهای دامنه"]
+ end
+ subgraph I["لایهٔ زیرساخت (Infrastructure)"]
+ I1["دسترسی به داده"]
+ I2["سرویس احراز هویت"]
+ I3["ارسال اعلان"]
+ I4["ذخیرهسازی فایل"]
+ end
+
+ P --> A
+ A --> D
+ A --> I
+ D -.->|"بدون وابستگی به زیرساخت"| I
+
+ classDef pres fill:#e3f2fd,stroke:#1565c0
+ classDef app fill:#fff3e0,stroke:#ef6c00
+ classDef dom fill:#e8f5e9,stroke:#2e7d32
+ classDef inf fill:#f3e5f5,stroke:#6a1b9a
+ class P1 pres
+ class A1,A2,A3 app
+ class D1,D2,D3,D4 dom
+ class I1,I2,I3,I4 inf
+```
+
+**قاعدهٔ وابستگی:** جهت وابستگی همیشه به سمت **دامنه** است. دامنه به هیچ لایهٔ دیگری وابسته نیست. این قاعده `NFR-06` را تضمین میکند و اجازه میدهد در آینده پایگاهداده یا سرویس احراز هویت عوض شود بدون تغییر منطق کسبوکار.
+
+## ۵. نمای ظرف (Container View)
+
+```mermaid
+flowchart TB
+ subgraph Client["مرورگر کاربر"]
+ C1["برنامهٔ وب
(رابط RTL فارسی)"]
+ end
+
+ subgraph Server["سرور برنامه"]
+ S1["API / لایهٔ برنامه"]
+ S2["ماژولهای M1 تا M5"]
+ S3["کارگر پسزمینه
(پردازش رویدادها)"]
+ end
+
+ subgraph Data["لایهٔ داده"]
+ DB[("پایگاهدادهٔ رابطهای
مرجع: PostgreSQL")]
+ FS[("ذخیرهسازی فایل
تصاویر اطلاعات تکمیلی")]
+ end
+
+ subgraph External["سرویسهای بیرونی"]
+ AUTH["سرویس احراز هویت"]
+ NOTIF["درگاه اعلان
(درونبرنامه / پیامک / ایمیل)"]
+ end
+
+ C1 -->|"HTTPS / JSON"| S1
+ S1 --> S2
+ S2 --> DB
+ S2 --> FS
+ S2 --> AUTH
+ S2 -.->|"انتشار رویداد"| S3
+ S3 --> NOTIF
+
+ classDef ext fill:#fff8e1,stroke:#f9a825,stroke-dasharray: 4 4
+ class AUTH,NOTIF ext
+```
+
+> **توضیح:** پردازش اعلان (M4) بهصورت **غیرهمگام** از طریق رویداد انجام میشود تا `NFR-04` حفظ شود: ثبت گزارش نباید منتظر ارسال پیامک بماند. کانال دقیق اعلان هنوز پرسش باز ۸ است؛ بنابراین `NOTIF` بهعنوان یک **آداپتور قابل تعویض** مدل شده است.
+
+## ۶. جریانهای کلیدی
+
+### ۶.۱. ورود به سامانه (AD-01، US-15)
+
+```mermaid
+sequenceDiagram
+ actor U as کاربر
+ participant UI as رابط کاربری
+ participant APP as لایهٔ برنامه
+ participant AUTH as سرویس احراز هویت
+ participant DB as پایگاهداده
+
+ U->>UI: نام کاربری و رمز عبور
+ UI->>UI: بررسی فیلد خالی
+ alt فیلد خالی
+ UI-->>U: «این فیلد الزامی است»
+ else کامل
+ UI->>APP: درخواست ورود
+ APP->>AUTH: اعتبارسنجی
+ alt سرویس در دسترس نیست
+ AUTH-->>APP: خطا
+ APP-->>UI: «خطا در ورود؛ لطفاً بعداً تلاش کنید»
+ else پاسخ دریافت شد
+ AUTH-->>APP: نتیجه
+ alt نامعتبر
+ APP-->>UI: «نام کاربری یا رمز عبور اشتباه است»
+ UI-->>U: خطای مبهم (بدون افشای فیلد اشتباه)
+ else معتبر
+ APP->>DB: ثبت رویداد ورود
+ APP-->>UI: نشست + نقش
+ UI-->>U: داشبورد متناسب با نقش
+ end
+ end
+ end
+```
+
+**الزامات امنیتی بازتابیافته:** پیام خطا نباید مشخص کند کدام فیلد اشتباه است (`US-15.feature`). این قاعده در لایهٔ برنامه اعمال میشود، نه در رابط کاربری.
+
+### ۶.۲. ثبت گزارش خرابی (AD-02، US-01، US-02)
+
+```mermaid
+sequenceDiagram
+ actor R as گزارشدهنده
+ participant UI as رابط کاربری
+ participant APP as لایهٔ برنامه
+ participant DOM as دامنه
+ participant DB as پایگاهداده
+
+ R->>UI: پر کردن فرم
+ UI->>UI: اعتبارسنجی سمت کلاینت
+ Note over UI: اجباری: عنوان، توضیحات، محل، نوع تجهیز
حداکثر عنوان: ۱۵۰ کاراکتر
+ alt نامعتبر
+ UI-->>R: نمایش خطا کنار فیلد، حفظ مقادیر
+ else معتبر
+ UI->>APP: ارسال
+ APP->>APP: کنترل دسترسی (نقش مجاز)
+ APP->>DOM: اعتبارسنجی مجدد
+ alt نامعتبر
+ DOM-->>APP: نقض قاعده
+ APP-->>UI: خطای اعتبارسنجی
+ UI-->>R: نمایش خطا
+ else معتبر
+ APP->>DB: درج گزارش (وضعیت: ثبتشده)
+ APP->>DB: درج رویداد تاریخچه REPORT_SUBMITTED
+ APP-->>UI: شناسهٔ گزارش
+ UI-->>R: پیام موفقیت + شناسهٔ یکتا
+ APP-)APP: انتشار ReportSubmitted
+ end
+ end
+```
+
+**نکتهٔ مهم (الزام `US-01.feature`):** «اعتبارسنجی سمت کلاینت» فقط برای تجربهٔ کاربری است. اعتبارسنجی **معتبر** در لایهٔ برنامه و دامنه انجام میشود. اگر درخواست مستقیماً به API ارسال شود، همان قواعد باید اعمال شوند.
+
+### ۶.۳. تخصیص تعمیرکار (AD-03، US-08)
+
+```mermaid
+sequenceDiagram
+ actor F as کارمند تأسیسات
+ participant APP as لایهٔ برنامه
+ participant DOM as دامنه
+ participant DB as پایگاهداده
+ participant N as ماژول اطلاعرسانی
+
+ F->>APP: انتخاب گزارش + تعمیرکار
+ APP->>APP: کنترل دسترسی
+ APP->>DOM: درخواست تخصیص
+ DOM->>DOM: بررسی وضعیت مجاز
+ alt وضعیت مجاز نیست
+ DOM-->>APP: خطا
+ APP-->>F: پیام خطا
+ else مجاز
+ DOM->>DB: درج تخصیص
+ DOM->>DB: تغییر وضعیت به ارجاعشده
+ DOM->>DB: درج رویداد تاریخچه TECHNICIAN_ASSIGNED
+ DOM-)N: انتشار TechnicianAssigned
+ N->>N: ارسال اعلان (غیرهمگام)
+ APP-->>F: پیام موفقیت
+ end
+```
+
+### ۶.۴. تأیید یا رد تعمیر (AD-05، US-05)
+
+```mermaid
+sequenceDiagram
+ actor R as گزارشدهنده
+ participant APP as لایهٔ برنامه
+ participant DOM as دامنه
+ participant DB as پایگاهداده
+
+ R->>APP: درخواست تأیید/رد
+ APP->>APP: کنترل دسترسی
+ APP->>DB: خواندن گزارش با قفل خوشبینانه
+ APP->>DOM: بررسی قواعد تأیید
+ DOM->>DOM: ۱) کاربر = گزارشدهندهٔ همان گزارش؟
۲) وضعیت = تعمیر انجامشده؟
۳) آیا قبلاً بازخورد ثبت شده؟
+ alt یکی از شروط نقض شد
+ DOM-->>APP: رد درخواست
+ APP-->>R: پیام متناسب
+ Note over APP,R: «دسترسی مجاز نیست» یا
«این گزارش در وضعیت قابل تأیید نیست»
+ else مجاز
+ alt رد بدون دلیل
+ APP-->>R: «ذکر دلیل رد الزامی است»
+ else
+ APP->>DB: درج بازخورد (UNIQUE روی نتیجهٔ تعمیر)
+ APP->>DB: درج رویداد تاریخچه
+ alt تأیید
+ APP->>DB: تغییر وضعیت به بستهشده + closed_at
+ end
+ APP-->>R: پیام موفقیت
+ end
+ end
+```
+
+**چرا قفل خوشبینانه؟** الزام ایدمپوتنسی در `US-05.feature`: «کلیک دوباره روی تأیید یک تغییر وضعیت بیشتر ایجاد نمیکند». ترکیب `UNIQUE (report_id, repair_result_id)` در `data-model.md` و بررسی `version` تضمین دوگانه میدهد.
+
+## ۷. دغدغههای عرضی (Cross-Cutting Concerns)
+
+| دغدغه | راهکار | لایه | مستند مرجع |
+|---|---|---|---|
+| **احراز هویت** | سرویس متمرکز؛ در صورت در دسترس نبودن، پیام «خطا در ورود؛ لطفاً بعداً تلاش کنید» و عدم ورود | برنامه | `FR-01`، `US-15.feature` |
+| **مجوزدهی** | کنترل سمت سرور در **هر** درخواست؛ هرگز فقط مخفیکردن دکمه در رابط کاربری | برنامه | `FR-02`، `US-15.feature` |
+| **اعتبارسنجی** | دو لایه: رابط کاربری (تجربهٔ کاربری) و دامنه (اعتبار واقعی) | نمایش + دامنه | `US-01.feature` |
+| **ثبت تاریخچه** | هر تغییر معنادار یک ردیف در `report_history`؛ append-only | برنامه + داده | `FR-16`، `NFR-05` |
+| **رویدادهای دامنه** | انتشار پس از commit موفق؛ مصرف غیرهمگام | دامنه → اطلاعرسانی | `FR-15` |
+| **مدیریت خطا** | خطاهای قابل نمایش (اعتبارسنجی/مجوز) در برابر خطاهای فنی؛ در خطای فنی، پیام عمومی و ثبت جزئیات در لاگ | برنامه | `US-01.feature` |
+| **زمان** | همهٔ زمانها با منطقهٔ زمانی (`timestamptz`) | داده | `data-model.md` §۹ |
+| **تراکنش** | تغییر وضعیت + درج تاریخچه در یک تراکنش | برنامه + داده | `NFR-05` |
+
+## ۸. تصمیمهای معماری (ADR)
+
+| شناسه | تصمیم | جایگزین ردشده | دلیل |
+|---|---|---|---|
+| **ADR-01** | مونولیت ماژولار | میکروسرویس | تیم سهنفره، نیاز به تراکنش اتمیک، `NFR-06` |
+| **ADR-02** | معماری لایهای با وابستگی به سمت دامنه | لایهبندی بدون قاعده | جلوگیری از نشت منطق کسبوکار به رابط کاربری |
+| **ADR-03** | مجوزدهی **سمت سرور** در هر درخواست | فقط مخفیکردن در رابط کاربری | `FR-02`، `US-15.feature` (سناریوی دسترسی مستقیم به آدرس) |
+| **ADR-04** | اعلان بر پایهٔ **رویداد دامنه** و غیرهمگام | فراخوانی مستقیم ارسال اعلان در همان تراکنش | `NFR-04`، جداسازی M4 از M2/M3 |
+| **ADR-05** | قفل خوشبینانه (`version`) | قفل بدبینانه | ایدمپوتنسی `US-05.feature` بدون بلوکهکردن |
+| **ADR-06** | فهرست وضعیتها و انتقالها بهصورت **داده** | `ENUM` یا `switch` در کد | پرسشهای باز ۳ و ۴ هنوز بسته نشدهاند |
+| **ADR-07** | تاریخچهٔ append-only | لاگ فایل یا `audit` سطح پایگاهداده | قابل مشاهده برای کاربر (`FR-16`، `US-10`) |
+| **ADR-08** | شناسههای فنی انگلیسی، متن رابط فارسی | همهچیز فارسی | تعارض با `CONTRIBUTING.md` ندارد؛ آن بند دربارهٔ متن مستندات است |
+
+## ۹. نمای استقرار (Deployment View)
+
+```mermaid
+flowchart LR
+ subgraph Browser["دستگاه کاربر"]
+ B1["مرورگر"]
+ end
+ subgraph Host["میزبان (تکسرور یا Docker Compose)"]
+ W1["سرور برنامه"]
+ D1[("پایگاهداده")]
+ F1[("ذخیرهسازی فایل")]
+ end
+ B1 -->|HTTPS| W1
+ W1 --> D1
+ W1 --> F1
+
+ classDef future fill:#f5f5f5,stroke:#9e9e9e,stroke-dasharray: 4 4
+```
+
+**فرض:** برای یک پروژهٔ دانشگاهی، استقرار تکسروری (یا `docker compose` با سه سرویس) کافی است. جزئیات فناورانه در پرسشهای باز آمدهاند.
+
+## ۱۰. نگاشت نیازمندیهای غیرکارکردی به راهکار معماری
+
+| NFR | راهکار معماری | محل تحقق |
+|---|---|---|
+| `NFR-01` امنیت | احراز هویت متمرکز، مجوزدهی سمت سرور، هش رمز، عدم افشای فیلد اشتباه | `M1`، لایهٔ برنامه |
+| `NFR-02` حریم خصوصی | فیلتر نتایج بر اساس نقش در سرویسهای کاربردی | لایهٔ برنامه |
+| `NFR-03` کاربردپذیری | رابط RTL، اعتبارسنجی درجا، پیامهای دقیق | لایهٔ نمایش (`ui-wireframes.md`) |
+| `NFR-04` زمان پاسخ | ایندکسهای `data-model.md` §۷، اعلان غیرهمگام، داشبورد بهصورت نمای تجمیعی | داده + `M4` + `M5` |
+| `NFR-05` صحت داده | تراکنش اتمیک، تاریخچهٔ append-only، قفل خوشبینانه، ممنوعیت حذف فیزیکی | دامنه + داده |
+| `NFR-06` نگهداشت | لایهبندی، مرز ماژول، جداسازی دامنه از زیرساخت، ADRها | کل معماری |
+
+## ۱۱. ریسکهای معماری
+
+| # | ریسک | اثر | کاهش |
+|---|---|---|---|
+| R1 | بستهنشدن پرسش باز ۹ (چند نقش برای کاربر) | تغییر در M1 و مدل داده و نمودار کلاس | تصمیمگیری پیش از پیادهسازی؛ در غیر این صورت تغییر سه سند |
+| R2 | نهایینشدن فهرست وضعیتها (پرسش ۴) | تغییر ماشین حالت و انتقالهای مجاز | ADR-06: انتقالها بهصورت داده |
+| R3 | رشد دامنه به خوابگاه و فضاهای اداری | تأثیر بر مدل محل و مجوزها | مدل محل قابل گسترش (`data-model.md` D2) |
+| R4 | انتخاب نشدن کانال اعلان (پرسش ۸) | تأخیر در `M4` | آداپتور قابل تعویض (بخش ۵) |
+| R5 | انتخابنشدن فناوری | عدم شروع پیادهسازی | پرسش باز ۱۶ |
+
+## ۱۲. نکات و پرسشهای باز
+
+| # | پرسش | نیازمند تصمیم |
+|---|---|---|
+| ۱۶ | فناوری لایهٔ نمایش، برنامه و داده چیست؟ (زبان، فریمورک، DBMS) | تیم — پیش از فاز پیادهسازی |
+| ۱۷ | سرویس احراز هویت داخلی ساخته شود یا از راهکار آماده استفاده شود؟ | تیم |
+| ۱۸ | ذخیرهسازی تصاویر اطلاعات تکمیلی در فایلسیستم یا پایگاهداده؟ | تیم |
+| ۱۹ | نیاز به API عمومی یا صرفاً مصرف داخلی رابط کاربری؟ | تیم |
+| ۲۰ | سطح دسترسی دقیق مدیر (پرسش باز ۹ در `activity.md`) چه اثری بر M1 و M5 دارد؟ | تیم |
+| ۲۱ | آیا نیاز به ثبت تلاشهای ورود ناموفق و قفل حساب وجود دارد؟ (در مستندات نیامده) | تیم |
+| ۲۲ | آیا رابط کاربری باید واکنشگرا (Responsive) باشد؟ (در `NFR-03` صریح نیست) | تیم |
+
+---
+
+**وضعیت سند:** نسخه اولیه (Draft) – آماده بازبینی
\ No newline at end of file