[codex] Harden deployment config startup#347
Conversation
|
Warning Review limit reached
Next review available in: 47 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (4)
📝 WalkthroughWalkthroughThe PR updates runtime configuration defaults and validation, adds resume scan handling and health reporting, changes Discord bot startup token handling, and introduces a Docker smoke stack with workflow and documentation support. ChangesRuntime config, startup, and smoke validation
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: dfc49fa338
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| try: | ||
| await asyncio.to_thread(run_job_migrations) | ||
| except Exception: | ||
| logger.exception("Failed to run job migrations during startup") |
There was a problem hiding this comment.
Don't mark the API healthy after skipped migrations
When run_job_migrations() fails here, startup now continues and the only later Postgres health check is SELECT 1. In a deploy where the migration fails because the DB is temporarily unavailable, permissions are wrong, or a migration SQL error occurs, the service can later return /health 200 once a bare connection succeeds even though Alembic never reran and required tables/columns may be missing, causing API routes and queued jobs to fail against a stale schema. Preserve the migration failure in health or retry migrations before allowing Postgres to be considered healthy.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Pull request overview
This PR adjusts runtime configuration and startup behavior across the API/worker/bot so deployments are less likely to crash on import/startup when optional or runtime-only environment variables are missing, shifting failures into /health and runtime reporting instead.
Changes:
- Relaxed settings validation defaults (notably Postgres/MinIO secrets and newsletter sync default) and updated corresponding unit tests.
- Made API startup resilient to Postgres migration/connection failures and gated CRM sync scheduler startup on ESPO credentials.
- Added a Docker Compose-based smoke script and a merge-queue workflow to validate API container startup +
/health.
Reviewed changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/unit/test_worker_config.py | Updates worker settings tests for ESPO-optional behavior and non-local virus-scan defaults. |
| tests/unit/test_shared_settings.py | Updates shared settings tests to allow non-local construction even when runtime deps are unset. |
| tests/unit/test_bot.py | Adds coverage for bot token being optional for config import but required at runtime start. |
| tests/unit/test_backend_api.py | Adds coverage for CRM scheduler gating + degraded health when Postgres startup fails. |
| scripts/docker-smoke.sh | New script to build/run an isolated API+Redis+Postgres stack and poll /health. |
| packages/shared/src/five08/settings.py | Changes shared defaults (newsletter sync off; Postgres default constant) and removes eager non-local secret validation. |
| ENVIRONMENT.md | Updates env var guidance for Postgres/ESPO/newsletter sync defaults. |
| docs/configuration.md | Updates configuration docs for virus-scan requirement removal and newsletter sync default. |
| DEVELOPMENT.md | Documents the new Docker smoke script for deployment-style startup checks. |
| apps/worker/src/five08/worker/config.py | Removes non-local ESPO requirement validation and adds espo_configured helper. |
| apps/discord_bot/src/five08/discord_bot/main.py | Enforces non-empty bot token at runtime start (after stripping). |
| apps/discord_bot/src/five08/discord_bot/config.py | Makes bot token default blank to avoid config import failures. |
| apps/api/src/five08/backend/api.py | Makes Postgres startup best-effort, adds CRM scheduler gating, and supports None postgres connection checks. |
| .github/workflows/docker-smoke.yml | Adds merge-group/manual workflow that runs the Docker smoke script. |
| .env.example | Updates the commented newsletter sync default to false. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if _should_start_crm_sync_scheduler(): | ||
| app.state.crm_sync_task = asyncio.create_task(_crm_sync_scheduler(app)) | ||
| else: | ||
| logger.info("CRM sync scheduler disabled by config") |
| def _should_start_crm_sync_scheduler() -> bool: | ||
| if not settings.crm_sync_enabled: | ||
| return False | ||
| if settings.espo_configured: | ||
| return True | ||
| logger.warning( | ||
| "CRM sync scheduler enabled but ESPO_BASE_URL/ESPO_API_KEY are not configured; skipping scheduler startup" | ||
| ) | ||
| return False |
| - `API_SHARED_SECRET` (required for protected endpoints) | ||
| - `POSTGRES_URL` (required in non-local environments) | ||
| - `MINIO_ROOT_PASSWORD` (required in non-local environments) | ||
| - `DISCORD_BOT_TOKEN` (Discord bot runtime) |
| ## Postgres + Compose Exposure | ||
|
|
||
| - `Optional`: `POSTGRES_URL` (default: `postgresql://postgres:postgres@127.0.0.1:5432/workflows`; `./scripts/dev.sh` overrides it to a deterministic per-worktree localhost port, Compose injects a Docker-network URL) | ||
| - `Required in non-local environments`: `POSTGRES_URL` (local default: `postgresql://postgres:postgres@127.0.0.1:5432/workflows`; `./scripts/dev.sh` overrides it to a deterministic per-worktree localhost port, Compose injects a Docker-network URL) |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (3)
tests/unit/test_backend_api.py (1)
64-65: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winAdd a migration-only degraded-health case.
This patches both migrations and connection setup to fail, so it doesn’t catch the case where migrations fail but
get_postgres_connection()succeeds. Add that isolated case to lock the intended startup-health contract.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/unit/test_backend_api.py` around lines 64 - 65, The degraded-health coverage in the backend API tests currently only exercises the case where both run_job_migrations and get_postgres_connection fail, so it misses the startup path where migrations fail but the database connection still succeeds. Add a separate test case in the test_backend_api suite that monkeypatches only run_job_migrations to fail while leaving get_postgres_connection successful, then assert the health state matches the intended migration-only degraded behavior..github/workflows/docker-smoke.yml (1)
11-11: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick winDisable checkout credential persistence.
The next step runs a repository shell script, so storing the workflow token in local git config is unnecessary exposure here. Set
persist-credentials: falseon checkout.Proposed fix
- - uses: actions/checkout@v6 + - uses: actions/checkout@v6 + with: + persist-credentials: false🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/docker-smoke.yml at line 11, The checkout step in the docker-smoke workflow is persisting credentials unnecessarily, which exposes the workflow token to the repository config. Update the existing actions/checkout configuration to set persist-credentials to false so the later shell script step can run without leaving the token in local git settings.Source: Linters/SAST tools
scripts/docker-smoke.sh (1)
99-100: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winMatch the health payload semantically, not by exact JSON formatting.
grep -q '"status":"healthy"'will false-fail if the response serializer adds whitespace while keeping the same/healthcontract. A whitespace-tolerant match is safer here.Proposed fix
- if [ "$last_code" = "200" ] && grep -q '"status":"healthy"' "$body_file"; then + if [ "$last_code" = "200" ] && grep -Eq '"status"[[:space:]]*:[[:space:]]*"healthy"' "$body_file"; then🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@scripts/docker-smoke.sh` around lines 99 - 100, The health check in the docker smoke test is matching the /health response by exact JSON text, which is too brittle. Update the check in scripts/docker-smoke.sh near the curl/grep logic to validate the payload semantically or with a whitespace-tolerant pattern so it still passes when the serializer changes formatting. Keep the status-code gate and adjust the grep/match around the health response body to use a more flexible check tied to the health contract.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/docker-smoke.yml:
- Around line 3-9: The docker-smoke workflow currently relies on the default
GITHUB_TOKEN scope, which is broader than needed for this job. Add an explicit
minimal permissions block to the docker-smoke job in the workflow so it only has
repository read access, and keep the change localized to the existing workflow
job definition.
In `@apps/api/src/five08/backend/api.py`:
- Around line 9099-9102: The startup migration failure in the
`run_job_migrations` block is only logged, so `/health` can still look healthy
even after migrations fail. Add a persistent startup state in `api.py` (set it
when `run_job_migrations()` raises in the `asyncio.to_thread` call) and have the
health check path that currently relies on `get_postgres_connection()`/`SELECT
1` also read that state. Make the health calculation return degraded/unhealthy
whenever the migration-failed flag is set, while keeping the existing connection
check behavior.
---
Nitpick comments:
In @.github/workflows/docker-smoke.yml:
- Line 11: The checkout step in the docker-smoke workflow is persisting
credentials unnecessarily, which exposes the workflow token to the repository
config. Update the existing actions/checkout configuration to set
persist-credentials to false so the later shell script step can run without
leaving the token in local git settings.
In `@scripts/docker-smoke.sh`:
- Around line 99-100: The health check in the docker smoke test is matching the
/health response by exact JSON text, which is too brittle. Update the check in
scripts/docker-smoke.sh near the curl/grep logic to validate the payload
semantically or with a whitespace-tolerant pattern so it still passes when the
serializer changes formatting. Keep the status-code gate and adjust the
grep/match around the health response body to use a more flexible check tied to
the health contract.
In `@tests/unit/test_backend_api.py`:
- Around line 64-65: The degraded-health coverage in the backend API tests
currently only exercises the case where both run_job_migrations and
get_postgres_connection fail, so it misses the startup path where migrations
fail but the database connection still succeeds. Add a separate test case in the
test_backend_api suite that monkeypatches only run_job_migrations to fail while
leaving get_postgres_connection successful, then assert the health state matches
the intended migration-only degraded behavior.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: cbcff1fe-e224-421f-96aa-581d3b6a1d77
📒 Files selected for processing (15)
.env.example.github/workflows/docker-smoke.ymlDEVELOPMENT.mdENVIRONMENT.mdapps/api/src/five08/backend/api.pyapps/discord_bot/src/five08/discord_bot/config.pyapps/discord_bot/src/five08/discord_bot/main.pyapps/worker/src/five08/worker/config.pydocs/configuration.mdpackages/shared/src/five08/settings.pyscripts/docker-smoke.shtests/unit/test_backend_api.pytests/unit/test_bot.pytests/unit/test_shared_settings.pytests/unit/test_worker_config.py
| redis_queue_name: str = "jobs.default" | ||
| redis_key_prefix: str = "jobs" | ||
| redis_socket_connect_timeout: float | None = 5.0 | ||
| redis_socket_timeout: float | None = 5.0 | ||
| postgres_url: str = "postgresql://postgres:postgres@127.0.0.1:5432/workflows" | ||
| postgres_url: str = DEFAULT_POSTGRES_URL |
| on: | ||
| merge_group: | ||
| pull_request: | ||
| types: [labeled] | ||
| workflow_dispatch: |
| def _should_start_crm_sync_scheduler() -> bool: | ||
| if not settings.crm_sync_enabled: | ||
| return False | ||
| if settings.espo_configured: | ||
| return True |
| - `POSTGRES_URL` (required in non-local environments) | ||
| - `MINIO_ROOT_PASSWORD` (required in non-local environments) |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3aea425c6f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if ( | ||
| self.intake_resume_require_virus_scan | ||
| and not (self.intake_resume_virus_scan_command or "").strip() |
There was a problem hiding this comment.
Restore production resume scan enforcement
In production with intake enabled and INTAKE_RESUME_REQUIRE_VIRUS_SCAN left unset/false, this validator now accepts the config, so IntakeFormProcessor._scan_resume_content() returns True immediately and document_processor.extract_text() parses the downloaded resume without a malware scan. This regresses the explicit AGENTS.md guidance: "Resume files are untrusted. Keep scanning required in production and configure a scanner command"; keep the non-local requirement or fail/degrade health instead of allowing production to process unscanned resumes.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
apps/api/src/five08/backend/api.py (1)
9110-9119: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winBound the Postgres startup calls.
run_job_migrations()andget_postgres_connection()still have no timeout here, so a stalled Postgres or locked migration can block lifespan indefinitely and keep/healthfrom ever coming up.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/api/src/five08/backend/api.py` around lines 9110 - 9119, The startup path in api.py still lets run_job_migrations and get_postgres_connection block indefinitely, which can stall lifespan and prevent /health from becoming ready. Add explicit timeouts around both asyncio.to_thread calls in the startup flow, handling timeout failures the same way other startup errors are handled by logging and setting the relevant app.state flag. Use the existing startup block near run_job_migrations and get_postgres_connection so the Postgres bootstrap work cannot hang forever.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@compose.yaml`:
- Around line 137-138: The `depends_on` entries for `web` and `worker` are
making `clamav` a hard startup dependency in all Compose runs, which conflicts
with the optional/degraded behavior introduced by
`effective_intake_resume_require_virus_scan`. Update the Compose configuration
so the `clamav: condition: service_healthy` dependency is only applied in
prod/smoke contexts, using a profile or override file, and make the same
adjustment for the `worker` service as well.
---
Outside diff comments:
In `@apps/api/src/five08/backend/api.py`:
- Around line 9110-9119: The startup path in api.py still lets
run_job_migrations and get_postgres_connection block indefinitely, which can
stall lifespan and prevent /health from becoming ready. Add explicit timeouts
around both asyncio.to_thread calls in the startup flow, handling timeout
failures the same way other startup errors are handled by logging and setting
the relevant app.state flag. Use the existing startup block near
run_job_migrations and get_postgres_connection so the Postgres bootstrap work
cannot hang forever.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 58491cf8-bf72-4841-9b2f-74d42b87b2b0
📒 Files selected for processing (13)
.github/workflows/docker-smoke.ymlENVIRONMENT.mdapps/api/Dockerfileapps/api/src/five08/backend/api.pyapps/worker/Dockerfileapps/worker/src/five08/worker/config.pyapps/worker/src/five08/worker/crm/intake_form_processor.pycompose.yamldocs/configuration.mdscripts/docker-smoke.shtests/unit/test_backend_api.pytests/unit/test_intake_form_processor.pytests/unit/test_worker_config.py
🚧 Files skipped from review as they are similar to previous changes (1)
- tests/unit/test_worker_config.py
| def _check_postgres_connection(connection: Connection | None) -> bool: | ||
| if connection is None: | ||
| return False | ||
| try: | ||
| with connection.cursor() as cursor: |
| MINIO_INTERNAL_BUCKET: ${MINIO_INTERNAL_BUCKET:-internal-transfers} | ||
| INTAKE_RESUME_VIRUS_SCAN_COMMAND: ${INTAKE_RESUME_VIRUS_SCAN_COMMAND-clamdscan --stream --no-summary --config-file=/etc/clamav/clamdscan.conf {path}} |
| MINIO_INTERNAL_BUCKET: ${MINIO_INTERNAL_BUCKET:-internal-transfers} | ||
| INTAKE_RESUME_VIRUS_SCAN_COMMAND: ${INTAKE_RESUME_VIRUS_SCAN_COMMAND-clamdscan --stream --no-summary --config-file=/etc/clamav/clamdscan.conf {path}} |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4a4486479b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| MINIO_INTERNAL_BUCKET: ${MINIO_INTERNAL_BUCKET:-internal-transfers} | ||
| # Use '-' intentionally: an explicitly blank value means "scanner not configured", | ||
| # allowing startup while /health reports degraded in non-local runtimes. | ||
| INTAKE_RESUME_VIRUS_SCAN_COMMAND: ${INTAKE_RESUME_VIRUS_SCAN_COMMAND-clamdscan --stream --no-summary --config-file=/etc/clamav/clamdscan.conf {path}} |
There was a problem hiding this comment.
Don't let copied env files suppress ClamAV default
Docker Compose interpolation reads the project .env file, and the Docker docs distinguish ${VAR-default} (default only when unset) from ${VAR:-default} (also when empty). Because .env.example:251 defines INTAKE_RESUME_VIRUS_SCAN_COMMAND= blank, a production .env copied from it makes this new Compose default resolve to an empty string, so /health is degraded instead of using the documented ClamAV sidecar command. Use :- here, or remove/comment the blank sample variable if an empty value should not opt out of the default. See the Compose interpolation docs: https://docs.docker.com/compose/how-tos/environment-variables/variable-interpolation/
Useful? React with 👍 / 👎.
| MINIO_INTERNAL_BUCKET: ${MINIO_INTERNAL_BUCKET:-internal-transfers} | ||
| # Use '-' intentionally: an explicitly blank value means "scanner not configured", | ||
| # allowing startup while /health reports degraded in non-local runtimes. | ||
| INTAKE_RESUME_VIRUS_SCAN_COMMAND: ${INTAKE_RESUME_VIRUS_SCAN_COMMAND-clamdscan --stream --no-summary --config-file=/etc/clamav/clamdscan.conf {path}} |
There was a problem hiding this comment.
Wait for ClamAV before starting resume workers
In the canonical Compose stack, this command points the worker at the clamav sidecar, but the worker depends_on below only waits for web/redis/postgres/minio; Compose only waits for healthchecks on dependencies declared with condition: service_healthy (as the smoke compose does for ClamAV in scripts/docker-smoke.sh:79-85; Docker docs: https://docs.docker.com/compose/how-tos/startup-order/). On deploys where ClamAV is still initializing and an intake job arrives, _scan_resume_content() treats the connection failure as a failed scan and the intake can complete with resume_uploaded: false, so add a clamav: service_healthy dependency for the worker.
Useful? React with 👍 / 👎.
| postgres_migrations_ok = getattr(request.app.state, "postgres_migrations_ok", True) | ||
| if not postgres_migrations_ok: | ||
| postgres_ok = False | ||
| elif hasattr(request.app.state, "postgres_conn"): | ||
| postgres_ok = await _is_postgres_connection_healthy(request.app) |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 202495710c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| MINIO_INTERNAL_BUCKET: ${MINIO_INTERNAL_BUCKET:-internal-transfers} | ||
| # Use '-' intentionally: an explicitly blank value means "scanner not configured", | ||
| # allowing startup while /health reports degraded in non-local runtimes. | ||
| INTAKE_RESUME_VIRUS_SCAN_COMMAND: ${INTAKE_RESUME_VIRUS_SCAN_COMMAND-clamdscan --stream --no-summary --config-file=/etc/clamav/clamdscan.conf {path}} |
There was a problem hiding this comment.
Avoid braces in the Compose scanner default
When deployers override INTAKE_RESUME_VIRUS_SCAN_COMMAND as the docs suggest, e.g. clamdscan --fdpass {path}, this Compose expression still parses the braced ${VAR-default} value up to the } in the default and leaves the final } as a literal; Docker documents that unquoted values are interpolated as braced expressions (https://docs.docker.com/compose/how-tos/environment-variables/variable-interpolation/). The worker then receives ... {path}}, _scan_resume_content() replaces it with a temp filename ending in }, and clamdscan scans a nonexistent path, causing resume intake jobs to fail. Since the code already appends the path when the placeholder is omitted, keep {path} out of the Compose interpolation default.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@compose.yaml`:
- Around line 119-121: The default scanner command interpolation is malformed
because the inline Compose fallback for INTAKE_RESUME_VIRUS_SCAN_COMMAND
includes {path}, which conflicts with Compose’s ${...} parsing. Move the default
ClamAV command out of the compose interpolation or source it from a separate env
value, and keep the command text in a place where {path} is not parsed by
Compose. Update the affected INTAKE_RESUME_VIRUS_SCAN_COMMAND entry so the
default is preserved without breaking either Compose configuration.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 42185892-34d8-4fc8-96c2-24ab273ff26d
📒 Files selected for processing (6)
.env.exampleapps/api/src/five08/backend/api.pyapps/worker/src/five08/worker/crm/intake_form_processor.pycompose.yamltests/unit/test_backend_api.pytests/unit/test_intake_form_processor.py
🚧 Files skipped from review as they are similar to previous changes (3)
- apps/worker/src/five08/worker/crm/intake_form_processor.py
- tests/unit/test_backend_api.py
- apps/api/src/five08/backend/api.py
Summary
/healthcan report degraded status, including preserved migration-failure stateDISCORD_BOT_TOKENrequired at bot runtime without breaking config imports/healthWhy
Coolify cleans up containers after startup failures, which makes env/config crashes hard to debug. This shifts failures from import/startup validation into health/runtime reporting where possible, while preserving required runtime behavior for the services that truly need credentials.
Validation
uv run ruff check packages/shared/src/five08/settings.py apps/worker/src/five08/worker/config.py apps/api/src/five08/backend/api.py apps/discord_bot/src/five08/discord_bot/config.py apps/discord_bot/src/five08/discord_bot/main.py tests/unit/test_shared_settings.py tests/unit/test_worker_config.py tests/unit/test_bot.py tests/unit/test_backend_api.pyuv run pytest tests/ -v --tb=short(1821 passed, 20 skipped)uv run pytest tests/unit/test_backend_api.py tests/unit/test_worker_config.py tests/unit/test_shared_settings.py -v --tb=short(313 passed, 1 warning)uv run pytest tests/unit/test_worker_config.py tests/unit/test_intake_form_processor.py -v --tb=short(62 passed, 1 warning)uv run pytest tests/unit/test_backend_api.py tests/unit/test_worker_config.py tests/unit/test_intake_form_processor.py -v --tb=short(329 passed, 1 warning)docker compose -f compose.yaml configgit diff --check./scripts/docker-smoke.shpassed on4e632b1f, including Redis/Postgres/ClamAV startup,/health, and a realclamdscan --streamcheck inside the API containerDocker Smoke / docker-smokepassed on latest commit4e632b1fSummary by CodeRabbit
/healthis healthy./healthto reflect Postgres migrations status and effective resume-scan configuration.