# کارهای سمت سرور (Backend / DevOps)

این فایل لیست کارهایی است که برای کامل شدن ریفکتور اپلیکیشن فلاتر، باید **سمت بک‌اند یا زیرساخت (DevOps)** انجام شوند. این موارد مستقل از کد فلاترند و کد اپ منتظر آن‌هاست.

> آخرین به‌روزرسانی: ۱۴۰۵/۰۲/۳۱ (2026-05-21)

---

## ✅ حل‌شده (۱۴۰۵/۰۲/۳۱) — blockerهای قبلی

### 1. باگ Keycloak Authorization (permission ↔ scope) — ✅ حل شد
- **علتِ واقعی باگ:** در `populateKeycloakPermissions` (در `apps/api-microservice/src/app.service.ts`)، فیلد `scopes` permission با **نامِ** scope (مثل `'get-market'`) پر می‌شد، ولی Keycloak آنجا **ID** می‌خواهد. در نتیجه permission بدون scope ذخیره می‌شد (`Scopes: -`) و همیشه Deny می‌داد.
- **رفع (کد):** متد `getScopeIds()` اضافه شد که نام scope را به ID نگاشت می‌کند؛ حالا permission با scope ID ساخته/آپدیت می‌شود. (commit روی `git.irfartak.com`)
- **رفع (تنظیم Keycloak):** در didvan-api → Authorization → Settings، **Decision Strategy** از `Unanimous` به **`Affirmative`** تغییر کرد. (چون scope `get-market` را هم permission user و هم permission admin پوشش می‌دادند؛ با Unanimous چون admin رد می‌کرد کل Deny می‌شد.)
- **نتیجه:** Evaluate حالا `market-user-role → Permit` و `GET /market → 200`. endpointها کار می‌کنند.

### 2. Deploy کد جدید api-microservice — ✅ انجام شد
- **روش (دور زدن مشکل npm/شبکه‌ی سرور):** یک `Dockerfile.fast` ساخته شد که `node_modules` را از image قدیمی `0.0.59` برمی‌دارد و فقط `npm run build` می‌زند (بدون `npm install`). سریع و آفلاین.
- image جدید `registry.didvan.com/api-microservice:0.0.61` ساخته شد؛ تگ در `~/microservices/didvan-iac/.env` (متغیر `API_MICROSERVICE_IMAGE_TAG`) به‌روز شد؛ با `docker compose -f compose.yml -f compose.prod.yml up -d --force-recreate api_gateway` بالا آمد.
- **نکته برای دیپلویِ بعدی:** خط mirror (`registry.npmmirror.com`) را به Dockerfile اصلی اضافه نکن — cache داکر را خراب می‌کند و npm install را از صفر اجرا می‌کند. از همان روش `Dockerfile.fast` استفاده کن.

### وضعیت enforcement (یادداشت)
- حالا که permissionها درست‌اند، می‌توان به **`ENFORCING`** برگشت. فعلا هنوز روی **PERMISSIVE** است (هم `policyEnforcement` در `app.module.ts`، هم Policy Enforcement Mode در didvan-api). برگشت به ENFORCING ریسک کم دارد ولی باید همه‌ی resourceها یک‌بار تست شوند.

---

## 🔴 باقی‌مانده‌ی زیرساخت

### 3. DNS ناپایدار کانتینرها (با workaround کار می‌کند)
- **مشکل:** سرور port 53 خروجی به DNSهای عمومی بسته دارد؛ DNS داخلی (`5.200.200.200`) کند/ناپایدار است → خطای `getaddrinfo EAI_AGAIN auth.didvan.com`.
- **راه‌حل موقت اعمال‌شده (فعال):** در `compose.prod.yml` برای سرویس `api_gateway` افزوده شد:
  `extra_hosts: ["auth.didvan.com:185.143.233.235"]`. الان gateway بدون خطای DNS بالا می‌آید.
- **راه‌حل دائمی:** یک DNS resolver محلی پایدار روی سرور راه‌اندازی شود، یا `extra_hosts` برای همه‌ی سرویس‌هایی که به دامنه‌های خارجی نیاز دارند اضافه شود (مثلا `market_service` برای `call4.tgju.org`, `tsetmc`).

---

## 🟡 endpointهای ناقص بک‌اند (برای کامل شدن feature های فلاتر لازم‌اند)

### 4. تنظیمات اعلان کاربر (User Notification Preferences)
- `notification-service` فقط CRUD روی notification و template دارد؛ مفهوم **ترجیحات کاربر** ندارد.
- نیاز به endpointهای:
  - دسته‌بندی‌های موردعلاقه برای اعلان (`favorites`)
  - وضعیت روشن/خاموش اعلان‌ها (`notification status`)
  - بازه‌ی زمانی سکوت / دریافت اعلان (`silence interval` / `notification time`)
