LoVisual/backend/STRUCTURE.md
loki5512344 7f4b532f99 chore(history): squash 67 commit(s) from 2026-09-25
- feat(accounts): persist device links with opaque hashed tokens, list and revoke endpoints
- feat(frontend): app shell, routing and landing page with the chat-command hero
- feat(frontend): Cyrillic-first fonts (Unbounded, Onest, JetBrains Mono); add i18next and motion
- docs: free mod, bilingual site, one-click download, theme editor, public profiles, rich landing in plans
- feat(accounts): internal gRPC AuthenticateDevice guarded by internal key
- feat(frontend): ru/en i18n with typed per-feature dictionaries and language switch
- feat(accounts): GET /me profile endpoint
- feat(gateway): scaffold crate with config validation and health check
- feat(gateway): reverse proxy to accounts and configs services
- feat(gateway): resolve identity once from access JWT or device token via gRPC
- feat(gateway): per-route and global rate limits with Retry-After
- feat(gateway): CORS for the site origin; docs for gateway and internal contract
- feat(configs): scaffold service with schema, config validation and health check
- feat(configs): four config slots per account with list, get and save
- feat(configs): permanent share codes with regenerate and public load-by-code
- feat(accounts): GetPublicProfiles gRPC for showcase author info
- style(accounts,common): apply rustfmt to existing sources
- feat(configs): public showcase with publish, browse, detail and copy-to-slot
- feat(backend): public profile endpoint and showcase author filter
- fix(gateway): silence clippy collapsible-if and needless-ref warnings
- docs(backend): configs-service implemented; Подсистема 1 backend complete
- feat(mod): add Optimize module skeleton with OptimizeState holder
- feat(mod): gate glass blur behind Optimize no_glass knob
- feat(mod): cut MotionBlur and DoF sample counts behind lite_post knob
- feat(mod): trim procedural sky noise behind lite_sky knob
- feat(mod): drop fade gradients and digit rolls behind lean_hud knob
- docs(todo): mark Optimize module phase 9.2 complete
- refactor(mod): drop dead Renderer2D compatibility shims
- refactor(mod): prune unreachable Renderer2D overload towers
- refactor(mod): remove unused Renderer2D overloads and imports
- docs(todo): mark Renderer2D giant-splitting done (2179 to 1597)
- refactor(mod): extract shader id constants from LoVisualRenderPipelines
- docs(todo): record registry wave 2026-09-25 (Renderer2D, pipelines)
- refactor(mod): move Renderer2D instance state into base class
- refactor(mod): extract Renderer2DRounded drawing family
- refactor(mod): extract Renderer2DPath connector and chamfer family
- refactor(mod): extract Renderer2DShapes circle line and texture primitives
- refactor(mod): extract Renderer2DGlass and Renderer2DItem families
- refactor(mod): prune Renderer2D imports after facade split
- docs(todo): record Renderer2D facade inheritance split (1597 to 475)
- docs: easter eggs — .env honeypot, konami troll mode, devtools banner, IDDQD config, breakable 404 block, 418 teapot
- feat(mod): introduce surface style system core (SurfaceStyle, StyleSpec, StyleConfig, SurfaceRenderer)
- refactor(mod): delegate HudRenderUtil liquid glass draws to SurfaceRenderer (dedupe glass constants)
- refactor(mod): route bespoke glass call sites through SurfaceRenderer.plateSpec
- feat(mod): add Auto option to HUD bg effects via shared HudBgStyles resolution
- feat(mod): flat fallback for no-glass optimize mode and persist global HUD config
- feat(mod): default HUD bg effects to Auto so the global surface style drives widgets
- feat(mod): add global cycle-style hotkey with surface style notification
- feat(mod): add surface style swatch strip under the global style picker
- feat(gateway): reject ambiguous paths and answer .env probes with a honeypot
- fix(gateway): charge failed credentials against the rate limit, allow stale ones on /auth
- feat(frontend): ClickGui theme pipeline generated from the mod, live site theming
- feat(frontend): landing v2 hero — voxel/particle backdrop, live ClickGui, theme strip
- docs(todo): drop the FPS A/B measurement from phase 9.3, close phase 9
- feat(gateway): answer /coffee with a 418 teapot
- feat(frontend): land the rest of landing v2 — HUD, module wall, showcase, FAQ, footer
- feat(frontend): one-click download from GitHub releases, changelog page, release CI
- feat(frontend): theme editor with live ClickGui preview, mod-compatible export and share links
- fix(frontend): landing HUD playground now shows real mod widgets (fps, coordinates, module list, keybinds, ping)
- style(frontend): apply ClickGui glass effect to landing HUD playground widgets
- fix(frontend): prevent color field row overflow in theme editor grid
- fix(frontend): never attach stale bearer token to /auth/* requests
- fix(configs): unpublish/publish can no longer bypass moderation
- refactor(accounts): shrink auth/handlers.rs under the 250-line cap
- fix(accounts): tolerate concurrent refresh without killing every session
- fix(gateway): minor hardening from the backend review
- feat(configs): IDDQD easter egg config
2026-09-25 20:22:13 +02:00

56 lines
4.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Backend Structure (продумано заранее, 2026-09-23)
Rust workspace (`backend/Cargo.toml`), один сервис — один крейт. Планировка
на все три подсистемы платформы (см. `TODO.md`, Фаза 10) сразу, чтобы не
переизобретать layout при переходе от Подсистемы 1 к 2/3.
```
backend/
Cargo.toml # workspace root — members растёт по мере реализации
STRUCTURE.md # этот файл
common/ # РЕАЛИЗОВАН — общий контракт: JWT, внутренние заголовки,
# proto/accounts.proto (gRPC AuthenticateDevice,
# GetPublicProfiles для авторов витрины)
accounts-service/ # РЕАЛИЗОВАН — backend/PLAN.md (Подсистема 1, часть 1)
gateway/ # РЕАЛИЗОВАН — gateway/PLAN.md: единственная публичная
# точка, identity, рейт-лимиты, CORS, reverse proxy
configs-service/ # РЕАЛИЗОВАН — configs-service/PLAN.md: 4 слота конфигов,
# share-коды, витрина publish/browse/detail/copy
# (Подсистема 1, часть 2)
chat-service/ # ПЛАН НЕ НАПИСАН — RPC-чат, друзья, presence,
# виджеты-телеметрия (Подсистема 2). Единственный
# сервис с WebSocket, а не только REST.
addons-registry/ # ПЛАН НЕ НАПИСАН — витрина аддонов, версии,
# публикация/модерация (Подсистема 3)
```
## Внутренний контракт (gateway ↔ сервисы)
Гейтвей — единственная публичная точка: он один раз резолвит вызывавшего
(JWT-access или `lvd_`-device-токен через gRPC `AuthenticateDevice`) и кладёт
аккаунт в заголовок `x-lovisual-account-id`; каждый запрос несёт общий секрет
`x-lovisual-internal-key`. Сервисы отвергают всё без этого ключа (403), поэтому
напрямую в них стучаться бесполезно. Снаружи — только REST/JSON на `api.<domain>`,
внутри — тот же REST сервисов + gRPC там, где публичного REST нет.
## Почему не добавлены в `[workspace] members` сразу
Пустой крейт без реализации — то же самое "без пустышек", что запрещено
правилами мода (см. `TODO.md`) — просто в Rust-обёртке: `cargo build
--workspace` не должен спотыкаться о нереализованные заглушки. Каждый
сервис входит в `members` в своём implementation-плане первым шагом (как
`accounts-service` в Task 1 `backend/PLAN.md`), не раньше.
## Общий код между сервисами (`common`, создан 2026-09-24)
Второй реальный потребитель появился вместе с `gateway`, поэтому общий код
уже вынесен: JWT `Claims`/`issue_access_token`/`verify_token`/`bearer_token`,
внутренний контракт (`require_internal_key`, `GatewayIdentity`, gRPC-перехватчики
ключа) и `proto/accounts.proto`. Следующий кандидат — типовой `AppError`:
сознательно НЕ вынесен, т.к. маппинг `From<sqlx::Error>` сервис-специфичен,
а `sqlx` не должен попадать в `gateway` (см. Global Constraints
`configs-service/PLAN.md`).
## Модульная структура внутри сервиса (эталон — `accounts-service`)
Домен, не технический слой: `auth/`, `accounts/`, `device/`, `avatars/` —
каждый со своими `mod.rs`/`handlers.rs`/`repo.rs` и т.п. (см. File Structure
в `backend/PLAN.md`). Тот же принцип — для `configs-service` (`slots/`,
`sharing/`, `showcase/`) и `chat-service` (`chat/`, `friends/`,
`telemetry/`) при их реализации.