- Changed from standalone script to proper migration with exports.up/down
- Removed process.exit() calls that were terminating the migration runner
- Removed immediate execution of runMigrations()
- Now properly exports migration functions like other migrations
This was the root cause - 001_init.js was executing immediately when
required and calling process.exit(), preventing it from being run as
a migration and causing 029 to run first on an empty database.
- Changed from string sort to numeric sort for migration files
- String sort was causing '029' to run before '001'
- Now properly extracts and compares numeric prefixes
- Applied fix to both run-migrations.js and run-migrations-safe.js
This ensures 001_init.js runs first and creates all necessary tables
before other migrations try to use them.
- Check for essential tables (events, photos, admin_users, activity_logs)
to determine if it's truly a new deployment
- Only run detectExistingSchema() for actual existing deployments
- Remove obsolete init.js references (now 001_init.js)
- Fix migration filters to handle renamed init file
The issue was that detectExistingSchema() was marking migrations as
applied from previous failed runs, causing the system to incorrectly
treat new deployments as existing ones and run legacy migrations that
expect tables to already exist.
- Renamed core/init.js to core/001_init.js to ensure it runs first
- Updated detectExistingSchema() to reference 001_init.js
- This fixes the issue where backup migrations tried to access
app_settings table before it was created
- Migrations now run in correct order: init first, then numbered
The error occurred because alphabetical sorting put 029 before init,
causing migrations to fail on new deployments.
- Updated all core migrations to use ../../src/ instead of ../src/
- Updated legacy migrations with the same path fix
- This fixes MODULE_NOT_FOUND errors during deployment
The error occurred because migrations were moved one level deeper
into core/ and legacy/ subdirectories without updating the relative
paths to the source files.
- Created core/ directory for essential migrations that always run
- Created legacy/ directory for migrations only needed when upgrading
- New deployments will only run core migrations for a clean database
- Existing deployments will run all migrations in proper sequence
- Fixed duplicate migration numbers (014 and 027)
- Updated migration runners to handle new directory structure
- Added README explaining the migration organization
This change optimizes deployment for new users who will get a clean
schema without running unnecessary upgrade migrations.
- Create docker-compose.dev.yml with Mailhog for development email testing
- Standardize all configurations to use PORT=3001 for backend
- Fix database service naming (postgres → db) across all files
- Add missing BACKEND_URL environment variable to all configs
- Update .env examples to match actual Docker setup requirements
- Remove orphaned postgres-init directory (Umami handles its own DB)
- Update README roadmap: mark gallery feedback as implemented, add multi-admin support
- Update deployment guide with development setup instructions
- Fix frontend Dockerfile.dev for proper hot-reload development
- Remove unused files (wedding-photos.db, frontend/README.md)
This ensures all configuration files are consistent and aligned with the deployment guide.
- Hide "Manage Feedback" button when feedback is disabled for an event
- Fix 500 error on feedback API endpoint by adding null-safe operators
- Fix TypeError on analytics page by calculating average_rating in backend
- Fix password validation for event creation by properly awaiting async validation
- Add proper null checks and fallbacks for feedback statistics
These fixes ensure:
- Date passwords like "19.07.2025" work with simple password complexity settings
- Feedback management page loads without errors
- Analytics display correctly even with no feedback data
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Users were being redirected from gallery pages to admin login due to
useLocalizedDate hook trying to fetch admin settings. Fixed by:
1. Added general_date_format to public settings endpoint
2. Created publicSettingsService for unauthenticated access
3. Updated useLocalizedDate to use public settings instead of admin
4. Fixed API interceptor to not redirect on public endpoint 401s
5. Added backups/ and test-archiver/ to .gitignore
This restores gallery access for all users.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Production failing because email_templates table has different columns.
Fixed column names:
- name → template_key
- subject → subject_en, subject_de
- body → body_html_en, body_html_de, body_text_en, body_text_de
- Added missing 'variables' field
- Removed language and is_active fields (not in schema)
Also fixed the down() function to use template_key instead of name.
URGENT: Production is still down.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
The app_settings table doesn't have a description column.
Removed all description fields to prevent migration failures.
This completes the fix for all app_settings inserts across migrations.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Production failing with "column description does not exist" error.
The app_settings table only has: id, setting_key, setting_value, setting_type, updated_at
Removed all description fields from migration 032.
URGENT: Production is down - this is blocking the backend from starting.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
The app_settings table in production doesn't have created_at/updated_at columns.
Fixed inconsistent usage across migrations:
- Migration 014: removed updated_at: new Date()
- Migration 027: removed updated_at: knex.fn.now()
- Migration 033: removed updated_at: new Date()
This ensures all migrations are consistent and won't fail in production.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Production was failing because app_settings and email_templates
tables don't have created_at/updated_at columns. Removed these
fields from all insert statements to restore service.
This is a critical production fix - system was down.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Removed unnecessary import that could cause issues if helpers.js
doesn't define formatBoolean. Migration already uses correct
boolean syntax without the helper.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Migration was failing with "formatBoolean is not a function" error,
preventing backend startup. Fixed by:
- Removing formatBoolean import
- Using direct boolean values for column defaults
- Using JSON.stringify for setting values
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Update form-data from 4.0.3 to 4.0.4 (fixes CVE GHSA-fjxv-7rqg-78g4)
- Update multer from 2.0.1 to 2.0.2 (fixes CVE GHSA-fjgf-rc76-4x9p)
- Both backend and frontend now have 0 vulnerabilities
- Tested upload functionality - all working correctly
These are patch updates with no breaking changes. The updates address:
- form-data: Critical vulnerability - unsafe random function for boundary
- multer: High vulnerability - DoS via unhandled exception
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
- Add S3/MinIO storage adapter with multipart upload support
- Implement database backup service for SQLite and PostgreSQL
- Create backup manifest generator for tracking backup contents
- Enhance backup service with S3 integration and incremental backups
- Add restore service with safety measures and rollback capability
- Create comprehensive test suite for all backup functionality
- Add admin API endpoints for backup/restore management
- Implement frontend UI with dashboard, configuration, and restore wizard
- Add roadmap section to README with implemented backup feature
This implementation provides:
- Multiple backup destinations (local, rsync, S3/MinIO)
- Intelligent change detection to minimize backup frequency
- Full database backups with compression
- Manifest-based restore with integrity validation
- Pre-restore safety backups with rollback
- Comprehensive error handling and monitoring
- User-friendly admin interface
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
- Fixed backend version endpoint by adding retry logic import
- Gallery login page improvements:
* Increased title size from text-xl to text-2xl (responsive scaling)
* Title now uses event's custom primary color (var(--color-primary))
* Removed event category badge from login page
- Fixed Umami analytics configuration check:
* Added proper enabled state tracking
* Warning now only shows when Umami is explicitly not configured
* Checks both admin settings and environment variables properly
These changes improve user experience and fix false warnings in production.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Disabled duplicate email service (emailService.js) that was creating redundant connections
- Increased connection pool size from 10 to 25 for production environment
- Extended session timeout cache from 5 to 30 minutes to reduce DB queries
- Added connection retry logic with exponential backoff for transient failures
- Fixed password validation to use retry wrapper and correct setting key
- Updated public settings and gallery middleware to handle connection failures gracefully
These changes address the "Connection terminated unexpectedly" errors in production by:
1. Reducing unnecessary database connections
2. Increasing available connection pool capacity
3. Implementing automatic retry for transient connection failures
4. Caching frequently accessed data for longer periods
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Password Complexity: Added 4-level complexity selector (Simple/Moderate/Strong/Very Strong) in admin security settings with dynamic backend validation
- Gallery Security: Removed event date from login page (security risk), replaced with event type badge
- Analytics Config: Fixed "Not Configured" detection logic to check both admin settings and env variables
- Analytics Accuracy: Aligned calculation logic between dashboard and analytics endpoints, added totals verification
- Translations: Added missing activity keys (analytics_settings_updated, cms_page_updated, security_settings_updated, password_reset, admin_logout, system_activity)
- UI Fixes: Fixed German text overflow in CMS page selector with proper CSS truncation
- Date Format: Event creation now respects admin-configured date format instead of browser locale
- Chrome Compatibility: Replaced emoji flags with SVG components for Windows Chrome support
All changes maintain backward compatibility and production stability.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Update publicSettings.js to handle missing analytics setting_type gracefully
- Add dedicated PUT /analytics endpoint for saving analytics settings
- Update frontend settings service to route to correct endpoints based on setting type
- Fix query to use WHERE clause that won't fail if analytics type doesn't exist
This fixes the "Connection terminated unexpectedly" error when fetching
public settings with analytics configuration.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Fix backend analytics to include both 'download' and 'download_all' actions
- Add Analytics tab to Settings page for Umami configuration
- Update public settings endpoint to expose Umami config when enabled
- Implement dynamic Umami initialization from backend settings
- Fix frontend analytics calculations (remove hardcoded estimations)
- Add proper download counts and unique visitor tracking
- Update CLAUDE.md with production safety guidelines
The analytics dashboard now shows accurate data for all metrics, and Umami
can be configured through the admin panel instead of environment variables.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Original: feat: enhance security logging and ensure rate limit blocks are properly tracked
- Add comprehensive logging for rate limit blocks with full request details
- IP address (with proper proxy detection), user agent, headers, timestamps
- Rate limit info (current count, limit, remaining, reset time)
- Separate tracking for auth vs general endpoints
- Enhance authentication failure logging
- JWT validation failures with detailed error info
- Admin auth attempts without token
- Failed token validation with user context
- All events include IP, path, method, user agent
- Improve Winston logger configuration for production
- Add automatic log rotation (10MB errors, 50MB combined)
- Create separate security.log for auth/rate limit events
- Ensure logs directory exists automatically
- Add structured JSON format for log aggregation
- Support container logging with LOG_TO_CONSOLE env var
- Create comprehensive documentation
- Security logging guide with examples
- Monitoring recommendations
- Configuration reference
- Add test script to verify logging functionality
All rate limit settings remain configurable via admin panel:
- Window duration, max requests, auth limits
- Skip authenticated requests option
- Public endpoints only option
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>