Skip to content

feat(user): user management system — email auth, per-user isolation, admin console - #4

Merged
SuTang-vain merged 4 commits into
mainfrom
feature/user-management
Aug 9, 2026
Merged

feat(user): user management system — email auth, per-user isolation, admin console#4
SuTang-vain merged 4 commits into
mainfrom
feature/user-management

Conversation

@SuTang-vain

Copy link
Copy Markdown
Owner

Summary

User management system per the product direction: email as primary key, self-set password auth, per-user data isolation, admin console with full generation records, per-user subscription configuration and model/API usage tracking. Business tiers (free / Pro / Team) are configurable and usage-visible; quota enforcement is deferred to a follow-up iteration.

⚠️ Depends on PR #3 (babel-only engine) — this branch stacks on it; once #3 merges, this PR's diff narrows to the user-management changes only.

Backend

  • api/db/usersDb.ts (node:sqlite, zero deps): users (email PRIMARY KEY, scrypt salt:hash password), sessions (sha256 token, 30d expiry), usage (per-user counters). Admin role from ADMIN_EMAILS env (live-synced).
  • api/routes/auth.ts: register (email format + password ≥ 8), login, logout, /me; Bearer session tokens.
  • api/middleware/auth.ts: requireAuth / requireAdmin.
  • Per-user isolation: StoragePaths + userDataPaths(email)data/users/<email>/{bubbles,snapshots,workspace.json}; workspace/bubbles/snapshots/ai/memory routes are auth-gated and resolve user dirs (legacy paths kept as defaults for compat).
  • Usage tracking: bubbles, snapshots, and successful AI calls increment per-user counters.
  • api/routes/admin.ts (auth + admin): user list with usage, subscription config (free|pro|team), all-user generation records (bubbles + snapshots with details), usage overview.

Frontend

  • Login page (/login): register/login toggle.
  • Admin console (/admin): users table with subscription select + usage, expandable generation records, usage table.
  • authStore + token injection in apiClient; route guard (unauthenticated → /login); nav menu shows user email / subscription badge / logout / admin entry (admin only).

Verification

  • E2E verified against the running dev server: register/login, 401 without token, 403 for non-admin, bubble persisted into the per-user dir, subscription patch, admin records/usage endpoints.
  • npm run check / npm run lint green; npm run test:integration 39/39 (integration tests register a user and attach tokens via a shared helper; .gitignore now excludes data/users.db + data/users/).

Notes

  • Admin bootstrap: set ADMIN_EMAILS=admin@example.com in .env (comma-separated).
  • Quota enforcement and payment/billing are the next iteration (decided: close the loop first, no hard limits yet).

Product decision (ADR-B7): remove ModelScope/DeepSeek/Moonshot direct
integration and the cross-provider fallback chain. BabeL-O is the sole
AI engine; models and keys are fully managed by BabeL-O (ADR-B2 endgame).

- aiProfiles: AIProvider='babel' only; drop providerOrder/defaultModels/
  providerBaseURLs/resolveAutoCandidates/resolveAIProviderFromEnv
- routes/ai: buildProfilePayload simplified (json_object always for
  non-stream); POST /config keeps only babel; GET /config + 412 guard
  use live babel configured check
- settingsStore: remove 3 provider API key states; persist version 2 +
  migrate clears stale localStorage
- Settings: only BabeL-O card + model picker + test connection; key/model
  form, save button, auto mode removed
- env.example: BABEL_NEXUS_URL/BABEL_NEXUS_API_KEY only
- docs: ADR-B7 + fallback-related updates
- ai-config: babel baseURL join + empty model (ADR-B2), URL-missing
  unavailability, API key optional, live GET /config reflection
- ai-routing: json_object + empty model on requests, followup cache hit,
  snapshot no-cache, schema failure -> direct error (no fallback),
  429 -> direct failure (no fallback chain)
…admin console, subscriptions & usage

- api/db/usersDb.ts (node:sqlite): users (email PK, scrypt hash),
  sessions (token 30d), usage tables; ADMIN_EMAILS env for admin role
- api/routes/auth.ts: register/login/logout/me with Bearer sessions
- api/middleware/auth.ts: requireAuth / requireAdmin
- per-user data isolation: StoragePaths + userDataPaths(email);
  workspace/bubbles/snapshots routes resolve user dirs
- usage tracking: bubbles/snapshots/ai_calls increments
- api/routes/admin.ts: user list, subscription config (free/pro/team),
  all-user generation records, usage overview
- frontend: Login page, Admin console, authStore, token in apiClient,
  route guard, nav user block + logout + admin entry
- tests: shared auth helper; 5 integration files register+token;
  39/39 pass
node:sqlite requires Node >= 22.13; CI was pinned to Node 20 which
failed with ERR_UNKNOWN_BUILTIN_MODULE. Add engines declaration.
@SuTang-vain
SuTang-vain merged commit 3c12f50 into main Aug 9, 2026
1 check passed
@SuTang-vain
SuTang-vain deleted the feature/user-management branch August 9, 2026 10:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant