Security / correctness
- Privilege escalation: rule/api-key/project-update routes now gate on
can_manage_members instead of is_member; plain members could previously
rewrite or disable moderation rules and delete API keys.
- Project.is_owner() AttributeError on non-admin API-user deletion (route
+ template) replaced with user_id comparison.
- Flask-Limiter on /auth/login, /auth/register, /auth/change-password,
and /api/moderate (per API key id).
- Remove silent SECRET_KEY fallback: docker-compose fails hard if unset;
production config validator refuses to boot without SECRET_KEY and
OPENAI_API_KEY.
- Require verified email in Google OAuth auto-link flow.
- User-supplied regex now evaluated via the regex package with a 1s
timeout, closing the ReDoS vector.
- Cap batched AI chunk count (max 40) and concurrent workers (200 -> 10).
- openai>=2.32 (from 1.55.3 so reasoning_effort kwarg works); add regex,
Flask-Limiter, gunicorn, eventlet, psycogreen; drop the stdlib-shadowing
pypi asyncio package.
Production runtime
- New wsgi.py: eventlet.monkey_patch + psycogreen.patch_psycopg so DB
queries cooperate with the event loop; sets SOCKETIO_ASYNC_MODE=eventlet
for app startup.
- Dockerfiles run as non-root app user and CMD gunicorn with
--worker-class eventlet. run.py refuses FLASK_CONFIG=production so a
misconfigured deploy fails loudly.
- cloudbuild.yaml stops managing env vars/secrets on deploy — it was
about to clobber secret-backed env vars with plain ones. Runtime config
is now owned by the Cloud Run service.
SocketIO async-mode fix (was causing full site lockup during API calls)
- async_mode picked via SOCKETIO_ASYNC_MODE env var, default "threading".
The previous sys.modules auto-detect false-positived because
flask_socketio / python-engineio import eventlet on load whenever it is
installed, pinning a non-monkey-patched eventlet server in front of
blocking stdlib I/O.
Real-time dashboard updates
- New content_received WebSocket event fires when the API accepts a
submission; UI renders a "Processing…" row immediately and updates it
in place when moderation_update arrives.
- Fix stale updated_at timestamp in moderation_update payloads.
Batched AI rule evaluation
- Replace the per-rule parallel fan-out (N OpenAI calls) with a single
batched call evaluating all AI-prompt rules at once. On a 6-rule
default project this drops safe-content cost from 5-12s to ~1-4s.
- response_format=json_object + max_completion_tokens=4000 so the model
emits strict JSON and stops at the close-brace.
- OPENAI_REASONING_EFFORT config: minimal/low/medium/high for gpt-5 /
o-series; accepts "none" on gpt-5.4. Works around the gpt-5-nano case
where reasoning tokens ate the full output budget and returned empty
responses.
Client errors
- Malformed / non-UTF-8 JSON bodies now return 400 with a clear message
about UTF-8 encoding instead of a generic 500.
Logging
- Single INFO line per moderation: the existing
"Content <id>: decision in Zs" summary.
- Per-stage timing, websocket scheduling, and batched-AI call details
moved to DEBUG so they are available when diagnosing latency without
cluttering steady-state logs.
Replaces detailed exception messages with generic error messages in API, dashboard, and manual review routes to prevent leaking sensitive information. Also updates the error handler to return a generic internal server error message.
Introduces an in-memory error tracker service for monitoring and debugging. Integrates error tracking into API and moderation logic, logs errors with details, and displays error statistics and recent errors in the admin system health page for improved visibility and diagnostics.
Raised content moderation limit from 1MB to 5MB and updated MAX_CONTENT_LENGTH to 10MB in config. Added logging for content size, missing JSON data, and validation errors to improve monitoring and debugging.
Moved analytics and statistics queries from route handlers to new async methods in DatabaseService for admin, API, and project analytics. Updated routes to use these service methods, improving separation of concerns and maintainability. Added type annotations and minor code cleanups across several modules.
Introduces Pydantic schemas for request/response validation and applies them to API endpoints for robust input handling. Replaces manual project membership checks in dashboard routes with async decorators for project access validation. Refactors database service methods to eagerly load related data and adds pagination for flagged content. Removes admin project detail view and updates templates to use new access patterns and data sources.
Centralizes database operations in db_service for user and API key creation, and project statistics. Introduces app/utils/error_handlers.py for consistent API and web error responses, and updates API routes to use these utilities. Adds thread pool configuration for async DB operations in config. Improves maintainability and error handling across admin, dashboard, and API routes.
Expanded and reorganized CLAUDE.md for improved onboarding, architecture, and API clarity. Updated docs to standardize endpoint naming, improve examples, and clarify model relationships. Deleted unused app/utils/__init__.py to clean up the codebase.