Fix mobile/tablet PDF viewer - enable viewing in all orientations with scrolling

This commit is contained in:
TheMaddax 2025-12-18 08:32:59 -07:00
parent 7b409eba81
commit 73b0e7ae9e
4 changed files with 502 additions and 242 deletions

141
Caddyfile.remote Normal file
View file

@ -0,0 +1,141 @@
{
admin 0.0.0.0:2019
email chris@sigd.net
}
# Internal Services
gitea.sigd.net {
reverse_proxy 10.4.0.156:3000
}
statistics.deafgain.org {
reverse_proxy matomo:80
}
archives.sigd.net {
reverse_proxy 10.4.0.159:8001
}
upload.sigd.net {
handle /api/* {
uri strip_prefix /api
reverse_proxy 10.4.0.159:3334
}
handle {
reverse_proxy 10.4.0.159:4174
}
}
preview.sigd.net {
reverse_proxy 10.4.0.83:3000
}
droppy.sigd.net {
reverse_proxy 10.4.0.159:6969
}
requests.sigd.net {
reverse_proxy 10.4.0.157:5055
}
documents.deafgain.org {
reverse_proxy 10.4.0.156:8001
}
documents.sigd.net {
reverse_proxy 10.4.0.159:8001
}
doculens.deafgain.org {
reverse_proxy 10.4.0.156:5015
}
firewall.sigd.net {
reverse_proxy 10.4.0.1:9080
}
# Public Websites (on this VM - 10.4.0.205)
# Deaf Summit Website
deafsummit.org {
# Route API requests to backend
handle /api/* {
reverse_proxy localhost:808
}
# Route everything else to frontend
handle {
reverse_proxy localhost:807
}
}
www.deafsummit.org {
redir https://deafsummit.org{uri} permanent
}
# DeafMissoula.org
www.deafmissoula.org {
redir https://deafmissoula.org{uri} permanent
}
deafmissoula.org {
reverse_proxy 172.18.0.7:801
}
# ChrisHaulmark.com
www.chrishaulmark.com {
redir https://chrishaulmark.com{uri} permanent
}
chrishaulmark.com {
reverse_proxy chrishaulmark-website-web-1:803
}
# DeafGain.org
www.deafgain.org {
redir https://deafgain.org{uri} permanent
}
deafgain.org {
reverse_proxy 172.18.0.4:804
}
# FinLion domains
finlion.com {
reverse_proxy 172.18.0.8:805
}
www.finlion.com {
redir https://finlion.com{uri} permanent
}
finlion.net, www.finlion.net {
redir https://finlion.com{uri} permanent
}
finlion.org, www.finlion.org {
redir https://finlion.com{uri} permanent
}
# MAD Lawsuit
www.mad-lawsuit.org {
redir https://mad-lawsuit.org{uri} permanent
}
mad-lawsuit.org {
reverse_proxy 172.18.0.6:806
}
files.mad-lawsuit.org {
reverse_proxy 172.18.0.5:901
}
# MAD Lawsuit V2 (Preview)
v2.mad-lawsuit.org {
reverse_proxy localhost:8080
}
www.v2.mad-lawsuit.org {
redir https://v2.mad-lawsuit.org{uri} permanent
}

View file

@ -1,55 +1,67 @@
# Active Context - Current Work Status # Active Context - Current Work Status
## Current Task: v2.0 PHASE 3 DATA MIGRATION - 100% COMPLETE ✅ ## Current Task: v2.0 PRODUCTION DEPLOYMENT - COMPLETE ✅
**MAD Lawsuit Website v2.0 - Data Migration from v1.0 Production**: **MAD Lawsuit Website v2.0 - Fully Operational at https://v2.mad-lawsuit.org**:
- **v1.0 Status**: Fully operational at https://mad-lawsuit.org (Next.js + Express + React) - **v1.0 Status**: Fully operational at https://mad-lawsuit.org (Next.js + Express + React)
- **v2.0 Goal**: Rebuild with Laravel + Inertia + Vue + TypeScript - **v2.0 Status**: **FULLY OPERATIONAL** at https://v2.mad-lawsuit.org (Laravel + Inertia + Vue)
- **Current Phase**: Phase 3 - Data Migration (100% complete) - **Current Phase**: Phase 4 - Production Deployment **COMPLETE**
- **Status**: ALL DATA MIGRATED SUCCESSFULLY - Ready for Phase 4 ✅ - **Status**: All systems operational, ready for DNS switchover 🎉
### Phase 3 Complete - Data Migration ### Phase 4 Deployment - COMPLETE
**All Steps Completed:** **All Steps Successfully Completed:**
1. **PostgreSQL Data Export** 1. **Docker Container Deployment**
- Exported via `pg_dump` from production server (10.4.0.205) - Fixed PHP-FPM issue: Changed `php-fpm8.3``php-fpm` in supervisord.conf
- File: `/tmp/v1-data.sql` (local machine) - Rebuilt container on production server (10.4.0.205)
- Contains: 63 docket entries, 63 documents, 28 subscriptions - Both nginx and PHP-FPM running successfully
- Container: `mad-lawsuit-v2` on port 8080
2. **PDF Files Transfer** 2. **Caddy Reverse Proxy Configuration**
- Copied via SCP from production: `/docker/websites/mad-lawsuit/uploads/*.pdf` - Added v2.mad-lawsuit.org to centralized Caddyfile
- Destination: `storage/app/public/documents/` - Configuration: `v2.mad-lawsuit.org``localhost:8080`
- Total: 69 PDF files (158MB transferred successfully) - Added www redirect: `www.v2.mad-lawsuit.org``v2.mad-lawsuit.org`
- Caddy reloaded successfully
- SSL certificate auto-provisioned by Let's Encrypt
3. **Parser Development** 3. **Environment Configuration** ✅
- Created `parse_sql_to_seeder.py` (v1) - captured 32/63 entries - Created .env file with PostgreSQL settings
- Identified limitation: only parsed single-line INSERT statements - Generated APP_KEY successfully
- Created `parse_sql_to_seeder_v2.py` - handles multi-line INSERTs - Vite build assets present (manifest.json exists)
- Successfully parsed ALL 63 entries from SQL dump - Added ASSET_URL for HTTPS asset loading
4. **Seeder Automation** ✅ 4. **Critical Fixes Applied** ✅
- Created `update_seeder.py` (v1) - for initial 32 entries - **AdminUser Password Issue**: Removed password mutator that was double-hashing
- Created `update_seeder_v2.py` - for complete 63 entries - **AdminSeeder Fix**: Updated to use correct bcrypt hash format (`$2y$`)
- Automatically updates V1DataMigrationSeeder.php - **Mixed Content Fix**: Added TrustProxies middleware to detect HTTPS from Caddy
- Fixes file paths: `/app/uploads/``documents/` - **Background Colors**: Matched v1 exactly (#6E6362 and rgba(57,64,83,0.95))
5. **Data Import Execution** ✅ 5. **Database Setup** ✅
- Cleared database: `php artisan migrate:fresh --seed --seeder=AdminSeeder` - Ran migrations successfully on production PostgreSQL
- Ran seeder: `php artisan db:seed --class=V1DataMigrationSeeder` - Seeded database with all v1 data (63 entries, 63 documents, 28 subscribers)
- Result: 63 entries, 63 documents, 28 subscriptions imported - All relationships intact and verified
6. **Data Integrity Verification** ✅ 6. **Admin Authentication** ✅
- Database counts: 63/63/28 ✅ - **URL**: https://v2.mad-lawsuit.org/admin/login
- Sample entries verified (IDs 1-76) - **Username**: eliza
- All dates and titles accurate - **Password**: AXEoZWk2AMAD0naw
- Relationships intact (entries → documents) - **Status**: Login working perfectly, password persists across rebuilds
- File paths corrected for v2.0 - **Dashboard**: Showing 63 entries, 63 documents, 27 subscribers
**Files Created:** 7. **Visual Design Match**
- `parse_sql_to_seeder_v2.py` - Multi-line INSERT parser - Extracted exact colors from v1 React container
- `update_seeder_v2.py` - Seeder automation script - Updated v2 to match v1 precisely
- `seeder_data_full.txt` - Complete parsed data (63 entries) - Background colors: #6E6362 (main), rgba(57,64,83,0.95) (header/footer)
- `DATA_COMPARISON_REPORT.md` - Detailed migration analysis - Eliza won't notice any visual differences
- `check_v1_data.js` - v1.0 data verification script
### Production URLs
- **v1.0 (Current)**: https://mad-lawsuit.org
- **v2.0 (Ready)**: https://v2.mad-lawsuit.org
- **v2.0 Admin**: https://v2.mad-lawsuit.org/admin/login
### Admin Credentials
- **Username**: eliza
- **Password**: AXEoZWk2AMAD0naw
- **Access**: Full CRUD operations on docket entries, documents, and subscribers
### v2.0 Phase 2 COMPLETED ✅ ### v2.0 Phase 2 COMPLETED ✅
**Admin Dashboard - Fully Functional**: **Admin Dashboard - Fully Functional**:
@ -85,16 +97,11 @@
- ✅ Success/error flash messages - ✅ Success/error flash messages
- ✅ Responsive design - ✅ Responsive design
**Admin Access**:
- URL: http://127.0.0.1:8000/admin/login
- Username: admin
- Password: password
### v2.0 Technology Stack ### v2.0 Technology Stack
**Backend**: **Backend**:
- **Framework**: Laravel 12.43.1 (latest stable) - **Framework**: Laravel 12.43.1 (latest stable)
- **PHP**: 8.3.28 - **PHP**: 8.3.28
- **Database**: SQLite (development), PostgreSQL (production) - **Database**: PostgreSQL 16-alpine (production)
- **ORM**: Eloquent (replacing Prisma) - **ORM**: Eloquent (replacing Prisma)
- **Auth**: Laravel Sanctum + Session - **Auth**: Laravel Sanctum + Session
- **API**: Inertia.js server-side - **API**: Inertia.js server-side
@ -106,12 +113,13 @@
- **Build Tool**: Vite 7.x - **Build Tool**: Vite 7.x
- **Components**: Vue SFC (Single File Components) - **Components**: Vue SFC (Single File Components)
**Development Environment**: **Production Environment**:
- **PHP**: Installed via Homebrew (8.3.28) - **Server**: 10.4.0.205 (dedicated server behind NAT)
- **Composer**: 2.9.2 - **Docker**: Alpine Linux containers
- **Node**: Latest stable - **Web Server**: nginx 1.28.0
- **NPM**: With legacy-peer-deps for Vite compatibility - **PHP**: PHP-FPM 8.3.28
- **Servers**: Laravel (8000), Vite (5173) - **Database**: PostgreSQL 16-alpine
- **Reverse Proxy**: Caddy (with auto-SSL)
### v2.0 Progress Checklist ### v2.0 Progress Checklist
**Phase 1 - Public Website** ✅ COMPLETE: **Phase 1 - Public Website** ✅ COMPLETE:
@ -158,12 +166,30 @@
- [x] Run seeder to import ALL data - [x] Run seeder to import ALL data
- [x] Verify 100% data integrity in database (63/63/28) - [x] Verify 100% data integrity in database (63/63/28)
**Phase 4 - Production Deployment** ⏳ PENDING: **Phase 4 - Production Deployment** ✅ COMPLETE (100%):
- [ ] Configure PostgreSQL connection (for production) - [x] Create Dockerfile and docker-compose.yml
- [ ] Implement email notifications - [x] Build Docker image with PHP-FPM + nginx
- [ ] Deploy to v2.mad-lawsuit.org for testing - [x] Fix PHP-FPM command issue (php-fpm8.3 → php-fpm)
- [ ] Final testing and verification - [x] Deploy container to production server
- [ ] Switch DNS to v2.0 - [x] Configure Caddy reverse proxy
- [x] Create production .env file
- [x] Generate APP_KEY
- [x] Fix AdminUser password double-hashing issue
- [x] Update AdminSeeder with correct bcrypt hash
- [x] Add TrustProxies middleware for HTTPS detection
- [x] Match v1 background colors exactly
- [x] Run migrations on production database
- [x] Seed production database with v1 data
- [x] Verify SSL certificate provisioning
- [x] Test admin login (working perfectly)
- [x] Test all functionality (all working)
- [x] Visual design matches v1 exactly
**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 ### v2.0 Design Specifications
**Complete v1.0 documentation captured**: **Complete v1.0 documentation captured**:
@ -173,22 +199,23 @@
- ✅ Data structures (63 entries, 63 PDFs, 28 subscribers) - ✅ Data structures (63 entries, 63 PDFs, 28 subscribers)
- ✅ Admin dashboard specs (complete CRUD operations) - ✅ Admin dashboard specs (complete CRUD operations)
- ✅ Production data verified from live database - ✅ Production data verified from live database
- ✅ Exact color matching from v1 container
**Reference Document**: `cline_docs/v1_design_specifications.md` (400+ lines) **Reference Document**: `cline_docs/v1_design_specifications.md` (400+ lines)
### Next Immediate Steps ### Next Steps (Optional Enhancements)
**Phase 3 Complete! Ready for Phase 4:** **Future Improvements**:
1. **Configure PostgreSQL** - Set up production database connection 1. **Email Notifications** - Configure SMTP for subscriber notifications
2. **Implement Email Notifications** - SMTP configuration for subscriber alerts 2. **Monitoring** - Set up application monitoring and alerts
3. **Deploy to v2.mad-lawsuit.org** - Test subdomain deployment 3. **Backups** - Automated database and file backups
4. **Final Testing** - Comprehensive verification of all features 4. **Performance** - Redis caching for improved speed
5. **Switch DNS** - Point mad-lawsuit.org to v2.0 5. **Analytics** - Track visitor statistics
### Data Migration Details ### Data Migration Details
**v1.0 Production Data**: **v1.0 Production Data**:
- **Docket Entries**: 63 entries with dates, titles, summaries - **Docket Entries**: 63 entries with dates, titles, summaries
- **Documents**: 63 PDF files (UUID filenames) - **Documents**: 63 PDF files (UUID filenames)
- **Subscriptions**: 28 email subscribers - **Subscriptions**: 28 email subscribers (27 active)
- **Total Size**: 158MB of PDF files - **Total Size**: 158MB of PDF files
**Schema Mapping** (v1.0 → v2.0): **Schema Mapping** (v1.0 → v2.0):
@ -241,7 +268,7 @@
4. **SSL Certificates** ✅ COMPLETED 4. **SSL Certificates** ✅ COMPLETED
- **Provider**: Let's Encrypt via Caddy - **Provider**: Let's Encrypt via Caddy
- **Domains**: mad-lawsuit.org, files.mad-lawsuit.org - **Domains**: mad-lawsuit.org, files.mad-lawsuit.org, v2.mad-lawsuit.org
- **Status**: Active and auto-renewing - **Status**: Active and auto-renewing
### Final Production Architecture ### Final Production Architecture
@ -249,8 +276,9 @@
┌─────────────────────────────────────────────────────────┐ ┌─────────────────────────────────────────────────────────┐
│ Caddy Reverse Proxy (10.4.0.205) │ │ Caddy Reverse Proxy (10.4.0.205) │
│ │ │ │
│ mad-lawsuit.org → 172.18.0.6:806 (Frontend) │ │ mad-lawsuit.org → 172.18.0.6:806 (Frontend v1) │
│ files.mad-lawsuit.org → 172.18.0.5:901 (Backend) │ │ files.mad-lawsuit.org → 172.18.0.5:901 (Backend v1) │
│ v2.mad-lawsuit.org → localhost:8080 (v2 LIVE) │
└─────────────────────────────────────────────────────────┘ └─────────────────────────────────────────────────────────┘
├─────────────────────────────┐ ├─────────────────────────────┐
@ -275,94 +303,100 @@
- **Hostname**: public-websites (internal: 10.4.0.205) - **Hostname**: public-websites (internal: 10.4.0.205)
- **External Access**: Via NAT through dedicated server - **External Access**: Via NAT through dedicated server
- **SSH Access**: `ssh chaulmark@10.4.0.205` - **SSH Access**: `ssh chaulmark@10.4.0.205`
- **Project Location**: `~/websites/mad-lawsuit.org/` - **v1 Project**: `~/websites/mad-lawsuit.org/`
- **v2 Project**: `~/websites/v2.mad-lawsuit.org/`
- **Docker Volumes**: `/docker/websites/mad-lawsuit/` - **Docker Volumes**: `/docker/websites/mad-lawsuit/`
**Deployment Commands**: **v2 Deployment Commands**:
```bash ```bash
# SSH to production server # SSH to production server
ssh chaulmark@10.4.0.205 ssh chaulmark@10.4.0.205
# Navigate to project # Navigate to v2 project
cd ~/websites/mad-lawsuit.org cd ~/websites/v2.mad-lawsuit.org
# Pull latest code # Pull latest code
git pull git pull origin main
# Rebuild and restart containers # Rebuild and restart containers
docker compose down docker compose down
docker compose build docker compose up -d --build
docker compose up -d
# Check container status # Check container status
docker compose ps docker compose ps
docker compose logs -f 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 ✅ ### Verification ✅
- **Website**: https://mad-lawsuit.org (HTTP/2 200 ✓) - **v1 Website**: https://mad-lawsuit.org (HTTP/2 200 ✓)
- **Backend API**: https://files.mad-lawsuit.org (HTTP/2 200 ✓) - **v1 Backend API**: https://files.mad-lawsuit.org (HTTP/2 200 ✓)
- **Database**: 63 docket entries with all historical data ✓ - **v1 Database**: 63 docket entries with all historical data ✓
- **PDF Files**: 69 court documents accessible ✓ - **v1 PDF Files**: 69 court documents accessible ✓
- **All Containers**: Running and healthy ✓ - **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 ✓
## Current Status ## Current Status
### What's Working ✅ ### What's Working ✅
- **v2.0 Phase 1**: Public website fully functional - **v1.0 Production**: Fully operational at https://mad-lawsuit.org
- **v2.0 Phase 2**: Admin dashboard complete with all CRUD operations - **v2.0 Production**: **FULLY OPERATIONAL** at https://v2.mad-lawsuit.org
- **v2.0 Phase 3**: 100% data migration complete (63/63/28) - **v2.0 Admin**: Login working, all CRUD operations functional
- **Development Servers**: Laravel (8000) and Vite (5173) running - **v2.0 Database**: All data migrated and verified
- **Admin Authentication**: Login working with session management - **v2.0 Design**: Matches v1 exactly (colors, layout, functionality)
- **SSL Certificates**: Active on all domains
- **File Storage**: PDFs uploading and downloading correctly - **File Storage**: PDFs uploading and downloading correctly
- **Database**: SQLite with complete production data, ready for PostgreSQL migration - **Authentication**: Admin login persists across rebuilds
- **All 63 Entries**: Imported and verified in database
- **All 63 Documents**: Linked correctly with proper file paths ### Ready for DNS Switchover 🎉
- **All 28 Subscriptions**: Active and ready for notifications 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
- SSL certificates active
- Performance tested
### Next Steps for User ### Next Steps for User
**Phase 4 - Production Deployment (On Hold)**: **Optional - DNS Switchover**:
1. **Configure PostgreSQL** - Set up production database connection 1. Update DNS: Point mad-lawsuit.org to v2.mad-lawsuit.org
2. **Implement Email Notifications** - SMTP configuration 2. Monitor for 24-48 hours
3. **Deploy to v2.mad-lawsuit.org** - Test subdomain 3. Decommission v1 containers once stable
4. **Final Testing** - Comprehensive verification 4. Consider future enhancements (email notifications, monitoring, etc.)
5. **DNS Switchover** - Point mad-lawsuit.org to v2.0
### Files Modified (Phase 2 & 3) ### Files Modified (Final Phase)
**Controllers**: **Critical Fixes**:
- `app/Http/Controllers/Admin/AuthController.php` - `app/Models/AdminUser.php` - Removed password mutator
- `app/Http/Controllers/Admin/DashboardController.php` - `database/seeders/AdminSeeder.php` - Fixed bcrypt hash
- `app/Http/Controllers/Admin/DocketEntryController.php` - `app/Http/Middleware/TrustProxies.php` - Created for HTTPS detection
- `app/Http/Controllers/Admin/DocumentController.php` - `bootstrap/app.php` - Registered TrustProxies middleware
- `app/Http/Controllers/Admin/SubscriberController.php` - `resources/js/Pages/Home.vue` - Matched v1 background colors exactly
**Vue Pages**:
- `resources/js/Pages/Admin/Login.vue`
- `resources/js/Pages/Admin/Dashboard.vue`
- `resources/js/Pages/Admin/DocketEntries/Index.vue`
- `resources/js/Pages/Admin/DocketEntries/Create.vue`
- `resources/js/Pages/Admin/DocketEntries/Edit.vue`
- `resources/js/Pages/Admin/DocketEntries/Show.vue`
- `resources/js/Pages/Admin/Subscribers/Index.vue`
**Middleware & Routes**:
- `app/Http/Middleware/AdminAuth.php`
- `routes/web.php`
**Database**:
- `database/seeders/AdminSeeder.php`
- `database/migrations/2025_12_17_223224_create_admin_users_table.php`
### Deployment Notes ### Deployment Notes
- **Phase 2 Complete**: All admin features working locally - **Phase 4 Complete**: All systems operational
- **Phase 3 In Progress**: Data migration 50% complete - **DNS Ready**: v2.mad-lawsuit.org fully functional
- **Ready for Seeder**: SQL dump and PDFs ready for import - **SSL Active**: Let's Encrypt certificates auto-renewed
- All code committed to Git repository - **Data Verified**: 100% migration success
- **Design Verified**: Exact match to v1
- All code committed to Git repository (latest commit: 7b409eba)
## Investigation Process ## Investigation Process
1. **Phase 1**: Built public website matching v1.0 design 1. **Phase 1**: Built public website matching v1.0 design ✅
2. **Phase 2**: Implemented complete admin dashboard with CRUD 2. **Phase 2**: Implemented complete admin dashboard with CRUD ✅
3. **Phase 3**: Exported production data and transferred PDF files 3. **Phase 3**: Exported production data and transferred PDF files, created seeders, imported all data ✅
4. **Next**: Create seeder to import v1.0 data into v2.0 4. **Phase 4**: Deployed to production, fixed all issues, verified functionality ✅
The MAD lawsuit website v2.0 rebuild is progressing well with Phase 2 complete and Phase 3 50% done. The MAD lawsuit website v2.0 rebuild is **100% COMPLETE** and ready for production use! 🎉

View file

@ -3,7 +3,7 @@
## Project Overview ## Project Overview
**Goal**: Rebuild MAD lawsuit website from Next.js/Express/Prisma to Laravel/Vue/Inertia **Goal**: Rebuild MAD lawsuit website from Next.js/Express/Prisma to Laravel/Vue/Inertia
**v1.0**: https://mad-lawsuit.org (fully operational) **v1.0**: https://mad-lawsuit.org (fully operational)
**v2.0**: Local development → Production deployment **v2.0**: https://v2.mad-lawsuit.org (FULLY OPERATIONAL) ✅
## Phase Status ## Phase Status
@ -40,47 +40,73 @@
- ✅ Professional UI with Tailwind CSS - ✅ Professional UI with Tailwind CSS
**Admin Access**: **Admin Access**:
- URL: http://127.0.0.1:8000/admin/login - Production: https://v2.mad-lawsuit.org/admin/login
- Username: admin - Username: eliza
- Password: password - Password: AXEoZWk2AMAD0naw
### Phase 3: Data Migration ⏳ IN PROGRESS (95%) ### Phase 3: Data Migration ✅ COMPLETE (100%)
**Status**: Seeder created and tested, ready for final import **Status**: All production data successfully migrated
**Started**: December 17, 2025 **Completion Date**: December 17, 2025
**Completed**: **Completed**:
- ✅ PostgreSQL data export from production (63 entries, 63 docs, 28 subs) - ✅ PostgreSQL data export from production (63 entries, 63 docs, 28 subs)
- ✅ PDF files transferred via SCP (69 files, 158MB) - ✅ PDF files transferred via SCP (69 files, 158MB)
- ✅ Files in storage/app/public/documents/ - ✅ Files in storage/app/public/documents/
- ✅ SQL dump in /tmp/v1-data.sql - ✅ SQL dump in /tmp/v1-data.sql
- ✅ Created V1DataMigrationSeeder (tested with sample data) - ✅ Created V1DataMigrationSeeder
- ✅ Created Python parser script (parse_sql_to_seeder.py) - ✅ Created Python parser script v1 (parse_sql_to_seeder.py)
- ✅ Generated PHP arrays (32 entries, 63 docs, 28 subs in seeder_data.txt) - ✅ Created Python parser script v2 (parse_sql_to_seeder_v2.py) - handles multi-line INSERTs
- ✅ Created completion instructions (PHASE3_COMPLETION_INSTRUCTIONS.md) - ✅ Generated complete PHP arrays (63 entries, 63 docs, 28 subs)
- ✅ Updated seeder with all production data
- ✅ Ran seeder and imported all data
- ✅ Verified data integrity (63/63/28) ✅
**Remaining** (Next Session): ### Phase 4: Production Deployment ✅ COMPLETE (100%)
- ⏳ Update seeder with generated arrays (15 min) **Status**: Fully operational at https://v2.mad-lawsuit.org
- ⏳ Run seeder and import data (2 min) **Completion Date**: December 17, 2025
- ⏳ Verify data integrity in admin dashboard (5 min)
### Phase 4: Production Deployment ⏳ PENDING **Completed Tasks**:
**Status**: Not started - ✅ Created Dockerfile and docker-compose.yml
**Dependencies**: Phase 3 completion - ✅ Built Docker image with PHP-FPM + nginx
- ✅ Fixed PHP-FPM command issue (php-fpm8.3 → php-fpm)
- ✅ Deployed container to production server (10.4.0.205)
- ✅ Configured Caddy reverse proxy for v2.mad-lawsuit.org
- ✅ Created production .env file with PostgreSQL settings
- ✅ Generated APP_KEY
- ✅ Fixed AdminUser password double-hashing issue
- ✅ Updated AdminSeeder with correct bcrypt hash ($2y$)
- ✅ Added TrustProxies middleware for HTTPS detection
- ✅ Matched v1 background colors exactly (#6E6362, rgba(57,64,83,0.95))
- ✅ Ran migrations on production PostgreSQL database
- ✅ Seeded production database with all v1 data
- ✅ Verified SSL certificate provisioning (Let's Encrypt)
- ✅ Tested admin login (working perfectly)
- ✅ Tested all CRUD operations (all functional)
- ✅ Verified visual design matches v1 exactly
**Production URLs**:
- **Public Site**: https://v2.mad-lawsuit.org
- **Admin Dashboard**: https://v2.mad-lawsuit.org/admin/login
- **Status**: All systems operational ✅
### Phase 5: DNS Switchover ⏳ PENDING (User Decision)
**Status**: Ready when user decides to switch
**Dependencies**: User approval
**Planned Tasks**: **Planned Tasks**:
- [ ] Configure PostgreSQL connection for production - [ ] Update DNS: Point mad-lawsuit.org to v2.mad-lawsuit.org
- [ ] Implement email notifications (SMTP) - [ ] Monitor for 24-48 hours
- [ ] Deploy to v2.mad-lawsuit.org subdomain - [ ] Decommission v1 containers once stable
- [ ] Final testing and verification - [ ] Optional: Implement email notifications (SMTP)
- [ ] Switch DNS to v2.0 - [ ] Optional: Set up monitoring and alerts
- [ ] Decommission v1.0 - [ ] Optional: Configure automated backups
## Technical Stack ## Technical Stack
### Backend ### Backend
- **Framework**: Laravel 12.43.1 - **Framework**: Laravel 12.43.1
- **PHP**: 8.3.28 - **PHP**: 8.3.28
- **Database**: SQLite (dev), PostgreSQL (prod) - **Database**: PostgreSQL 16-alpine (production)
- **ORM**: Eloquent - **ORM**: Eloquent
- **Auth**: Laravel Sanctum + Session - **Auth**: Laravel Sanctum + Session
@ -90,41 +116,47 @@
- **Styling**: Tailwind CSS 3.x - **Styling**: Tailwind CSS 3.x
- **Build**: Vite 7.x - **Build**: Vite 7.x
### Development Environment ### Production Environment
- **PHP**: Homebrew installation - **Server**: 10.4.0.205 (dedicated server behind NAT)
- **Composer**: 2.9.2 - **Docker**: Alpine Linux containers
- **Node**: Latest stable - **Web Server**: nginx 1.28.0
- **Servers**: Laravel (8000), Vite (5173) - **PHP**: PHP-FPM 8.3.28
- **Database**: PostgreSQL 16-alpine
- **Reverse Proxy**: Caddy (with auto-SSL)
## Data Statistics ## Data Statistics
### v1.0 Production Data ### v1.0 Production Data
- **Docket Entries**: 63 entries - **Docket Entries**: 63 entries
- **Documents**: 63 PDF files (UUID filenames) - **Documents**: 63 PDF files (UUID filenames)
- **Subscriptions**: 28 email subscribers - **Subscriptions**: 28 email subscribers (27 active)
- **Total PDF Size**: 158MB - **Total PDF Size**: 158MB
- **Database Size**: 47MB (PostgreSQL) - **Database Size**: 47MB (PostgreSQL)
### v2.0 Current Data ### v2.0 Production Data (Migrated)
- **Docket Entries**: 5 (test data from DocketSeeder) - **Docket Entries**: 63 (100% migrated) ✅
- **Documents**: 5 (test PDFs) - **Documents**: 63 (100% migrated) ✅
- **Subscriptions**: 0 - **Subscriptions**: 28 (100% migrated) ✅
- **Admin Users**: 1 (admin/password) - **Admin Users**: 1 (eliza)
- **Status**: All data verified and operational ✅
## Key Milestones ## Key Milestones
### Completed ✅ ### Completed ✅
1. **December 17, 2025**: Phase 1 complete - Public website functional 1. **December 17, 2025 (5:00 PM)**: Phase 1 complete - Public website functional
2. **December 17, 2025**: Phase 2 complete - Admin dashboard with full CRUD 2. **December 17, 2025 (5:30 PM)**: Phase 2 complete - Admin dashboard with full CRUD
3. **December 17, 2025**: Phase 3 started - Data export and PDF transfer complete 3. **December 17, 2025 (6:00 PM)**: Phase 3 started - Data export and PDF transfer
4. **December 17, 2025 (7:00 PM)**: Phase 3 complete - All data migrated and verified
5. **December 17, 2025 (8:00 PM)**: Phase 4 started - Docker deployment
6. **December 17, 2025 (10:30 PM)**: Phase 4 complete - Production fully operational ✅
### Upcoming ⏳ ### Upcoming ⏳
4. **Next**: Complete Phase 3 - Create seeder and import production data 7. **Future**: Phase 5 - DNS switchover (when user decides)
5. **Future**: Phase 4 - Production deployment and DNS switch 8. **Optional**: Email notifications, monitoring, backups
## Files Created/Modified ## Files Created/Modified
### Controllers (7 files) ### Controllers (8 files)
- `app/Http/Controllers/HomeController.php` - `app/Http/Controllers/HomeController.php`
- `app/Http/Controllers/SubscriptionController.php` - `app/Http/Controllers/SubscriptionController.php`
- `app/Http/Controllers/DocumentController.php` - `app/Http/Controllers/DocumentController.php`
@ -156,13 +188,33 @@
- `database/migrations/2025_12_17_223201_create_subscriptions_table.php` - `database/migrations/2025_12_17_223201_create_subscriptions_table.php`
- `database/migrations/2025_12_17_223224_create_admin_users_table.php` - `database/migrations/2025_12_17_223224_create_admin_users_table.php`
### Seeders (2 files) ### Seeders (3 files)
- `database/seeders/DocketSeeder.php` (test data) - `database/seeders/DocketSeeder.php` (test data)
- `database/seeders/AdminSeeder.php` (admin user) - `database/seeders/AdminSeeder.php` (admin user)
- `database/seeders/V1DataMigrationSeeder.php` (production data)
### Middleware & Routes ### Middleware & Routes
- `app/Http/Middleware/AdminAuth.php` - `app/Http/Middleware/AdminAuth.php`
- `app/Http/Middleware/TrustProxies.php`
- `routes/web.php` - `routes/web.php`
- `bootstrap/app.php`
### Docker & Deployment
- `Dockerfile`
- `docker-compose.yml`
- `docker/nginx.conf`
- `docker/default.conf`
- `docker/supervisord.conf`
- `.env.production`
- `DEPLOYMENT.md`
### Data Migration Scripts
- `parse_sql_to_seeder.py` (v1 - single-line INSERTs)
- `parse_sql_to_seeder_v2.py` (v2 - multi-line INSERTs)
- `update_seeder.py` (v1)
- `update_seeder_v2.py` (v2)
- `check_v1_data.js` (verification script)
- `DATA_COMPARISON_REPORT.md`
## Testing Status ## Testing Status
@ -185,45 +237,51 @@
- [x] Deactivate subscriber - [x] Deactivate subscriber
- [x] Pagination works correctly - [x] Pagination works correctly
### Phase 3 Testing ⏳ ### Phase 3 Testing ✅
- [ ] Import all 63 docket entries - [x] Import all 63 docket entries
- [ ] Verify all 63 documents accessible - [x] Verify all 63 documents accessible
- [ ] Confirm 28 subscribers imported - [x] Confirm 28 subscribers imported
- [ ] Test entry-document relationships - [x] Test entry-document relationships
- [ ] Verify timestamps preserved - [x] Verify timestamps preserved
- [ ] Check data integrity - [x] Check data integrity
### Phase 4 Testing ✅
- [x] Docker container builds successfully
- [x] nginx and PHP-FPM running
- [x] Database connection working
- [x] Migrations run successfully
- [x] Seeder imports all data
- [x] SSL certificate provisioned
- [x] Admin login functional
- [x] All CRUD operations working
- [x] File uploads/downloads working
- [x] Visual design matches v1 exactly
## Known Issues ## Known Issues
### Current Issues ### Current Issues
- None - all implemented features working correctly - None - all features working correctly in production ✅
### Future Considerations ### Future Enhancements
- Email notification system needs SMTP configuration - Email notification system (SMTP configuration)
- PostgreSQL connection for production deployment - Application monitoring and alerts
- SSL certificates for v2.mad-lawsuit.org subdomain - Automated database backups
- Redis caching for performance
- Analytics tracking
## Next Actions ## Next Actions
### Immediate (Phase 3 Completion) ### Immediate (Optional)
1. Create `database/seeders/V1DataMigrationSeeder.php` 1. **DNS Switchover** - When user decides to replace v1 with v2
2. Parse SQL INSERT statements from `/tmp/v1-data.sql` 2. **Monitoring** - Set up application monitoring
3. Transform to Laravel Eloquent creates 3. **Backups** - Configure automated backups
4. Run seeder: `php artisan db:seed --class=V1DataMigrationSeeder` 4. **Email** - Implement SMTP for subscriber notifications
5. Verify in admin dashboard
### Short-term (Phase 4 Preparation) ### Long-term (Optional)
1. Configure PostgreSQL connection in `.env` 1. Performance optimization with Redis
2. Test database connection 2. Analytics integration
3. Implement email notification system 3. Enhanced admin features
4. Prepare deployment scripts 4. Mobile app considerations
### Long-term (Production Deployment)
1. Deploy to v2.mad-lawsuit.org
2. Final testing on production subdomain
3. Switch DNS from v1.0 to v2.0
4. Monitor for issues
5. Decommission v1.0 after verification
## Success Metrics ## Success Metrics
@ -238,24 +296,47 @@
- File upload/download working: **100%** - File upload/download working: **100%**
- UI/UX professional: **100%** - UI/UX professional: **100%**
### Phase 3 ### Phase 3
- Data export complete: **100%** - Data export complete: **100%**
- PDF transfer complete: **100%** - PDF transfer complete: **100%**
- Seeder creation: **100%** - Seeder creation: **100%**
- Python parser created: **100%** - Python parser created: **100%**
- PHP arrays generated: **100%** - PHP arrays generated: **100%**
- Data import: **0%** (next session) - Data import: **100%**
- Verification: **0%** (next session) - Verification: **100%**
- **Overall Phase 3**: **95%** - **Overall Phase 3**: **100%**
### Phase 4 ⏳ ### Phase 4 ✅
- Not started: **0%** - Docker deployment: **100%**
- Database setup: **100%**
- SSL certificates: **100%**
- Admin login: **100%**
- All features tested: **100%**
- Visual design match: **100%**
- **Overall Phase 4**: **100%**
## Overall Project Progress ## Overall Project Progress
**Phases Complete**: 2 / 4 (50%) **Phases Complete**: 4 / 5 (80%)
**Current Phase**: 3 (95% complete) **Current Phase**: 5 (Pending user decision for DNS switchover)
**Estimated Completion**: Phase 3 - 20 minutes (next session), Phase 4 - 2-4 hours **Status**: **PRODUCTION READY**
--- ---
*Last Updated: December 17, 2025 at 5:51 PM MST* ## 🎉 PROJECT COMPLETE 🎉
The MAD Lawsuit Website v2.0 is **fully operational** and ready for production use!
- **Public Site**: https://v2.mad-lawsuit.org
- **Admin Dashboard**: https://v2.mad-lawsuit.org/admin/login
- **All Data Migrated**: 63 entries, 63 documents, 28 subscribers
- **Visual Design**: Exact match to v1
- **All Features**: Working perfectly
- **SSL**: Active and auto-renewing
- **Performance**: Tested and verified
The website can replace v1.0 at any time with a simple DNS update.
---
*Last Updated: December 17, 2025 at 10:30 PM MST*
*Status: PRODUCTION READY ✅*

View file

@ -13,32 +13,29 @@ const emit = defineEmits<{
}>(); }>();
const isMobile = ref(false); const isMobile = ref(false);
const isPortrait = ref(false);
// Check if device is mobile/tablet // Check if device is mobile/tablet and orientation
const checkMobile = () => { const checkDevice = () => {
isMobile.value = window.innerWidth < 1024; // Less than 1024px = mobile/tablet isMobile.value = window.innerWidth < 1024; // Less than 1024px = mobile/tablet
isPortrait.value = window.innerHeight > window.innerWidth; // Portrait mode
}; };
onMounted(() => { onMounted(() => {
checkMobile(); checkDevice();
window.addEventListener('resize', checkMobile); window.addEventListener('resize', checkDevice);
window.addEventListener('orientationchange', checkDevice);
}); });
onUnmounted(() => { onUnmounted(() => {
window.removeEventListener('resize', checkMobile); window.removeEventListener('resize', checkDevice);
window.removeEventListener('orientationchange', checkDevice);
}); });
// Handle body scroll lock when modal is open // Handle body scroll lock when modal is open
watch(() => props.isOpen, (isOpen) => { watch(() => props.isOpen, (isOpen) => {
if (isOpen) { if (isOpen) {
document.body.style.overflow = 'hidden'; document.body.style.overflow = 'hidden';
// On mobile, open PDF directly in new tab
if (isMobile.value) {
window.open(props.documentUrl, '_blank');
// Close modal immediately on mobile
emit('close');
}
} else { } else {
document.body.style.overflow = 'unset'; document.body.style.overflow = 'unset';
} }
@ -56,41 +53,46 @@ const handleDownload = () => {
</script> </script>
<template> <template>
<!-- Only show modal on desktop (>= 1024px) -->
<div <div
v-if="isOpen && !isMobile" v-if="isOpen"
class="fixed inset-0 bg-black/75 flex items-center justify-center z-50 p-4" class="fixed inset-0 bg-black/75 flex items-center justify-center z-50"
:class="isMobile ? 'p-2' : 'p-4'"
@click="handleBackdropClick" @click="handleBackdropClick"
> >
<div <div
class="bg-white rounded-lg w-[95%] h-[95%] max-w-[1200px] max-h-[900px] flex flex-col shadow-2xl" class="bg-white rounded-lg flex flex-col shadow-2xl"
:class="isMobile ? 'w-full h-full' : 'w-[95%] h-[95%] max-w-[1200px] max-h-[900px]'"
@click.stop @click.stop
> >
<!-- Header --> <!-- Header -->
<div class="flex items-center justify-between px-6 py-4 border-b bg-[#394053] rounded-t-lg"> <div class="flex items-center justify-between border-b bg-[#394053] rounded-t-lg"
<div class="flex items-center gap-3"> :class="isMobile ? 'px-3 py-2' : 'px-6 py-4'">
<svg class="w-5 h-5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <div class="flex items-center gap-2 min-w-0 flex-1">
<svg class="w-5 h-5 text-white flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" /> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
</svg> </svg>
<h2 class="text-lg font-semibold text-white"> <h2 class="font-semibold text-white truncate"
:class="isMobile ? 'text-sm' : 'text-lg'">
{{ documentTitle }} {{ documentTitle }}
</h2> </h2>
</div> </div>
<div class="flex items-center gap-2"> <div class="flex items-center gap-1 flex-shrink-0">
<button <button
@click="handleDownload" @click="handleDownload"
class="flex items-center gap-2 px-4 py-2 bg-[#7CAE7A] text-white rounded-md hover:bg-[#6b9c69] transition-colors text-sm font-medium" class="flex items-center gap-1 bg-[#7CAE7A] text-white rounded-md hover:bg-[#6b9c69] transition-colors font-medium"
:class="isMobile ? 'px-2 py-1 text-xs' : 'px-4 py-2 text-sm gap-2'"
> >
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg class="w-4 h-4 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4" /> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4" />
</svg> </svg>
Download <span v-if="!isMobile || !isPortrait">Download</span>
</button> </button>
<button <button
@click="emit('close')" @click="emit('close')"
class="flex items-center justify-center w-10 h-10 text-white hover:bg-white/10 rounded-md transition-colors" class="flex items-center justify-center text-white hover:bg-white/10 rounded-md transition-colors"
:class="isMobile ? 'w-8 h-8' : 'w-10 h-10'"
> >
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" /> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
</svg> </svg>
</button> </button>
@ -98,11 +100,13 @@ const handleDownload = () => {
</div> </div>
<!-- PDF Content --> <!-- PDF Content -->
<div class="flex-1 p-4 bg-gray-50"> <div class="flex-1 bg-gray-50 overflow-hidden"
:class="isMobile ? 'p-1' : 'p-4'">
<iframe <iframe
:src="`${documentUrl}#view=FitH&toolbar=1&navpanes=1&scrollbar=1`" :src="`${documentUrl}#view=FitH&toolbar=1&navpanes=0&scrollbar=1`"
class="w-full h-full border-0 rounded-md bg-white" class="w-full h-full border-0 rounded-md bg-white"
:title="documentTitle" :title="documentTitle"
style="overflow: auto; -webkit-overflow-scrolling: touch;"
/> />
</div> </div>
</div> </div>