---
phase: 06-signing-flow
plan: "01"
subsystem: database
tags: [jwt, jose, postgres, drizzle, pdf, sha256, audit, signature_pad, react-email]

# Dependency graph
requires:
  - phase: 05-pdf-fill-and-field-mapping
    provides: documents table with signatureFields, preparedFilePath, @cantoo/pdf-lib installed

provides:
  - signingTokens PostgreSQL table (jti pk, documentId FK, expiresAt, usedAt)
  - auditEvents PostgreSQL table with 6-value audit_event_type enum
  - signedFilePath, pdfHash, signedAt columns on documents table
  - createSigningToken() — HS256 JWT creation with jti stored in DB
  - verifySigningToken() — JWT verification, throws on expired/invalid
  - logAuditEvent() — typed audit event insert with server-side timestamp
  - embedSignatureInPdf() — embeds PNG sigs into PDF, returns SHA-256 hex digest
  - signature_pad, @react-email/render, @react-email/components installed

affects: [06-02, 06-03, 06-04, 06-05]

# Tech tracking
tech-stack:
  added: [signature_pad, "@react-email/render", "@react-email/components"]
  patterns:
    - jose HS256 JWT with jti stored in DB for one-time-use enforcement
    - atomic rename (tmp -> final path) for PDF writes prevents corruption
    - SHA-256 hash computed from disk after atomic rename (not from in-memory bytes)
    - server-side defaultNow() for audit timestamps — never accept timestamp from client

key-files:
  created:
    - teressa-copeland-homes/src/lib/signing/token.ts
    - teressa-copeland-homes/src/lib/signing/audit.ts
    - teressa-copeland-homes/src/lib/signing/embed-signature.ts
    - teressa-copeland-homes/drizzle/0005_signing_flow.sql
  modified:
    - teressa-copeland-homes/src/lib/db/schema.ts
    - teressa-copeland-homes/package.json

key-decisions:
  - "SIGNING_JWT_SECRET uses a real openssl rand -base64 32 value (not placeholder) — generated at plan execution time"
  - "auditEventTypeEnum defined before auditEvents table — pgEnum must precede referencing table in schema.ts"
  - "jose already present as next-auth transitive dependency — no reinstall needed"
  - "Migration file renamed from drizzle-kit default to 0005_signing_flow.sql for readability; journal updated to match"

patterns-established:
  - "Signing utilities live in src/lib/signing/ — server-only, never imported from client components"
  - "JWT jti stored in signingTokens table on createSigningToken — enables one-time-use enforcement in later plans"
  - "Audit log uses server defaultNow() exclusively — createdAt never passed from caller"

requirements-completed: [SIGN-02, LEGAL-01, LEGAL-02]

# Metrics
duration: 2min
completed: 2026-03-20
---

# Phase 6 Plan 01: Signing Foundation Summary

**PostgreSQL signing tables (signingTokens, auditEvents), three new documents columns, and server-side utilities for HS256 JWT token creation, typed audit logging, and atomic PDF signature embedding with SHA-256 hash**

## Performance

- **Duration:** 2 min
- **Started:** 2026-03-20T17:22:43Z
- **Completed:** 2026-03-20T17:25:09Z
- **Tasks:** 2
- **Files modified:** 6

## Accomplishments

- Migration 0005_signing_flow.sql applied — signingTokens and auditEvents tables live in PostgreSQL
- documents table extended with signedFilePath, pdfHash, signedAt columns
- Three signing utilities created and compile cleanly: token.ts, audit.ts, embed-signature.ts
- signature_pad, @react-email/render, @react-email/components installed for Phase 6 plans 02-05

## Task Commits

Each task was committed atomically:

1. **Task 1: Install packages + extend schema + generate migration** - `fa68a1b` (feat)
2. **Task 2: Create signing utility library (token + audit + embed)** - `2929581` (feat)

**Plan metadata:** (docs commit — see below)

## Files Created/Modified

- `teressa-copeland-homes/src/lib/db/schema.ts` - Added auditEventTypeEnum, signingTokens table, auditEvents table; added signedFilePath/pdfHash/signedAt to documents table
- `teressa-copeland-homes/drizzle/0005_signing_flow.sql` - Migration file adding all new tables and columns
- `teressa-copeland-homes/drizzle/meta/_journal.json` - Updated journal tag to 0005_signing_flow
- `teressa-copeland-homes/drizzle/meta/0005_snapshot.json` - Generated drizzle snapshot
- `teressa-copeland-homes/src/lib/signing/token.ts` - createSigningToken() and verifySigningToken() using jose HS256
- `teressa-copeland-homes/src/lib/signing/audit.ts` - logAuditEvent() with typed enum + server-side timestamp
- `teressa-copeland-homes/src/lib/signing/embed-signature.ts` - embedSignatureInPdf() with atomic write and SHA-256 hash (LEGAL-02)
- `teressa-copeland-homes/package.json` - Added signature_pad, @react-email/render, @react-email/components

## Decisions Made

- jose was already installed as a transitive dependency of next-auth — skipped reinstall
- Migration filename renamed from drizzle-kit default `0005_abandoned_albert_cleary.sql` to `0005_signing_flow.sql`; `drizzle/meta/_journal.json` updated to match — drizzle-kit migrate uses the journal tag, not filename, so this is safe
- `SIGNING_JWT_SECRET` generated with `openssl rand -base64 32` (real value, not placeholder) and added directly to `.env.local`
- `auditEventTypeEnum` positioned before `auditEvents` table in schema.ts — pgEnum must precede referencing table per established project convention (see Phase 3 decision log)

## Deviations from Plan

None - plan executed exactly as written.

## Issues Encountered

None.

## User Setup Required

`SIGNING_JWT_SECRET` has been added to `.env.local` with a real generated value. No additional manual setup required for this plan.

When Phase 6 goes to production, the secret must be set in the Docker server environment. The `.env.local` value can be reused or regenerated.

## Next Phase Readiness

Phase 6 foundation is fully in place:
- signingTokens and auditEvents tables in PostgreSQL (migration 0005 applied)
- documents table has signedFilePath, pdfHash, signedAt columns
- createSigningToken, verifySigningToken, logAuditEvent, embedSignatureInPdf all compile
- npm run build passes cleanly
- Plans 02-05 can now import from `@/lib/signing/token`, `@/lib/signing/audit`, and `@/lib/signing/embed-signature`

---
*Phase: 06-signing-flow*
*Completed: 2026-03-20*
