Skip to content

Add Tally onboarding intake workflow#335

Open
michaelmwu wants to merge 12 commits into
mainfrom
michaelmwu/google-form-crm-onboarding
Open

Add Tally onboarding intake workflow#335
michaelmwu wants to merge 12 commits into
mainfrom
michaelmwu/google-form-crm-onboarding

Conversation

@michaelmwu

@michaelmwu michaelmwu commented Jun 12, 2026

Copy link
Copy Markdown
Member

Summary

  • add an onboarding-specific Tally webhook at /webhooks/tally/onboarding with signature verification, form allowlisting, and compatibility aliases for existing TALLY_* env vars
  • persist normalized/raw intake submissions in a new onboarding_intake_submissions table and surface latest application details in the onboarding queue
  • add dashboard-managed onboarding Tally config, including a generate/copy/hide flow for webhook signing secrets
  • require a configured malware scan command before parsing downloaded resume files, while still storing intake data

Notes

  • Keep Tally posting to our app as source of truth; Discord should be a downstream notification path, not the canonical intake endpoint.
  • Existing Google Sheets responses can be backfilled later as metadata with Drive links preserved, then imported/scanned in a separate one-time job if needed.

Tests

  • ./scripts/test.sh
  • ./scripts/lint.sh
  • git diff --check

Summary by CodeRabbit

Release Notes

  • New Features

    • Added Tally form integration as an alternative intake source
    • Resume virus scanning capability for uploaded resumes
    • Application details view in admin dashboard showing submitted form data
    • Automatic signing-secret generator for webhook configuration
    • Support for intake submissions from applicants without existing CRM records
  • Documentation

    • Updated configuration guide with Tally intake form settings and virus scan options

Copilot AI review requested due to automatic review settings June 12, 2026 16:08
@coderabbitai

coderabbitai Bot commented Jun 12, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds Tally form webhook ingestion to the existing intake pipeline: HMAC signature verification, form-ID allowlisting, Tally-to-intake payload conversion, and job enqueueing. Introduces durable onboarding_intake_submissions Postgres storage with upsert in IntakeFormProcessor. Adds configurable resume virus-scan gating, "orphan" intake rows (no CRM contact) in the onboarding dashboard, and a signing-secret generator in the admin configuration UI.

Changes

Tally Intake Webhook System

Layer / File(s) Summary
Configuration, runtime config, and documentation
apps/worker/src/five08/worker/config.py, packages/shared/src/five08/runtime_config.py, .env.example, docs/configuration.md
WorkerSettings gains Tally and virus-scan fields with validators; three RuntimeConfigDefinition entries expose them in the dashboard; .env.example and docs describe all new variables, legacy aliases, and fail-closed semantics.
Pydantic models and intake field aliases
apps/worker/src/five08/worker/models.py
Four new TallyWebhook* Pydantic types model the nested FORM_RESPONSE payload; GoogleFormsIntakePayload gains last_name_is_placeholder, chat_availability, native_name, ideal_weekly_hours, and expanded alias mappings.
Tally webhook handler, helpers, and routes
apps/api/src/five08/backend/api.py
TALLY_INTAKE_FIELD_LABEL_MAP constant, field-value rendering, HMAC verification with X-API-Secret fallback, form-ID allowlist check, Tally→intake conversion, idempotency key computation, and job enqueueing; registers /webhooks/tally and /webhooks/tally/onboarding; tightens Google Forms invalid-payload error response.
Alembic migration for onboarding_intake_submissions
apps/worker/src/five08/worker/migrations/versions/20260613_0300_create_onboarding_intake_submissions.py
Creates the table with JSONB payload columns, source check constraint, COALESCE-based unique index, two non-unique indexes, and an updated_at trigger; downgrade() reverses all DDL.
Intake processing, persistence, and resume scanning
apps/worker/src/five08/worker/crm/intake_form_processor.py
Source-aware form-ID validation, best-effort Postgres upsert via _persist_intake_submission, placeholder last-name gating that queues without CRM create, website_linkcWebsiteLink normalization, new DESCRIPTION_SECTIONS entries, and _scan_resume_content subprocess gate with temp-file cleanup.
Dashboard people and onboarding listing SQL enrichment
apps/api/src/five08/backend/api.py
LEFT JOIN LATERAL adds latest_intake_submission to both people and onboarding queries; intake-based resume presence replaces CRM-only detection; orphan intake submissions (no CRM contact) are fetched and merged; raw_payload is stripped from shaped rows.
Admin dashboard onboarding display and secret workflow
apps/admin_dashboard/src/main.tsx, apps/api/src/five08/backend/static/dashboard/...
IntakeSubmission type and latest_intake_submission on Person; OnboardingRow shows "Application only" badge and expandable Application panel for intake-only prospects; ConfigurationView.onSave updated to Promise<boolean>; Tally signing-secret generate/copy/hide UI added; static assets updated.
Unit tests
tests/unit/test_backend_api.py, tests/unit/test_intake_form_processor.py, tests/unit/test_runtime_config.py, tests/unit/test_worker_config.py
Tests cover HMAC auth, allowlist enforcement, normalization edge cases, orphan listing, runtime-config definitions, WorkerSettings alias/virus-scan validation, persistence SQL correctness, resume-scan gating, and website-link normalization; existing non-local config tests updated for new virus-scan requirements.

