From 73a9c18a101808398332822e90230701a4975629 Mon Sep 17 00:00:00 2001 From: Thorsten Bus Date: Mon, 11 May 2026 10:37:31 +0200 Subject: [PATCH] docs(ccli): add CCLI import section to AGENTS.md --- AGENTS.md | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/AGENTS.md b/AGENTS.md index ed9b415..9218a19 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -98,6 +98,48 @@ ## SongDB Import --- +## CCLI Import + +Songs can be imported from CCLI SongSelect via a paste-based flow (no server-side scraping — ToS-compliant). + +### How it works + +1. User opens a song on **songselect.ccli.com** in their browser (must be logged in with their CCL account) +2. User copies the full page text (Ctrl+A → Ctrl+C) +3. User clicks "Aus CCLI importieren" in the SongDB or service form, pastes the text, clicks "Vorschau", then "Importieren" + +Alternatively, install the **browser bookmarklet** from Settings → CCLI Import. The bookmarklet automates step 2-3 in two clicks. + +### Key files + +| File | Purpose | +|------|---------| +| `app/Services/CcliPasteParser.php` | Pure-PHP parser: extracts title/author/CCLI-Nr/year/sections from pasted text | +| `app/Services/CcliImportService.php` | Upserts Song + Arrangement + Labels + Slides; handles duplicates and soft-delete restore | +| `app/Services/CcliTranslationPairingService.php` | Auto-pairs CCLI sections with local song labels for translation import | +| `app/Support/CcliLabels.php` | Section-label regex + EN↔DE name mapping (Verse↔Strophe, Chorus↔Refrain, etc.) | +| `app/Http/Controllers/CcliPasteController.php` | POST /api/ccli/preview + POST /api/songs/import-from-ccli-paste (3 modes) | +| `app/Http/Controllers/BookmarkletController.php` | GET /bookmarklets/ccli-import.js — serves the bookmarklet JS | +| `resources/js/Components/CcliPasteDialog.vue` | Modal: textarea → preview → import buttons (surface-aware) | +| `resources/js/Pages/Songs/ImportFromCcliPaste.vue` | Bookmarklet redirect landing page | +| `tests/Fixtures/ccli/` | 22 synthetic CCLI-format fixture files for parser tests | + +### Test coverage + +- `tests/Feature/CcliPasteParserTest.php` — parser against all 22 fixtures +- `tests/Feature/CcliImportServiceTest.php` — upsert, duplicate, restore, transaction +- `tests/Feature/CcliTranslationPairingServiceTest.php` — label pairing, line distribution +- `tests/Feature/CcliPasteControllerTest.php` — API endpoints, auth, throttle +- `tests/e2e/ccli-paste-import.spec.ts` — SongDB import flow +- `tests/e2e/ccli-bookmarklet.spec.ts` — bookmarklet endpoint + Settings page +- `tests/e2e/ccli-translation-pairing.spec.ts` — Translate.vue prefill + +### Maintenance note + +If SongSelect changes their HTML structure, update the bookmarklet DOM selectors in `resources/js/bookmarklet/ccli-import.ts` (or the inline JS in `BookmarkletController.php`). The server-side parser (`CcliPasteParser.php`) is independent of SongSelect's HTML — it only parses the plain-text lyrics format. + +--- + ## Repository Structure Two git repositories, both local (no remote):