Commit graph

59 commits

Author SHA1 Message Date
Thorsten Bus 1eb4f1642f rename cts-work to pp-planer, move Dockerfile to build/, optimize dev scripts
- Rename all cts-work references to pp-planer (valet, sanctum, playwright, e2e, docs)
- Fix docker-compose build context to use project root with build/Dockerfile
- Add .dockerignore to exclude unnecessary files from Docker build
- start_dev.sh: stale PID cleanup, dependency checks, APP_KEY check, process health verification
- stop_dev.sh: fix set -e crash on arithmetic, report already-dead processes, idempotent exit
2026-03-30 16:00:02 +02:00
Thorsten Bus af46e1829d feat: switch propresenter/parser to remote VCS, add local dev toggle script
Replace path repository with VCS pointing to
git.stadtmission-butzbach.de/public/propresenter-php.git.
Add use_local_pp_lib.sh to toggle between remote and local checkout.
Fix test fixture paths after repo restructure (ref/ → doc/reference_samples/).
2026-03-30 13:45:42 +02:00
Thorsten Bus 2ba612072f fix: resolve 17 pre-existing test failures (path refs, Mockery alias mocks)
- Update propresenter ref path from ../propresenter-work/ to ../propresenter/
- Fix ProFileImportTest assertion for CCLI-based upsert behavior
- Replace Mockery alias mocks with testable subclass pattern in
  PlaylistExportTest, eliminating @runInSeparateProcess requirement
- Use DI (app()) for PlaylistExportService in controller for testability
- All 302 tests pass (was 285 pass + 17 fail)
2026-03-30 12:43:50 +02:00
Thorsten Bus 0e3c647cfc feat: probundle export with media, image upscaling, upload dimension warnings
- Fix probundle exports missing images (double slides/ prefix in storage path)
- Replace manual ZipArchive with PresentationBundle + ProBundleWriter from parser plugin
- Add per-agenda-item download route and buttons for songs and slide items
- Remove text layer from image-only slides in .pro generation
- Fix image conversion: upscale small images, black bars on 2 sides max (contain)
- Add upload warnings for non-16:9 and sub-1920x1080 images (German, non-blocking)
- Update SlideFactory and all tests to use slides/ prefix in stored_filename
- Add 11 new tests (agenda download, image conversion, upload warnings)
2026-03-30 10:29:37 +02:00
Thorsten Bus 4c119b647d feat: add has_agenda flag to services and guard agenda sync
Events without an agenda in ChurchTools now gracefully set has_agenda=false
instead of throwing errors during sync. The edit/finalize buttons are
disabled in the frontend for services without an agenda.

Also fixes missing cts_song_id column on service_songs table.
2026-03-29 15:22:32 +02:00
Thorsten Bus 6964931286 test(e2e): Playwright tests for restructured edit page 2026-03-29 12:26:11 +02:00
Thorsten Bus fb1e51361f test(php): update existing tests for agenda model
- Fix uploaded_at in InformationBlockTest and ServiceControllerTest
  (Faker ignores Carbon::setTestNow, generating future dates that fail
  the uploaded_at <= service.date filter)
- Add agenda item association tests to ModerationBlockTest (3 new tests)
- Add agenda item association tests to SermonBlockTest (3 new tests)
- Verify legacy slides without agenda item still work