Sequence Diagram(s)

sequenceDiagram
  participant TallyForm
  participant APIHandler as tally_intake_webhook_handler
  participant HMACVerify as HMAC / X-API-Secret auth
  participant Allowlist as form_id allowlist
  participant Worker as process_intake_form_job
  participant Processor as IntakeFormProcessor
  participant Postgres as onboarding_intake_submissions
  participant CRM

  TallyForm->>APIHandler: POST /webhooks/tally/onboarding (raw body + Tally-Signature)
  APIHandler->>HMACVerify: verify signature against ONBOARDING_TALLY_WEBHOOK_SIGNING_SECRET
  HMACVerify-->>APIHandler: 401 if invalid
  APIHandler->>Allowlist: check formId in ONBOARDING_TALLY_ALLOWED_FORM_IDS
  Allowlist-->>APIHandler: 403 if unset or unapproved
  APIHandler->>APIHandler: convert Tally fields → GoogleFormsIntakePayload
  APIHandler->>Worker: enqueue process_intake_form_job (tally: idempotency key)
  APIHandler-->>TallyForm: 202 queued
  Worker->>Processor: process_intake(payload)
  alt last_name_is_placeholder
    Processor->>Postgres: _persist_intake_submission (contact_id=None)
    Processor-->>Worker: pending_review=True
  else normal flow
    Processor->>CRM: create or update prospect contact
    Processor->>Postgres: _persist_intake_submission (contact_id)
    Processor->>Processor: _scan_resume_content (subprocess virus scan)
    Processor-->>Worker: success
  end
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

  • 508-dev/508-workflows#74: Established the original Google Forms intake webhook and IntakeFormProcessor pipeline that this PR extends with Tally source support and Postgres persistence.
  • 508-dev/508-workflows#140: Modified _build_resume_updates resume-download/validation logic that this PR now gates behind _scan_resume_content.
  • 508-dev/508-workflows#333: Introduced the ConfigurationView component whose onSave contract this PR changes to Promise<boolean> and extends with the signing-secret generator UI.

Poem

🐇 A webhook arrives with a Tally form ring,
The rabbit checks HMAC — a validated thing!
Orphan submissions now get their own row,
Secrets are generated with a cryptographic glow.
Virus-scanned résumés hop through the gate,
New intakes persist — the pipeline is great! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 39.17% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Add Tally onboarding intake workflow' is concise, specific, and directly describes the main feature being added. It clearly communicates the primary change from the changeset.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch michaelmwu/google-form-crm-onboarding

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9666b38a48

ℹ️ 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".

Comment thread apps/admin_dashboard/src/main.tsx

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a Tally-based onboarding intake workflow end-to-end (API webhook → queue job → worker CRM updates + durable submission storage), plus admin-dashboard configuration and onboarding-queue surfacing of the latest application details.

