Tier model: registered=basic (recipes, 12 photos, QR), PRO=verified or admin-activated (HSL, tools/gradient mask, RAW, export > source longest edge); admin users table gets Activated Pro column

This commit is contained in:
2026-09-30 11:50:28 +07:00
parent 35d8d57984
commit 74c0b2747f
10 changed files with 264 additions and 122 deletions
+6 -1
View File
@@ -19,6 +19,9 @@ export interface User {
// Signed-in accounts only unlock the PRO tier once their address is proven;
// an unverified one is served exactly like a guest. Admins count as verified.
verified?: boolean;
// The PRO tier itself: the proof above, or a grant the operator ticked for
// this account in the admin users table.
pro?: boolean;
// A ready-to-use picture URL (`/api/users/<id>/avatar?v=<file>`), or null.
// The version segment is the file's own name, so a replacement is never
// served from cache.
@@ -126,6 +129,8 @@ export interface AdminUser {
// but restorable (a hard delete drops the row entirely).
blocked: boolean;
removed: boolean;
// The "Activated Pro" box: true hands this account the studio's PRO tier.
pro: boolean;
}
// One row of a grouped count on the traffic screen. The API sorts them, largest
@@ -313,7 +318,7 @@ export const api = {
// Moderation of an account. Both flags are reversible; `adminDeleteUser` is
// the final act and takes the account's photos and recipes with it.
adminSetUser: (id: number, patch: { blocked?: boolean; removed?: boolean }) =>
adminSetUser: (id: number, patch: { blocked?: boolean; removed?: boolean; pro?: boolean }) =>
call<{ user: AdminUser }>(`/admin/users/${id}`, { method: 'PATCH', body: JSON.stringify(patch) }),
adminDeleteUser: (id: number) => call<void>(`/admin/users/${id}`, { method: 'DELETE' }),