P15d: storage usage display + owner admin panel

- Server: AccountStore gains admin gating (ADMIN_USERS env), per-user quotaBytes
  override, listUsers + blobBytes. /api/usage now reports total bytes (backup blob +
  cloud characters) + an admin flag. Admin routes GET /api/admin/users and POST
  /api/admin/quota (gated). Quotas are tracked, not yet enforced. +1 test.
- Client: Settings cloud panel shows "Your cloud storage", and for an admin a users
  table with per-user usage + an editable quota (GB). compose sets ADMIN_USERS=nilsb.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-08 17:48:27 +02:00
parent e8371f6d3b
commit ea4522f877
6 changed files with 118 additions and 4 deletions
+11
View File
@@ -43,3 +43,14 @@ export function listCloudCharacters(campaignId: string): Promise<CloudCharInfo[]
export async function cloudUsageBytes(): Promise<number> {
return (await req<{ bytes: number }>('/usage')).bytes;
}
export interface AdminUserRow { username: string; usageBytes: number; quotaBytes: number }
export function getUsage(): Promise<{ bytes: number; admin: boolean }> {
return req<{ bytes: number; admin: boolean }>('/usage');
}
export function adminListUsers(): Promise<{ users: AdminUserRow[] }> {
return req<{ users: AdminUserRow[] }>('/admin/users');
}
export function adminSetQuota(username: string, quotaBytes: number): Promise<{ ok: boolean }> {
return req<{ ok: boolean }>('/admin/quota', { method: 'POST', body: JSON.stringify({ username, quotaBytes }) });
}