Агуулгыг алгасах

Frontend (BFF)

Frontend нь Backend-for-Frontend загвартай Next.js 15 (App Router) апп. Браузер зөвхөн ижил-origin /api/* route handler руу залгадаг; тэдгээр нь сервер талаас Go API руу проксиолно.

Яагаад BFF вэ?

sequenceDiagram
  participant B as Браузер
  participant N as Next.js route handler
  participant A as Go API
  B->>N: fetch('/api/gov/applications', {headers: x-dgov-csrf})
  Note over N: httpOnly cookie-оос токен уншина<br/>origin шалгана
  N->>A: GET /api/v1/gov/applications<br/>Authorization: Bearer …
  A-->>N: {data: …}
  N-->>B: {data: …}  (токен ХЭЗЭЭ Ч буцахгүй)

Үр дүн: access / refresh токен нь httpOnly cookie-д амьдарна, клиентийн JavaScript түүнийг унших боломжгүй. XSS гарсан ч токен шууд алдагдахгүй.

Давхар CSRF хамгаалалт

Мутаци хийдэг бүх браузерийн дуудлага lib/client.ts-ийн sendJSON / postJSON-оор явна. Тэдгээр нь x-dgov-csrf толгойг нэмнэ; BFF талын lib/bff.ts доторх checkOrigin нь дараах хоёуланг шаардана:

  1. Custom header — cross-site form илгээлт үүнийг тавьж чадахгүй.
  2. Origin / Referer шалгалт — өөрийн origin-той таарах ёстой.

Шинэ мутаци route бичихдээ

Шинэ POST/PUT/DELETE BFF route үүсгэвэл эхний мөрөнд checkOrigin дуудна. Мартвал CSRF нээлттэй үлдэнэ.

Токен ба сессийн урсгал

Файл Үүрэг
lib/cookies.ts httpOnly cookie бичих / унших
lib/session.ts Session төлөв, хугацаа
lib/api.ts Server талын fetch + tryRefresh
lib/signout.ts Logout — backend + cookie цэвэрлэх

RSC дотор refresh бүү дууд

Refresh нь токеныг эргүүлдэг (rotation). React Server Component-ийн контекстээс дуудвал шинэ токеныг cookie-д бичих боломжгүй тул хуучин нь хүчингүй болж, хэрэглэгч гацна. Тиймээс tryRefresh нь эхлээд cookie бичигдэх боломжтой эсэхийг шалгадаг (lib/api.ts).

Өгөгдөл татах

Компонент доторх өгөгдөл TanStack Query-ээр явна:

const { data } = useQuery({
  queryKey: ['gov', 'applications'],
  queryFn: () => getJSON('/api/gov/applications'),
});
// мутацийн дараа:
queryClient.invalidateQueries({ queryKey: ['gov', 'applications'] });

Provider нь components/Providers.tsx-д. Хамаарал багатай байлгах бодлого тул UI сан ашигладаггүй — lucide-react (icon), qrcode.react (eID QR) л байна.

Олон хэл (i18n)

UI мөрүүд lib/i18n.ts дотор төвлөрсөн, дөрвөн хэл: mn · en · zh · ru. Компонентод useT()-ээр хэрэглэнэ.

export const LANGS = ['mn', 'en', 'zh', 'ru'] as const;

lib/i18n.test.ts нь түлхүүрийн бүрэн байдлыг шалгана — түлхүүр аль нэг хэлэнд дутвал тест унана. prefersLatinName() нь кирилл бус хэл дээр латин нэрийг илүүд үздэг (орос нь кирилл тул монгол бичлэгээ хадгална).

AI-ийн хариултын хэл

Чатын хүсэлт бүрд UI-ийн хэл lang талбараар илгээгддэг ба тэр нь эцсийн шийдэгч — хэрэглэгч өөр хэлээр бичсэн ч хариулт UI-ийн хэлээр ирнэ. Дэлгэрэнгүйг AI туслах-аас үз.

Харагдац (theming)

Сайтын харагдацыг админ тохируулна (accent өнгө, фонт, нягтрал, гэрэл/харанхуй), хэрэглэгч тус бүр өөрийн override хийж чадна:

Гадаргуу API
Нийтийн default GET /api/site/appearance
Админ өөрчлөх PUT /api/admin/site/appearance (settings.manage)
Нэрлэсэн theme /api/admin/themes/* — CRUD + идэвхжүүлэх

Брэндийн өнгийг кодод hardcode хийхгүй — Admin → Theme editor-оос тохируулна.

BFF route-ийн бүтэц

src/app/api/ дор 150 гаруй route handler бий. Backend модуль бүрт тохирсон бүлэг:

api/auth/*          eID нэвтрэлт, SSO, superadmin onboarding
api/me/*            профайл, eID PKI самбар, гарын үсэг
api/gov/*           төрийн үйлчилгээ + албан хаагчийн дараалал
api/registry/*      үйлчилгээний регистр
api/relay/*         хүсэлт дамжуулах
api/gateway/*       API gateway
api/applications/*  OAuth client бүртгэл
api/ai/*            чат · STT · TTS · орчуулга
api/public/ai/*     нэвтрэлтгүй чат (stream)
api/integrations/*  Google Drive/Meet · Dropbox
api/gspace/*        SFTP хадгалалт
api/provider/*      OIDC login / consent / logout
api/audit, api/security, api/site, api/themes, api/superadmin …

Backend-ийн алдааг клиент рүү proxyResult / toClientResponse-оор дамжуулна — токен эсвэл дотоод мессеж хэзээ ч задрахгүй.

Тест

npm run test      # vitest
Тест Юуг батална
i18n.test.ts Толь бичиг + landing текстийн дөрвөн хэлний бүрэн байдал
bff.test.ts checkOrigin, прокси хариултын хэлбэр
securityHeaders.test.ts CSP болон бусад толгойн утга
chatStream.test.ts SSE чатын урсгалын задаргаа
navigation.test.ts Эрхээс хамаарсан цэсний бүтэц