Mijn aanvragen (B): store document bytes + content endpoint

- StoredDocument gains ContentType + byte[] Content; POST /uploads now captures
  the file bytes (in-memory, reset on restart — POC).
- GET /uploads/{documentId}/content streams the bytes: inline for pdf/image
  (browser preview), attachment otherwise (download). 404 for unknown ids
  (covers the demo-* simulation sentinels, which have no bytes).
- Bytes are never serialized into a JSON response; only this endpoint streams them.
- Tests: content served back with type inline for pdf, 404 for unknown. 56/56 green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-01 11:36:28 +02:00
parent 8c3f4c22ee
commit 7b6aac394b
3 changed files with 40 additions and 7 deletions

View File

@@ -107,11 +107,25 @@ api.MapPost("/uploads", async (HttpRequest request) =>
var reject = DocumentRules.RejectUpload(category, file.ContentType, file.Length);
if (reject is not null) return Results.Problem(detail: reject, statusCode: 400);
var doc = DocumentStore.Add(localId, categoryId, wizardId, file.FileName, file.Length, DocumentStore.DemoOwner);
using var ms = new MemoryStream();
await file.CopyToAsync(ms);
var doc = DocumentStore.Add(localId, categoryId, wizardId, file.FileName, file.ContentType, ms.ToArray(), DocumentStore.DemoOwner);
return Results.Created($"/api/v1/uploads/{doc.DocumentId}", new UploadResponse(doc.DocumentId, localId));
})
.ExcludeFromDescription();
// Serve stored bytes so a re-opened wizard can preview/download an upload. Inline
// for pdf/image (browser renders it), attachment otherwise (download).
api.MapGet("/uploads/{documentId}/content", (string documentId) =>
{
var doc = DocumentStore.Get(documentId);
if (doc is null) return Results.NotFound();
var inline = doc.ContentType == "application/pdf" || doc.ContentType.StartsWith("image/");
return Results.File(doc.Content, doc.ContentType, fileDownloadName: inline ? null : doc.FileName);
})
.Produces(StatusCodes.Status200OK)
.Produces(StatusCodes.Status404NotFound);
// Poll-on-return: which of these client localIds have arrived at the BFF.
api.MapGet("/uploads/status", (string? localIds) =>
{