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