fix(quick-260922-hk4): fehlende Bilddatei aus der alten data-Spalte wiederherstellen

Beim Rundgang aufgefallen: nach dem Umzug zeigt eine Zeile auf eine Datei,
die es auf diesem Server nicht gibt — lokal, weil der Umzug am Host lief und
der Container ein eigenes Volume hat. Derselbe Zustand entsteht im Betrieb,
wenn jemand einen `pg_dump` von vor dem Umzug zurueckspielt: die Bytes
stecken noch in der Spalte `data`, das getrennt gesicherte Volume
`user-files` ist aber leer.

`getBytes` schreibt die Datei in diesem Fall aus `data` neu und liefert sie
aus, statt 404 zu melden. Fehlt beides, bleibt es bei 404. Nach dem
Entfernen der Spalte (eigenes Todo) faellt der Zweig ersatzlos weg.

api-Tests 1186 -> 1188, type-check und lint unveraendert gruen.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-22 15:33:55 +02:00
parent 8cbfb8b69d
commit 82472ee665
2 changed files with 51 additions and 0 deletions
@@ -340,6 +340,37 @@ describe('DashboardImagesService (quick-260921-pi9)', () => {
expect(Buffer.from(result.data).equals(PNG)).toBe(true);
});
it('Test 10b: getBytes — Datei fehlt, aber die alte Spalte `data` traegt die Bytes noch: wiederherstellen statt 404', async () => {
// Fall aus dem Browser-Rundgang 22.09.2026: ein `pg_dump` von vor dem Umzug
// traegt die Bytes noch, das Volume `user-files` wird getrennt gesichert —
// wer nur den Abzug zurueckspielt, haette sonst Zeilen ohne Datei.
const row = makeRow({
id: 'img-alt',
data: PNG,
storagePath: 'user-files/dashboard-images/user-1/img-alt.png',
});
const prisma = makeFakePrisma([row]);
expect(fs.existsSync(storedFile('user-1', 'img-alt'))).toBe(false);
const result = await makeService(prisma).getBytes('img-alt', 'user-1', 'tenant-1');
expect(Buffer.from(result.data).equals(PNG)).toBe(true);
expect(fs.existsSync(storedFile('user-1', 'img-alt'))).toBe(true);
expect(fs.readFileSync(storedFile('user-1', 'img-alt')).equals(PNG)).toBe(true);
});
it('Test 10c: getBytes — Datei fehlt UND `data` ist leer -> 404', async () => {
const row = makeRow({
id: 'img-weg',
data: null,
storagePath: 'user-files/dashboard-images/user-1/img-weg.png',
});
const prisma = makeFakePrisma([row]);
await expect(makeService(prisma).getBytes('img-weg', 'user-1', 'tenant-1')).rejects.toThrow(
NotFoundException,
);
});
it('Test 11: remove — eigenes Bild wird geloescht und { id } geliefert; fremdes (Benutzer ODER Mandant) -> 404 ohne Loeschung', async () => {
const prisma = makeFakePrisma([
makeStoredRow({ id: 'eigen' }),