feat(user): user management system — email auth, per-user isolation, admin console - #4
Merged
Merged
Conversation
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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.
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 fromADMIN_EMAILSenv (live-synced).api/routes/auth.ts: register (email format + password ≥ 8), login, logout,/me; Bearer session tokens.api/middleware/auth.ts:requireAuth/requireAdmin.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).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): register/login toggle./admin): users table with subscription select + usage, expandable generation records, usage table./login); nav menu shows user email / subscription badge / logout / admin entry (admin only).Verification
npm run check/npm run lintgreen;npm run test:integration39/39 (integration tests register a user and attach tokens via a shared helper;.gitignorenow excludesdata/users.db+data/users/).Notes
ADMIN_EMAILS=admin@example.comin.env(comma-separated).