feat(admin-ui): minimal React+Vite+TanStack scaffolding

- Vite 7 + React 19 + TanStack Router (file-based) + TanStack Query
- Tailwind v4 (CSS-first config, OKLCH brand colors)
- i18next + react-i18next с RU/EN switcher в header
- Axios client с Accept-Language interceptor + JWT placeholder
- 2 pages: /dictionaries (list cards) + /dictionaries/$name (records table)
- Dockerfile (node build + nginx serving + API proxy)
- README + .gitignore

Backend:
- Новый GET /api/v1/dictionaries в read-api (DictionaryListController),
  фильтрует по доступному scope через ScopeContext
- DictionaryListItem DTO без heavy schema_json

routeTree.gen.ts — stub; реальное содержимое генерится Vite plugin'ом при
первом 'pnpm dev'.
This commit is contained in:
Александр Зимин
2026-05-04 00:55:04 +03:00
parent adc5315948
commit 1eba2ee59b
20 changed files with 609 additions and 0 deletions
+36
View File
@@ -0,0 +1,36 @@
server {
listen 80;
server_name _;
# SPA history fallback
root /usr/share/nginx/html;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
# API proxy в read-api/writer (через k8s service DNS).
# Реальный endpoint задаётся через env-template или ENV в pod, в v1
# просто проксируем на ordinis-read-api (только GET) и ordinis-app (write).
location /api/v1/dictionaries {
# POST/PUT идут в writer, GET — в read-api. Простое разделение по methods:
if ($request_method ~ ^(POST|PUT|PATCH|DELETE)$) {
proxy_pass http://ordinis-app:80;
}
proxy_pass http://ordinis-read-api:80;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass_request_headers on;
}
location ~ ^/api/v1/[^/]+/records {
if ($request_method ~ ^(POST|PUT|PATCH|DELETE)$) {
proxy_pass http://ordinis-app:80;
}
proxy_pass http://ordinis-read-api:80;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass_request_headers on;
}
}