- Fix SNAKKIMO_URL.replace('/api','') bug that stripped both /api occurrences
producing wrong auth URL → use endswith/slice to remove only trailing /api
- Replace directus_users_me with JWT decode (snakkimo has no /users/me endpoint)
Returns Directus-compatible shape with role.admin_access for UI admin checks
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Replace all db_* routes with snakkimo API equivalents
- Stub out Llama AI functions (generate_details, generate_sentence) with 501 error
- Map field names: user_notes↔notes, picture↔picture_link, level↔difficulty_level, statement_de↔positive_sentence_de
- Use word_id as junction_id for M2M deletes (snakkimo uses resource IDs not junction row IDs)
- Normalize db-pictures response to include picture/blurhash/status/design
- Extract unique design values from pictures table for design-options endpoint
- Pair DELETE now also deletes linked statement and question
- FLAG: question words, distractor_words, objects.parent not supported in snakkimo
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Home-Seite nach Login mit Begrüßung und 3 Kacheln (Content erstellen, Content verwalten, User verwalten)
- AuthContext speichert User-Profil + Rolle; AdminRoute blockt Nicht-Admins
- Content verwalten (admin-only): Status-Dashboard pro Collection, Liste/Kachel-View, generisches Edit-Formular
- Nur aktive db_-Collections im Dashboard (alte pictures/objects/words/questions entfernt)
- Wort-Autocomplete in DrawIt: ab dem ersten Buchstaben Vorschläge aus db_words, Tastatur-Navigation, Duplikat-Filter
- Backend: /users/me Proxy, db-words/search Endpoint, generische Collection-Endpoints
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Textarea zeigt {1.Hund} (Index + Wort), Directus speichert {uuid.uuid}
- displayToStorage / storageToDisplay Konvertierung bei Save und Edit
- PreviewText-Komponente: Placeholder farblich hervorgehoben (blau)
- Chip-Klick fügt {1.Hund} an Cursor-Position ein
- startEdit konvertiert gespeicherte UUIDs zurück zu lesbarem Format
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
✏️ Button pro Objekt in der linken Sidebar öffnet Edit-Panel:
- Notizen-Textarea bearbeitbar
- Wörter: Chips mit × + neues Wort hinzufügen (Enter oder +)
- Speichern / Abbrechen
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Alle fehlenden 'Bearer '-Prefixe ergänzt. Ohne Bearer lehnt Directus die
Requests stillschweigend ab → Wörter wurden nie gespeichert → leer in DB
→ keine Anzeige in GenerateIt → keine Chips im Pair-Form.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
/fields/ braucht Admin-Rechte – Session-Token des Users hat keinen Zugriff.
DIRECTUS_ADMIN_TOKEN als Konstante (überschreibbar via Env-Var).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- DrawCanvas: call onImageLoad for cached images (fixes permanent blur)
- DrawIt: reset imageLoaded immediately on navigation (shows blur right away)
- Design dropdown: always visible when picture loaded, no longer gated on designOptions or objects count
- Fertigstellen: always visible when picture loaded, disabled when no objects
- Hauptwörter: new panel above object list for picture-level words (db_words_db_pictures)
- Backend: DELETE /api/directus/db-pictures/<id>/words/<junction_id>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Words panel moved to right sidebar: shows selected object's words or pending words for new object
- Pending words auto-saved to object after creation
- Remove word chips from left sidebar object cards
- Design dropdown in left sidebar (above Fertigstellen), loads choices dynamically from Directus field metadata
- Include design field in db_pictures GET response
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Annotate: multiple words per object via db_objects_db_words M2M, word chips with add/remove per object card
- Generate sidebar: objects shown with comma-separated word list as display name
- Generate pair form: all object words as suggestion chips, click inserts {objectId.wordId} at cursor
- Preview resolves {objectId.wordId} → actual word text
- Backend: POST adds single word (no replace), new DELETE /db-objects/<id>/words/<junctionId>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Annotate: per-object single label input (M2M via db_objects_db_words), auto-save on blur, remove picture-level word section
- Generate: object chips insert {obj:UUID} at cursor position in question/statement textarea
- Live preview resolves {obj:UUID} → actual object label
- PairsList display also resolves placeholders
- Remove F/A/B word chip system from pair form (replaced by object placeholders)
- Backend: POST /api/directus/db-objects/<id>/words replaces existing word with single label
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Words in pair form now linkable individually per word (Frage/Aussage/Beide toggle)
- Edit form includes full word management: view existing words with link indicator, remove/restore, add new words with link_to selector
- Fix word suggestions: load from picture words (db_words_db_pictures) instead of object words (always empty)
- Backend PATCH /api/directus/db-pairs/<id> handles words_add with link_to and words_remove with junction IDs
- Level range 1-100 throughout
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Backend: GET /api/directus/db-objects/<id>/words via db_objects_db_words
- GenerateIt: load objectWords on object select, show as chips in left sidebar
- PairForm: show object words as clickable suggestion chips above word input
(click to add, greyed out if already added)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Dedup via deep field query auf Object (1 GET statt 2 Junction-GETs)
- Wörter batch-linked via PATCH objects/{id}.linked_words create
- Fragen batch-linked via PATCH objects/{id}.linked_questions create
- related_words + distractor_words via PATCH questions/{id} create
- Keine direkten Junction-Table-POSTs mehr
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove per-call _ensure_junction (junction tables already exist)
- Load existing word/question links upfront (2 GET requests instead of N)
- Batch POST all new words_objects links in a single request
- Batch POST related_words and distractor_words per new question
- Eliminates O(N) serial GET+POST pattern in favour of O(1) upfront dedup + batch writes
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- GET: Deep-Query über pictures.linked_words statt manuelle Junction-Abfrage
- POST: PATCH /items/pictures/{id} mit linked_words.create statt _ensure_link
- _ensure_junction/_ensure_link für words_pictures entfernt
- Setup-Logik in _setup_words_pictures() ausgelagert (idempotent)
- Batch-Insert aller neuen Links in einem einzigen PATCH-Call
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
words_pictures M2M-Relationen werden idempotent beim POST eingerichtet –
kein manueller Setup-Call nötig.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Einmaliger Setup-Endpoint: setzt special=m2m auf Alias-Felder,
erstellt Relations für words_pictures Junction in Directus.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
_find_or_create_word gibt is_new zurück; bei is_new=False wird das Level
via PATCH aktualisiert. _ensure_link läuft immer → Picture-Junction wird
auch für bereits existierende Wörter angelegt.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Rechte Sidebar in zwei Frames aufgeteilt: Objects (bisherig) + Words (neu)
- Words-Frame: Wörter + Level (1–100) per Bild anlegen, dedupliziert via words_pictures Junction
- Pending-Words in Primary-Farbe mit inline Level-Edit, gespeicherte Words in neutralem Grau
- Save-Button speichert alle pending Words nach Directus (status=draft, title_de, level, picture-Link)
- Automatisches Laden der Bild-Words bei Bildwechsel
- Backend: GET/POST /api/directus/pictures/<pic_id>/words (words_pictures Junction, _find_or_create_word)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Purge lief parallel zum Reload – Fragen wurden vor der Bereinigung geladen.
Globaler Bereinigen-Button lädt jetzt auch direkt neu.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Backend: DELETE question/word räumt alle Junction-Zeilen mit auf
- Backend: /purge-orphans bereinigt verwaiste Junctions per Objekt
- Frontend: reloadQW ruft purgeOrphans vor dem Neu-Laden auf
- Frontend: ↺-Button in Wörter- und Fragen-Sidebar
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Neue Endpoints: GET /api/object/<id>/questions+words, DELETE /api/question/<id>, DELETE /api/word/<id>
- GenerateIt: Wörter-Sidebar mit ×-Chips, Fragen-Sidebar mit Level-Badge und ×
- Laden beim Objekt-Wechsel und nach Generate it
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>