Commit Graph

111 Commits

Author SHA1 Message Date
Chandler Copeland
5c7a0fd061 fix(04-03): style Browse files as a visible button with selected filename display 2026-03-19 21:54:07 -06:00
Chandler Copeland
7ddc690482 docs(04-03): complete PDF viewer UI plan summary
- SUMMARY: AddDocumentModal, PdfViewer, /portal/documents/[docId] page
- STATE: current position updated to 04-03 complete, 3/4 plans in phase
- ROADMAP: phase 4 progress updated (3 summaries of 4 plans)
- REQUIREMENTS: DOC-03 marked complete
2026-03-19 21:47:09 -06:00
Chandler Copeland
c1f60cadf6 feat(04-03): add AddDocumentModal, PdfViewer, and document detail page
- Create AddDocumentModal: searchable forms library list + custom file picker
- Wire Add Document button into ClientProfileClient in Documents section header
- Update DocumentsTable: document names now link to /portal/documents/{id}
- Create PdfViewer with page nav, zoom, and download controls (pdfjs worker via import.meta.url)
- Create /portal/documents/[docId] page: server component with auth check, doc/client query
- Add documentsRelations and clientsRelations to schema.ts for db.query with-relations support
- Build verified: /portal/documents/[docId] route present, no errors
2026-03-19 21:44:17 -06:00
Chandler Copeland
63e5888968 feat(04-03): install react-pdf and configure Next.js transpilePackages
- npm install react-pdf (v9+ pulls in pdfjs-dist automatically)
- Add transpilePackages: ['react-pdf', 'pdfjs-dist'] to next.config.ts
- Build verified passing after config change
2026-03-19 21:42:06 -06:00
Chandler Copeland
7ddb920467 docs(04-02): complete PDF API routes plan summary
- Created 04-02-SUMMARY.md with task commits, decisions, and dependency graph
- Updated STATE.md: position advanced to 04-02 complete, decisions added
- Updated ROADMAP.md: phase 4 progress to 2/4 plans
2026-03-19 21:38:37 -06:00
Chandler Copeland
32e129c097 feat(04-02): create POST /api/documents and GET /api/documents/[id]/file routes
- POST handles both form-data (custom upload) and JSON (template copy) paths
- Copies seed PDF or writes uploaded file to uploads/clients/{clientId}/{uuid}.pdf
- Path traversal guard on destPath before writing
- GET streams PDF bytes with Content-Type: application/pdf
- Path traversal guard on filePath before reading
- Both routes return 401 for unauthenticated requests
2026-03-19 21:36:54 -06:00
Chandler Copeland
e0f180c3d8 feat(04-02): create GET /api/forms-library authenticated template list
- Queries form_templates ordered by name (asc)
- Returns 401 for unauthenticated requests
- Returns JSON array of { id, name, filename } for authenticated agents
2026-03-19 21:36:21 -06:00
Chandler Copeland
c830951afe docs(04-01): complete PDF ingest data layer plan summary
- Create 04-01-SUMMARY.md: form_templates schema + seed:forms CLI
- Update STATE.md: position advanced to Phase 4 Plan 1 complete
- Update ROADMAP.md: Phase 04 plan progress (1/4 complete)
- Mark requirements DOC-01, DOC-02 complete in REQUIREMENTS.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 21:34:51 -06:00
Chandler Copeland
f82364d2c7 feat(04-01): create seed-forms script and npm run seed:forms command
- Create scripts/seed-forms.ts: reads seeds/forms/, upserts PDFs into form_templates via onConflictDoUpdate on filename
- Add seed:forms script to package.json with DOTENV_CONFIG_PATH=.env.local prefix
- Empty seeds/forms/ prints guidance message and exits 0 (monthly-sync workflow ready)
2026-03-19 21:33:02 -06:00
Chandler Copeland
bbbbdbed5e feat(04-01): add formTemplates table and extend documents schema
- Add formTemplates table (id text PK, name, filename unique, createdAt, updatedAt)
- Add formTemplateId (nullable FK) and filePath (nullable text) to documents table
- Generate and apply migration 0002_wealthy_zzzax.sql
- Create seeds/forms/.gitkeep to track seed directory in git
2026-03-19 21:32:30 -06:00
Chandler Copeland
c896fa5e82 docs(04-pdf-ingest): create phase 4 plan (4 plans, 4 waves)
Plans 04-01 through 04-04 cover DOC-01, DOC-02, DOC-03:
schema/seed, API routes, UI modal + PDF viewer, human verification.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 21:28:39 -06:00
Chandler Copeland
521646f312 docs(04): research phase PDF ingest domain 2026-03-19 21:24:01 -06:00
Chandler Copeland
5fc9ccc6c8 docs(04): capture phase context 2026-03-19 21:20:10 -06:00
Chandler Copeland
dc076cf309 docs(phase-3): complete phase execution and verification 2026-03-19 17:53:40 -06:00
Chandler Copeland
7a19a10a0c docs(03-04): complete client profile page and Phase 3 portal verification summary 2026-03-19 17:34:55 -06:00
Chandler Copeland
b186ac5f38 feat(03-04): add client profile page with edit/delete and documents table
- Create ConfirmDialog component with overlay, title, message, cancel/confirm buttons
- Create ClientProfilePage server component (awaits params Promise — Next.js 16)
- Create ClientProfileClient client component with edit modal and delete confirmation
- Documents section uses DocumentsTable with showClientColumn={false}
- deleteClient called directly from async event handler in client component
2026-03-19 16:58:21 -06:00
Chandler Copeland
b94720bde8 docs(03-03): complete dashboard and clients plan summary 2026-03-19 16:54:35 -06:00
Chandler Copeland
3fa2e1c424 feat(03-03): extend seed.ts with client and placeholder document rows
- Added import of clients, documents, inArray from drizzle-orm
- Seeds 2 clients: Sarah Johnson and Mike Torres (onConflictDoNothing)
- Queries back seeded client IDs, then seeds 4 placeholder documents
- Documents cover Signed/Sent/Draft statuses across both clients
- Seed is idempotent via onConflictDoNothing guard
2026-03-19 16:49:29 -06:00
Chandler Copeland
df1924acc4 feat(03-03): add Clients page with card grid and create modal
- ClientCard.tsx: server component with name, email, doc count, last activity; wrapped in Link to /portal/clients/[id]
- ClientModal.tsx: use client component with useActionState from react; supports create/edit modes via bind pattern; closes on success
- ClientsPageClient.tsx: use client wrapper holding isOpen modal state, renders card grid or empty state CTA
- clients/page.tsx: async server component fetching clients with docCount + lastActivity via Drizzle LEFT JOIN + GROUP BY
2026-03-19 16:47:28 -06:00
Chandler Copeland
e55d7a1de5 feat(03-03): add Dashboard page with filterable documents table
- Async server component queries all documents with LEFT JOIN to clients
- Filter state lives in URL (?status=Draft|Sent|Viewed|Signed) via DashboardFilters client component
- Rows filtered in JavaScript after fetch (tiny dataset in Phase 3)
- DashboardFilters extracted to _components/DashboardFilters.tsx (use client + useRouter)
- Displays agent first name extracted from session email
2026-03-19 16:46:26 -06:00
Chandler Copeland
59acc62606 docs(03-02): complete portal shell plan — layout, nav, components, client actions
- 03-02-SUMMARY.md: plan summary with task commits, deviations, and decisions
- STATE.md: updated current position to Phase 3 Plan 02 complete, added decisions
- ROADMAP.md: Phase 3 progress updated (2/4 plans complete)
2026-03-19 16:43:37 -06:00
Chandler Copeland
5b87201b28 feat(03-02): add createClient, updateClient, deleteClient server actions
- 'use server' file with Zod validation (name min 1 char, valid email)
- createClient: validate, insert, revalidatePath /portal/clients
- updateClient: bind pattern (id, prevState, formData), revalidates client list + profile
- deleteClient: auth check, delete by id, revalidatePath /portal/clients
- Fixed Zod v4 .issues access (not .errors — v4 API change)
2026-03-19 16:38:49 -06:00
Chandler Copeland
28d42f5d9b feat(03-02): add StatusBadge and DocumentsTable shared portal components
- StatusBadge: color-coded pill for Draft=gray, Sent=blue, Viewed=amber, Signed=green
- DocumentsTable: reusable table with optional Client column, StatusBadge integration
- Date format: toLocaleDateString en-US short month; null sentAt renders as em-dash
2026-03-19 16:37:30 -06:00
Chandler Copeland
9c4caeedba feat(03-02): add portal authenticated layout and PortalNav
- Create portal/(protected)/layout.tsx with auth() check and redirect to /agent/login
- Create PortalNav.tsx as client component with Dashboard/Clients links and active state
- Nav uses usePathname() for active gold underline, LogoutButton for sign-out
- CSS variables --navy/--gold/--cream applied throughout portal shell
2026-03-19 16:37:03 -06:00
Chandler Copeland
00f9c7c9f0 feat(03-01): protect /portal routes and update post-login redirect
- middleware.ts: add /portal/:path* to matcher array
- auth.config.ts: add isPortalRoute check, redirect unauthenticated to /agent/login
- auth.config.ts: change post-login redirect from /agent/dashboard to /portal/dashboard
- agent dashboard page: replace stub with redirect to /portal/dashboard
2026-03-19 16:17:59 -06:00
Chandler Copeland
f8f8b8f4ba feat(03-01): add clients and documents tables to Drizzle schema
- Add pgEnum import and documentStatusEnum (Draft, Sent, Viewed, Signed)
- Add clients table (id, name, email, createdAt, updatedAt)
- Add documents table (id, name, clientId FK, status enum, sentAt, createdAt)
- Generate migration 0001_watery_blindfold.sql and apply to local PostgreSQL
2026-03-19 16:17:26 -06:00
Chandler Copeland
3cda82df51 docs(03-agent-portal-shell): create phase 3 plan — 4 plans in 4 waves 2026-03-19 16:13:10 -06:00
Chandler Copeland
d4fd2bcdc8 docs(03): research phase agent-portal-shell 2026-03-19 16:04:17 -06:00
Chandler Copeland
c6cd488fa3 docs(03): capture phase context 2026-03-19 15:59:08 -06:00
Chandler Copeland
4d9c74a1e3 docs(phase-02): complete phase execution 2026-03-19 15:27:47 -06:00
Chandler Copeland
9500f812e0 docs(02-03): complete human verification — phase 2 approved
- All 7 checklist items approved by human reviewer
- Visual fixes applied: hero objectPosition 20%, contact form white inputs, testimonial gold accent bar
- Phase 2 marketing site marked complete (MKTG-01 through MKTG-04 satisfied)
- STATE.md updated: phase 2 complete, 6/6 plans done, progress 40%
2026-03-19 15:19:22 -06:00
Chandler Copeland
5842ffc9f3 docs(02-02): complete contact form plan — SUMMARY, STATE, plans tracked
- Create 02-02-SUMMARY.md: contact form outcomes, decisions, deviations
- Update STATE.md: position, decisions (nodemailer v7 pin, useActionState React 19, honeypot pattern)
- Add 02-01-PLAN.md, 02-02-PLAN.md, 02-03-PLAN.md to version control
- Mark MKTG-03 requirement complete

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 15:04:45 -06:00
Chandler Copeland
ffb1ab629d docs(02-01): complete marketing site shell plan — nav, hero, testimonials, footer
- Create 02-01-SUMMARY.md with execution results and deviation docs
- Update STATE.md position and session continuity
- Update ROADMAP.md phase 02 progress
- Mark MKTG-01, MKTG-02, MKTG-04 requirements complete
2026-03-19 15:04:15 -06:00
Chandler Copeland
a33b4c9520 fix(02-01): restore TestimonialsSection in page.tsx section order
- Add TestimonialsSection import and render between HeroSection and ListingsPlaceholder
- Correct section order: SiteNav → HeroSection → TestimonialsSection → ListingsPlaceholder → ContactSection → SiteFooter
2026-03-19 15:02:19 -06:00
Chandler Copeland
47c6dd9e62 feat(02-02): add ContactSection client component and wire into homepage
- Create src/app/_components/ContactSection.tsx: useActionState form with
  name, email, phone, message fields and gold Send Message button
