feat(tradein/auth): expire praktika trial access + trial-ended screen (contact Artem) #1977

Merged
lekss361 merged 1 commit from feat/tradein-praktika-trial-ended into main 2026-06-27 10:35:07 +00:00
Owner

Summary

Revoke the praktika pilot trial account's access to the Мера (trade-in) section and show it a dedicated "пробный доступ закончился → contact Артём Копылов" screen. Soft block at the app layer — praktika keeps Caddy basic-auth so it still reaches the frontend and sees the message (rather than a raw browser 401). Only praktika is cut; kopylov (= Артём Копылов, the contact) is unaffected and keeps full access + unlimited quota.

Mechanism:

  • New expired role in auth/roles.yaml (paths: [], deny: ["/**"]); praktika: pilot → expired.
  • /me now returns role: "expired" for praktika → RouteGuard renders a new NoAccessScreen variant="trial" with a real Telegram link (https://t.me/ArtemKopylov87).
  • Role type extended with "expired" in backend (app/core/auth.py) and frontend (useMe.ts).

Trial screen copy:

Пробный доступ закончился — Пробный доступ к сервису «Мера» закончился. Чтобы продлить доступ или получить полную версию — напишите Артёму Копылову: @ArtemKopylov87

Test plan

  • Backend RBAC: test_rbac.py, test_me_brand.py, test_account_quota.py60 passed (kopylov still pilot/unlimited; praktika now expired, no trade-in access).
  • Frontend tsc --noEmit clean (source; pre-existing .next/ cache noise unrelated).
  • Post-deploy: praktika login → trial screen with working Telegram link; kopylov + other pilots → full access unchanged.

Notes

  • Path-level gating for non-admin roles is frontend (RouteGuard) per the roles.yaml architecture; the backend hard-gates only /api/v1/admin/**. So this blocks praktika in the UI (as requested). A backend hard-block for expired (defense-in-depth against manual API calls) is an easy follow-up if wanted.
  • auth/roles.yaml is repo-root (shared with the Site Finder stack). The expired role validates fine in both backends; the change reaches prod via the deploy git reset --hard + tradein-backend restart (lru_cache reload).
## Summary Revoke the `praktika` pilot **trial** account's access to the Мера (trade-in) section and show it a dedicated "пробный доступ закончился → contact Артём Копылов" screen. **Soft block at the app layer** — praktika keeps Caddy basic-auth so it still reaches the frontend and sees the message (rather than a raw browser 401). Only `praktika` is cut; **`kopylov` (= Артём Копылов, the contact) is unaffected** and keeps full access + unlimited quota. Mechanism: - New `expired` role in `auth/roles.yaml` (`paths: []`, `deny: ["/**"]`); `praktika: pilot → expired`. - `/me` now returns `role: "expired"` for praktika → `RouteGuard` renders a new `NoAccessScreen variant="trial"` with a real Telegram link (`https://t.me/ArtemKopylov87`). - `Role` type extended with `"expired"` in backend (`app/core/auth.py`) and frontend (`useMe.ts`). Trial screen copy: > **Пробный доступ закончился** — Пробный доступ к сервису «Мера» закончился. Чтобы продлить доступ или получить полную версию — напишите Артёму Копылову: @ArtemKopylov87 ## Test plan - [x] Backend RBAC: `test_rbac.py`, `test_me_brand.py`, `test_account_quota.py` — **60 passed** (kopylov still `pilot`/unlimited; praktika now `expired`, no trade-in access). - [x] Frontend `tsc --noEmit` clean (source; pre-existing `.next/` cache noise unrelated). - [ ] Post-deploy: praktika login → trial screen with working Telegram link; kopylov + other pilots → full access unchanged. ## Notes - Path-level gating for non-admin roles is frontend (`RouteGuard`) per the `roles.yaml` architecture; the backend hard-gates only `/api/v1/admin/**`. So this blocks praktika in the **UI** (as requested). A backend hard-block for `expired` (defense-in-depth against manual API calls) is an easy follow-up if wanted. - `auth/roles.yaml` is repo-root (shared with the Site Finder stack). The `expired` role validates fine in both backends; the change reaches prod via the deploy `git reset --hard` + tradein-backend restart (lru_cache reload).
lekss361 added 1 commit 2026-06-27 10:32:21 +00:00
feat(tradein/auth): expire praktika trial access + trial-ended screen (contact Artem)
All checks were successful
CI / changes (pull_request) Successful in 6s
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
703e411a17
praktika pilot→expired role in roles.yaml (paths:[], deny:/**); RouteGuard
short-circuits on role=expired with a dedicated trial-ended screen (not the
generic path-deny path). NoAccessScreen gains variant="trial" with title
«Пробный доступ закончился» and a Telegram link to @ArtemKopylov87. Backend
Role Literal and frontend Role type extended to include "expired". kopylov
(pilot) unaffected.
lekss361 added the
scope/backend
scope/frontend
tradein
labels 2026-06-27 10:32:32 +00:00
lekss361 merged commit 86ddf99bb6 into main 2026-06-27 10:35:07 +00:00
lekss361 deleted branch feat/tradein-praktika-trial-ended 2026-06-27 10:35:07 +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#1977
No description provided.