Skip to content
AskFlorence
Main Navigation ArchitectureFlorence AIAgentsMembersAgent PlatformValidationInfrastructure

Appearance

Sidebar Navigation

Overview

Home

Glossary

System Architecture

Consumer & Agent Flow

Florence AI

Overview

Principles

Runtime

Tool surface

Adding a tool

Tool registry

Knowledge: SBC scenarios & CSR

Voice

Evals & observability

Provider risk & portability

Outage playbook

Roadmap

Build plan

Agents

Overview

Workflows & pain points

Members

Overview

Medicaid coverage gap

Carriers

Overview

Marketplaces

Overview

Agency

Overview

Regulations

Overview

Agent Platform

Overview

Auth Architecture

MongoDB Permissioning

Compliance Model

Data Models

Data Sources

Overview

CMS Marketplace API

CMS dependency map

PUF Data

State Subsidies

SBE Ingestion Playbook

SBE State Watchouts + Decisions

CA Phase C/D Playbook

NY Phase C/D Playbook

Validation

Overview

Methodology

APTC Formula

California 2026

New York 2026

CAPS Formula

Scenario Results

Infrastructure

Account Inventory

AWS Setup Runbook

AWS Organizations

CloudTrail

GuardDuty

Security Hub

Config

CloudFront + WAFv2

Data sources & ingest

Phase 4 DNS

Change Log

Vulnerability Management

MongoDB Setup

Access Control

Data Classification

Documentation Hosting

Post-deploy Smoke

Development

Preflight (local CI mirror)

Testing strategy

Compliance

Overview (auditor entry point)

SOC 2 Control Mapping

HIPAA Control Mapping

CMS EDE Appendix A Mapping

Risk Assessment

Encryption Policy

Data Retention Policy

Privacy Impact Assessment

Consent Capture & Versioning

Incident Response Plan

Access Control Policy

Marketing vs. Portal Analytics

Vendor / Subprocessor Register

Dependency Vulnerability Policy

BAA / Compliance Evidence

Compliance-Automation Integration

Compliance-Automation Vendor Evaluation

Penetration Test Reports

Architecture

Portal entry handoff

Mobile app strategy

Deferred architecture decisions

Session cookie architecture

Share flows

Decisions (ADRs)

Index

0001 — Atlas project isolation

0002 — Append-only audit log

0003 — Narrow-scoped Mongo users

0004 — Cross-cluster Atlas PrivateLink

0005 — Delayed-job architecture

0006 — Mongo user simplification

0007 — Terraform owns ECS task def

0008 — E2E testing strategy

0009 — Self-hosted analytics + observability (superseded)

0010 — PostHog HIPAA Cloud (supersedes 0009)

Runbooks

Security Incident Response

Break-Glass Root Login

Onboard Team Member

Offboard Team Member

Atlas user provisioning

Deploy via Terraform (ENG-277)

Rollback via Terraform (ENG-277)

S3 data bucket migration (planned Phase 11)

Access Reviews

2026-Q2 Review

Session log

Index

2026-04-23 — Phase 10 DNS cutover

2026-04-22 — Phase 8 prod AWS mirror

2026-04-22 — Phase 7 Atlas VPC peering

2026-04-22 — Phase 6 CloudFront + WAF

2026-04-21 — Phase 5 staging go-live

2026-04-17 — Atlas staging

Briefs

Index

Member portal plan (ENG-187)

2026-04-16/17 handoff

2026-04-17 Atlas handoff

System briefing (2026-04-17)

Creative AdBundance proposal brief

Creative AdBundance analytics brief

ElevenLabs RN integration research

Policies

Overview

On this page

Post-deploy smoke tests ​

The post-deploy smoke (scripts/audit/post-deploy-smoke.ts) runs at the end of every staging and prod deploy. If it fails, the deploy workflow turns red and the deploy is NOT marked green.