Changes:

  • Add Tally onboarding intake webhook handler with signature verification, form allowlisting, and legacy TALLY_* env aliases.
  • Persist normalized/raw intake submissions into a new onboarding_intake_submissions table and surface the latest submission in the onboarding queue API/UI.
  • Require a configured malware scan command before parsing downloaded resume files (while still accepting/storing intake data).

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tests/unit/test_worker_config.py Adds coverage for Tally allowed-form parsing, legacy env aliases, and virus-scan timeout validation.
tests/unit/test_runtime_config.py Verifies new onboarding Tally settings are dashboard-configurable (secrets + CSV allowlist).
tests/unit/test_intake_form_processor.py Updates resume-processing tests for new scan gate; adds coverage for website/weekly-hours intake fields and scan-failure behavior.
tests/unit/test_backend_api.py Adds unit tests for Tally webhook auth, allowlisting, signature verification, and field normalization/enqueueing.
packages/shared/src/five08/runtime_config.py Introduces runtime-config definitions for onboarding Tally API key, signing secret, and allowed form IDs (with legacy env aliases).
docs/configuration.md Documents new Tally intake settings and resume malware scan settings.
apps/worker/src/five08/worker/models.py Adds Pydantic models for Tally webhooks and expands intake aliasing/fields for onboarding questions.
apps/worker/src/five08/worker/migrations/versions/20260613_0200_create_onboarding_intake_submissions.py Creates onboarding_intake_submissions table, indexes, and updated-at trigger.
apps/worker/src/five08/worker/crm/intake_form_processor.py Adds persistence of intake submissions, website link mapping, and malware scan enforcement before resume parsing.
apps/worker/src/five08/worker/config.py Adds onboarding Tally settings + resume scan settings to worker configuration.
apps/api/src/five08/backend/api.py Adds Tally webhook endpoint(s), signature validation, field mapping to intake payload, and onboarding queue enrichment with latest submission JSON.
apps/admin_dashboard/src/main.tsx Surfaces latest intake submission summary in onboarding queue; adds signing-secret generate/copy/hide UX; adjusts config save to return success boolean.
.env.example Adds example env vars for onboarding Tally intake and resume malware scan configuration.
Comments suppressed due to low confidence (1)