- Honeypot field (name="website") with display:none, tabIndex=-1, autoComplete="off"
- Success state: form replaced by thank-you message on successful submission
- Error state: inline alert for validation failures
- page.tsx: replace <section id="contact" /> stub with <ContactSection />
- useActionState imported from 'react' (not react-dom, React 19 compatible)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 15:01:36 -06:00
Chandler Copeland
6d701b7faa feat(02-01): add testimonials carousel and wire into homepage
- Create TestimonialsSection with 5 placeholder reviews
- Auto-rotates every 5s, pauses on hover, clearInterval cleanup
- ChevronLeft/ChevronRight arrow controls and dot indicators
- Wire TestimonialsSection into page.tsx between hero and listings
2026-03-19 15:01:07 -06:00
Chandler Copeland
c26a0b1b62 feat(02-01): scaffold marketing site nav, hero, listings, footer
- Add scroll-behavior: smooth and scroll-margin-top to globals.css
- Create SiteNav with sticky navy bar, desktop links, mobile hamburger
- Create HeroSection with split-panel layout and next/image
- Create ListingsPlaceholder with brand navy background and gold CTA
- Create SiteFooter with license number and TODO verify comment
- Update page.tsx to compose all section components
- Install lucide-react for icons

[Rule 1 - Bug] Fixed event handlers in server components — used CSS hover classes instead
2026-03-19 14:59:56 -06:00
Chandler Copeland
39f233dbb4 feat(02-02): install nodemailer and create contact mailer + server action
- Add nodemailer@^7.0.7 and @types/nodemailer (v7 required by next-auth peer dep)
- Create src/lib/contact-mailer.ts: Nodemailer SMTP transporter + sendContactEmail()
- Create src/lib/contact-action.ts: Server Action with Zod validation, honeypot check
- SMTP credentials read from CONTACT_EMAIL_USER/PASS/SMTP_HOST/PORT env vars
- Add CONTACT_* placeholder vars to .env.local (gitignored, for local setup docs)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 14:59:23 -06:00
Chandler Copeland
0cdf3e5f7d docs(02): research phase - marketing site
Research covering Next.js App Router patterns, Nodemailer SMTP contact form,
pure-React testimonials carousel, honeypot spam protection, and React 19
useActionState API for the public marketing homepage phase.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 14:50:36 -06:00
Chandler Copeland
0167c00462 docs(02): add placeholder assets guidance to context 2026-03-19 14:46:01 -06:00
Chandler Copeland
8b9163eda3 docs(02): capture marketing site phase context 2026-03-19 14:45:43 -06:00
Chandler Copeland
6590e5fcf5 docs(phase-1): complete phase execution — Foundation ✓
All 3 plans executed, 4/4 requirements satisfied, 5/5 must-haves verified.
Auth flow human-approved. Switching to local PostgreSQL + home Docker server.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 14:34:56 -06:00
Chandler Copeland
0ca13987f5 docs(01-03): complete local env setup and auth flow verification
All 7 auth flow tests passed (human verified). Fixed Edge Runtime
middleware incompatibility and (protected) route group split.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 14:23:20 -06:00
Chandler Copeland
39af0f19ba fix(auth): resolve middleware Edge Runtime + layout redirect loop
Two bugs:
1. auth.ts imported postgres (Node.js TCP) which crashes in Edge Runtime,
   causing Auth.js to silently fall back to redirecting all requests to login.
   Fix: split into auth.config.ts (Edge-safe, no DB) used by middleware,
   and auth.ts (full, with DB) used by server components.

