feat(tradein): аккаунт praktika + лимит 15 оценок/мес, чистка PRINZIP в UI #635

Merged
lekss361 merged 1 commit from feat/tradein-quota-praktika into main 2026-05-28 22:04:59 +00:00
Owner

Summary

  • Аккаунт praktika (роль pilot) — caddy/users.caddy.snippet + auth/roles.yaml
  • Лимит 15 успешных оценок/месяц на аккаунт (server-side по X-Authenticated-User):
    • таблица account_estimate_usage (миграция 076, идемпотентная)
    • app/services/account_quota.py + enforcement в POST /estimate (429) + GET /quota
    • admin и kopylov — без лимита; нет заголовка (dev) → fail-open
    • frontend: useQuota hook, счётчик «осталось N из 15», блок формы + баннер «Свяжитесь с Артёмом Копыловым»
  • Брендинг PRINZIP убран только из UI (футер + css-коммент). Таблица brands, PDF white-label и скрейпер Яндекса (реальный застройщик PRINZIP) — НЕ тронуты.

Notes

  • Лимит сбрасывается по календарному месяцу (UTC). Сброс/правка вручную — UPDATE/DELETE в account_estimate_usage.
  • TOCTOU: при гонке возможен off-by-one (приемлемо для пилота).

Test plan

  • pytest tests/test_account_quota.py — 28 passed
  • ruff check — clean
  • tsc --noEmit — clean
  • smoke: praktika логинится, после 15 оценок видит баннер; admin/kopylov без лимита
## Summary - **Аккаунт `praktika`** (роль pilot) — caddy/users.caddy.snippet + auth/roles.yaml - **Лимит 15 успешных оценок/месяц на аккаунт** (server-side по `X-Authenticated-User`): - таблица `account_estimate_usage` (миграция 076, идемпотентная) - `app/services/account_quota.py` + enforcement в `POST /estimate` (429) + `GET /quota` - admin и `kopylov` — без лимита; нет заголовка (dev) → fail-open - frontend: `useQuota` hook, счётчик «осталось N из 15», блок формы + баннер «Свяжитесь с Артёмом Копыловым» - **Брендинг PRINZIP убран только из UI** (футер + css-коммент). Таблица `brands`, PDF white-label и скрейпер Яндекса (реальный застройщик PRINZIP) — НЕ тронуты. ## Notes - Лимит сбрасывается по календарному месяцу (UTC). Сброс/правка вручную — UPDATE/DELETE в `account_estimate_usage`. - TOCTOU: при гонке возможен off-by-one (приемлемо для пилота). ## Test plan - [x] `pytest tests/test_account_quota.py` — 28 passed - [x] `ruff check` — clean - [x] `tsc --noEmit` — clean - [ ] smoke: praktika логинится, после 15 оценок видит баннер; admin/kopylov без лимита
lekss361 added 1 commit 2026-05-28 22:00:57 +00:00
Account quota (server-side, по X-Authenticated-User):
- новая таблица account_estimate_usage (миграция 076, идемпотентная)
- app/services/account_quota.py: 15 успешных оценок в календарный месяц на аккаунт
- enforcement в POST /estimate (429 при исчерпании) + GET /quota
- admin и kopylov — без лимита; нет заголовка (dev) → fail-open
- frontend: useQuota hook, счётчик «осталось N из 15», блок формы + баннер
  «Свяжитесь с Артёмом Копыловым» при исчерпании

Account praktika:
- caddy/users.caddy.snippet + auth/roles.yaml (роль pilot)

Брендинг PRINZIP убран только из UI (футер + css-коммент); таблица brands,
PDF white-label и скрейпер Яндекса (реальный застройщик PRINZIP) не тронуты.
lekss361 merged commit bd3e5c8216 into main 2026-05-28 22:04:59 +00:00
lekss361 deleted branch feat/tradein-quota-praktika 2026-05-28 22:04:59 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#635
No description provided.