import { createHash, randomUUID } from "node:crypto"; import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs"; import { tmpdir } from "node:os"; import { join, resolve } from "node:path"; import { afterEach, describe, expect, it } from "vitest"; import { createApp } from "../../apps/api/src/app.js"; import { LatestExportService } from "../../apps/api/src/latest-exports.js"; import { HARD_LIMIT_BYTES, ManagedStorage } from "../../apps/api/src/managed-storage.js"; import { ProjectService } from "../../apps/api/src/projects.js"; import { RegistrationService } from "../../apps/api/src/registration.js"; import { MockResendAdapter } from "../../apps/api/src/resend-adapter.js"; const now = Date.parse("2026-08-03T08:00:00.000Z"); const roots: string[] = []; const closeables: Array<{ close(): void }> = []; const baseHeaders = { host: "127.0.0.1:43121", origin: "http://127.0.0.1:43121" }; const png = Buffer.concat([Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]), Buffer.from("dada-export")]); const jpeg = Buffer.concat([Buffer.from([0xff, 0xd8, 0xff]), Buffer.from("dada-export-jpg")]); function writeEvidence(caseId: string, file: string, value: unknown) { const root = process.env.DADA_EVIDENCE_DIR_LATEST_EXPORTS; if (!root) return; const directory = resolve(root, caseId); mkdirSync(directory, { recursive: true }); writeFileSync(resolve(directory, file), `${JSON.stringify(value, null, 2)}\n`); } async function multipart(fields: Record, bytes: Buffer, type = "image/png") { const form = new FormData(); for (const [key, value] of Object.entries(fields)) form.append(key, value); form.append("export_file", new Blob([bytes], { type }), type === "image/png" ? "latest.png" : "latest.jpg"); const serialized = new Response(form); return { contentType: serialized.headers.get("content-type")!, payload: Buffer.from(await serialized.arrayBuffer()) }; } afterEach(() => { for (const value of closeables.splice(0).reverse()) value.close(); for (const root of roots.splice(0)) rmSync(root, { force: true, recursive: true }); }); async function fixture() { const dataRoot = mkdtempSync(join(tmpdir(), "dada-wp2-07-api-")); roots.push(dataRoot); mkdirSync(join(dataRoot, "db"), { recursive: true }); const databasePath = join(dataRoot, "db", "dada.sqlite3"); const registration = new RegistrationService({ challengePepper: Buffer.alloc(32, 0x31), clock: () => now, currentPrivacyNoticeVersion: "p0a-registration-notice-v1", databasePath, invitePepper: Buffer.alloc(32, 0x32), resend: new MockResendAdapter(), sessionPepper: Buffer.alloc(32, 0x33), }); const projects = new ProjectService({ clock: () => now, databasePath }); const storage = new ManagedStorage({ dataRoot, databasePath }); const latestExports = new LatestExportService({ clock: () => now, databasePath, storage }); closeables.push(latestExports, storage, projects, registration); const ownerId = randomUUID(); registration.database.prepare(`INSERT INTO users ( user_id, normalized_email, role, status, counts_toward_stage_limit, registration_id, created_at ) VALUES (?, 'exports@example.invalid', 'user', 'active', 1, ?, ?)`).run(ownerId, randomUUID(), now); registration.database.prepare("INSERT INTO user_profiles (user_id, creator_name, social_id) VALUES (?, 'Export User', '@export')").run(ownerId); registration.database.prepare("INSERT INTO credit_accounts (user_id, available_balance, reserved_balance, updated_at) VALUES (?, 10, 0, ?)").run(ownerId, now); const session = registration.issueAuthenticatedSession(ownerId, "user"); const csrf = registration.issueUserCsrfToken(session.sessionToken); const created = projects.createProjectForGeneration({ ownerId, prompt: "导出服务", ratio: "3:4", status: "queued" }); const original = await storage.commitStream({ content: (await import("node:stream")).Readable.from(png), expectedMimeType: "image/png", fileKind: "generated", fileName: "original.png", operationId: randomUUID(), ownerRef: ownerId, projectedWriteBytes: png.byteLength, }); projects.linkManagedResource(ownerId, created.project.projectId, original.file_id, "generated"); projects.recordSuccessfulImage({ generationId: created.generation.generationId, imageId: original.file_id }); const app = await createApp({ browserGate: false, latestExports, networkBoundary: { allowTestPort: true }, projects, registration, }); const headers = { ...baseHeaders, cookie: `dada_session=${session.sessionToken}`, "x-csrf-token": csrf }; return { app, created, headers, latestExports, ownerId, projects, registration, storage }; } describe("TDD-WP2-EXP-001 latest export API", () => { it("saves the uploaded bytes as the only latest export for that format and replays export_id without re-metering", async () => { const test = await fixture(); const projectId = test.created.project.projectId; const stateVersion = test.projects.getProject(test.ownerId, projectId).stateVersion; const exportId = randomUUID(); const sha256 = createHash("sha256").update(png).digest("hex"); const body = await multipart({ byte_size: String(png.byteLength), export_id: exportId, format: "png", pixel_height: "1440", pixel_width: "1080", sha256, state_version: String(stateVersion) }, png); const request = () => test.app.inject({ headers: { ...test.headers, "content-type": body.contentType }, method: "PUT", payload: body.payload, url: `/api/v1/projects/${projectId}/latest-exports/png` }); const saved = await request(); const metered = test.storage.getState().managed_content_bytes; const replay = await request(); expect(saved.statusCode).toBe(200); expect(saved.json()).toMatchObject({ export_id: exportId, format: "png", sha256, state_version: stateVersion }); expect(replay.json()).toEqual(saved.json()); expect(test.storage.getState().managed_content_bytes).toBe(metered); expect(test.registration.database.prepare("SELECT COUNT(*) AS count FROM latest_exports WHERE project_id = ? AND format = 'png'").get(projectId)).toEqual({ count: 1 }); const downloaded = await test.app.inject({ headers: { ...baseHeaders, cookie: test.headers.cookie }, method: "GET", url: `/api/v1/projects/${projectId}/latest-exports/png` }); expect(downloaded.statusCode).toBe(200); expect(downloaded.headers["cache-control"]).toContain("no-store"); expect(downloaded.rawPayload).toEqual(png); writeEvidence("TDD-WP2-EXP-001-same-blob-success", "download.json", { byte_size: downloaded.rawPayload.byteLength, sha256: createHash("sha256").update(downloaded.rawPayload).digest("hex") }); writeEvidence("TDD-WP2-EXP-001-same-blob-success", "request.json", { byte_size: png.byteLength, export_id: exportId, format: "png", sha256, state_version: stateVersion }); writeEvidence("TDD-WP2-EXP-001-same-blob-success", "response.json", saved.json()); writeEvidence("TDD-WP2-EXP-001-same-blob-success", "db-diff.json", { latest_rows: 1, replay_metered_delta: 0 }); writeEvidence("TDD-WP2-EXP-001-same-blob-success", "fs-before.json", { managed_export_files: 0 }); writeEvidence("TDD-WP2-EXP-001-same-blob-success", "fs-after.json", { managed_export_files: 1, sha256 }); await test.app.close(); }); it("replaces only the selected format and preserves old latest across conflict, persistence, full, and unavailable failures", async () => { const test = await fixture(); const projectId = test.created.project.projectId; const stateVersion = test.projects.getProject(test.ownerId, projectId).stateVersion; const save = async (format: "jpg" | "png", bytes: Buffer, overrides: Partial> = {}) => { const fields = { byte_size: String(bytes.byteLength), export_id: overrides.export_id ?? randomUUID(), format, pixel_height: "1440", pixel_width: "1080", sha256: overrides.sha256 ?? createHash("sha256").update(bytes).digest("hex"), state_version: overrides.state_version ?? String(stateVersion), }; const body = await multipart(fields, bytes, format === "png" ? "image/png" : "image/jpeg"); return test.app.inject({ headers: { ...test.headers, "content-type": body.contentType }, method: "PUT", payload: body.payload, url: `/api/v1/projects/${projectId}/latest-exports/${format}`, }); }; const oldPng = await save("png", png); const jpg = await save("jpg", jpeg); const replacementBytes = Buffer.concat([png, Buffer.from("-replacement")]); const replacement = await save("png", replacementBytes); expect([oldPng.statusCode, jpg.statusCode, replacement.statusCode]).toEqual([200, 200, 200]); const latestRows = test.registration.database.prepare("SELECT format, export_id FROM latest_exports WHERE project_id = ? ORDER BY format").all(projectId) as Array<{ export_id: string; format: string }>; expect(latestRows).toEqual([ { export_id: jpg.json().export_id, format: "jpg" }, { export_id: replacement.json().export_id, format: "png" }, ]); expect(test.registration.database.prepare("SELECT COUNT(*) AS count FROM managed_files WHERE file_kind = 'export' AND status = 'purged'").get()).toEqual({ count: 1 }); expect(test.registration.database.prepare("SELECT COUNT(*) AS count FROM file_cleanup_queue WHERE reason = 'purge' AND status = 'pending'").get()).toEqual({ count: 1 }); const expectedLatestId = replacement.json().export_id as string; const beforeOldReplay = test.storage.getState().managed_content_bytes; const oldReplay = await save("png", png, { export_id: oldPng.json().export_id }); expect(oldReplay.statusCode).toBe(200); expect(oldReplay.json()).toEqual(oldPng.json()); expect(test.storage.getState().managed_content_bytes).toBe(beforeOldReplay); const stale = await save("png", png, { state_version: String(stateVersion + 1) }); const badHash = await save("png", png, { sha256: "0".repeat(64) }); expect(stale.statusCode).toBe(409); expect(badHash.statusCode).toBe(503); expect(test.registration.database.prepare("SELECT export_id FROM latest_exports WHERE project_id = ? AND format = 'png'").get(projectId)).toEqual({ export_id: expectedLatestId }); test.storage.applyControlledMeasurement(HARD_LIMIT_BYTES); const full = await save("png", png); expect(full.statusCode).toBe(507); expect(full.json()).toMatchObject({ error: { code: "STORAGE_CAPACITY_EXCEEDED", details: { capacity_status: "full" } } }); test.storage.applyControlledMeasurement(0); test.storage.setAvailability({ dataRootWritable: false, diskSpaceAvailable: true, sqliteWritable: true }); const unavailable = await save("png", png); expect(unavailable.statusCode).toBe(507); expect(unavailable.json()).toMatchObject({ error: { details: { capacity_status: "unavailable" } } }); expect(test.registration.database.prepare("SELECT export_id FROM latest_exports WHERE project_id = ? AND format = 'png'").get(projectId)).toEqual({ export_id: expectedLatestId }); writeEvidence("TDD-WP2-EXP-001-result-matrix", "response.json", { content_hash_failure: badHash.statusCode, storage_full: full.statusCode, storage_unavailable: unavailable.statusCode, state_conflict: stale.statusCode, }); writeEvidence("TDD-WP2-EXP-001-result-matrix", "db-diff.json", { latest_export_id_after_failures: expectedLatestId, old_latest_preserved: true }); await test.app.close(); }, 15_000); it("returns stable empty latest state without creating a row and serves only owned originals", async () => { const test = await fixture(); const projectId = test.created.project.projectId; const before = test.registration.database.prepare("SELECT COUNT(*) AS count FROM latest_exports").get(); const missing = await test.app.inject({ headers: { ...baseHeaders, cookie: test.headers.cookie }, method: "GET", url: `/api/v1/projects/${projectId}/latest-exports/jpg` }); const detail = await test.app.inject({ headers: { ...baseHeaders, cookie: test.headers.cookie }, method: "GET", url: `/api/v1/projects/${projectId}` }); const original = await test.app.inject({ headers: { ...baseHeaders, cookie: test.headers.cookie }, method: "GET", url: `/api/v1/private-assets/projects/${projectId}/images/${test.projects.getProject(test.ownerId, projectId).currentImageId}` }); const intruderId = randomUUID(); test.registration.database.prepare(`INSERT INTO users ( user_id, normalized_email, role, status, counts_toward_stage_limit, registration_id, created_at ) VALUES (?, 'exports-other@example.invalid', 'user', 'active', 1, ?, ?)`).run(intruderId, randomUUID(), now); test.registration.database.prepare("INSERT INTO user_profiles (user_id, creator_name, social_id) VALUES (?, 'Other User', '@other_export')").run(intruderId); test.registration.database.prepare("INSERT INTO credit_accounts (user_id, available_balance, reserved_balance, updated_at) VALUES (?, 10, 0, ?)").run(intruderId, now); const intruder = test.registration.issueAuthenticatedSession(intruderId, "user"); const denied = await test.app.inject({ headers: { ...baseHeaders, cookie: `dada_session=${intruder.sessionToken}` }, method: "GET", url: `/api/v1/private-assets/projects/${projectId}/images/${test.projects.getProject(test.ownerId, projectId).currentImageId}`, }); expect(missing.statusCode).toBe(404); expect(detail.json().latest_exports).toEqual([]); expect(test.registration.database.prepare("SELECT COUNT(*) AS count FROM latest_exports").get()).toEqual(before); expect(original.statusCode).toBe(200); expect(original.rawPayload).toEqual(png); expect(denied.statusCode).toBe(404); writeEvidence("TDD-WP2-EXP-002-empty-latest", "response.json", { detail_latest_exports: detail.json().latest_exports, intruder_status: denied.statusCode, jpg_status: missing.statusCode, original_status: original.statusCode }); writeEvidence("TDD-WP2-EXP-002-empty-latest", "db-diff.json", { after: before, before, created_by_read: 0 }); await test.app.close(); }); });