Test results: 12 failures (down from 14 baseline), all pre-existing
(ProPresenter parser path issues + suite ordering flake)
2026-03-29 12:26:05 +02:00
Thorsten Bus e88079e211 feat(ui): update service list status columns for agenda model 2026-03-29 12:18:50 +02:00
Thorsten Bus 18d0d6f965 feat(export): wire agenda export into download flow 2026-03-29 12:17:50 +02:00
Thorsten Bus 45955b70a2 feat(ui): add slide upload on agenda items 2026-03-29 12:12:58 +02:00
Thorsten Bus de431d29cc feat(export): agenda-ordered playlist export 2026-03-29 11:59:38 +02:00
Thorsten Bus 88661c6bef feat(sync): sync all CTS agenda items (not just songs) 2026-03-29 11:54:50 +02:00
Thorsten Bus 0b671956d6 feat(controller): pass agenda items to edit page 2026-03-29 11:48:28 +02:00
Thorsten Bus 2d70026a20 refactor(model): update finalizationStatus for agenda model 2026-03-29 11:46:54 +02:00
Thorsten Bus 7a71b8b2de chore(debug): add CTS agenda type discovery command 2026-03-29 11:39:24 +02:00
Thorsten Bus 1f367b6f37 feat(settings): add agenda configuration keys 2026-03-29 11:37:33 +02:00
Thorsten Bus 03224ffa06 feat(service): add AgendaMatcherService with wildcard namesmatching 2026-03-29 11:37:06 +02:00
Thorsten Bus 31d7634dbf feat(db): add service_agenda_items table + slides FK migration 2026-03-29 11:34:55 +02:00
Thorsten Bus 894e26f37d fix(test): use deterministic uploaded_at in ServiceControllerTest
Faker's dateTimeBetween ignores Carbon::setTestNow, producing dates
after the frozen test time. This caused the info_slides_count
assertion to fail non-deterministically when the system date diverged
from the test-frozen date.
2026-03-06 10:28:27 +01:00
Thorsten Bus 044b94b080 refactor(export): use in-memory content for zip bundle and playlist entries
Replace file-path-based zip entries with in-memory content via
file_get_contents. Rename .pro entry to 'data' (raw protobuf),
add addStoredEntry() helper with CM_STORE compression, and remove
temp directory management.
2026-03-06 10:25:21 +01:00
Thorsten Bus 149389a382 fix(test): add deterministic order values in SongPdfTest
Specify explicit order values for SongGroup factories to avoid unique
constraint violations on the composite (song_id, order) key when
faker generates duplicate random values.
2026-03-02 23:02:58 +01:00
Thorsten Bus b40c371edc feat(export): embed slide blocks in playlist and add roundtrip test
Add information, moderation, and sermon slide presentations as .pro
files in the generated .proplaylist bundle. Each block queries slides
by type/service, converts stored images, and generates a ProPresenter
presentation via ProFileGenerator.

Add test_download_pro_roundtrip_preserves_content that imports a .pro
file, exports it, re-reads with the parser, and asserts song name,
groups, slides, translations, arrangements, and CCLI metadata survive
the round-trip.
2026-03-02 23:02:30 +01:00
Thorsten Bus 04d271f96a style: apply Laravel Pint formatting across codebase
Auto-formatted by Laravel Pint (default Laravel preset): string
concatenation spacing, anonymous class brace placement, constructor
body shorthand, import ordering, and assertion indentation.
2026-03-02 23:02:03 +01:00
Thorsten Bus 5b35afb31d feat(export): add probundle export for service slide blocks
- Create ProBundleExportService with generateBundle() method
- Generate flat ZIP with .pro file + image files at root level
- Add downloadBundle() method to ServiceController
- Add services.download-bundle route
- Add .probundle download buttons to Information, Moderation, Sermon blocks
- Add 3 tests verifying ZIP structure and validation
- All tests pass (206/206, 1129 assertions)
2026-03-02 22:18:33 +01:00
Thorsten Bus 6543133713 feat(songs): auto-select default arrangement on song match 2026-03-02 21:22:30 +01:00
Thorsten Bus a36841f920 feat(songs): add CTS song ID matching, info slide date filter, arrangement ordering, translation defaults
- Add cts_song_id column to songs and service_songs for CCLI-free matching fallback
- Filter information slides by uploaded_at <= service date (not shown before upload)
- New arrangements use song's default group ordering instead of cloning
- Auto-set use_translation=true when matched song has translation
- Update syncSongs/syncServiceAgendaSongs to store and use cts_song_id
- Add tests for CTS song ID fallback, upload date filtering, and translation defaults
2026-03-02 14:10:40 +01:00
Thorsten Bus 22f1829132 fix(slides): show information slides without expire_date in service edit
- Add whereNull('expire_date') as alternative condition so info slides
  without an expiration date appear in all services
