Files
resolutionflow/docker-compose.dev.yml
Michael Chihlas 8494366ec6
Some checks failed
Mirror to GitHub / mirror (push) Successful in 5s
CI / e2e (pull_request) Failing after 1m57s
CI / frontend (pull_request) Failing after 2m35s
CI / backend (pull_request) Successful in 9m46s
feat(billing): add INTERNAL_TESTER_EMAILS allowlist for self-serve soft cutover
Phase O Task 46 needs internal validation of the full self-serve flow
against the prod backend before flipping SELF_SERVE_ENABLED public. This
adds the per-email allowlist that bypasses the global flag for specific
authenticated users.

- INTERNAL_TESTER_EMAILS: comma-separated list, parsed by a Pydantic
  field_validator into a normalized lowercase list. Settings.is_internal_tester
  and Settings.is_self_serve_active_for centralize the allowlist + global-flag
  check; both endpoints below call the latter.
- New get_current_user_optional dep — best-effort auth that returns None
  on missing/invalid token instead of 401. Used by /config/public so the
  same endpoint serves anonymous public callers and authenticated allowlist
  members.
- /config/public now accepts optional auth and returns self_serve_enabled=True
  for authenticated allowlist members even when the global flag is off.
  Anonymous callers always see the global flag.
- /auth/register replaces the SELF_SERVE_ENABLED check with the helper so a
  registering email on the allowlist can join without an invite code.
  Non-allowlist emails still 400 when self-serve is off.
- docker-compose.dev.yml passes SELF_SERVE_ENABLED + INTERNAL_TESTER_EMAILS
  through; backend/.env.example documents both.

Tests cover: allowlisted authenticated user sees true, non-allowlisted
authenticated user sees the global flag, anonymous calls ignore the
allowlist, allowlisted email registers without invite code, non-allowlisted
email still blocked.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 16:57:25 -04:00

78 lines
2.5 KiB
YAML

name: resolutionflow
services:
db:
image: pgvector/pgvector:pg16
container_name: resolutionflow_postgres
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: resolutionflow
ports:
- "${POSTGRES_PORT:-5433}:5432"
volumes:
- rf_postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 5s
retries: 5
backend:
build:
context: ./backend
dockerfile: Dockerfile.dev
container_name: resolutionflow_backend
command: uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload
ports:
- "8000:8000"
volumes:
- ${REPO_ROOT}/backend:/app
environment:
- APP_NAME=ResolutionFlow
- DEBUG=true
- DATABASE_URL=postgresql+asyncpg://postgres:postgres@db:5432/resolutionflow
- DATABASE_URL_SYNC=postgresql://postgres:postgres@db:5432/resolutionflow
# Dedicated test database — pytest will refuse to run against any DB
# whose name doesn't contain 'test' (conftest.py safety assertion).
- DATABASE_TEST_URL=postgresql+asyncpg://postgres:postgres@db:5432/resolutionflow_test
- SECRET_KEY=${SECRET_KEY}
- ALGORITHM=HS256
- ACCESS_TOKEN_EXPIRE_MINUTES=15
- REFRESH_TOKEN_EXPIRE_DAYS=7
- REQUIRE_INVITE_CODE=false
- FEEDBACK_EMAIL=feedback@resolutionflow.com
- AI_PROVIDER=anthropic
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
- GOOGLE_AI_API_KEY=${GOOGLE_AI_API_KEY:-}
- STRIPE_SECRET_KEY=${STRIPE_SECRET_KEY:-}
- STRIPE_PUBLISHABLE_KEY=${STRIPE_PUBLISHABLE_KEY:-}
- STRIPE_WEBHOOK_SECRET=${STRIPE_WEBHOOK_SECRET:-}
- SELF_SERVE_ENABLED=${SELF_SERVE_ENABLED:-false}
- INTERNAL_TESTER_EMAILS=${INTERNAL_TESTER_EMAILS:-}
- ENABLE_MCP_MICROSOFT_LEARN=true
- FRONTEND_URL=http://docker-01:5173
- CORS_ORIGINS=["http://localhost:5173","http://127.0.0.1:5173","http://docker-01:5173","http://100.64.78.44:5173"]
depends_on:
db:
condition: service_healthy
frontend:
build:
context: ./frontend
dockerfile: Dockerfile.dev
container_name: resolutionflow_frontend
command: npm run dev -- --host 0.0.0.0 --port 5173
ports:
- "5173:5173"
volumes:
- ${REPO_ROOT}/frontend:/app
- /app/node_modules
environment:
- VITE_API_URL=http://docker-01:8000
- CHOKIDAR_USEPOLLING=true
depends_on:
- backend
volumes:
rf_postgres_data: