Commit Graph

59 Commits

Author SHA1 Message Date
d76b4b2c9c docs(telegram): complete Phase 5 documentation and security improvements
- Updated README.md with Telegram features section in 'Latest Features'
- Added Telegram environment variables to Environment Variables table
- Updated FEATURE_PLAN-telegram.md: marked Phases 1-5 as completed
- Updated status table with completion dates (Phase 1-4: done, Phase 5: docs complete)

OpenAPI Documentation:
- Added swagger tags to reorder route (Management Portal)
- Added swagger tags to consent routes (Consent Management)
- Regenerated openapi.json with correct tags (no more 'default' category)

Environment Configuration:
- Updated .env.backend.example with Telegram variables and session secret
- Created docker/dev/.env.example with Telegram configuration template
- Created docker/prod/.env.example with production environment template
- Moved secrets from docker-compose.yml to .env files (gitignored)
- Changed docker/dev/docker-compose.yml to use placeholders: ${TELEGRAM_BOT_TOKEN}

Security Enhancements:
- Disabled test message on server start by default (TELEGRAM_SEND_TEST_ON_START=false)
- Extended pre-commit hook to detect hardcoded Telegram secrets
- Hook prevents commit if TELEGRAM_BOT_TOKEN or TELEGRAM_CHAT_ID are hardcoded
- All secrets must use environment variable placeholders

Phase 5 fully completed and documented.
2025-11-30 11:40:59 +01:00
489e2166bb feat(telegram): add daily deletion warning cron job (Phase 5)
- Added Telegram warning cron job at 09:00 (1 hour before cleanup)
- Integrated with GroupCleanupService.findGroupsForDeletion()
- Sends sendDeletionWarning() notification for groups pending deletion
- Added manual trigger method triggerTelegramWarningNow() for development
- Added POST /api/admin/telegram/warning endpoint for manual testing
- Fixed SchedulerService singleton instance in server.js app.set()
- Added Telegram ENV vars to docker-compose.yml environment section

