mad-lawsuit/cline_docs/activeContext.md

22 KiB

Active Context - Current Work Status

Current Task: DNS SWITCHOVER COMPLETE + EMAIL NOTIFICATIONS ENABLED

MAD Lawsuit Website v2.0 - NOW LIVE AT MAIN DOMAIN:

  • v1.0 Status: DECOMMISSIONED (containers stopped)
  • v2.0 Status: LIVE AT https://mad-lawsuit.org (Laravel + Inertia + Vue)
  • Current Phase: Phase 5 - DNS Switchover COMPLETE
  • Status: All systems operational at main domain 🎉

Latest Changes (December 19, 2025)

Phase 5.1 - DNS Switchover COMPLETE:

  • Old Domain: v2.mad-lawsuit.org (preview)
  • New Domain: mad-lawsuit.org (production)
  • Changes Made:
    • Updated .env: Changed APP_URL and ASSET_URL to https://mad-lawsuit.org
    • Updated docker-compose.yml: Changed port from 8080 to 806 (matching v1)
    • Updated Caddyfile: Point mad-lawsuit.org → localhost:806
    • Added redirects: v2.mad-lawsuit.org → mad-lawsuit.org
    • Stopped old v1.0 containers
  • SSL Certificate: Automatically issued by Caddy/Let's Encrypt
  • Status: Website fully accessible at https://mad-lawsuit.org

Phase 5.2 - Email Notifications to All Subscribers COMPLETE:

  • Previous: Only sent test emails to chris@deafgain.org
  • Now: Sends to all active subscribers in database
  • Implementation:
    • Modified app/Http/Controllers/Admin/DocketEntryController.php
    • Queries all active subscribers: Subscription::where('is_active', true)->get()
    • Loops through each subscriber and sends personalized email
    • Each email includes unique unsubscribe token
    • Added detailed logging (success/failure tracking)
    • Handles individual failures gracefully
  • Subscriber Count: 27 active subscribers (28 total, 1 inactive)
  • Status: Deployed and ready to use

Phase 5.3 - iPad PDF Viewing Fix COMPLETE:

  • Issue: iPad Safari couldn't scroll PDFs in modal viewer
  • Solution: Detect iOS devices and open PDFs in new tab (native Safari viewer)
  • Implementation:
    • Updated resources/js/Pages/Home.vue
    • Added iOS detection: /iPad|iPhone|iPod/.test(navigator.userAgent)
    • Desktop: Opens PDF in modal viewer
    • iOS/Mobile: Opens PDF in new tab
  • Status: Deployed and working perfectly

Latest Enhancements (December 18, 2025)

Phase 4.1 - PDF Upload Fix COMPLETE:

  • Problem: PDF uploads failing with "Permission denied" error
  • Root Cause: nginx temp directories had incorrect permissions (750 on parent /var/lib/nginx)
  • Solution: Updated Dockerfile to set parent directory to 755
  • Files Modified:
    • Dockerfile - Added chmod 755 /var/lib/nginx command
    • Rebuilt container with proper permissions
  • Status: PDF uploads now working perfectly (tested with large files)