apps/admin_dashboard/src/main.tsx:7483

  • onSave now returns a Promise, but the Save button click handler doesn't await it or mark it as intentionally fire-and-forget. This can trigger lint warnings (and makes it easier to accidentally introduce unhandled rejections if onSave changes).
            <Button
              type="button"
              size="sm"
              onClick={() => onSave(item.key, draft)}
              disabled={

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread apps/api/src/five08/backend/api.py

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (1)
tests/unit/test_backend_api.py (1)

8717-8792: ⚡ Quick win

Add signature enforcement tests for the canonical onboarding path.

Line 8738 and Line 8763 validate signatures only on /webhooks/tally, but Line 8677 uses /webhooks/tally/onboarding for the canonical flow. A route-specific auth regression on /webhooks/tally/onboarding would currently slip through.

Suggested test hardening
+@pytest.mark.parametrize("path", ["/webhooks/tally", "/webhooks/tally/onboarding"])
+def test_tally_intake_accepts_valid_tally_signature_for_all_routes(
+    client: TestClient,
+    monkeypatch: pytest.MonkeyPatch,
+    path: str,
+) -> None:
+    monkeypatch.setattr(api.settings, "onboarding_tally_webhook_signing_secret", "signing-secret")
+    monkeypatch.setattr(api.settings, "onboarding_tally_allowed_form_ids", "tally-form-1")
+    body = json.dumps(_TALLY_INTAKE_PAYLOAD, separators=(",", ":")).encode("utf-8")
+    signature = base64.b64encode(
+        hmac.new(b"signing-secret", body, hashlib.sha256).digest()
+    ).decode("ascii")
+
+    with patch("five08.backend.api.enqueue_job") as mock_enqueue:
+        mock_enqueue.return_value = Mock(id="job-tally-1")
+        response = client.post(
+            path,
+            content=body,
+            headers={"Content-Type": "application/json", "Tally-Signature": signature},
+        )
+
+    assert response.status_code == 202
+    mock_enqueue.assert_called_once()
🤖 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 8717 - 8792, Add parallel
signature-enforcement tests for the canonical onboarding endpoint
/webhooks/tally/onboarding: duplicate the logic from
test_tally_intake_accepts_valid_tally_signature and
test_tally_intake_rejects_invalid_tally_signature but target the route
"/webhooks/tally/onboarding" and use the same setup of monkeypatching
api.settings.onboarding_tally_webhook_signing_secret and computing/setting the
Tally-Signature header (or sending an invalid signature) while asserting the
expected status codes (202 for valid, 401 for invalid) and enqueue_job behavior
(mock_enqueue.assert_called_once / assert_not_called). Ensure you reuse the same
body payload encoding/hmac computation as in the existing tests so the
verification covers the onboarding route.
🤖 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 `@apps/admin_dashboard/src/main.tsx`:
- Around line 7295-7304: The copyGeneratedSecret function currently calls
navigator.clipboard.writeText(secret) without handling rejections, so failing
writes reject and prevent the fallback; update copyGeneratedSecret to wrap the
writeText call in a try/catch (or handle its Promise rejection) and on error
fall back to locating the input by id `generatedSecret-${key}` and calling
select() (or log/surface an error) so the UX still works when clipboard API
fails; reference the function name copyGeneratedSecret and the DOM id pattern
generatedSecret- to locate where to add the try/catch and fallback logic.

In `@apps/api/src/five08/backend/api.py`:
- Around line 7086-7116: The handler currently enqueues only normalized_payload,
dropping the original Tally webhook body; modify the enqueue call so the
canonical/raw Tally payload is passed through to the worker (e.g., add a
raw_payload argument alongside normalized_payload in the args passed to
enqueue_job), using the original payload/tally_payload dump (preserve
aliases/None handling as needed), and keep the idempotency_key logic unchanged;
update the worker (process_intake_form_job) to expect and persist raw_payload
instead of reconstructing it from normalized_payload.
- Around line 743-752: The current _validate_tally_submission treats an empty
settings.onboarding_tally_allowed_form_ids_set as permissive; change it to fail
closed by returning JSONResponse({"error":"invalid_form_id"}, status_code=403)
when allowed_form_ids is empty or missing. In _validate_tally_submission,
reference settings.onboarding_tally_allowed_form_ids_set and
payload.data.form_id: if the set is falsy or empty, immediately return the error
response; otherwise strip payload.data.form_id and allow only when the stripped
form_id is non-empty and present in the allowed set, returning the same 403
JSONResponse for all other cases.

In
`@apps/worker/src/five08/worker/migrations/versions/20260613_0200_create_onboarding_intake_submissions.py`:
- Around line 56-61: The current
sa.UniqueConstraint("source","form_id","submission_id",
name="uq_onboarding_intake_submissions_source_form_submission") allows NULLs and
breaks UPSERTs; replace this UniqueConstraint with a database-level unique index
that normalizes NULLs using COALESCE (e.g., index on source plus
COALESCE(form_id, '') and COALESCE(submission_id, '')) in the migration (replace
the UniqueConstraint declaration in the migration creating
onboarding_intake_submissions), and update the processor SQL that uses ON
CONFLICT to match the index expressions (use ON CONFLICT (source,
COALESCE(form_id, ''), COALESCE(submission_id, '')) so conflicts fire when
form_id or submission_id are NULL).

In `@tests/unit/test_worker_config.py`:
- Around line 153-168: The test
test_legacy_tally_env_aliases_still_populate_onboarding_settings is flaky
because existing ONBOARDING_TALLY_* env vars can override the legacy TALLY_*
aliases; before setting TALLY_API_KEY, TALLY_WEBHOOK_SIGNING_SECRET, and
TALLY_ALLOWED_FORM_IDS, ensure you clear any ONBOARDING_TALLY_API_KEY,
ONBOARDING_TALLY_WEBHOOK_SIGNING_SECRET, and ONBOARDING_TALLY_ALLOWED_FORM_IDS
from the environment (use monkeypatch.delenv or equivalent) so WorkerSettings()
will read the legacy aliases and the assertions on onboarding_tally_api_key,
onboarding_tally_webhook_signing_secret, and
onboarding_tally_allowed_form_ids_set reliably validate the compatibility
behavior.

---

Nitpick comments:
In `@tests/unit/test_backend_api.py`:
- Around line 8717-8792: Add parallel signature-enforcement tests for the
canonical onboarding endpoint /webhooks/tally/onboarding: duplicate the logic
from test_tally_intake_accepts_valid_tally_signature and
test_tally_intake_rejects_invalid_tally_signature but target the route
"/webhooks/tally/onboarding" and use the same setup of monkeypatching
api.settings.onboarding_tally_webhook_signing_secret and computing/setting the
Tally-Signature header (or sending an invalid signature) while asserting the
expected status codes (202 for valid, 401 for invalid) and enqueue_job behavior
(mock_enqueue.assert_called_once / assert_not_called). Ensure you reuse the same
body payload encoding/hmac computation as in the existing tests so the
verification covers the onboarding route.
🪄 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: 88109ddd-b953-47eb-9d5a-668528e4f817

📥 Commits

Reviewing files that changed from the base of the PR and between 404db50 and 9666b38.

📒 Files selected for processing (13)
  • .env.example
  • apps/admin_dashboard/src/main.tsx
  • apps/api/src/five08/backend/api.py
  • apps/worker/src/five08/worker/config.py
  • apps/worker/src/five08/worker/crm/intake_form_processor.py
  • apps/worker/src/five08/worker/migrations/versions/20260613_0200_create_onboarding_intake_submissions.py
  • apps/worker/src/five08/worker/models.py
  • docs/configuration.md
  • packages/shared/src/five08/runtime_config.py
  • tests/unit/test_backend_api.py
  • tests/unit/test_intake_form_processor.py
  • tests/unit/test_runtime_config.py
  • tests/unit/test_worker_config.py

Comment thread apps/admin_dashboard/src/main.tsx
Comment thread apps/api/src/five08/backend/api.py
Comment thread apps/api/src/five08/backend/api.py
Comment thread tests/unit/test_worker_config.py
Comment thread apps/api/src/five08/backend/api.py Fixed
Comment thread apps/api/src/five08/backend/api.py Fixed

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e7e048e627

ℹ️ 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".

Comment thread apps/worker/src/five08/worker/crm/intake_form_processor.py
…m-crm-onboarding

# Conflicts:
#	apps/api/src/five08/backend/static/dashboard/.vite/manifest.json
#	apps/api/src/five08/backend/static/dashboard/assets/index-BOSn0NiV.js
#	apps/api/src/five08/backend/static/dashboard/index.html

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 16 out of 18 changed files in this pull request and generated 2 comments.

Comment thread apps/worker/src/five08/worker/crm/intake_form_processor.py
Comment thread apps/worker/src/five08/worker/crm/intake_form_processor.py Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1a4a979235

ℹ️ 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".

Comment thread apps/worker/src/five08/worker/config.py Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 00cf41cd0c

ℹ️ 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".

Comment thread apps/api/src/five08/backend/api.py
Comment thread apps/api/src/five08/backend/api.py

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 `@apps/worker/src/five08/worker/config.py`:
- Around line 110-112: The configuration field
`intake_resume_require_virus_scan` defaults to `False`, and the validation logic
only checks the `intake_resume_virus_scan_command` when scanning is enabled.
This allows non-local deployments to parse unscanned resumes if the flag is
omitted. Add a validator method (likely a `@field_validator` or similar) that
checks the environment context and enforces that
`intake_resume_require_virus_scan` must be `True` in non-local environments,
while also ensuring the `intake_resume_virus_scan_command` is populated when
scanning is required. This guard should apply wherever environment validation
occurs in the configuration class.
🪄 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: cea5d9f6-fd30-42e4-bba3-1ae7eb86e455

📥 Commits

Reviewing files that changed from the base of the PR and between 1a4a979 and 7b8a82f.

📒 Files selected for processing (13)
  • .env.example
  • apps/admin_dashboard/src/main.tsx
  • apps/api/src/five08/backend/api.py
  • apps/api/src/five08/backend/static/dashboard/.vite/manifest.json
  • apps/api/src/five08/backend/static/dashboard/assets/index-MEvq0Meo.js
  • apps/api/src/five08/backend/static/dashboard/index.html
  • apps/worker/src/five08/worker/config.py
  • apps/worker/src/five08/worker/crm/intake_form_processor.py
  • apps/worker/src/five08/worker/models.py
  • docs/configuration.md
  • tests/unit/test_backend_api.py
  • tests/unit/test_intake_form_processor.py
  • tests/unit/test_worker_config.py
✅ Files skipped from review due to trivial changes (3)
  • docs/configuration.md
  • apps/api/src/five08/backend/static/dashboard/index.html
  • apps/api/src/five08/backend/static/dashboard/.vite/manifest.json
🚧 Files skipped from review as they are similar to previous changes (3)
  • apps/worker/src/five08/worker/models.py
  • apps/api/src/five08/backend/api.py
  • apps/admin_dashboard/src/main.tsx

Comment thread apps/worker/src/five08/worker/config.py

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7b8a82f0e1

ℹ️ 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".

Comment thread apps/api/src/five08/backend/api.py
Comment thread apps/worker/src/five08/worker/crm/intake_form_processor.py
…m-crm-onboarding

# Conflicts:
#	apps/api/src/five08/backend/static/dashboard/.vite/manifest.json
#	apps/api/src/five08/backend/static/dashboard/assets/index-B-BtbFCt.css
#	apps/api/src/five08/backend/static/dashboard/assets/index-BoK8s4aw.css
#	apps/api/src/five08/backend/static/dashboard/assets/index-C6NyLxSa.css
#	apps/api/src/five08/backend/static/dashboard/index.html

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 16 out of 18 changed files in this pull request and generated 1 comment.

Comment thread apps/api/src/five08/backend/api.py Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a0f881fd74

ℹ️ 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".

Comment thread apps/api/src/five08/backend/api.py Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/admin_dashboard/src/main.tsx (1)

5968-5975: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Prefer the stable person.id before optional application/display fields.

OnboardingRow owns draft/onboarder state, but application-only rows lack crm_contact_id; if submission_id is absent or duplicated, the key falls through to non-unique email/name values and can reuse row state for the wrong applicant.

Proposed fix
-              {props.people.map((person) => (
+              {props.people.map((person, index) => (
                 <OnboardingRow
                   key={
                     person.crm_contact_id ||
+                    person.id ||
                     person.latest_intake_submission?.submission_id ||
                     person.email ||
-                    person.name
+                    person.name ||
+                    `onboarding-row-${index}`
                   }
🤖 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/admin_dashboard/src/main.tsx` around lines 5968 - 5975, The key prop for
the OnboardingRow component in the map function should prioritize the stable
person.id field before falling back to optional application or display fields.
Change the key logic to check person.id first, followed by crm_contact_id,
submission_id, email, and name in that order. This ensures each row maintains a
stable, unique identifier and prevents row state from being reused for the wrong
applicant when crm_contact_id or submission_id are missing or duplicated.
🤖 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.

Outside diff comments:
In `@apps/admin_dashboard/src/main.tsx`:
- Around line 5968-5975: The key prop for the OnboardingRow component in the map
function should prioritize the stable person.id field before falling back to
optional application or display fields. Change the key logic to check person.id
first, followed by crm_contact_id, submission_id, email, and name in that order.
This ensures each row maintains a stable, unique identifier and prevents row
state from being reused for the wrong applicant when crm_contact_id or
submission_id are missing or duplicated.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a5faca3d-0101-437c-84f0-4eabad5fe47f

📥 Commits

Reviewing files that changed from the base of the PR and between 7b8a82f and a0f881f.

📒 Files selected for processing (7)
  • apps/admin_dashboard/src/main.tsx
  • apps/api/src/five08/backend/api.py
  • apps/api/src/five08/backend/static/dashboard/.vite/manifest.json
  • apps/api/src/five08/backend/static/dashboard/assets/index-B94wT6z-.css
  • apps/api/src/five08/backend/static/dashboard/assets/index-juzZ-WBH.js
  • apps/api/src/five08/backend/static/dashboard/index.html
  • tests/unit/test_backend_api.py
✅ Files skipped from review due to trivial changes (1)
  • apps/api/src/five08/backend/static/dashboard/.vite/manifest.json
🚧 Files skipped from review as they are similar to previous changes (2)
  • tests/unit/test_backend_api.py
  • apps/api/src/five08/backend/api.py

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 543d16b0c9

ℹ️ 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".

Comment thread apps/api/src/five08/backend/api.py
Comment thread apps/admin_dashboard/src/main.tsx

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 16 out of 19 changed files in this pull request and generated 3 comments.

Files not reviewed (1)
  • apps/api/src/five08/backend/static/dashboard/assets/index-B5Jst3Rt.css: Generated file

Comment thread apps/worker/src/five08/worker/crm/intake_form_processor.py
Comment thread docs/configuration.md Outdated
Comment thread apps/admin_dashboard/src/main.tsx

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: cae126378d

ℹ️ 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".

Comment thread apps/api/src/five08/backend/api.py

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
apps/api/src/five08/backend/static/dashboard/assets/index-B5Jst3Rt.css (1)

1-3: ⚡ Quick win

This is compiled/generated CSS output; stylelint issues should be addressed in the build configuration.

This file is minified Tailwind CSS v4.3.0 output. Stylelint flagged several issues (duplicate -webkit-text-decoration, deprecated appearance: button, font-family quoting, casing). These occur in the compiled artifact, not source code, and should be remedied by adjusting the build configuration, Tailwind version, or post-processing rather than manual edits to this file (which would be overwritten on rebuild).

If this is checked into the repository as a fingerprinted asset, verify that the build process generates it reproducibly and that the CI/build pipeline is expected to commit built assets.

🤖 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/static/dashboard/assets/index-B5Jst3Rt.css`
around lines 1 - 3, Do not manually edit this compiled CSS file as it is
automatically generated by the Tailwind CSS build process and will be
overwritten on rebuild. Instead, investigate the root cause of the stylelint
issues (duplicate -webkit-text-decoration, deprecated appearance values,
font-family quoting inconsistencies) by examining your Tailwind configuration
file, the build pipeline, and post-processing steps. Consider updating Tailwind
CSS to the latest version, adjusting your build configuration to handle the
compilation more cleanly, or configuring stylelint to ignore known issues in
generated artifacts. If this file is committed as a fingerprinted asset, verify
the build process generates it reproducibly and document that the CI pipeline is
expected to update this generated file rather than manually editing it.

Source: Linters/SAST tools

🤖 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.

Nitpick comments:
In `@apps/api/src/five08/backend/static/dashboard/assets/index-B5Jst3Rt.css`:
- Around line 1-3: Do not manually edit this compiled CSS file as it is
automatically generated by the Tailwind CSS build process and will be
overwritten on rebuild. Instead, investigate the root cause of the stylelint
issues (duplicate -webkit-text-decoration, deprecated appearance values,
font-family quoting inconsistencies) by examining your Tailwind configuration
file, the build pipeline, and post-processing steps. Consider updating Tailwind
CSS to the latest version, adjusting your build configuration to handle the
compilation more cleanly, or configuring stylelint to ignore known issues in
generated artifacts. If this file is committed as a fingerprinted asset, verify
the build process generates it reproducibly and document that the CI pipeline is
expected to update this generated file rather than manually editing it.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c3a998eb-70ca-4e88-a2d5-10f56bcfeece

📥 Commits

Reviewing files that changed from the base of the PR and between a0f881f and 4cac543.

📒 Files selected for processing (13)
  • apps/admin_dashboard/src/main.tsx
  • apps/api/src/five08/backend/api.py
  • apps/api/src/five08/backend/static/dashboard/.vite/manifest.json
  • apps/api/src/five08/backend/static/dashboard/assets/index-B5Jst3Rt.css
  • apps/api/src/five08/backend/static/dashboard/assets/index-S82ik8An.js
  • apps/api/src/five08/backend/static/dashboard/index.html
  • apps/worker/src/five08/worker/config.py
  • apps/worker/src/five08/worker/crm/intake_form_processor.py
  • apps/worker/src/five08/worker/migrations/versions/20260613_0300_create_onboarding_intake_submissions.py
  • docs/configuration.md
  • tests/unit/test_backend_api.py
  • tests/unit/test_intake_form_processor.py
  • tests/unit/test_worker_config.py
✅ Files skipped from review due to trivial changes (2)
  • apps/api/src/five08/backend/static/dashboard/.vite/manifest.json
  • docs/configuration.md
🚧 Files skipped from review as they are similar to previous changes (6)
  • apps/api/src/five08/backend/static/dashboard/index.html
  • apps/worker/src/five08/worker/config.py
  • tests/unit/test_worker_config.py
  • tests/unit/test_backend_api.py
  • apps/admin_dashboard/src/main.tsx
  • apps/worker/src/five08/worker/crm/intake_form_processor.py

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4cac54336c

ℹ️ 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".

Comment on lines +1974 to +1977
AND coalesce(
nullif(btrim(resume_intake.normalized_payload->>'resume_file_name'), ''),
nullif(btrim(resume_intake.normalized_payload->>'resume_url'), '')
) IS NOT NULL

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep resume filters and displayed intake in sync

When a contact has multiple intake submissions where an older one has resume_url/resume_file_name and a newer one does not, this EXISTS still makes resume=present include the contact, but the lateral latest_intake_submission selected later is ordered only by submission date. _shape_dashboard_people_rows() then sees the newer no-resume payload and renders the row as missing a resume with no link even though it matched the present filter; select the resume-bearing intake for this case or carry the EXISTS result into the shaped status/link data.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants