feat: SaaS foundation for CrowdSight
Elevate MiroFish/CrowdSight from single-container dev to a SaaS foundation: - Local memory backend (Zep-compatible): memory services/models, local graph builder + updater, AgentActivity seam, import-boundary isolation; Zep stays default, local is opt-in behind MEMORY_BACKEND. Semantic parity not yet proven. - Durable product persistence: projects/simulations/reports schema (migration 0007) + tenant/owner-scoped ProductRepository + dual-write + scoped_project read-first + ArtifactStore abstraction; durable JobQueue + worker.py. - SaaS hardening: durable RateLimiter (wired to login), UsageService (LLM accounting), redacted AuditService, idempotency, CORS allowlist, safe API errors, single-use PasswordResetService + endpoints (covers invite-pending). - Exactly 3 roles (super_admin/admin/user) with tenant authz policy. - Admin UI: GET/POST/PATCH /api/admin/users + GET/PUT /api/admin/settings (super-admin only, encrypted/masked); AdminView.vue + SettingsView.vue with admin/super-admin route guards, th/en i18n. - Production deploy topology: multi-stage Dockerfile (frontend build + gunicorn wsgi + nginx SPA-proxy + supervisord worker), backend/wsgi.py, gunicorn dep. Backend 197 passed; frontend 10 tests + build green. ruff unavailable (gap). No commit of credentials; secrets handled via env/.env.example. Deferred: Zep semantic A/B parity, object storage cutover, mobile QA, EasyPanel container build of deploy topology.
This commit is contained in:
@@ -13,6 +13,10 @@
|
||||
"failed": "Failed",
|
||||
"unknown": "Unknown",
|
||||
"unknownError": "Unknown error",
|
||||
"requestFailed": "Request failed. Please try again.",
|
||||
"networkError": "Network error. Please check your connection.",
|
||||
"requestTimeout": "The request timed out. Please try again.",
|
||||
"unauthorized": "Your session has expired. Please sign in again.",
|
||||
"none": "None",
|
||||
"close": "Close",
|
||||
"back": "Back",
|
||||
@@ -23,7 +27,20 @@
|
||||
"minutes": "minutes",
|
||||
"rounds": "rounds",
|
||||
"items": "items",
|
||||
"files": "files"
|
||||
"files": "files",
|
||||
"notFound": "The requested resource was not found."
|
||||
},
|
||||
"auth": {
|
||||
"eyebrow": "Secure workspace",
|
||||
"title": "Sign in to CrowdSight",
|
||||
"subtitle": "Use your company account to continue.",
|
||||
"email": "Email",
|
||||
"emailPlaceholder": "name@company.com",
|
||||
"password": "Password",
|
||||
"passwordPlaceholder": "Enter your password",
|
||||
"signIn": "Sign in",
|
||||
"signingIn": "Signing in...",
|
||||
"signInFailed": "Sign-in failed. Please try again."
|
||||
},
|
||||
"meta": {
|
||||
"title": "CrowdSight - Predict Everything",
|
||||
@@ -404,12 +421,26 @@
|
||||
"envRunning": "Environment is running and ready for Interview commands",
|
||||
"envNotRunningShort": "Environment not running or closed",
|
||||
"requireGraphIdAndQuery": "Please provide graph_id and query",
|
||||
"internalError": "The server could not complete the request.",
|
||||
"requestError": "The request could not be completed.",
|
||||
"idempotencyRequired": "Please provide an Idempotency-Key header.",
|
||||
"idempotencyInvalid": "The Idempotency-Key header is invalid.",
|
||||
"idempotencyConflict": "This Idempotency-Key was already used for a different request.",
|
||||
"idempotencyInProgress": "An identical request is already in progress.",
|
||||
"invalidCredentials": "Invalid email or password.",
|
||||
"tooManyAttempts": "Too many attempts. Please try again later.",
|
||||
"organizationRequired": "Please specify organization_slug.",
|
||||
"organizationNotFound": "Organization not found.",
|
||||
"invalidEmail": "Please provide a valid email address.",
|
||||
"invalidRole": "The requested role is not valid.",
|
||||
"userExists": "A user with this email already exists.",
|
||||
"initReportAgent": "Initializing Report Agent..."
|
||||
},
|
||||
"progress": {
|
||||
"initGraphService": "Initializing graph build service...",
|
||||
"textChunking": "Chunking text...",
|
||||
"creatingZepGraph": "Creating Zep graph...",
|
||||
"creatingGraph": "Creating graph...",
|
||||
"settingOntology": "Setting ontology definition...",
|
||||
"addingChunks": "Adding {count} text chunks...",
|
||||
"waitingZepProcess": "Waiting for Zep to process data...",
|
||||
@@ -432,6 +463,7 @@
|
||||
"taskFailed": "Task failed",
|
||||
"startPreparingEnv": "Preparing simulation environment...",
|
||||
"connectingZepGraph": "Connecting to Zep graph...",
|
||||
"connectingGraph": "Connecting to graph...",
|
||||
"readingNodeData": "Reading node data...",
|
||||
"readingComplete": "Done, {count} entities found",
|
||||
"startGenerating": "Starting generation...",
|
||||
@@ -688,5 +720,36 @@
|
||||
"fiction_story": "Fiction & Stories",
|
||||
"social_culture": "Social & Culture",
|
||||
"fillPrompt": "Edit prompt before running"
|
||||
},
|
||||
"admin": {
|
||||
"title": "User management",
|
||||
"refresh": "Refresh",
|
||||
"loading": "Loading users…",
|
||||
"empty": "No users found.",
|
||||
"colEmail": "Email",
|
||||
"colRole": "Role",
|
||||
"colStatus": "Status",
|
||||
"colActions": "Actions",
|
||||
"roleUser": "User",
|
||||
"roleAdmin": "Admin",
|
||||
"roleSuperAdmin": "Super admin",
|
||||
"status_active": "Active",
|
||||
"status_disabled": "Disabled",
|
||||
"deactivate": "Disable",
|
||||
"activate": "Activate"
|
||||
},
|
||||
"settings": {
|
||||
"title": "Platform LLM settings",
|
||||
"provider": "Provider",
|
||||
"model": "Model",
|
||||
"baseUrl": "Base URL",
|
||||
"apiKey": "API key",
|
||||
"apiKeyPlaceholder": "•••••••• (leave empty to keep current)",
|
||||
"save": "Save settings",
|
||||
"saved": "Settings saved.",
|
||||
"error": "Could not save settings.",
|
||||
"loading": "Loading settings…",
|
||||
"noneStored": "No settings stored yet.",
|
||||
"version": "Version"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user