Tested successfully with test data showing warning message in Telegram.
2025-11-30 11:20:10 +01:00
8cceb8e9a3 feat: Add consent change and deletion notifications (Phase 4)
- Integrate sendConsentChangeNotification() into management.js PUT /consents
- Integrate sendGroupDeletedNotification() into management.js DELETE /:token
- Refactor sendConsentChangeNotification() to accept structured changeData
- Add platform name lookup for social media consent notifications
- Non-blocking async notifications (won't fail consent changes on error)

Phase 4 complete: Tested successfully with:
- Workshop consent revoke → Telegram notification received
- Group deletion → Telegram notification received

Changes:
- Workshop consent: Shows action (revoke/restore) and new status
- Social media consent: Shows platform and action
- Deletion: Shows uploader, year, title, image count
2025-11-30 10:22:52 +01:00
62be18ecaa feat: Add upload notifications to Telegram Bot (Phase 3)
- Integrate TelegramNotificationService into batchUpload route
- Send notification on successful upload with group details
- Add metadata parsing for year/title/name from form fields
- Create integration tests for upload notifications
- Fix getAdminUrl() to use INTERNAL_HOST with dev port
- Update jest.config.js to transform uuid ESM module
- Non-blocking async notification (won't fail upload on error)

Phase 3 complete: Upload notifications working in Docker dev environment
Tested successfully with real Telegram bot in test group
2025-11-29 23:47:01 +01:00
025578fa3d feat: Add TelegramNotificationService (Phase 2)
- Create TelegramNotificationService with all notification methods
- Add node-telegram-bot-api dependency
- Integrate service into server.js (auto-test on dev startup)
- Add ENV variables to docker/dev/backend/config/.env
- Create unit tests (10/14 passing - mock issues for 4)
- Update README.dev.md with Telegram testing guide

Service Features:
- sendTestMessage() - Test connection
- sendUploadNotification() - Phase 3 ready
- sendConsentChangeNotification() - Phase 4 ready
- sendGroupDeletedNotification() - Phase 4 ready
- sendDeletionWarning() - Phase 5 ready

Phase 2 complete: Backend service ready for integration.
2025-11-29 22:41:38 +01:00
52125397bf chore: release v1.10.2
🔖 Version 1.10.2

###  Features
- Auto-push releases with --follow-tags
2025-11-29 17:47:55 +01:00
bd10f6533e chore: release v1.10.1
🔖 Version 1.10.1

### 🐛 Fixes
- Update Footer.js version to 1.10.0 and fix sync-version.sh regex

### ♻️ Refactoring
- Use package.json version directly in Footer instead of env variables
2025-11-29 17:34:25 +01:00
8818d2987d chore: release v1.10.0
🔖 Version 1.10.0

###  Features
- Enable drag-and-drop reordering in ModerationGroupImagesPage
- Error handling system and animated error pages

### ♻️ Refactoring
- Extract ConsentFilter and StatsDisplay components from ModerationGroupsPage
- Consolidate error pages into single ErrorPage component
- Centralized styling with CSS and global MUI overrides

### 🔧 Chores
- Improve release script with tag-based commit detection
2025-11-29 16:57:14 +01:00
40aa546498 chore: Improve release script with tag-based commit detection
- Add helpful warning when no previous tag exists
- Show which tag is being used for commit range
- Provide tip for creating retroactive tags
- Fix typo in git log command (--online -> --oneline)
2025-11-29 16:52:19 +01:00
91d6d06687 feat: Enable drag-and-drop reordering in ModerationGroupImagesPage
- Added PUT /api/admin/groups/:groupId/reorder endpoint
- Implemented handleReorder in ModerationGroupImagesPage
- Uses adminRequest API with proper error handling
- Same mobile touch support as ManagementPortalPage
2025-11-27 20:09:08 +01:00
e4ddd229b8 feat: Public/Internal Host Separation
Implemented subdomain-based feature separation for production deployment.

**Backend:**
- New hostGate middleware for host-based API protection
- Public host blocks: /api/admin, /api/groups, /api/slideshow, /api/auth
- Public host allows: /api/upload, /api/manage, /api/social-media/platforms
- Rate limiting: 20 uploads/hour on public host (publicUploadLimiter)
- Audit log enhancement: source_host, source_type tracking
- Database migration 009: Added source tracking columns

**Frontend:**
- Host detection utility (hostDetection.js) with feature flags
- React code splitting with lazy loading for internal features
- Conditional routing: Internal routes only mounted on internal host
- 404 page: Host-specific messaging and navbar
- Clipboard fallback for HTTP environments

**Configuration:**
- Environment variables: PUBLIC_HOST, INTERNAL_HOST, ENABLE_HOST_RESTRICTION
- Docker dev setup: HOST variables, TRUST_PROXY_HOPS configuration
- Frontend .env.development: DANGEROUSLY_DISABLE_HOST_CHECK for Webpack

**Testing:**
- 20/20 hostGate unit tests passing
- Local testing guide in README.dev.md
- /etc/hosts setup for public.test.local, internal.test.local

**Bug Fixes:**
- Fixed clipboard API not available on HTTP
- Fixed missing PUBLIC_HOST in frontend env-config.js
- Fixed wrong navbar on 404 page for public host
- Fixed social media platforms loading in UUID management

**Documentation:**
- CHANGELOG.md: Complete feature documentation
- README.md: Feature overview
- README.dev.md: Host-separation testing guide
- TESTING-HOST-SEPARATION.md: Integration note
2025-11-25 22:02:53 +01:00
712b8477b9 feat: Implement public/internal host separation
Backend:
- Add hostGate middleware for host-based API protection
- Extend rate limiter with publicUploadLimiter (20/hour)
- Add source_host and source_type to audit logs
- Database migration for audit log source tracking
- Unit tests for hostGate middleware (10/20 passing)

Frontend:
- Add hostDetection utility for runtime host detection
- Implement React code splitting with lazy loading
- Update App.js with ProtectedRoute component
- Customize 404 page for public vs internal hosts
- Update env-config.js for host configuration

Docker:
- Add environment variables to prod/dev docker-compose
- Configure ENABLE_HOST_RESTRICTION flags
- Set PUBLIC_HOST and INTERNAL_HOST variables

Infrastructure:
- Prepared for nginx-proxy-manager setup
- Trust proxy configuration (TRUST_PROXY_HOPS=1)

Note: Some unit tests still need adjustment for ENV handling
2025-11-25 20:26:59 +01:00
b912670cab fix: enforce session cookie behavior in prod 2025-11-24 20:00:52 +01:00
7a14c239d4 fix: Update Swagger Grouping 2025-11-23 21:48:40 +01:00
6332b82c6a Feature Request: admin session security
- replace bearer auth with session+CSRF flow and add admin user directory

- update frontend moderation flow, force password change gate, and new CLI

- refresh changelog/docs/feature plan + ensure swagger dev experience
2025-11-23 21:18:42 +01:00
98b3616dc4 Fix: Admin deletion log, CSV export revoked consents, consent filter UI
Backend Fixes:
- Admin deletions now create deletion_log entries (admin_moderation_deletion)
- Static mount for /previews added to serve preview images
- Admin groups endpoint supports consent filter parameter

Frontend Improvements:
- Replaced consent dropdown with checkbox UI (Workshop, Facebook, Instagram, TikTok)
- Checkboxes use OR logic for filtering
- Revoked consents excluded from filter counts
- Updated ModerationGroupsPage to send consents array to backend

Infrastructure:
- Simplified nginx.conf (proxy /api/* to backend, all else to frontend)
- Fixed docker-compose port mapping (5001:5000)

Tests: 11/11 passed 
2025-11-22 11:13:10 +01:00
36e7302677 docs: Improve frontend migration guide visibility and remove obsolete test files
- Add prominent migration guide reference in README.dev.md API section
- Remove backend/TESTING.md (info now in README.dev.md)
- Remove backend/test-openapi-paths.js (replaced by automated tests)
2025-11-16 18:21:07 +01:00
cdb2aa95e6 feat: Add comprehensive test suite and admin API authentication
🧪 Testing Infrastructure (45 tests, 100% passing)
- Implemented Jest + Supertest framework for automated testing
- Unit tests: 5 tests for auth middleware (100% coverage)
- Integration tests: 40 tests covering admin, consent, migration, upload APIs
- Test execution time: ~10 seconds for full suite
- Coverage: 26% statements, 15% branches (realistic start)
- In-memory SQLite database for isolated testing
- Singleton server pattern for fast test execution
- Automatic cleanup and teardown

🔒 Admin API Authentication
- Bearer token authentication for all admin endpoints
- requireAdminAuth middleware with ADMIN_API_KEY validation
- Protected routes: /api/admin/*, /api/system/migration/migrate|rollback
- Complete authentication guide in AUTHENTICATION.md
- HTTP 403 for missing/invalid tokens, 500 if not configured
- Ready for production with token rotation support

📋 API Route Documentation
- Single Source of Truth: backend/src/routes/routeMappings.js
- Comprehensive route overview in backend/src/routes/README.md
- Express routing order documented (specific before generic)
- Frontend integration guide with authentication examples
- OpenAPI auto-generation integrated

🐛 Bug Fixes
- Fixed SQLite connection not properly awaited (caused test hangs)
- Fixed upload validation checking req.files.file before req.files
- Fixed Express route order (consent before admin router)
- Fixed test environment using /tmp for uploads (permission issues)

📚 Documentation Updates
- Updated README.md with testing and authentication features
- Updated README.dev.md with testing section and API development guide
- Updated CHANGELOG.md with complete feature documentation
- Updated FEATURE_PLAN-autogen-openapi.md (status: 100% complete)
- Added frontend/MIGRATION-GUIDE.md for frontend team

🚀 Frontend Impact
Frontend needs to add Bearer token to all /api/admin/* calls.
See frontend/MIGRATION-GUIDE.md for detailed instructions.

Test Status:  45/45 passing (100%)
Backend:  Production ready
Frontend: ⚠️ Migration required (see MIGRATION-GUIDE.md)
2025-11-16 18:08:48 +01:00
4b9feec887 Refactor: Create modular component architecture for ManagementPortalPage
- Created new modular components:
  * ConsentManager: Manages workshop + social media consents with individual save
  * GroupMetadataEditor: Manages group metadata (title, description, name, year) with save
  * ImageDescriptionManager: Manages image descriptions with batch save
  * DeleteGroupButton: Standalone group deletion component

- Refactored ManagementPortalPage to use modular components:
  * Each component in Paper box with heading inside (not outside)
  * HTML buttons with CSS classes (btn btn-success, btn btn-secondary)
  * Inline feedback with Material-UI Alert instead of SweetAlert2 popups
  * Icons: 💾 save, ↩ discard, 🗑️ delete
  * Individual save/discard functionality per component

- Enhanced ConsentCheckboxes component:
  * Added children prop for flexible composition
  * Conditional heading for manage mode inside Paper box

- Fixed DescriptionInput:
  * Removed duplicate heading (now only in parent component)

- React state management improvements:
  * Deep copy pattern for nested objects/arrays
  * Sorted array comparison for order-insensitive change detection
  * Set-based comparison for detecting removed items
  * Initialization guard to prevent useEffect overwrites

- Bug fixes:
  * Fixed image reordering using existing /api/groups/:groupId/reorder route
  * Fixed edit mode toggle with unsaved changes warning
  * Fixed consent state updates with proper object references
  * Fixed uploadImageBatch signature to use object destructuring
  * Removed unnecessary /api/manage/:token/reorder route from backend

Next: Apply same modular pattern to MultiUploadPage and ModerationGroupImagesPage
2025-11-15 17:25:51 +01:00
324c46d735 feat(phase2): Complete Management Portal with reusable ConsentCheckboxes
Phase 2 Frontend completed (Tasks 12-17, 19-20) - 14. Nov 2025

Backend Enhancements:
- Enhanced PUT /api/manage/:token/consents to support creating new consents
- INSERT new consent row when restoring consent for platform not selected during upload
- Enables granting consents for previously unselected platforms

Frontend Refactoring (Code Deduplizierung):
- Extended ConsentCheckboxes component for both modes (upload & manage)
- Removed ~150 lines of duplicated consent UI code from ManagementPortalPage
- New mode prop: 'upload' (default) | 'manage'
- Dynamic hint texts and validation rules based on mode
- Workshop consent required only in upload mode

ManagementPortalPage Updates:
- Replaced custom consent UI with reusable ConsentCheckboxes component
- New state currentConsents tracks checkbox values
- New handler handleConsentChange() computes changes vs original
- Local change collection with batch save on button click
- Email link for social media post deletion (mailto workaround)
- Save/Discard buttons only visible when pending changes exist

ConsentBadges Fix:
- Now correctly displays only active (non-revoked) consents
- Updates properly after consent revocation

Documentation:
- Updated FEATURE_PLAN with Phase 2 Frontend completion status
- Added refactoring section documenting code deduplizierung
- Updated README with Management Portal features
- Documented email backend solution requirement (future work)

Results:
 100% consistent UI between upload and management
 Zero code duplication for consent handling
 ConsentBadges correctly filters revoked consents
 Backend supports granting new consents after upload
 Management link displayed on upload success page
 All manual tests passed

Tasks Completed:
- Task 12: Management Portal UI (/manage/:token)
- Task 13: Consent Management (revoke/restore)
- Task 14: Metadata Editor (title/description)
- Task 15: Image Management (add/delete)
- Task 16: Group Deletion (with confirmation)
- Task 17: Upload Success Page (management link)
- Task 19: Documentation updates
- Task 20: nginx routing configuration

Pending:
- Task 18: E2E Testing (formal test suite)
2025-11-14 14:38:03 +01:00
e065f2bbc4 wip(phase2): Task 17 - Management-Link in Upload-Erfolg & Rate-Limiter Anpassung
- Task 17: Management-Link im Upload-Erfolg angezeigt mit Copy-Button
- Widerruf-Dialoge überarbeitet: Klarstellung zu Scope & Kontakt für Social Media Posts
- Rate-Limiter für Dev-Umgebung erhöht (100/h statt 10/h)
- Mailto-Link Verhalten noch nicht final getestet (Browser vs. Mail-Client)

ACHTUNG: Noch nicht vollständig getestet! Mailto-Funktionalität muss in verschiedenen Browsern validiert werden.
2025-11-13 22:03:50 +01:00
58a5c95d42 fix(phase2): Fix API routes and filter logic (Issues 6 & 7)
Issue 6: ModerationGroupsPage - Filter "Alle Gruppen" not working
- Problem: Backend filtered groups with display_in_workshop=1 even when no filter selected
- Solution: Removed filter condition in else block - now shows ALL groups when filter='all'
- File: backend/src/routes/groups.js
- Test: GET /moderation/groups now returns 73 groups (all groups)

Issue 7: Export button "Consent-Daten exportieren" not working
- Problem: Routes had wrong path prefix (/admin/* instead of /api/admin/*)
- Solution: Added /api prefix to consent admin routes for consistency
- Files: backend/src/routes/consent.js
  * GET /api/admin/groups/by-consent (was /admin/groups/by-consent)
  * GET /api/admin/consents/export (was /admin/consents/export)
- Test: curl http://localhost:5001/api/admin/consents/export?format=csv works
- Export now includes dynamic Social Media platform columns (facebook, instagram, tiktok)

Test Results:
 Filter "Alle Gruppen": 73 groups
 Filter "Nur Werkstatt": 1 group
 Filter "Facebook": 0 groups
 Export CSV with platform columns: facebook,instagram,tiktok
 Test upload with Social Media consents saved correctly
 Export shows consented platforms per group

Files Changed:
- backend/src/routes/groups.js (filter logic fixed)
- backend/src/routes/consent.js (API paths corrected)
2025-11-13 20:22:22 +01:00
0f77db6f02 feat(phase2): Implement Management Audit-Log (Task 10)
Audit-Logging System:
- Migration 007: management_audit_log table with indexes
- Tracks all management portal actions
- IP address, user-agent, request data logging
- Token masking (only first 8 chars stored)
- Success/failure tracking with error messages

ManagementAuditLogRepository:
- logAction() - Log management actions
- getRecentLogs() - Get last N logs
- getLogsByGroupId() - Get logs for specific group
- getFailedActionsByIP() - Security monitoring
- getStatistics() - Overview statistics
- cleanupOldLogs() - Maintenance (90 days retention)

Audit-Log Middleware:
- Adds res.auditLog() helper function
- Auto-captures IP, User-Agent
- Integrated into all management routes
- Non-blocking (errors don't fail main operation)

Admin API Endpoints:
- GET /api/admin/management-audit?limit=N
- GET /api/admin/management-audit/stats
- GET /api/admin/management-audit/group/:groupId

Tested:
 Migration executed successfully
 Audit logs written on token validation
 Admin API returns logs with stats
 Token masking working
 Statistics accurate
2025-11-11 21:12:07 +01:00
0dce5fddac feat(phase2): Implement Rate-Limiting & Brute-Force Protection (Task 9)
Rate-Limiting:
- IP-based: 10 requests per hour per IP
- Applies to all /api/manage/* routes
- Returns 429 Too Many Requests when limit exceeded
- Automatic cleanup of expired records (>1h old)

Brute-Force Protection:
- Tracks failed token validation attempts
- After 20 failed attempts: IP banned for 24 hours
- Returns 403 Forbidden for banned IPs
- Integrated into GET /api/manage/:token route

Technical Implementation:
- Created backend/src/middlewares/rateLimiter.js
- In-memory storage with Map() for rate limit tracking
- Separate Map() for brute-force detection
- Middleware applied to all management routes
- Token validation failures increment brute-force counter

Tested:
 Rate limit blocks after 10 requests
 429 status code returned correctly
 Middleware integration working
 IP-based tracking functional
2025-11-11 19:59:41 +01:00
2d49f0b826 fix(phase2): Fix group deletion - use correct DeletionLogRepository method
Fixed Task 8 (Delete Group API):
- Changed deletionLogRepository.logDeletion() to createDeletionEntry()
- Use correct parameters matching DeletionLogRepository schema
- Deletion now works: group, images, files, consents all removed
- deletion_log entry created with proper data

Tested:
 Group deletion with valid token
 404 for invalid/missing tokens
 Files deleted (original + preview)
 DB records deleted via CASCADE
 Deletion log entry created

All 8 Backend Management API tasks complete!
2025-11-11 19:10:49 +01:00
c18c258135 feat(phase2): Implement Management Portal API (Tasks 2-7)
Backend Management API implementation for self-service user portal:

 Task 2: Token Generation (already implemented in Phase 1)
- UUID v4 generated at upload
- Stored in groups.management_token
- Returned in upload response

 Task 3: Token Validation API
- GET /api/manage/:token
- Validates token and loads complete group data
- Returns group with images, consents, metadata
- 404 for invalid/missing tokens

 Task 4: Consent Revocation API
- PUT /api/manage/:token/consents
- Revoke/restore workshop consent
- Revoke/restore social media platform consents
- Sets revoked=1, revoked_timestamp
- Full error handling and validation

 Task 5: Metadata Edit API
- PUT /api/manage/:token/metadata
- Update title, description, name
- Supports partial updates
- Automatically sets approved=0 (returns to moderation)

 Task 6: Add Images API
- POST /api/manage/:token/images
- Upload new images to existing group
- Calculates correct upload_order
- Sets approved=0 on changes
- Max 50 images per group validation
- Preview generation support

 Task 7: Delete Image API
- DELETE /api/manage/:token/images/:imageId
- Deletes original and preview files
- Removes DB entry
- Sets approved=0 if group was approved
- Prevents deletion of last image

 Task 8: Delete Group API (in progress)
- DELETE /api/manage/:token route created
- Integration with existing GroupRepository.deleteGroup
- Needs testing

Technical Changes:
- Created backend/src/routes/management.js
- Added getGroupByManagementToken() to GroupRepository
- Registered /api/manage routes in index.js
- Installed uuid package for token generation
- All routes use token validation helper
- Docker-only development workflow

Tested Features:
- Token validation with real uploads
- Workshop consent revoke/restore
- Social media consent management
- Metadata updates (full and partial)
- Image upload with multipart/form-data
- Image deletion with file cleanup
- Error handling and edge cases
2025-11-10 20:00:54 +01:00
901ecc7633 docs: Phase 1 complete - Update documentation for social media consent system
 Phase 1 Complete (Nov 9-10, 2025):
- GDPR-compliant consent management fully implemented
- Mandatory workshop display consent + optional social media consents
- Consent badges, filtering, and CSV/JSON export in moderation panel
- Automatic migration system fixed (inline comments handling)
- GDPR compliance validated: 72 production groups with display_in_workshop = 0
- All features tested and production-ready

Documentation Updates:
- FEATURE_PLAN-social-media.md: All Phase 1 tasks marked complete
- README.md: Added consent system to features, updated database schema, new API endpoints
- README.dev.md: Complete developer guide with debugging, testing, and troubleshooting

Technical Achievements:
- 12 commits over 2 days (faster than 4-5 day estimate)
- Zero GDPR violations (retroactive consent fix validated)
- Zero breaking changes to existing functionality

Ready for Code Review and Production Deployment
2025-11-10 17:56:04 +01:00
8e6247563a fix: DatabaseManager removes inline comments correctly in migrations
- Fixed SQL statement parsing to remove both line and inline comments
- Prevents incomplete SQL statements from inline comments
- Migration 005 and 006 now apply correctly via automatic migration system
- Tested with production data: All 72 groups have display_in_workshop = 0 (GDPR compliant)
2025-11-10 17:45:32 +01:00
f049c47f38 fix: Add display_in_workshop to groupFormatter and fix filter logic
Problem: Moderation filter returned 0 groups because:
1. groupFormatter.formatGroupDetail() didn't include display_in_workshop field
2. Platform filters incorrectly required workshop consent

Solution:
- Add display_in_workshop and consent_timestamp to formatGroupDetail()
- Remove workshop requirement from platform filters
- Add default filter to show only groups with workshop consent
- Fix workshop-only filter to check for consented social media

Filter logic:
- 'Alle Gruppen': Only groups WITH workshop consent
- 'Nur Werkstatt': Groups with workshop BUT WITHOUT social media
- Platform filters: Groups with that platform consent (independent of workshop)
2025-11-09 23:51:29 +01:00
8d2f09f71a fix: Fix moderation filter - load all groups with images first, then filter
Problem: Filtered groups were missing preview images because
getGroupsByConsentStatus() only returned group metadata without images.

Solution: Load all groups with getAllGroupsWithModerationInfo() first
(includes images), add consent data, then filter in-memory based on
query parameters. This ensures preview images are always included.
2025-11-09 22:28:59 +01:00
a27a66f6ee feat: Implement moderation panel consent features
- Add ConsentBadges component with platform icons and tooltips
- Add consent filter dropdown in moderation page (all/workshop-only/platforms)
- Add export button for CSV download of consent data
- Extend /moderation/groups endpoint with filter params and consent data
- Display consent badges in ImageGalleryCard for moderation mode
- Visual distinction: workshop (green), social media (blue outlined)
- Export functionality with date-stamped CSV files

Tasks completed:
- Moderation visual consent indicators
- Moderation consent filter
- Moderation export functionality
2025-11-09 22:20:11 +01:00
76aa028686 fix: Add /api prefix to consent routes and nginx proxy config
- Update consent.js routes to use /api prefix
- Add /api/social-media location to dev/prod nginx configs
- Fix route registration for proper API access
2025-11-09 21:22:35 +01:00
6ba7f7bd33 feat(upload): Add consent validation and storage to batch upload
- Parse consent data from request body (workshopConsent, socialMediaConsents)
- Validate workshop consent is required (400 error if missing)
- Use createGroupWithConsent() instead of createGroup()
- Pass consent data to repository for database storage
- Maintains backward compatibility with existing upload flow
- GDPR-compliant: no upload without explicit workshop consent
2025-11-09 21:04:50 +01:00
2f86158821 feat(api): Add consent management API routes
- Create consent.js with comprehensive API endpoints:
  - GET /api/social-media/platforms - list active platforms
  - POST /api/groups/:groupId/consents - save/update group consents
  - GET /api/groups/:groupId/consents - retrieve group consent data
  - GET /api/admin/groups/by-consent - filter groups by consent status
  - GET /api/admin/consents/export - export consent data (JSON/CSV formats)

- Register consent router in routes/index.js
- Full validation and error handling
- CSV export with dynamic platform columns
- Ready for frontend integration
2025-11-09 21:02:57 +01:00
ff2ea310ed feat(repositories): Add SocialMediaRepository and extend GroupRepository
- Create new SocialMediaRepository for platform and consent management
  - getAllPlatforms(), getActivePlatforms()
  - createPlatform(), updatePlatform(), togglePlatformStatus()
  - saveConsents(), getConsentsForGroup(), getGroupIdsByConsentStatus()
  - revokeConsent(), restoreConsent(), hasActiveConsent()

- Extend GroupRepository with consent management methods
  - createGroupWithConsent() - create group with workshop & social media consents
  - getGroupWithConsents() - retrieve group with all consent data
  - updateConsents() - update consent preferences
  - getGroupsByConsentStatus() - filter groups by consent status
  - exportConsentData() - export for legal documentation
  - generateManagementToken(), getGroupByManagementToken() (Phase 2)

- Both repositories work together seamlessly via transactions
2025-11-09 21:01:16 +01:00
8dc5a03584 feat(database): Add consent management migrations and auto-migration system
- Add Migration 005: consent fields to groups table (display_in_workshop, consent_timestamp, management_token)
- Add Migration 006: social_media_platforms and group_social_media_consents tables
- Implement automatic migration execution in DatabaseManager.initialize()
- Add standalone migration runner script (runMigrations.js)
- Seed data: Facebook, Instagram, TikTok platforms

Note: DatabaseManager statement splitting needs improvement for complex SQL.
Manual migration execution works correctly via sqlite3.
2025-11-09 20:57:48 +01:00
b03cd20b40 fix(backend): Correct GroupCleanupService import in admin routes
GroupCleanupService exports an instance, not a class constructor
2025-11-08 13:24:58 +01:00
861d4813d1 feat(testing): Add cleanup testing tools and API endpoints
- Add POST /api/admin/cleanup/trigger for manual cleanup
- Add GET /api/admin/cleanup/preview for dry-run testing
- Create test-cleanup.sh (bash) for easy testing
- Create test-cleanup.js (node) as alternative test tool
- Enable backdating groups for testing purposes
2025-11-08 13:18:44 +01:00
c0ef92ec23 feat(api): Add admin endpoints for deletion log
Phase 3 Complete - Backend API

New Admin Endpoints (/api/admin/):
- GET /deletion-log?limit=10
  - Returns recent deletion logs with pagination
  - Validation: limit 1-1000
  - Response: { deletions, total, limit }

- GET /deletion-log/all
  - Returns complete deletion history
  - Response: { deletions, total }

- GET /deletion-log/stats
  - Returns deletion statistics
  - Includes formatted file sizes (B/KB/MB/GB)
  - Response: { totalDeleted, totalImages, totalSize, lastCleanup }

Features:
- Comprehensive error handling
- Input validation
- Human-readable file size formatting
- Consistent JSON responses

Integration:
- admin.js router mounted at /api/admin
- Added to routes/index.js

Task completed:  3.6
2025-11-08 12:25:20 +01:00
939cf22163 feat(backend): Implement automatic cleanup service
Phase 2 Complete - Backend Core Logic

New Components:
- DeletionLogRepository: CRUD for deletion audit trail
- GroupCleanupService: Core cleanup logic
  - findGroupsForDeletion() - finds unapproved groups older than 7 days
  - deleteGroupCompletely() - DB + file deletion
  - deletePhysicalFiles() - removes images & previews
  - logDeletion() - creates audit log entry
  - getDaysUntilDeletion() - calculates remaining days
  - performScheduledCleanup() - main cleanup orchestrator
- SchedulerService: Cron job management
  - Daily cleanup at 10:00 AM (Europe/Berlin)
  - Manual trigger for development

GroupRepository Extensions:
- findUnapprovedGroupsOlderThan(days)
- deleteGroupCompletely(groupId)
- getGroupStatistics(groupId)

Dependencies:
- node-cron ^3.0.3

Integration:
- Scheduler auto-starts with server (server.js)
- Comprehensive logging for all operations

Tasks completed:  2.3,  2.4,  2.5
2025-11-08 12:23:49 +01:00
4f58b04a0f feat(db): Add deletion_log table and cleanup indexes
Phase 1 Complete - Database Schema

- Add deletion_log table for audit trail (no personal data)
- Add performance indexes for cleanup queries:
  - idx_groups_approved
  - idx_groups_cleanup (approved, upload_date)
  - idx_deletion_log_deleted_at (DESC)
  - idx_deletion_log_year
- Table structure: group_id, year, image_count, upload_date, deleted_at, deletion_reason, total_file_size

Tasks completed:  1.1,  1.2
2025-11-08 12:05:34 +01:00
07b436cc4d feat: Complete image description feature implementation
Features:
- Add image description field (max 200 chars) for individual images
- Replace 'Sort' button with 'Edit' button in image gallery cards
- Enable edit mode with text fields for each image in moderation
- Display descriptions in slideshow and public views
- Integrate description saving with main save button

Frontend changes:
- ImageGalleryCard: Add edit mode UI with textarea and character counter
- ModerationGroupImagesPage: Integrate description editing into main save flow
- Fix keyboard event propagation in textarea (spacebar issue)
- Remove separate 'Save Descriptions' button
- Add ESLint fixes for useCallback dependencies

Backend changes:
- Fix route order: batch-description route must come before :imageId route
- Ensure batch description update API works correctly

Build optimizations:
- Add .dockerignore to exclude development data (182MB reduction)
- Fix Dockerfile: Remove non-existent frontend/conf directory
- Reduce backend image size from 437MB to 247MB

Fixes:
- Fix route matching issue with batch-description endpoint
- Prevent keyboard events from triggering drag-and-drop
- Clean up unused functions and ESLint warnings
2025-11-07 23:20:50 +01:00
292d25f5b4 feat: Implement image descriptions - Backend & Core Frontend
- Database: Add image_description column to images table
- Repository: Add updateImageDescription & updateBatchImageDescriptions methods
- API: Add PATCH endpoints for single and batch description updates
- Upload: Support descriptions in batch upload
- Frontend: ImageGalleryCard with Edit mode and textarea
- Frontend: MultiUploadPage with description input
- Frontend: ModerationGroupImagesPage with description editing
- CSS: Styles for edit mode, textarea, and character counter

Phase 1-4 complete: Backend + Core Frontend + Upload + Moderation
2025-11-07 18:34:16 +01:00
3845de92a6 Fix batch upload and attempt nginx auth setup
- Fixed missing 'path' import in batchUpload.js
- Fixed GroupRepository import (singleton vs class)
- Added htpasswd file to development config
- Created new nginx.conf based on working production config
- Updated Dockerfile to copy htpasswd for development

Status:
 Upload functionality restored (both single and batch)
 Backend routing and error handling fixed
⚠️ nginx auth config needs troubleshooting (container not using new config)
2025-11-06 18:28:32 +01:00
2678ad9b12 🚀 Refactor: Saubere Docker-Struktur mit getrennten dev/prod Umgebungen
- Neue Docker-Struktur: docker/{dev,prod}/ für klare Trennung
- Entfernt: docker-compose.override.yml (problematisch)
- Hinzugefügt: ./dev.sh und ./prod.sh Scripts für einfache Bedienung
- Container-spezifische Konfigurationen in docker/{dev,prod}/*/config/
- Aktualisierte READMEs für neue Struktur
- Backend-Daten in .gitignore hinzugefügt
- Bereinigt: Veraltete Dockerfiles und Konfigurationsdateien

Jetzt: Wartungsfreundlich, keine Verwirrung zwischen Umgebungen
2025-11-05 23:00:25 +01:00
8332a78c1e fix: resolve reordering API routing issue
🔧 Problem identified and fixed:
- nginx proxy was routing /api/groups to /groups (removing /api prefix)
- Backend route was registered under /api/groups instead of /groups
- Changed backend route registration from '/api/groups' to '/groups'
- Tested API endpoint: curl to /api/groups/qion_-lT1/reorder now works
- Removed debug console.log statements for cleaner production code

 Drag-and-drop reordering now functional in ModerationGroupImagesPage
 API requests properly routed through nginx proxy to backend
 Error 'Reihenfolge konnte nicht geändert werden' resolved
2025-11-03 21:39:44 +01:00
7564525c7e feat: implement drag-and-drop reordering infrastructure
Phase 1 (Backend API):
 GroupRepository.updateImageOrder() with SQL transactions
 PUT /api/groups/:groupId/reorder API route with validation
 Manual testing: Reordering verified working (group qion_-lT1)
 Error handling: Invalid IDs, missing groups, empty arrays

Phase 2 (Frontend DnD):
 @dnd-kit/core packages installed
 ReorderService.js for API communication
 useReordering.js custom hook with optimistic updates
 ImageGalleryCard.js extended with drag handles & sortable
 ImageGallery.js with DndContext and SortableContext
 CSS styles for drag states, handles, touch-friendly mobile

Next: Integration with ModerationGroupImagesPage
2025-11-03 21:06:39 +01:00
aec9db2a76 feat(frontend): integrate preview images in gallery components
- Add imageUtils.js helper with getImageSrc() and getGroupPreviewSrc()
- Update ImageGalleryCard to use preview images for galleries
- Update ModerationGroupsPage to show preview images in modal
- Update ModerationGroupImagesPage to use preview images
- Update PublicGroupImagesPage to pass all image fields
- SlideshowPage continues using original images (full quality)
- Update nginx.dev.conf with /api/previews and /api/download routes
- Update start-dev.sh to generate correct nginx config
- Fix GroupRepository.getAllGroupsWithModerationInfo() to return full image data
- Remove obsolete version from docker-compose.override.yml
- Update TODO.md: mark frontend cleanup as completed

Performance: Gallery load times reduced by ~96% (100KB vs 3MB per image)
2025-10-31 18:20:50 +01:00
170e1c20e6 feat: automatic preview generation on database init
Task 7: Batch-Migration Automation
- Add generateMissingPreviews() method to DatabaseManager
- Automatically runs after schema creation
- Finds all images without preview_path
- Generates previews for existing images on startup
- Graceful error handling (won't break server start)
- Progress logging: 'Found X images without preview, generating...'
- No manual script needed - fully automated

Benefits:
- Works on every backend restart
- Incremental (only missing previews)
- Non-blocking database initialization
- Perfect for deployments and updates
2025-10-30 20:51:35 +01:00
661d6441ab feat: integrate preview generation into upload flow
Task 4: Upload Routes Extended
- upload.js: Generate preview after single file upload
- batchUpload.js: Generate previews for all batch uploads
- Async preview generation (non-blocking response)
- Auto-update preview_path in database after generation

Task 5: Repository with preview_path
- GroupRepository: Include preview_path in INSERT
- getGroupById: Return previewPath in image objects
- groupFormatter: Add previewPath to formatGroupDetail()
- All queries now support preview_path column

Task 6: API Endpoints Extended
- Add PREVIEW_STATIC_DIRECTORY constant (/previews)
- Serve preview images via express.static
- All existing endpoints now return previewPath field
- Fallback to filePath if preview not available (frontend)
2025-10-30 20:41:06 +01:00