refactor: migrate to new db_* Directus collections
- DrawIt: load db_pictures (status=draft), create db_objects/db_words with blurhash placeholder, finish sets status=objects_created - GenerateIt: load db_pictures (status=objects_created), right panel replaced with manual QA pairs (db_pairs + db_question + db_statement) - Backend: new routes for db_pictures, db_objects, db_words, db_pairs - Types/API: full db_* type definitions and API helpers - Directus: user_notes field in db_objects, M2M db_words<->db_pictures Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -325,3 +325,131 @@ export async function purgeAllOrphans(token: string): Promise<{ orphans_removed:
|
||||
if (!res.ok) throw new Error('Fehler beim globalen Bereinigen')
|
||||
return data
|
||||
}
|
||||
|
||||
// ── DB Pictures ───────────────────────────────────────────────────────────────
|
||||
|
||||
import type { DbPicture, DbObject, DbWord, DbPair } from './types'
|
||||
|
||||
export async function getDbPictures(token: string, status = 'draft'): Promise<DbPicture[]> {
|
||||
const res = await fetch(`/api/directus/db-pictures?status=${status}`, {
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
})
|
||||
if (!res.ok) throw new Error('Fehler beim Laden der db_pictures')
|
||||
const data = await res.json()
|
||||
return data.data as DbPicture[]
|
||||
}
|
||||
|
||||
export async function updateDbPictureStatus(pictureId: string, status: string, token: string): Promise<void> {
|
||||
const res = await fetch(`/api/directus/db-pictures/${pictureId}`, {
|
||||
method: 'PATCH',
|
||||
headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` },
|
||||
body: JSON.stringify({ status }),
|
||||
})
|
||||
if (!res.ok) throw new Error('Fehler beim Aktualisieren des Bild-Status')
|
||||
}
|
||||
|
||||
// ── DB Objects ────────────────────────────────────────────────────────────────
|
||||
|
||||
export async function getDbObjects(pictureId: string, token: string): Promise<DbObject[]> {
|
||||
const res = await fetch(`/api/directus/db-objects?picture_id=${pictureId}`, {
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
})
|
||||
if (!res.ok) throw new Error('Fehler beim Laden der db_objects')
|
||||
const data = await res.json()
|
||||
return data.data as DbObject[]
|
||||
}
|
||||
|
||||
export async function createDbObject(payload: {
|
||||
picture: string
|
||||
selections: import('./types').Selection[] | null
|
||||
user_notes: string | null
|
||||
}, token: string): Promise<DbObject> {
|
||||
const res = await fetch('/api/directus/db-objects', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` },
|
||||
body: JSON.stringify({ ...payload, status: 'draft' }),
|
||||
})
|
||||
const data = await res.json()
|
||||
if (!res.ok) throw new Error(data.errors?.[0]?.message || 'Fehler beim Erstellen des Objekts')
|
||||
return data.data as DbObject
|
||||
}
|
||||
|
||||
export async function updateDbObject(
|
||||
objId: string,
|
||||
payload: Partial<Pick<DbObject, 'user_notes'>>,
|
||||
token: string
|
||||
): Promise<DbObject> {
|
||||
const res = await fetch(`/api/directus/db-objects/${objId}`, {
|
||||
method: 'PATCH',
|
||||
headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` },
|
||||
body: JSON.stringify(payload),
|
||||
})
|
||||
const data = await res.json()
|
||||
if (!res.ok) throw new Error(data.errors?.[0]?.message || 'Fehler beim Aktualisieren')
|
||||
return data.data as DbObject
|
||||
}
|
||||
|
||||
export async function deleteDbObject(objId: string, token: string): Promise<void> {
|
||||
const res = await fetch(`/api/directus/db-objects/${objId}`, {
|
||||
method: 'DELETE',
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
})
|
||||
if (!res.ok) throw new Error('Fehler beim Löschen des Objekts')
|
||||
}
|
||||
|
||||
// ── DB Words for a picture ────────────────────────────────────────────────────
|
||||
|
||||
export async function getDbPictureWords(pictureId: string, token: string): Promise<DbWord[]> {
|
||||
const res = await fetch(`/api/directus/db-pictures/${pictureId}/words`, {
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
})
|
||||
const data = await res.json()
|
||||
if (!res.ok) throw new Error('Fehler beim Laden der Wörter')
|
||||
return data.data as DbWord[]
|
||||
}
|
||||
|
||||
export async function saveDbPictureWords(
|
||||
pictureId: string,
|
||||
words: { titel_de: string; level: number }[],
|
||||
token: string
|
||||
): Promise<{ saved: number }> {
|
||||
const res = await fetch(`/api/directus/db-pictures/${pictureId}/words`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` },
|
||||
body: JSON.stringify({ words }),
|
||||
})
|
||||
const data = await res.json()
|
||||
if (!res.ok) throw new Error(data.error || 'Fehler beim Speichern der Wörter')
|
||||
return data
|
||||
}
|
||||
|
||||
// ── DB Pairs for an object ────────────────────────────────────────────────────
|
||||
|
||||
export async function getDbObjectPairs(objectId: string, token: string): Promise<DbPair[]> {
|
||||
const res = await fetch(`/api/directus/db-objects/${objectId}/pairs`, {
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
})
|
||||
const data = await res.json()
|
||||
if (!res.ok) throw new Error('Fehler beim Laden der Pairs')
|
||||
return data.data as DbPair[]
|
||||
}
|
||||
|
||||
export async function createDbPair(
|
||||
objectId: string,
|
||||
payload: {
|
||||
question_de?: string
|
||||
statement_de: string
|
||||
level: number
|
||||
words: { titel_de: string; level: number }[]
|
||||
},
|
||||
token: string
|
||||
): Promise<{ ok: boolean; pair_id: string; statement_id: string; question_id: string | null }> {
|
||||
const res = await fetch(`/api/directus/db-objects/${objectId}/pairs`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` },
|
||||
body: JSON.stringify(payload),
|
||||
})
|
||||
const data = await res.json()
|
||||
if (!res.ok) throw new Error(data.error || 'Fehler beim Erstellen des Pairs')
|
||||
return data
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user