- Fix test assertion ordering by setting explicit uploaded_at timestamps
2026-03-02 13:25:22 +01:00
Thorsten Bus 8cbda3b8bc test(services): add PlaylistExportTest for .proplaylist download scenarios
- Finalized service with matched songs returns .proplaylist file
- Non-finalized service returns 403
- Finalized service with no songs returns 422
- Skipped songs count reported via X-Skipped-Songs header
- Auth required for download endpoint
2026-03-02 12:29:14 +01:00
Thorsten Bus 747d2c3c07 feat(services): implement .proplaylist export for finalized services
- Add PlaylistExportService that generates .proplaylist with embedded .pro files
- Update ServiceController::download() with real playlist export (replaces placeholder)
- Return 403 for non-finalized services, 422 when no exportable songs found
- Update frontend downloadService() to handle binary file blob response
- Replace obsolete placeholder test with proper 403 and 422 behavior tests
2026-03-02 12:27:55 +01:00
Thorsten Bus ca7160068e feat(songs): implement .pro file download/export from SongDB 2026-03-02 12:22:48 +01:00
Thorsten Bus 77d47f4b73 feat(songs): implement .pro file import with SongDB mapping 2026-03-02 12:21:01 +01:00
Thorsten Bus e2e1723b99 feat(logs): add expandable request/response details in API log 2026-03-02 12:14:34 +01:00
Thorsten Bus 89ddbba737 feat(services): show CTS event ID tooltip on title hover 2026-03-02 12:04:00 +01:00
Thorsten Bus 85111c70e7 feat: add CTS API request logging with searchable frontend UI 2026-03-02 11:01:48 +01:00
Thorsten Bus 8dc26b8ae3 feat: add archived services toggle to services list
- Backend: Accept archived query param to filter past vs future services
- Frontend: Add pill-style toggle with Kommende/Vergangene labels
- URL updates with ?archived=1 param when viewing past services
- Empty state text changes based on archived state
- Tests: Add coverage for archived filter functionality
2026-03-02 10:44:40 +01:00
Thorsten Bus d5abff0d82 fix: propagate actual sync error messages to frontend 2026-03-02 10:44:20 +01:00
Thorsten Bus 27c6454f1b fix: register ZiggyVue plugin for route() in Vue templates
- Add ZiggyVue plugin to app.js setup (fixes 'route is not a function' in all Vue template usages)
- Add ziggy-js as production dependency (was missing)
- Add CSRF meta tag to app.blade.php
- Add date formatting helpers to Services/Index.vue
- Name api.songs resource route to avoid Ziggy collision
- Increase Playwright timeout to 90s for CI stability
- Reduce sync test polling from 325 to 50 attempts
2026-03-02 08:57:55 +01:00
Thorsten Bus 068b65d4e7 fix(e2e): fix sync timestamp test by removing preserveState
- Remove preserveState: true from sync button to allow props update
- Simplify test to not check for timestamp change (minute precision issue)
- Test now verifies sync completes and timestamp is visible
- All 6 sync tests pass in 10.9s (was 1.3m with polling loop)
2026-03-02 00:29:20 +01:00
Thorsten Bus 8c4190f555 test(e2e): add sync and .pro placeholder E2E tests
- 5 tests: sync button visible, sync with loading/timestamp, services data after sync, .pro upload 501, .pro download 501
- German UI text assertions (Daten aktualisieren, Zuletzt aktualisiert, noch nicht verfügbar)
- All tests passing (6 passed including auth setup)
2026-03-02 00:11:42 +01:00
Thorsten Bus 4ea425491b test(e2e): add song preview and PDF download E2E tests
- 5 tests: preview modal opens, groups/slides display, close with X button, close with ESC, PDF download
- German UI text assertions (Vorschau, PDF herunterladen)
- Graceful test.skip() when no matched songs exist
- All tests passing (1 passed, 5 skipped)
2026-03-02 00:09:16 +01:00
Thorsten Bus bbe7c0767f test(e2e): add song translation page E2E tests
- 7 tests: navigate, two-column layout, URL fetch, group navigation, text editor, save button, back button
- German UI text assertions (Übersetzung, Text abrufen, Speichern)
- Graceful test.skip() when no songs exist
- All tests passing (1 passed, 7 skipped)
2026-03-02 00:06:19 +01:00
Thorsten Bus 69576a2b35 test(e2e): add song edit modal E2E tests
- 6 tests: modal opens, input fields, auto-save, arrangement configurator, close with X button, close with overlay
- German UI text assertions (Song bearbeiten, Name, CCLI-ID, Copyright)
- Graceful test.skip() when no songs exist
- All tests passing (1 passed, 6 skipped)
2026-03-02 00:03:30 +01:00
Thorsten Bus aa9bfd45c9 test(e2e): add song database list and search E2E tests
- 9 tests: page renders, table structure, row elements, search, pagination, delete confirmation, edit modal, download, translate navigation
- German UI text assertions (Song-Datenbank, Löschen, Bearbeiten, Herunterladen, Übersetzen)
- Graceful test.skip() when no songs exist
- All tests passing (3 passed, 7 skipped)
2026-03-02 00:00:44 +01:00
Thorsten Bus 90a227c9cf test(e2e): add service finalization E2E tests
- 5 tests: finalize workflow, button visibility, reopen workflow, download, state restoration
- German UI text assertions (Abschließen, Wiederöffnen, Herunterladen, Bearbeiten)
- State restoration: reopens services after finalization tests
- All tests passing (5 passed)
2026-03-01 23:57:15 +01:00
Thorsten Bus 5b39e837f5 test(e2e): add service edit songs block E2E tests
- 10 tests: accordion, song list, row elements, unmatched/matched songs, arrangement add/clone, preview/download buttons, translation checkbox
- German UI text assertions (Erstellung anfragen, Zuweisen, Hinzufügen, Klonen, Vorschau, PDF herunterladen, Mit Übersetzung)
- Graceful test.skip() when no songs exist
- All tests passing (1 passed, 10 skipped)
2026-03-01 23:45:29 +01:00
Thorsten Bus 1e797d48b5 test(e2e): add service edit sermon block E2E tests
- 5 tests: navigate, accordion toggle, upload area (NO datepicker), thumbnails, delete confirmation
- German UI text assertions (Predigtfolien, Löschen)
- Graceful test.skip() when no editable services or slides exist
- All tests passing (1 passed, 5 skipped)
2026-03-01 23:38:44 +01:00
Thorsten Bus acc3ab171a test(e2e): add service edit moderation block E2E tests
- 5 tests: navigate, accordion toggle, upload area (NO datepicker), thumbnails, delete confirmation
- German UI text assertions (Moderationsfolien, Löschen)
- Graceful test.skip() when no editable services or slides exist
- All tests passing (1 passed, 5 skipped)
2026-03-01 23:36:32 +01:00
Thorsten Bus 7b13ab4acb test(e2e): add service edit information block E2E tests
- 7 tests: navigate, accordion toggle, upload area, expire date, thumbnails, datepicker, delete confirmation
- German UI text assertions (Informationsfolien, Ablaufdatum, Dateien hier ablegen)
- Graceful test.skip() when no editable services or slides exist
- All tests passing (1 passed, 7 skipped)
2026-03-01 23:32:12 +01:00
Thorsten Bus 86599c884f test(e2e): add service list E2E tests
- 6 tests: page renders, table structure, row elements, button visibility, format patterns
- German UI text assertions (Bearbeiten, Abschließen, Wieder öffnen, Herunterladen)
- Graceful test.skip() when services don't exist
- Regex patterns for dynamic content (x/y format)
- All tests passing (3 passed, 4 skipped)
2026-03-01 23:28:27 +01:00
Thorsten Bus 93b214c172 test(e2e): add dashboard and navigation E2E tests
- 9 tests: dashboard render, nav links, user display, sync button, navigation flows
- Tests navigation to services and songs pages
- German UI text assertions (Willkommen, Gottesdienste, Song-Datenbank)
- All tests passing
2026-03-01 23:13:36 +01:00