We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/tbrennem-source/sf-permits-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server
# CHECKCHAT-A: Sprint 53 Session A — Staging Environment + Test Login
**Agent:** session-a-dev-env
**Date:** 2026-02-24
**Branch:** worktree-agent-a171aff9
**Status:** COMPLETE
---
## 1. VERIFY
**RELAY gate:** No unprocessed qa-results/ files from this session.
**New QA script written:** `qa-drop/session-a-staging-qa.md`
**Tests:** 1604 passed, 1 skipped, 17 deselected (network) — full suite green
**No regressions:** All 1554 pre-existing tests still pass
---
## 2. DOCUMENT
### Files Changed (6 modified, 5 new)
**Modified (Session A owned files):**
- `web/auth.py` — added `handle_test_login()` function + `SESSION A: TEST LOGIN` block
- `web/app.py` — added `ENVIRONMENT`/`IS_STAGING` detection, `inject_environment` context processor, `/auth/test-login` route
- `web/templates/index.html` — staging banner injected after `<body>`
- `web/templates/landing.html` — staging banner injected after `<body>`
- `web/templates/auth_login.html` — staging banner injected after `<body>`
- `scenarios-pending-review.md` — 3 new scenarios appended
**New files:**
- `scripts/setup_staging.sh` — Railway staging setup reference guide
- `tests/e2e/__init__.py` — E2E package init
- `tests/e2e/conftest.py` — Playwright fixtures, PERSONAS dict, login_as helper
- `tests/test_staging_env.py` — 29 unit tests for test-login and staging banner
- `qa-drop/session-a-staging-qa.md` — QA script for DeskRelay
### What Was Built
**Test Login Endpoint (`POST /auth/test-login`):**
- Returns 404 when `TESTING` env var not set (production safe)
- Returns 403 when secret is wrong or missing
- Returns 200 + sets session cookie when `TESTING=true` and correct `TEST_LOGIN_SECRET`
- Creates user if not exists, sets admin flag
- Session identical to magic-link flow
**Environment Detection (`web/app.py`):**
- `ENVIRONMENT` env var (default: `"production"`)
- `IS_STAGING = ENVIRONMENT == "staging"`
- `inject_environment` context processor: `is_staging`, `environment_name` in all templates
**Staging Banner (3 templates):**
- Bright yellow bar: "STAGING ENVIRONMENT — changes here do not affect production"
- Conditional on `{% if is_staging %}` — invisible on production
- Injected in: `index.html`, `landing.html`, `auth_login.html`
**Staging Setup Script (`scripts/setup_staging.sh`):**
- Reference guide with step-by-step Railway setup instructions
- Lists required env vars, security notes, what NOT to set on prod
**Playwright Conftest (`tests/e2e/conftest.py`):**
- `PERSONAS` dict: 12 test personas (admin, expediter, homeowner, architect, contractor, engineer, developer, planner, reviewer, owner, inspector, guest)
- `base_url` fixture (reads `E2E_BASE_URL`)
- `test_login_secret` fixture (reads `TEST_LOGIN_SECRET`)
- `login_as(page, base_url, secret, email)` helper function
- `authenticated_page` fixture (pre-authenticated as admin)
- `make_authenticated_page` factory fixture
- `skip_if_no_e2e` mark + `E2E_AVAILABLE` gate for CI
---
## 3. CAPTURE
**Scenarios appended to `scenarios-pending-review.md`:** 3
1. "When TESTING is not set, /auth/test-login returns 404 and no information leaks"
2. "Every page shows yellow banner when ENVIRONMENT=staging"
3. "When DeskRelay POSTs correct test secret, it gets admin session"
---
## 4. DeskRelay HANDOFF
For DeskRelay to run RELAY against staging, the following steps must pass:
1. Navigate to staging URL → verify yellow banner visible at top of page
2. Navigate to `{STAGING_URL}/auth/login` → verify yellow banner present
3. `POST /auth/test-login` with `{"secret": "<TEST_LOGIN_SECRET>", "email": "test-admin@sfpermits.ai"}` → verify 200 + `{"ok": true}`
4. Navigate to `/account` → verify logged in (no redirect to /auth/login)
5. Navigate to `/admin` → verify admin access (200, not 403)
6. Navigate to prod URL → verify NO staging banner
7. `POST /auth/test-login` on prod → verify 404
8. Screenshot: staging banner on homepage → `qa-results/screenshots/session-a/01-staging-banner-homepage.png`
9. Screenshot: staging banner on `/auth/login` → `qa-results/screenshots/session-a/02-staging-banner-login.png`
10. Screenshot: `/account` after test-login → `qa-results/screenshots/session-a/03-account-after-test-login.png`
**QA script location:** `qa-drop/session-a-staging-qa.md`
---
## 5. STAGING SETUP
To provision the staging Railway service, run:
```bash
bash scripts/setup_staging.sh
```
Then set these env vars on the staging service:
```
ENVIRONMENT=staging
TESTING=true
TEST_LOGIN_SECRET=<generate with: python3 -c "import secrets; print(secrets.token_urlsafe(32))">
DATABASE_URL=<same as prod or separate staging DB>
FLASK_SECRET_KEY=<generate fresh>
CRON_SECRET=<same as prod>
ADMIN_EMAIL=<your email>
ANTHROPIC_API_KEY=<same as prod>
OPENAI_API_KEY=<same as prod>
BASE_URL=https://sfpermits-ai-staging.up.railway.app
```
**NEVER set `TESTING` or `TEST_LOGIN_SECRET` on the production service.**
---
## 6. BLOCKED ITEMS REPORT
None. All 6 deliverables completed.
---
## 7. TEST COUNT
- **New tests added:** 29 (all in `tests/test_staging_env.py`)
- **Pre-existing tests:** 1554 (all still passing)
- **Total after session:** 1583 collected, 1604 passed (e2e conftest adds importable fixtures)
---
## Return to Orchestrator
```
status: COMPLETE
new_tests: 29
files_changed: 11 (6 modified + 5 new)
blockers: none
test_login_secret_example: run `python3 -c "import secrets; print(secrets.token_urlsafe(32))"` on staging to generate
```
**Key implementation notes for orchestrator:**
- `/auth/test-login` is 100% safe on production — the `TESTING` env var gate makes it return 404 without revealing anything
- `IS_STAGING` is evaluated at import time — if you need to change it at runtime in tests, monkeypatch `web.app.IS_STAGING` directly (as the tests demonstrate)
- The staging banner is in 3 templates: `index.html`, `landing.html`, `auth_login.html` — other templates (admin pages, account, etc.) are NOT covered yet — add banner to additional templates if needed
- Playwright conftest requires `playwright` package to be installed (`pip install playwright && playwright install chromium`)