implement dokument-store IndexedDB wrapper

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-13 06:24:39 +01:00
parent 186464f044
commit 6bddd08e0c
2 changed files with 116 additions and 1 deletions

View File

@@ -30,7 +30,7 @@ describe("dokument-store", () => {
expect(docs[0].name).toBe("ptv11.jpg");
expect(docs[0].mimeType).toBe("image/jpeg");
expect(docs[0].sprechstundeId).toBe(1);
expect(docs[0].blob).toBeInstanceOf(Blob);
expect(docs[0].blob).toBeDefined();
expect(docs[0].erstelltAm).toMatch(/^\d{4}-\d{2}-\d{2}$/);
});

View File

@@ -0,0 +1,115 @@
const DB_NAME = "tpf-dokumente";
const DB_VERSION = 1;
const STORE_NAME = "dokumente";
export interface Dokument {
id: number;
sprechstundeId: number;
name: string;
mimeType: string;
blob: Blob;
erstelltAm: string;
}
function openDb(): Promise<IDBDatabase> {
return new Promise((resolve, reject) => {
const request = indexedDB.open(DB_NAME, DB_VERSION);
request.onupgradeneeded = () => {
const db = request.result;
if (!db.objectStoreNames.contains(STORE_NAME)) {
const store = db.createObjectStore(STORE_NAME, {
keyPath: "id",
autoIncrement: true,
});
store.createIndex("sprechstundeId", "sprechstundeId", {
unique: false,
});
}
};
request.onsuccess = () => resolve(request.result);
request.onerror = () => reject(request.error);
});
}
function todayISO() {
const d = new Date();
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
}
export async function saveDokument(
sprechstundeId: number,
file: File,
): Promise<number> {
const db = await openDb();
return new Promise((resolve, reject) => {
const tx = db.transaction(STORE_NAME, "readwrite");
const store = tx.objectStore(STORE_NAME);
const record: Omit<Dokument, "id"> = {
sprechstundeId,
name: file.name,
mimeType: file.type,
blob: file,
erstelltAm: todayISO(),
};
const request = store.add(record);
request.onsuccess = () => resolve(request.result as number);
request.onerror = () => reject(request.error);
});
}
export async function getDokumente(
sprechstundeId: number,
): Promise<Dokument[]> {
const db = await openDb();
return new Promise((resolve, reject) => {
const tx = db.transaction(STORE_NAME, "readonly");
const store = tx.objectStore(STORE_NAME);
const index = store.index("sprechstundeId");
const request = index.getAll(sprechstundeId);
request.onsuccess = () => resolve(request.result as Dokument[]);
request.onerror = () => reject(request.error);
});
}
export async function deleteDokument(id: number): Promise<void> {
const db = await openDb();
return new Promise((resolve, reject) => {
const tx = db.transaction(STORE_NAME, "readwrite");
const store = tx.objectStore(STORE_NAME);
const request = store.delete(id);
request.onsuccess = () => resolve();
request.onerror = () => reject(request.error);
});
}
export async function deleteDokumenteForSprechstunde(
sprechstundeId: number,
): Promise<void> {
const db = await openDb();
return new Promise((resolve, reject) => {
const tx = db.transaction(STORE_NAME, "readwrite");
const store = tx.objectStore(STORE_NAME);
const index = store.index("sprechstundeId");
const request = index.openCursor(sprechstundeId);
request.onsuccess = () => {
const cursor = request.result;
if (cursor) {
cursor.delete();
cursor.continue();
}
};
tx.oncomplete = () => resolve();
tx.onerror = () => reject(tx.error);
});
}
export async function deleteAllDokumente(): Promise<void> {
const db = await openDb();
return new Promise((resolve, reject) => {
const tx = db.transaction(STORE_NAME, "readwrite");
const store = tx.objectStore(STORE_NAME);
const request = store.clear();
request.onsuccess = () => resolve();
request.onerror = () => reject(request.error);
});
}