2. /agent/layout.tsx applied to /agent/login, so unauthenticated login page
   visits redirected to themselves in an infinite loop.
   Fix: moved dashboard + layout into (protected) route group so login page
   has no auth layout.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 14:08:04 -06:00
Chandler Copeland
0a75442af3 fix(db): swap @neondatabase/serverless for postgres.js (local dev support)
Neon serverless driver requires remote WebSocket — incompatible with local
PostgreSQL. Replaced with postgres.js (drizzle-orm/postgres-js) in db/index.ts,
scripts/seed.ts, and drizzle.config.ts.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 14:00:32 -06:00
Chandler Copeland
8bc09e4ea7 docs: switch infrastructure to local PostgreSQL + home Docker server (no Vercel/Neon) 2026-03-19 13:51:49 -06:00
Chandler Copeland
410fc10e9b docs(01-02): complete login pages and auth UI plan
- 01-02-SUMMARY.md: branded login page, password toggle, dashboard stub, logout
- STATE.md: advanced to plan 2/3, added three new auth UI decisions
- ROADMAP.md: updated phase 01 progress to 2/3 plans complete
- REQUIREMENTS.md: AUTH-04 marked complete (logout with signed-out confirmation)
2026-03-19 13:41:19 -06:00
Chandler Copeland
32dc2d3ee5 feat(01-02): build agent portal layout, dashboard stub, and logout mechanism
- LogoutButton: client component with server action calling signOut to ?signed_out=1
- AgentLayout: defense-in-depth auth() check, header with email and sign-out button
- DashboardPage: belt-and-suspenders auth() check, welcome message with agent email
- HomePage: updated to Teressa Copeland Homes placeholder (Phase 2 marketing site)
- npm run build and npx tsc --noEmit both pass with zero errors
2026-03-19 13:39:25 -06:00
Chandler Copeland
f221597677 feat(01-02): build branded login page with password toggle and error handling
- Split-screen layout: agent photo left (lg+), login card right
- loginAction server action: signIn credentials, redirects on AuthError
- PasswordField client component: show/hide toggle with eye/eye-off SVG
- Signed-out confirmation banner on ?signed_out=1
- Error banner on ?error=invalid with generic message
- Brand colors: gold #C9A84C accent, navy #1B2B4B text, off-white #FAF9F7 bg
- Copied /Users/ccopeland/Downloads/red.jpg to public/red.jpg
2026-03-19 13:38:42 -06:00
Chandler Copeland
7fdce32d0d docs(01-01): complete foundation scaffold plan 2026-03-19 13:36:14 -06:00