feat(proj): init

This commit is contained in:
vl.arkhangelskii
2026-09-21 03:53:15 +03:00
commit 3e34f391b3
258 changed files with 20968 additions and 0 deletions
@@ -0,0 +1,41 @@
# Аккаунты, токены и SPA
Поверх тайлового пайплайна: Яндекс OAuth, персональные стили/URL, учёт запросов, Vite-кабинет на том же origin.
## Данные
- EF Core SQLite, файл `/data/app.db` (`IDataPaths.AppDatabase`).
- Таблицы: `Users`, `ApiTokens` (только SHA-256 hash + prefix `ts_...`), `UserStyles`, `UsageDaily`.
- Миграция `InitialAccounts`, `Database.Migrate()` на старте.
## Auth
- `GET /api/v1/auth/yandex/start` → 302 на oauth.yandex.ru.
- SPA ловит `?code=&state=` на `/`, `POST /api/v1/auth/yandex`.
- Cookie `ts_session` HttpOnly, SameSite=Lax, Secure=SameAsRequest.
- Кабинет: cookie. Выдача тайлов/стилей: `?token=` или `Authorization: Bearer`.
- Секрет Яндекса только в env: `TileServer__Yandex__ClientId|ClientSecret|RedirectUri`. Не коммитить.
## Выдача и usage
- `/u/{slug}/tiles/{source}/{z}/{x}/{y}.pbf?token=`
- `/u/{slug}/tiles/{source}.json?token=`
- `/u/{slug}/styles/{name}?source=&token=`
- Счётчик в `ConcurrentDictionary`, flush каждые 5 с в `UsageDaily`.
- Публичные `/api/v1/tiles` и `/api/v1/styles` без счётчика.
## Стили
- Клон пресета: `POST /api/v1/me/styles`.
- Bind персонального стиля: `tiles[0]` = `/u/{slug}/tiles/{source}/...pbf?token=`.
- Свои имена перекрывают пресеты.
## Фронт и деплой
- `web/`: Vite + React + styled-components, тема HUD (`#e8923d`).
- Docker: stage `node:22``wwwroot/app`. `/` — SPA, `/demo` — старое Razor-демо.
- Compose: `YANDEX_CLIENT_ID` / `YANDEX_CLIENT_SECRET` с хоста.
## Тесты
26 unit-тестов: hash/verify/revoked, slug, bind `/u/{slug}/` + token, батч usage.