# کارهای سمت سرور (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).