- پیشنهاد: یا یک سرویس/endpoint جدید (مثل `GET/PUT /user/preferences`)، یا ذخیره به‌صورت Keycloak user attributes.
- **در فلاتر:** صفحه‌ی تنظیمات اعلان فعلا ایمن‌سازی شده (با `AuthConfig.useLegacyApi=false` پیام «به‌زودی» نشان می‌دهد).

### 5. Aggregator صفحه‌ی اصلی (Home)
- `content-service` endpoint یکپارچه برای صفحه‌ی اصلی ندارد (مثل `/home` قدیمی که banners + lists می‌داد).
- بخش‌های زیر در فلاتر فعلا منبع ندارند: `topBanner`, `didvanPlus`, `didvanVoice`, و ساختار `lists` صفحه‌ی اصلی.
- پیشنهاد: یک endpoint مرکب (مثلا `GET /home` یا `/main-page`) که این داده‌ها را برگرداند.

#### 5.1 اسلایدر «تازه‌ترین کاوش‌ها»
- «کاوش» = ترکیب چند نوع: **swot + خبر + رادار + ماهنامه + دلفی + پویش‌افق**. endpoint واحدی برای گرفتن آخرین کاوش‌ها وجود ندارد.
- **در فلاتر فعلا:** اسلایدر فقط `swot` را نشان می‌دهد (تنها منبعی که قطعا کاوش است و در دسترس داریم). `lib/views/home/main/main_page.dart` → شاخه‌ی `_ExploreLatestSliderNew` با `items: []`.
- برای کامل شدن لازم است یکی از این‌ها:
  - یک endpoint مرکب «latest کاوش» که آخرین آیتم هر نوع را برگرداند، یا
  - مشخص شدن **شناسه/نام `category`** خبر/رادار/ماهنامه در `content-service` (تا بتوان با filter گرفت)، به‌علاوه‌ی اتصال `delphi-service` و منبعِ «پویش افق».

### 6. دسته‌بندی در market-service (نبض صنعت)
- `GET /market` فقط لیست تخت symbolها را می‌دهد (بدون دسته‌بندی).
- صفحه‌ی آمار فلاتر برای ۶ دسته (ارز/طلا، کریپتو، فلزات، کامودیتی، فولاد، سرمایه) طراحی شده.
- نیاز: افزودن فیلد `category` به market data یا یک endpoint گروه‌بندی‌شده.

### 7. عضویت خودکار کاربران در گروه‌های دسترسی
- کاربران جدید باید خودکار در گروه‌های `content-users-group`, `market-users-group` (و سایر گروه‌های لازم) قرار بگیرند.
- اقدام: این گروه‌ها در Keycloak → Realm Settings → User registration → **Default Groups** اضافه شوند (برای کاربران جدید). کاربران موجود باید دستی اضافه شوند.

### 8. آپلود عکس پروفایل (S3)
- مسیر جدید دومرحله‌ای است: آپلود فایل به `s3-service` و گرفتن `key`، سپس `PATCH /auth/users/:id/profile-picture` با آن key.
- **در فلاتر:** `UserProvider.setProfilePhoto` فعلا فقط `false` برمی‌گرداند (TODO). نیاز به مشخص شدن endpoint آپلود s3 (presigned URL یا multipart).

---

## 🟢 سرویس‌هایی که آماده‌اند و فلاتر باید بهشان migrate شود

این‌ها سمت بک‌اند موجودند؛ فقط کد فلاتر باید بهشان وصل شود (مورد ۱ حل شد، پس حالا قابل تست‌اند):

- `ai-service` — هوشان / دستیار هوش مصنوعی
- `comments-service` — کامنت‌ها
- `swot-service` — بایدها و نبایدها (از طریق `opportunity-threat.didvan.com` که الان هم کار می‌کند)
- `delphi-service` — سها / نظرسنجی
- `ticketing-service` — احتمالا معادل دایرکت/پیام
- `activity-service` — فعالیت‌ها
- `content-service` — اخبار، رادار، اینفوگرافی، ماهنامه، پادکست (همه به‌صورت `Content` با category/tag)

---

## ℹ️ نکات

- دامنه‌ی قدیمی `https://api.didvan.app` کاملا **down / SSL fail** است؛ هیچ endpoint قدیمی‌ای از آن جواب نمی‌دهد.
- دامنه‌ی `https://opportunity-threat.didvan.com` (swot + stories) **فعال و در دسترس** است.
- دامنه‌ی جدید API gateway: `https://api2.didvan.com` (در `lib/config/auth_config.dart`).
- Keycloak: `https://auth.didvan.com`، realm `didvan`، client اپ `didvan-app` (public)، client بک‌اند `didvan-api` (confidential, authorization).
