---
phase: 23-classification-disposition-per-client-automation-gate
plan: 03
subsystem: api
tags: [postgres, admin-api, migration, requirements-doc]

# Dependency graph
requires:
  - phase: 15-data-model-detection-ticket-evidence
    provides: companies table + phishing schema conventions this migration builds on
provides:
  - phishing_automation_gate table (opt-in per-company automation flags)
  - Admin GET/PATCH/DELETE API for reading and setting the gate flags
  - REQUIREMENTS.md backfill for all six phase-23 requirement IDs
affects: [23-04-admin-phishing-automation-page, 23-05-gated-webhook-chain]

# Tech tracking
tech-stack:
  added: []
  patterns: [opt-in settings table mirroring company_scope's opt-out shape with flipped boolean defaults]

key-files:
  created:
    - migrations/100_phishing_automation_gate.sql
    - app/api/admin/phishing-automation/route.ts
    - app/api/admin/phishing-automation/[companyId]/route.ts
  modified:
    - .planning/REQUIREMENTS.md

key-decisions:
  - "PATCH requires all three boolean flags in the body (client always sends current values) rather than supporting partial updates — avoids partial-update SQL complexity, matches company-scope's single-field simplicity"
  - "Phase 23 requirement entries added under the existing v1 Requirements heading (not a new v3 heading) since v2 is explicitly documented as deferred/future work and Phase 23 is active roadmap work"

patterns-established:
  - "Opt-in settings table + COALESCE(..., false) read pattern (mirrors company_scope's opt-out + COALESCE(..., true), with defaults flipped)"

requirements-completed: [AUTOGATE-01]

# Metrics
duration: 12min
completed: 2026-07-16
---

# Phase 23 Plan 03: Migration 100 + Admin Phishing-Automation API Summary

**New opt-in `phishing_automation_gate` table (auto_parse/auto_classify/auto_report, all default false) plus admin-gated GET/PATCH/DELETE routes mirroring the existing company-scope pattern, and REQUIREMENTS.md backfilled with the six Phase 23 requirement IDs.**

## Performance

- **Duration:** ~12 min
- **Started:** 2026-07-16T23:31:00Z (approx)
- **Completed:** 2026-07-16T23:37:57Z
- **Tasks:** 3 completed
- **Files modified:** 4 (3 created, 1 modified)

## Accomplishments
- `phishing_automation_gate` table created and applied to the running dev Postgres (existing volume — file alone would not auto-run)
- Admin GET route lists every active company with COALESCE(..., false)-defaulted gate flags, admin-gated
- Admin PATCH/DELETE `[companyId]` route upserts all three flags with actor+timestamp stamping and reverts to all-OFF default on DELETE
- REQUIREMENTS.md now documents all six Phase 23 requirement IDs (CLASSDISP-01/02/03, AUTOGATE-01/02/03) with Traceability rows, closing the gap where they existed only in ROADMAP.md

## Task Commits

Each task was committed atomically:

1. **Task 1: Create migration 100 phishing_automation_gate + apply to dev DB** - `db7d67c` (feat)
2. **Task 2: Admin GET list route + [companyId] PATCH/DELETE route** - `ea5047c` (feat)
3. **Task 3: Backfill v3 CLASSDISP-*/AUTOGATE-* requirement entries + Traceability rows in REQUIREMENTS.md** - `78b6b49` (docs)

_No TDD tasks in this plan — all `type="auto"` without `tdd="true"`._

## Files Created/Modified
- `migrations/100_phishing_automation_gate.sql` - New table: company_id PK -> companies(id) ON DELETE CASCADE, three `NOT NULL DEFAULT false` booleans (auto_parse/auto_classify/auto_report), updated_by/updated_at audit columns, applied live to pulse-postgres
- `app/api/admin/phishing-automation/route.ts` - Admin-gated GET: LEFT JOIN + COALESCE(..., false), search/type filters, camelCase response
- `app/api/admin/phishing-automation/[companyId]/route.ts` - Admin-gated PATCH (upsert all three flags, actor stamp) and DELETE (revert to default)
- `.planning/REQUIREMENTS.md` - New "Classification Disposition + Automation Gate" subsection under v1 Requirements with 6 entries; 6 new Traceability rows (Phase 23, Pending); Coverage footer updated (32 -> 38 total)

## Decisions Made
- PATCH validates and requires `autoParse`/`autoClassify`/`autoReport` all present as booleans in the body (no partial-update support) — matches the plan's stated rationale that the admin page's per-Switch toggle already knows the other two current values from local state.
- Requirement entries were placed as a new subsection under the existing `## v1 Requirements` heading rather than creating a `## v3 Requirements` heading, per the plan's explicit instruction that v2 is documented as "deferred to future release" and a v3 heading would misleadingly read the same way for active roadmap work.

## Deviations from Plan

None - plan executed exactly as written.

## Issues Encountered

None.

## User Setup Required

None - no external service configuration required. The migration was applied directly to the existing dev Postgres volume as instructed (Postgres only auto-applies migrations on first volume boot).

## Next Phase Readiness

- The `phishing_automation_gate` table and its admin API are ready for Plan 04 (`/admin/phishing-automation` page with three per-company Switch toggles) and Plan 05 (gated webhook auto-pipeline) to consume.
- Both routes verified with `npx tsc --noEmit --pretty` (exit 0) and all plan-specified grep-based acceptance checks pass.
- REQUIREMENTS.md and ROADMAP.md are now consistent on the six Phase 23 requirement IDs.

---
*Phase: 23-classification-disposition-per-client-automation-gate*
*Completed: 2026-07-16*

## Self-Check: PASSED

- FOUND: migrations/100_phishing_automation_gate.sql
- FOUND: app/api/admin/phishing-automation/route.ts
- FOUND: app/api/admin/phishing-automation/[companyId]/route.ts
- FOUND: .planning/REQUIREMENTS.md
- FOUND: commit db7d67c (Task 1)
- FOUND: commit ea5047c (Task 2)
- FOUND: commit 78b6b49 (Task 3)
- FOUND: commit 63d6e85 (SUMMARY.md)