Phase 4.2 - Unsubscribe Confirmation Page COMPLETE:

  • Feature: Two-step unsubscribe confirmation to prevent accidental unsubscribes
  • Implementation:
    • Created resources/js/Pages/Unsubscribe.vue with beautiful confirmation UI
    • Matches site styling (#6E6362 background, #6b9080 green buttons)
    • Shows user's email address
    • Two buttons: "Yes, Unsubscribe" (red) and "Cancel" (green)
    • Success/error feedback with appropriate icons
    • "Return to Home" button after completion
  • Backend Changes:
    • Added showUnsubscribe() method to SubscriptionController
    • Updated routes: GET /unsubscribe/{token} → confirmation page
    • Kept POST /api/unsubscribe/{token} for processing
    • Updated email template to use new route
  • CSRF Fix: Fixed token retrieval with proper TypeScript casting
  • Status: Fully deployed and working at https://v2.mad-lawsuit.org/unsubscribe/{token}

Phase 4.3 - Date Format Consistency COMPLETE:

  • Issue: Subscriber page showing inconsistent date format
  • Fix: Updated resources/js/Pages/Admin/Subscribers/Index.vue
  • Format: Now shows American format (MM/DD/YYYY) matching home page and docket entries
  • Implementation: new Date(subscriber.created_at).toLocaleDateString('en-US', { month: '2-digit', day: '2-digit', year: 'numeric' })
  • Status: All dates now consistent across the application

Phase 4.4 - Remove Pagination from Docket Entries COMPLETE:

  • Change: Admin docket entries page now shows all entries on one page (no pagination)
  • Backend Changes:
    • app/Http/Controllers/Admin/DocketEntryController.php:
      • Changed from paginate(20) to get()
      • Removed pagination data from response
  • Frontend Changes:
    • resources/js/Pages/Admin/DocketEntries/Index.vue:
      • Removed pagination interface and props
      • Removed pagination UI (Previous/Next buttons)
      • Shows total count: "X total entries"
  • Rationale: Simpler interface for managing all entries at once
  • Status: Deployed and working at https://v2.mad-lawsuit.org/admin/docket-entries

Production URLs

Admin Credentials

  • Username: eliza
  • Password: AXEoZWk2AMAD0naw
  • Access: Full CRUD operations on docket entries, documents, and subscribers

v2.0 Phase 2 COMPLETED

Admin Dashboard - Fully Functional:

Controllers Implemented:

  • AuthController - Login/logout with session management
  • DashboardController - Statistics and recent entries
  • DocketEntryController - Full CRUD (7 resource methods, no pagination)
  • DocumentController - PDF upload/delete with UUID naming (working perfectly)
  • SubscriberController - List and deactivate subscribers

Vue Pages Created:

  • Admin/Login.vue - Professional authentication page
  • Admin/Dashboard.vue - Statistics cards, quick actions, recent entries
  • Admin/DocketEntries/Index.vue - All entries on one page (no pagination)
  • Admin/DocketEntries/Create.vue - Form for new entries
  • Admin/DocketEntries/Edit.vue - Update existing entries
  • Admin/DocketEntries/Show.vue - View details + upload documents
  • Admin/Subscribers/Index.vue - Manage email subscribers (50 per page, American dates)
  • Unsubscribe.vue - Two-step confirmation page with matching styling

Features Implemented:

  • Session-based authentication (separate from Breeze)
  • Full CRUD operations for docket entries
  • PDF document upload with validation (500MB max, PDF only) - WORKING
  • UUID-based file naming for security
  • File storage in storage/app/public/documents
  • Storage symlink configured (php artisan storage:link)
  • No pagination for docket entries (all on one page)
  • Pagination for subscribers (50 per page)
  • Soft delete for subscribers (deactivate)
  • Cascade delete for entries (removes documents)
  • Professional UI with Tailwind CSS
  • Form validation with error display
  • Success/error flash messages
  • Responsive design
  • Mobile PDF viewing optimized (opens in new tab on screens < 768px)
  • Unsubscribe confirmation page (prevents accidental unsubscribes)
  • Consistent American date format (MM/DD/YYYY) across all pages

v2.0 Technology Stack

Backend:

  • Framework: Laravel 12.43.1 (latest stable)
  • PHP: 8.3.28
  • Database: PostgreSQL 16-alpine (production)
  • ORM: Eloquent (replacing Prisma)
  • Auth: Laravel Sanctum + Session
  • API: Inertia.js server-side

Frontend:

  • Framework: Vue 3 + TypeScript
  • Routing: Inertia.js (SSR-like experience)
  • Styling: Tailwind CSS 3.x
  • Build Tool: Vite 7.x
  • Components: Vue SFC (Single File Components)

Production Environment:

  • Server: 10.4.0.205 (dedicated server behind NAT)
  • Docker: Alpine Linux containers
  • Web Server: nginx 1.28.0
  • PHP: PHP-FPM 8.3.28
  • Database: PostgreSQL 16-alpine
  • Reverse Proxy: Caddy (with auto-SSL)

v2.0 Progress Checklist

Phase 1 - Public Website COMPLETE:

  • Install PHP 8.3 and Composer locally
  • Create Laravel 12 project
  • Install Laravel Breeze with Vue + Inertia + TypeScript
  • Resolve NPM dependency conflicts (Vite 7 compatibility)
  • Install all NPM packages successfully
  • Create database migrations (docket_entries, documents, subscriptions, admin_users)
  • Create Eloquent models with relationships
  • Run migrations successfully (SQLite)
  • Create HomeController with Inertia
  • Build Vue home page component matching v1.0 design
  • Test locally with development servers (php artisan serve + npm run dev)
  • Verify website rendering correctly
  • Implement email subscription API
  • Add document download functionality

Phase 2 - Admin Dashboard COMPLETE:

  • Build admin authentication (session-based)
  • Create AdminUser model and migration
  • Implement AuthController (login/logout)
  • Create AdminAuth middleware
  • Build Admin/Login.vue page
  • Implement DashboardController with statistics
  • Create Admin/Dashboard.vue page
  • Implement DocketEntryController (all 7 CRUD methods)
  • Create all DocketEntry Vue pages (Index, Create, Edit, Show)
  • Implement DocumentController (store, destroy)
  • Implement SubscriberController (index, destroy)
  • Create Admin/Subscribers/Index.vue page
  • Set up file storage for PDFs
  • Configure storage symlink

Phase 3 - Data Migration COMPLETE (100%):

  • Export v1.0 production data (PostgreSQL dump)
  • Copy PDF files from production (69 files, 158MB)
  • Create V1DataMigrationSeeder (tested with sample data)
  • Create Python parser script (parse_sql_to_seeder.py)
  • Identify parser limitation (only captured 32/63 entries)
  • Create improved parser v2 (parse_sql_to_seeder_v2.py) with multi-line support
  • Generate complete PHP arrays (63 entries, 63 docs, 28 subs)
  • Update seeder with all production data
  • Run seeder to import ALL data
  • Verify 100% data integrity in database (63/63/28)

Phase 4 - Production Deployment COMPLETE (100%):

  • Create Dockerfile and docker-compose.yml
  • Build Docker image with PHP-FPM + nginx
  • Fix PHP-FPM command issue (php-fpm8.3 → php-fpm)
  • Deploy container to production server
  • Configure Caddy reverse proxy
  • Create production .env file
  • Generate APP_KEY
  • Fix AdminUser password double-hashing issue
  • Update AdminSeeder with correct bcrypt hash
  • Add TrustProxies middleware for HTTPS detection
  • Match v1 background colors exactly
  • Run migrations on production database
  • Seed production database with v1 data
  • Verify SSL certificate provisioning
  • Test admin login (working perfectly)
  • Test all functionality (all working)
  • Visual design matches v1 exactly

Phase 4.1 - Post-Deployment Enhancements COMPLETE (100%):

  • Fix PDF upload permissions (nginx temp directories)
  • Create unsubscribe confirmation page
  • Fix CSRF token issue in unsubscribe page
  • Update email template with new unsubscribe route
  • Fix subscriber date format to American (MM/DD/YYYY)
  • Remove pagination from docket entries admin page
  • Deploy all enhancements to production
  • Test all new features

Phase 5 - DNS Switchover (PENDING USER DECISION):

  • Update DNS: mad-lawsuit.org → v2.mad-lawsuit.org
  • Monitor for 24-48 hours
  • Decommission v1 containers
  • Implement email notifications (future enhancement)

v2.0 Design Specifications

Complete v1.0 documentation captured:

  • Visual design (colors, typography, layout)
  • Component specifications (forms, cards, buttons)
  • Functional requirements (interactions, animations)
  • Data structures (63 entries, 63 PDFs, 28 subscribers)
  • Admin dashboard specs (complete CRUD operations)
  • Production data verified from live database
  • Exact color matching from v1 container

Reference Document: cline_docs/v1_design_specifications.md (400+ lines)

Next Steps (Optional Enhancements)

Future Improvements:

  1. Email Notifications - Configure SMTP for subscriber notifications
  2. Monitoring - Set up application monitoring and alerts
  3. Backups - Automated database and file backups
  4. Performance - Redis caching for improved speed
  5. Analytics - Track visitor statistics

Data Migration Details

v1.0 Production Data:

  • Docket Entries: 63 entries with dates, titles, summaries
  • Documents: 63 PDF files (UUID filenames)
  • Subscriptions: 28 email subscribers (27 active)
  • Total Size: 158MB of PDF files

Schema Mapping (v1.0 → v2.0):

  • docket_entries.iddocket_entries.id
  • docket_entries.datedocket_entries.date
  • docket_entries.titledocket_entries.title
  • docket_entries.summarydocket_entries.summary
  • docket_entries.notesdocket_entries.notes
  • docket_entries.createdAtdocket_entries.created_at
  • docket_entries.updatedAtdocket_entries.updated_at
  • documents.docketEntryIddocuments.docket_entry_id
  • documents.storedFilenamedocuments.stored_filename
  • documents.originalFilenamedocuments.original_filename
  • documents.fileSizedocuments.file_size
  • documents.mimeTypedocuments.mime_type
  • documents.displayOrderdocuments.display_order
  • subscriptions.isActivesubscriptions.is_active
  • subscriptions.unsubscribeTokensubscriptions.unsubscribe_token
  • subscriptions.createdAtsubscriptions.created_at

Previous Task: v1.0 PRODUCTION SERVER MIGRATION COMPLETED

MAD Lawsuit Website Successfully Migrated to New Infrastructure:

  • Old Server: chrishaulmark.com (DigitalOcean VPS - being decommissioned)
  • New Server: 10.4.0.205 (Dedicated server behind NAT)
  • Status: FULLY OPERATIONAL WITH ALL DATA MIGRATED
  • v1.0 Tagged: Git tag v1.0 created and pushed to Gitea

Migration Implementation Details

Infrastructure Changes:

  1. Package Upgrades COMPLETED

    • Frontend: React 18→19, Next.js 15→16, Tailwind 3→4
    • Backend: Prisma 5→7, Express 4→5
    • All Dependencies: Updated to latest stable versions
    • Docker Images: Rebuilt with new package versions
  2. Caddy Reverse Proxy Fix COMPLETED

    • Problem: Docker DNS resolving container hostnames to wrong network IPs
    • Impact: Caddy timing out trying to reach containers
    • Solution: Updated Caddyfile to use direct IP addresses on caddy_network
    • Frontend IP: 172.18.0.6:806 (instead of hostname)
    • Backend IP: 172.18.0.5:901 (instead of hostname)
    • File: /home/chaulmark/docker/caddy/config/Caddyfile on server
  3. Data Migration COMPLETED

    • Database: PostgreSQL data (47MB) migrated from old server
    • PDF Files: 158MB of court documents (69 files) migrated
    • Redis Cache: Cache data migrated
    • Method: Created tar archive, transferred via rsync, extracted on new server
    • Location: /docker/websites/mad-lawsuit/ on 10.4.0.205
  4. SSL Certificates COMPLETED

    • Provider: Let's Encrypt via Caddy
    • Domains: mad-lawsuit.org, files.mad-lawsuit.org, v2.mad-lawsuit.org
    • Status: Active and auto-renewing

Final Production Architecture

┌─────────────────────────────────────────────────────────┐
│              Caddy Reverse Proxy (10.4.0.205)          │
│                                                         │
│  mad-lawsuit.org → 172.18.0.6:806 (Frontend v1)       │
│  files.mad-lawsuit.org → 172.18.0.5:901 (Backend v1)  │
│  v2.mad-lawsuit.org → localhost:8080 (v2 LIVE)        │
└─────────────────────────────────────────────────────────┘
                           │
                           ├─────────────────────────────┐
                           │                             │
                    ┌──────▼──────┐              ┌──────▼──────┐
                    │  Frontend   │              │   Backend   │
                    │  Port 806   │──────────────│   Port 901  │
                    │  Next.js 16 │   API Calls  │  Express 5  │
                    │  React 19   │              │  Prisma 7   │
                    └─────────────┘              └─────────────┘
                                                        │
                                                 ┌──────▼──────┐
                                                 │  PostgreSQL │
                                                 │  + Redis    │
                                                 └─────────────┘

Deployment Server Information

IMPORTANT: All deployments now go to 10.4.0.205 (NOT chrishaulmark.com)

Server Details:

  • Hostname: public-websites (internal: 10.4.0.205)
  • External Access: Via NAT through dedicated server
  • SSH Access: ssh chaulmark@10.4.0.205
  • v1 Project: ~/websites/mad-lawsuit.org/
  • v2 Project: ~/websites/v2.mad-lawsuit.org/
  • Docker Volumes: /docker/websites/mad-lawsuit/

v2 Deployment Commands:

# SSH to production server
ssh chaulmark@10.4.0.205

# Navigate to v2 project
cd ~/websites/v2.mad-lawsuit.org

# Pull latest code
git pull origin main

# Build frontend assets inside container
docker exec mad-lawsuit-v2 npm run build

# For major changes, rebuild container
docker compose down
docker compose up -d --build

# Check container status
docker compose ps
docker compose logs -f app

# Run migrations
docker exec mad-lawsuit-v2 php artisan migrate --force

# Seed database
docker exec mad-lawsuit-v2 php artisan db:seed --class=V1DataMigrationSeeder --force

# Clear caches
docker exec mad-lawsuit-v2 php artisan config:clear
docker exec mad-lawsuit-v2 php artisan cache:clear
docker exec mad-lawsuit-v2 php artisan route:clear

Verification

  • v1 Website: https://mad-lawsuit.org (HTTP/2 200 ✓)
  • v1 Backend API: https://files.mad-lawsuit.org (HTTP/2 200 ✓)
  • v1 Database: 63 docket entries with all historical data ✓
  • v1 PDF Files: 69 court documents accessible ✓
  • v1 All Containers: Running and healthy ✓
  • v2 Website: https://v2.mad-lawsuit.org (HTTP/2 200 ✓)
  • v2 Admin: https://v2.mad-lawsuit.org/admin/login (Working ✓)
  • v2 Database: 63 entries, 63 documents, 27 subscribers ✓
  • v2 All Features: Fully operational ✓
  • v2 PDF Upload: Working perfectly ✓
  • v2 Unsubscribe: Confirmation page working ✓
  • v2 Date Format: Consistent American format ✓
  • v2 Pagination: Removed from docket entries ✓

Current Status

What's Working

  • v1.0 Production: Fully operational at https://mad-lawsuit.org
  • v2.0 Production: FULLY OPERATIONAL at https://v2.mad-lawsuit.org
  • v2.0 Admin: Login working, all CRUD operations functional
  • v2.0 Database: All data migrated and verified
  • v2.0 Design: Matches v1 exactly (colors, layout, functionality)
  • v2.0 PDF Upload: Working perfectly with proper permissions
  • v2.0 Unsubscribe: Two-step confirmation page prevents accidental unsubscribes
  • v2.0 Date Format: Consistent American format (MM/DD/YYYY) across all pages
  • v2.0 Docket Entries: All entries on one page (no pagination)
  • SSL Certificates: Active on all domains
  • File Storage: PDFs uploading and downloading correctly
  • Authentication: Admin login persists across rebuilds

Ready for DNS Switchover 🎉

The v2.0 website is production-ready and can replace v1.0 at any time:

  • All features working
  • All data migrated
  • Visual design matches exactly
  • Admin dashboard fully functional
  • PDF upload working
  • Unsubscribe confirmation page active
  • Date formats consistent
  • Simplified admin interface (no pagination)
  • SSL certificates active
  • Performance tested

Next Steps for User

Optional - DNS Switchover:

  1. Update DNS: Point mad-lawsuit.org to v2.mad-lawsuit.org
  2. Monitor for 24-48 hours
  3. Decommission v1 containers once stable
  4. Consider future enhancements (email notifications, monitoring, etc.)

Files Modified (Latest Session - December 18, 2025)

PDF Upload Fix:

  • Dockerfile - Added chmod 755 /var/lib/nginx for proper permissions

Unsubscribe Feature:

  • resources/js/Pages/Unsubscribe.vue - Created confirmation page
  • app/Http/Controllers/SubscriptionController.php - Added showUnsubscribe() method
  • routes/web.php - Added GET route for confirmation page
  • resources/views/emails/new-docket-entry.blade.php - Updated unsubscribe link

Date Format Fix:

  • resources/js/Pages/Admin/Subscribers/Index.vue - American date format

Pagination Removal:

  • app/Http/Controllers/Admin/DocketEntryController.php - Changed to get() from paginate()
  • resources/js/Pages/Admin/DocketEntries/Index.vue - Removed pagination UI

Deployment Notes

  • Phase 4.1 Complete: All post-deployment enhancements operational
  • DNS Ready: v2.mad-lawsuit.org fully functional with all improvements
  • SSL Active: Let's Encrypt certificates auto-renewed
  • Data Verified: 100% migration success
  • Design Verified: Exact match to v1
  • Latest Commit: b48b51ab (December 18, 2025)

Investigation Process

  1. Phase 1: Built public website matching v1.0 design
  2. Phase 2: Implemented complete admin dashboard with CRUD
  3. Phase 3: Exported production data and transferred PDF files, created seeders, imported all data
  4. Phase 4: Deployed to production, fixed all issues, verified functionality
  5. Phase 4.1: Post-deployment enhancements (PDF upload, unsubscribe, dates, pagination)

The MAD lawsuit website v2.0 rebuild is 100% COMPLETE with all enhancements and ready for production use! 🎉