Two anti-pattern classes motivate the script:

  1. ENG-272 reads — silent fallback when an Atlas user was narrowed and MONGODB_REFERENCE_URI lost FIND on the reference collections. /api/providers/covered + /api/drugs/covered 500'd for days before a real user noticed.
  2. ENG-275 writes — silent no-op (or try/catch-swallow) when a new env var was added in code but never bound to ECS (ENG-272 RESUME_TOKEN_SECRET, ENG-274 SCHEDULER_*, GitHub #171 home-page capture). Write paths were intentionally excluded from the original 6-check script and are now covered by this Phase 1 expansion.

What runs (11 checks) ​

#CheckWhat it proves
1GET /api/healthTask is responding
2POST /api/eligibilityCMS API key valid + primary Mongo cluster
3POST /api/providers/autocompleteCMS API only (no DB)
4POST /api/providers/coveredCMS API + getReferenceDb() — the ENG-272 catcher
5POST /api/drugs/autocompleteCMS API only
6POST /api/drugs/coveredCMS API + getReferenceDb() — the ENG-272 catcher
7POST /api/waitlist (agent)Agent signup write-path → Mongo row + cleanup
8POST /api/agents/discovery (partial)Partial-save write-path → Mongo row + cleanup
9POST /api/agents/discovery/resumeToken verify — valid (404 expected since no row), tampered (401), expired (401), missing (400)
10POST /api/agents/discovery/send-reminderAuth boundary — 401 without token, 200 with token
11GET /, /plans, /agents, /agent-onboarding, /agent-discovery, /updates, /team/how-we-workEvery primary route 200 + Content-Type text/html

Checks 1-6 always run. Checks 7-10 require additional env vars (see below); each skips with a clear message if its dependencies are missing.

When it runs ​

WorkflowTriggerURL targeted
deploy-staging.ymlPush to staging branch (or workflow_dispatch)https://origin.stage.askflorence.health
deploy-prod.ymlworkflow_dispatch onlyhttps://origin.askflorence.health

Both target the origin.* subdomain (bypasses CloudFront + WAF), since AWS managed-rule false-positives block GitHub Actions runner IPs.

Synthetic test data ​

Every write check uses an email matching:

taha+ci-smoke-<runId>-<checkN>@askflorence.health

runId = GITHUB_RUN_ID in CI, ISO timestamp locally. The plus-address pattern lets us GDPR-delete the resulting HubSpot contacts safely (per CLAUDE.md May 9 precedent — never on real work emails).

Test inputs (when applicable):

  • full_name = CI Smoke
  • role = individual
  • npn = 99999999
  • phone = 5555550100

These match the manual smoke flow inputs documented in CLAUDE.md → "Standard smoke tests".

Cleanup ​

Each write check runs a cleanup in its finally block:

ResourceHow it's cleaned
agent_waitlist_submissions rowMongoClient.deleteOne({ email }) via MONGODB_WRITE_URI
agent_survey_responses rowSame pattern
EBS scheduleSchedulerClient.send(DeleteScheduleCommand) against askflorence-<env>-agent-reminders group
HubSpot contactPOST /crm/v3/objects/contacts/gdpr-delete — gated on the synthetic-email regex (defense in depth)

End-of-run sweep deletes any orphans matching the synthetic pattern older than 5 minutes (handles crashed prior runs). The 5-minute floor is to avoid clobbering in-flight rows from a parallel CI run.

Required env vars ​

scripts/audit/post-deploy-smoke.ts reads from process.env. In CI, the deploy workflows inject these via aws secretsmanager get-secret-value shell calls in a step before the smoke step. Each value is ::add-mask::-ed so it doesn't echo to the workflow log.

Env varUsed bySource
SMOKE_TARGET_URLAll checksHardcoded per workflow (origin.* URL)
MONGODB_WRITE_URIChecks 7, 8 + cleanup + end-of-run sweepstaging/mongodb/app-write (or prod/)
RESUME_TOKEN_SECRETCheck 9 (token minting)staging/resume-token-secret (or prod/)
INTERNAL_REMINDER_TOKENCheck 10 (200-case)staging/internal-reminder-token (or prod/)
SCHEDULER_GROUP_NAMECheck 7 cleanupHardcoded per workflow
AWS_REGIONCheck 7 cleanup defaultHardcoded us-east-1
HUBSPOT_ACCESS_TOKENHubSpot cleanup (optional)staging/hubspot-access-token (or prod/); skip if unset
SMOKE_TIMEOUT_MSPer-request timeoutOptional, default 15000

Locally, set these in .env.local or export them in your shell before running.

Running locally ​

Against local dev:

bash
SMOKE_TARGET_URL=http://localhost:3004 \
MONGODB_WRITE_URI="mongodb+srv://..." \
RESUME_TOKEN_SECRET="..." \
INTERNAL_REMINDER_TOKEN="..." \
npx tsx scripts/audit/post-deploy-smoke.ts

Against staging:

bash
SMOKE_TARGET_URL=https://origin.stage.askflorence.health \
MONGODB_WRITE_URI="mongodb+srv://..." \
RESUME_TOKEN_SECRET="..." \
INTERNAL_REMINDER_TOKEN="..." \
SCHEDULER_GROUP_NAME=askflorence-staging-agent-reminders \
npx tsx scripts/audit/post-deploy-smoke.ts

Or via npm run smoke:post-deploy (same script).

Or via the preflight orchestrator in --full mode:

bash
npm run preflight -- --full --base-url=https://origin.stage.askflorence.health

Known limitations ​

  • HTTP-only, not DOM-level. The browser-page smoke (Check 11) asserts HTTP 200 + text/html; it does NOT exercise React hydration, click handlers, or form interactions. For that, use the manual flows in CLAUDE.md → "Standard smoke tests" (member 9-step + agent 7-step). Full Playwright E2E is Phase 3a (separate Linear ticket).
  • No cross-region edge probes (CloudFront / DNS / WAF). Those happen out-of-band via the Phase 11 follow-up canaries.
  • HubSpot cleanup uses GDPR-delete which permanently blocklists the email at the portal level. Safe ONLY for +ci-smoke-* addresses. The script enforces this with a regex gate (defense in depth); the call still requires HUBSPOT_ACCESS_TOKEN to be set. If HUBSPOT_ACCESS_TOKEN is unset, HubSpot cleanup is skipped — manual cleanup via the portal is needed in that case.

How to interpret a failure ​

Failing checkLikely root cause
/api/providers/covered / /api/drugs/covered 500MONGODB_REFERENCE_URI binding or role privileges (ENG-272)
/api/eligibility 500Primary cluster MONGODB_URI binding or CMS_API_KEY
/api/waitlist (agent) non-200Waitlist write privileges (ENG-279) or schema-validation regression
agent_waitlist_submissions row not foundRoute returned 200 but didn't persist; check ECS CloudWatch logs
Resume-token tests failRESUME_TOKEN_SECRET drift between Secrets Manager + ECS + smoke env
send-reminder 401 with valid tokenINTERNAL_REMINDER_TOKEN drift between ECS + reminder Lambda + smoke env
HTML 4xx/5xx on a browser routeRoute deleted, build incomplete, or runtime crash; check ECS logs

Cross-references ​

  • scripts/audit/post-deploy-smoke.ts — the script (in the repo root)
  • .github/workflows/deploy-staging.yml — staging deploy + smoke (in the repo root)
  • .github/workflows/deploy-prod.yml — prod deploy + smoke (in the repo root)
  • CLAUDE.md → "Standard smoke tests" section — the manual browser-flow companion (repo root)
  • docs/development/preflight.md — the local mirror of PR-time CI
  • ENG-275 — original Phase 1 issue (closed docs-only; Phase 1 actually shipped under ENG-284)
  • ENG-284 — the issue this script + doc shipped under
  • GitHub #156 — PR-level smoke expansion tracking
Pager
Previous pageDocumentation Hosting
Next pagePreflight (local CI mirror)

AskFlorence Internal Documentation. Not for public distribution.

AskFlorence

Internal Documentation

Access restricted. Not for public distribution.