Merged in feature/download-pdf (pull request #216)
retrieve document by id and tests * working * missing files
This commit is contained in:
@@ -4,9 +4,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
|
||||
|
||||
## linting all edits after every change
|
||||
|
||||
Always run `task lint` once you think you are done with edits to verify your changes have not caused other issues.
|
||||
When running `task lint` output should always be clean. 0 errors.
|
||||
Warnings about variable not set are ok.
|
||||
Always run `task lint` once you think you are done with edits to verify your changes have not caused other issues output must always be clean. 0 errors.
|
||||
Lint output output must contain ‘Linting passed, A perfect score! well done!’ or you must fix an issue to resume.
|
||||
|
||||
Use `task go:lint -- --fix` to fix go (file not formmatted) types of errors from lint. Always run this before running `task fullsuite:ci`
|
||||
@@ -45,6 +43,7 @@ Use `task go:lint -- --fix` to fix go (file not formmatted) types of errors from
|
||||
- Never use mocks unless its too difficult to use the real asset and then you must get Q permission first to mock.
|
||||
|
||||
## Architecture Overview
|
||||
see docs/ai.generated/README.md for an index of all of the system documentation files in docs/ai.generated for more detailed information but this document here should suffice for most jobs.
|
||||
|
||||
### System Design
|
||||
|
||||
@@ -54,7 +53,7 @@ This is a **document processing platform** with microservices architecture using
|
||||
- **RESTful API** (queryAPI on port 8080) for external interactions
|
||||
- **Runner services** (ports 8081-8089) as queue consumers
|
||||
- **PostgreSQL** with migration-driven schema management
|
||||
- **AWS services** (S3, SQS, Textract, Cognito) for cloud functionality
|
||||
- **AWS services** (S3, SQS, Cognito) for cloud functionality
|
||||
|
||||
### Document Processing Pipeline
|
||||
|
||||
|
||||
+323
-298
@@ -1645,6 +1645,9 @@ type ServerInterface interface {
|
||||
// Get document details by its id
|
||||
// (GET /document/{id})
|
||||
GetDocument(ctx echo.Context, id DocumentID, params GetDocumentParams) error
|
||||
// Download the original document file
|
||||
// (GET /document/{id}/download)
|
||||
DownloadDocument(ctx echo.Context, id DocumentID) error
|
||||
// Get all labels for a document
|
||||
// (GET /documents/{documentId}/labels)
|
||||
GetDocumentLabels(ctx echo.Context, documentId openapi_types.UUID) error
|
||||
@@ -2446,6 +2449,24 @@ func (w *ServerInterfaceWrapper) GetDocument(ctx echo.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// DownloadDocument converts echo context to params.
|
||||
func (w *ServerInterfaceWrapper) DownloadDocument(ctx echo.Context) error {
|
||||
var err error
|
||||
// ------------- Path parameter "id" -------------
|
||||
var id DocumentID
|
||||
|
||||
err = runtime.BindStyledParameterWithOptions("simple", "id", ctx.Param("id"), &id, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true})
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter id: %s", err))
|
||||
}
|
||||
|
||||
ctx.Set(JwtAuthScopes, []string{})
|
||||
|
||||
// Invoke the callback with all the unmarshaled arguments
|
||||
err = w.Handler.DownloadDocument(ctx, id)
|
||||
return err
|
||||
}
|
||||
|
||||
// GetDocumentLabels converts echo context to params.
|
||||
func (w *ServerInterfaceWrapper) GetDocumentLabels(ctx echo.Context) error {
|
||||
var err error
|
||||
@@ -2958,6 +2979,7 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL
|
||||
router.GET(baseURL+"/clients", wrapper.ListClients)
|
||||
router.DELETE(baseURL+"/document/:id", wrapper.DeleteDocument)
|
||||
router.GET(baseURL+"/document/:id", wrapper.GetDocument)
|
||||
router.GET(baseURL+"/document/:id/download", wrapper.DownloadDocument)
|
||||
router.GET(baseURL+"/documents/:documentId/labels", wrapper.GetDocumentLabels)
|
||||
router.POST(baseURL+"/documents/:documentId/labels", wrapper.ApplyLabel)
|
||||
router.GET(baseURL+"/eula", wrapper.GetCurrentEula)
|
||||
@@ -2990,304 +3012,307 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL
|
||||
// Base64 encoded, gzipped, json marshaled Swagger object
|
||||
var swaggerSpec = []string{
|
||||
|
||||
"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",
|
||||
"li7fPn37/wMAAP//PHTNMpLfAQA=",
|
||||
"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",
|
||||
}
|
||||
|
||||
// GetSwagger returns the content of the embedded swagger specification file
|
||||
|
||||
+15
-13
@@ -8,6 +8,7 @@ import (
|
||||
collectorset "queryorchestration/internal/collector/set"
|
||||
"queryorchestration/internal/document"
|
||||
documentbatch "queryorchestration/internal/document/batch"
|
||||
documentdownload "queryorchestration/internal/document/download"
|
||||
documentupload "queryorchestration/internal/document/upload"
|
||||
"queryorchestration/internal/eula"
|
||||
"queryorchestration/internal/export"
|
||||
@@ -24,19 +25,20 @@ const Name = "queryAPI"
|
||||
// Services contains all service dependencies for the API controllers.
|
||||
// Query-related services have been removed - see remove_query_plan.md.
|
||||
type Services struct {
|
||||
Export *export.Service
|
||||
Collector *collector.Service
|
||||
CollectorSet *collectorset.Service
|
||||
Client *client.Service
|
||||
ClientUpdate *clientupdate.Service
|
||||
Document *document.Service
|
||||
DocumentUpload *documentupload.Service
|
||||
DocumentBatch *documentbatch.Service
|
||||
UISettings *uisettings.Service
|
||||
FieldExtraction *fieldextraction.Service
|
||||
Folder *folder.Service
|
||||
Label *label.Service
|
||||
Eula *eula.Service
|
||||
Export *export.Service
|
||||
Collector *collector.Service
|
||||
CollectorSet *collectorset.Service
|
||||
Client *client.Service
|
||||
ClientUpdate *clientupdate.Service
|
||||
Document *document.Service
|
||||
DocumentUpload *documentupload.Service
|
||||
DocumentDownload *documentdownload.Service
|
||||
DocumentBatch *documentbatch.Service
|
||||
UISettings *uisettings.Service
|
||||
FieldExtraction *fieldextraction.Service
|
||||
Folder *folder.Service
|
||||
Label *label.Service
|
||||
Eula *eula.Service
|
||||
}
|
||||
|
||||
// ConfigProvider combines auth, objectstore, and background runner for the Controllers.
|
||||
|
||||
@@ -15,6 +15,23 @@ import (
|
||||
openapi_types "github.com/oapi-codegen/runtime/types"
|
||||
)
|
||||
|
||||
// DownloadDocument streams the original uploaded document file to the client.
|
||||
func (s *Controllers) DownloadDocument(ctx echo.Context, id DocumentID) error {
|
||||
result, err := s.svc.DocumentDownload.GetDownload(ctx.Request().Context(), uuid.UUID(id))
|
||||
if err != nil {
|
||||
slog.Error("unable to download document", "error", err, "document_id", id)
|
||||
return echo.NewHTTPError(http.StatusNotFound, fmt.Sprintf("Unable to download document: %s", err))
|
||||
}
|
||||
defer result.Body.Close()
|
||||
|
||||
ctx.Response().Header().Set("Content-Disposition",
|
||||
fmt.Sprintf(`attachment; filename="%s"`, result.Filename))
|
||||
ctx.Response().Header().Set("Content-Length",
|
||||
fmt.Sprintf("%d", result.Size))
|
||||
|
||||
return ctx.Stream(http.StatusOK, result.ContentType, result.Body)
|
||||
}
|
||||
|
||||
func (s *Controllers) UploadDocument(ctx echo.Context, clientId ClientID) error {
|
||||
form, err := ctx.MultipartForm()
|
||||
if err != nil {
|
||||
|
||||
@@ -759,6 +759,123 @@ func TestGetDocument_NilFileSize(t *testing.T) {
|
||||
assert.Nil(t, result.FileSizeBytes, "legacy document should have nil file size")
|
||||
}
|
||||
|
||||
func TestDownloadDocument_Handler(t *testing.T) {
|
||||
cfg := &ControllerConfig{}
|
||||
test.CreateDB(t, cfg)
|
||||
initializeTestConfig(t, cfg)
|
||||
test.CreateAWSResources(t, cfg)
|
||||
|
||||
svc := createControllerServices(cfg)
|
||||
cons := queryapi.NewControllers(svc, cfg)
|
||||
|
||||
// Create test client with root folder
|
||||
test.CreateTestClient(t, cfg, "download_client", "Download Client")
|
||||
|
||||
// Create document with filename
|
||||
filename := "test-report.pdf"
|
||||
fileContent := []byte("test file content for download")
|
||||
docId, err := cfg.GetDBQueries().CreateDocument(t.Context(), &repository.CreateDocumentParams{
|
||||
Clientid: "download_client",
|
||||
Hash: "download_hash",
|
||||
Filename: &filename,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
// Upload content to S3
|
||||
bucket := cfg.GetBucket()
|
||||
s3Key := "test/download/" + docId.String()
|
||||
_, err = cfg.GetStoreClient().PutObject(t.Context(), &s3.PutObjectInput{
|
||||
Bucket: &bucket,
|
||||
Key: &s3Key,
|
||||
Body: bytes.NewReader(fileContent),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
// Create document entry linking document to S3 object
|
||||
err = cfg.GetDBQueries().AddDocumentEntry(t.Context(), &repository.AddDocumentEntryParams{
|
||||
Documentid: docId,
|
||||
Bucket: bucket,
|
||||
Key: s3Key,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
// Call handler
|
||||
ctx, rec := createContext(t)
|
||||
err = cons.DownloadDocument(ctx, docId)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, http.StatusOK, rec.Code)
|
||||
assert.Equal(t, "application/pdf", rec.Header().Get("Content-Type"))
|
||||
assert.Contains(t, rec.Header().Get("Content-Disposition"), "test-report.pdf")
|
||||
assert.Equal(t, fileContent, rec.Body.Bytes())
|
||||
}
|
||||
|
||||
func TestDownloadDocument_Handler_NotFound(t *testing.T) {
|
||||
cfg := &ControllerConfig{}
|
||||
test.CreateDB(t, cfg)
|
||||
initializeTestConfig(t, cfg)
|
||||
test.CreateAWSResources(t, cfg)
|
||||
|
||||
svc := createControllerServices(cfg)
|
||||
cons := queryapi.NewControllers(svc, cfg)
|
||||
|
||||
// Call handler with non-existent document ID
|
||||
ctx, _ := createContext(t)
|
||||
err := cons.DownloadDocument(ctx, uuid.New())
|
||||
require.Error(t, err)
|
||||
httpErr, ok := err.(*echo.HTTPError)
|
||||
require.True(t, ok)
|
||||
assert.Equal(t, http.StatusNotFound, httpErr.Code)
|
||||
}
|
||||
|
||||
func TestDownloadDocument_Handler_ContentDisposition(t *testing.T) {
|
||||
cfg := &ControllerConfig{}
|
||||
test.CreateDB(t, cfg)
|
||||
initializeTestConfig(t, cfg)
|
||||
test.CreateAWSResources(t, cfg)
|
||||
|
||||
svc := createControllerServices(cfg)
|
||||
cons := queryapi.NewControllers(svc, cfg)
|
||||
|
||||
// Create client
|
||||
test.CreateTestClient(t, cfg, "dl_disposition_client", "Disposition Client")
|
||||
|
||||
// Create document with specific filename
|
||||
filename := "quarterly-financial-report.pdf"
|
||||
fileContent := []byte("financial report content")
|
||||
docId, err := cfg.GetDBQueries().CreateDocument(t.Context(), &repository.CreateDocumentParams{
|
||||
Clientid: "dl_disposition_client",
|
||||
Hash: "disposition_hash",
|
||||
Filename: &filename,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
bucket := cfg.GetBucket()
|
||||
s3Key := "test/download/" + docId.String()
|
||||
_, err = cfg.GetStoreClient().PutObject(t.Context(), &s3.PutObjectInput{
|
||||
Bucket: &bucket,
|
||||
Key: &s3Key,
|
||||
Body: bytes.NewReader(fileContent),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
err = cfg.GetDBQueries().AddDocumentEntry(t.Context(), &repository.AddDocumentEntryParams{
|
||||
Documentid: docId,
|
||||
Bucket: bucket,
|
||||
Key: s3Key,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
ctx, rec := createContext(t)
|
||||
err = cons.DownloadDocument(ctx, docId)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, http.StatusOK, rec.Code)
|
||||
|
||||
// Verify Content-Disposition header contains the original filename
|
||||
contentDisposition := rec.Header().Get("Content-Disposition")
|
||||
assert.Contains(t, contentDisposition, "attachment")
|
||||
assert.Contains(t, contentDisposition, "quarterly-financial-report.pdf")
|
||||
}
|
||||
|
||||
// Helper function to create test ZIP with multiple PDFs
|
||||
func createTestZIPFile(t *testing.T, pdfCount int) *bytes.Reader {
|
||||
var buf bytes.Buffer
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
collectorset "queryorchestration/internal/collector/set"
|
||||
"queryorchestration/internal/document"
|
||||
documentbatch "queryorchestration/internal/document/batch"
|
||||
documentdownload "queryorchestration/internal/document/download"
|
||||
documentupload "queryorchestration/internal/document/upload"
|
||||
"queryorchestration/internal/eula"
|
||||
"queryorchestration/internal/export"
|
||||
@@ -47,6 +48,7 @@ func createControllerServices(cfg *ControllerConfig) *queryapi.Services {
|
||||
})
|
||||
doc := document.New(cfg)
|
||||
docup := documentupload.New(cfg)
|
||||
docdownload := documentdownload.New(cfg)
|
||||
docbatch := documentbatch.New(cfg)
|
||||
fieldext := fieldextraction.New(cfg)
|
||||
fld := folder.New(cfg)
|
||||
@@ -55,18 +57,19 @@ func createControllerServices(cfg *ControllerConfig) *queryapi.Services {
|
||||
uiSvc := uisettings.New(cfg)
|
||||
|
||||
return &queryapi.Services{
|
||||
Export: exp,
|
||||
Collector: col,
|
||||
CollectorSet: colupdate,
|
||||
Client: cli,
|
||||
ClientUpdate: cliUpdate,
|
||||
Document: doc,
|
||||
DocumentUpload: docup,
|
||||
DocumentBatch: docbatch,
|
||||
UISettings: uiSvc,
|
||||
FieldExtraction: fieldext,
|
||||
Folder: fld,
|
||||
Label: lbl,
|
||||
Eula: eul,
|
||||
Export: exp,
|
||||
Collector: col,
|
||||
CollectorSet: colupdate,
|
||||
Client: cli,
|
||||
ClientUpdate: cliUpdate,
|
||||
Document: doc,
|
||||
DocumentUpload: docup,
|
||||
DocumentDownload: docdownload,
|
||||
DocumentBatch: docbatch,
|
||||
UISettings: uiSvc,
|
||||
FieldExtraction: fieldext,
|
||||
Folder: fld,
|
||||
Label: lbl,
|
||||
Eula: eul,
|
||||
}
|
||||
}
|
||||
|
||||
+16
-13
@@ -28,6 +28,7 @@ import (
|
||||
collectorset "queryorchestration/internal/collector/set"
|
||||
"queryorchestration/internal/document"
|
||||
documentbatch "queryorchestration/internal/document/batch"
|
||||
documentdownload "queryorchestration/internal/document/download"
|
||||
documentupload "queryorchestration/internal/document/upload"
|
||||
"queryorchestration/internal/eula"
|
||||
"queryorchestration/internal/export"
|
||||
@@ -75,6 +76,7 @@ func main() {
|
||||
})
|
||||
doc := document.New(cfg)
|
||||
docup := documentupload.New(cfg)
|
||||
docdownload := documentdownload.New(cfg)
|
||||
docbatch := documentbatch.New(cfg)
|
||||
fieldext := fieldextraction.New(cfg)
|
||||
fld := folder.New(cfg)
|
||||
@@ -83,19 +85,20 @@ func main() {
|
||||
uiSvc := uisettings.New(cfg)
|
||||
|
||||
services := &queryapi.Services{
|
||||
Export: exp,
|
||||
Collector: col,
|
||||
CollectorSet: colupdate,
|
||||
Client: cli,
|
||||
ClientUpdate: cliUpdate,
|
||||
Document: doc,
|
||||
DocumentUpload: docup,
|
||||
DocumentBatch: docbatch,
|
||||
UISettings: uiSvc,
|
||||
FieldExtraction: fieldext,
|
||||
Folder: fld,
|
||||
Label: lbl,
|
||||
Eula: eul,
|
||||
Export: exp,
|
||||
Collector: col,
|
||||
CollectorSet: colupdate,
|
||||
Client: cli,
|
||||
ClientUpdate: cliUpdate,
|
||||
Document: doc,
|
||||
DocumentUpload: docup,
|
||||
DocumentDownload: docdownload,
|
||||
DocumentBatch: docbatch,
|
||||
UISettings: uiSvc,
|
||||
FieldExtraction: fieldext,
|
||||
Folder: fld,
|
||||
Label: lbl,
|
||||
Eula: eul,
|
||||
}
|
||||
|
||||
cons := queryapi.NewControllers(services, cfg)
|
||||
|
||||
@@ -387,6 +387,44 @@ Retrieves enriched document details by ID, including metadata such as folder, fi
|
||||
}
|
||||
```
|
||||
|
||||
### `GET /document/{id}/download`
|
||||
|
||||
Streams the original uploaded document file directly from S3. The response Content-Type is auto-detected from the stored filename extension.
|
||||
|
||||
**Security**: Requires JWT authentication
|
||||
|
||||
**Path Parameters**:
|
||||
|
||||
- `id`: Document UUID (max 36 chars)
|
||||
|
||||
**Response** (`200`): Raw file bytes (streamed)
|
||||
|
||||
- `Content-Type`: Auto-detected from filename (e.g., `application/pdf`, `image/png`, `application/vnd.openxmlformats-officedocument.wordprocessingml.document`)
|
||||
- `Content-Disposition`: `attachment; filename="<original_filename>"`
|
||||
- `Content-Length`: File size in bytes
|
||||
|
||||
**Error Responses**:
|
||||
|
||||
- `400`: Invalid document ID format
|
||||
- `401`: Missing or invalid JWT token
|
||||
- `404`: Document not found or no S3 entry for the document
|
||||
- `500`: S3 retrieval failure
|
||||
|
||||
**Example**:
|
||||
|
||||
```bash
|
||||
curl -H "Authorization: Bearer <token>" \
|
||||
-o report.pdf \
|
||||
http://localhost:8080/document/019580df-ef65-7676-8de9-94435a93337a/download
|
||||
```
|
||||
|
||||
**Notes**:
|
||||
|
||||
- No query parameters needed -- file type is automatically determined from the stored filename
|
||||
- Response streams directly from S3, suitable for large files
|
||||
- Returns 404 if the document has no stored file (e.g., legacy documents without S3 entries)
|
||||
- Supports any file type without code changes (PDF, PNG, DOCX, CSV, etc.)
|
||||
|
||||
### `DELETE /document/{id}`
|
||||
|
||||
Permanently deletes a document and all dependent data: document entries, cleans (and their entries), text extractions (and their entries), field extractions (versions and array fields), labels, results, and result dependencies. Source documents in S3 are NOT deleted; their paths are logged and optionally returned.
|
||||
@@ -1874,6 +1912,7 @@ The following table shows what data is passed to Permit.io for each protected en
|
||||
| `POST` | `/client/{id}/document` | `client` | `post` | Upload document |
|
||||
| `GET` | `/client/{id}/document` | `client` | `get` | List client documents |
|
||||
| `GET` | `/document/{id}` | `document` | `get` | Get document details |
|
||||
| `GET` | `/document/{id}/download` | `document` | `get` | Download document file |
|
||||
| `DELETE` | `/document/{id}` | `document` | `delete` | Hard-delete document (super_admin only) |
|
||||
| **Batch Document Operations** |
|
||||
| `POST` | `/client/{id}/document/batch` | `client` | `post` | Upload batch (ZIP) |
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
## Overview
|
||||
|
||||
|
||||
This documentation provides comprehensive coverage of the DoczyAI Document Processing Platform - a cloud-native document processing system designed to extract structured information from documents.
|
||||
|
||||
## Documentation Structure
|
||||
@@ -105,7 +106,7 @@ This documentation provides comprehensive coverage of the DoczyAI Document Proce
|
||||
- **Monitoring**: Prometheus + OpenTelemetry
|
||||
|
||||
### 📊 Key Capabilities
|
||||
- **Document Processing**: PDF upload, initialization, sync-gating, and cleaning
|
||||
- **Document Processing**: PDF upload, download, initialization, sync-gating, and cleaning
|
||||
- **Multi-tenant Support**: Isolated client environments
|
||||
- **Document Organization**: Folders and labels for document management
|
||||
- **Export Operations**: Structured data export in multiple formats
|
||||
|
||||
@@ -25,6 +25,7 @@ This document provides a comprehensive summary of all REST API endpoints availab
|
||||
| /client/{id}/document/batch | GET, POST | DocumentsService |
|
||||
| /client/{id}/document/batch/{batch_id} | GET | DocumentsService |
|
||||
| /document/{id} | GET, DELETE | DocumentsService |
|
||||
| /document/{id}/download | GET | DocumentsService |
|
||||
| /documents/{documentId}/labels | GET, POST | LabelService |
|
||||
| /labels/{labelName}/documents | GET | LabelService |
|
||||
| /field-extractions | GET, POST | FieldExtractionService |
|
||||
@@ -165,6 +166,12 @@ This document provides a comprehensive summary of all REST API endpoints availab
|
||||
- `textRecord` (optional, default: false) - When true, includes full text extraction record
|
||||
- Returns: `{id, client_id, hash, folder_id, filename, labels[], fields{}, text_record?}`
|
||||
|
||||
- **GET /document/{id}/download** - Download the original document file
|
||||
- Streams file directly from S3 storage
|
||||
- Content-Type auto-detected from stored filename extension
|
||||
- Returns: Raw file bytes with `Content-Disposition: attachment` header
|
||||
- Supports any file type (PDF, PNG, DOCX, CSV, etc.)
|
||||
|
||||
- **DELETE /document/{id}** - Hard-delete a document and all dependent data (super_admin only)
|
||||
- Query Parameters:
|
||||
- `verbose` (optional, default: false) - When true, returns S3 paths of orphaned source documents
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
package documentdownload
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"mime"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
// DownloadResult contains the data needed to stream a document file to the client.
|
||||
type DownloadResult struct {
|
||||
Body io.ReadCloser // S3 object body - caller must close
|
||||
Filename string // Original filename (for Content-Disposition)
|
||||
ContentType string // MIME type detected from filename extension
|
||||
Size int64 // File size in bytes (for Content-Length)
|
||||
}
|
||||
|
||||
// GetDownload retrieves the document file bytes from S3.
|
||||
// Returns a DownloadResult with a streaming body that the caller must close.
|
||||
func (s *Service) GetDownload(ctx context.Context, id uuid.UUID) (*DownloadResult, error) {
|
||||
// Get document metadata (filename) from DB
|
||||
doc, err := s.cfg.GetDBQueries().GetDocumentEnriched(ctx, id)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("document not found: %w", err)
|
||||
}
|
||||
|
||||
// Get S3 entry (bucket, key) from documentEntries
|
||||
entry, err := s.cfg.GetDBQueries().GetDocumentEntry(ctx, id)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("no S3 entry for document: %w", err)
|
||||
}
|
||||
|
||||
// GetObject from S3
|
||||
output, err := s.cfg.GetStoreClient().GetObject(ctx, &s3.GetObjectInput{
|
||||
Bucket: &entry.Bucket,
|
||||
Key: &entry.Key,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to retrieve file from S3: %w", err)
|
||||
}
|
||||
|
||||
// Detect MIME type from filename extension
|
||||
filename := ""
|
||||
if doc.Filename != nil {
|
||||
filename = *doc.Filename
|
||||
}
|
||||
contentType := detectContentType(filename)
|
||||
|
||||
// Get file size
|
||||
var size int64
|
||||
if output.ContentLength != nil {
|
||||
size = *output.ContentLength
|
||||
}
|
||||
|
||||
return &DownloadResult{
|
||||
Body: output.Body,
|
||||
Filename: filename,
|
||||
ContentType: contentType,
|
||||
Size: size,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// detectContentType determines the MIME type based on file extension.
|
||||
func detectContentType(filename string) string {
|
||||
if filename == "" {
|
||||
return "application/octet-stream"
|
||||
}
|
||||
contentType := mime.TypeByExtension(filepath.Ext(filename))
|
||||
if contentType == "" {
|
||||
return "application/octet-stream"
|
||||
}
|
||||
return contentType
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
package documentdownload_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"testing"
|
||||
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3"
|
||||
"github.com/google/uuid"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"queryorchestration/internal/client"
|
||||
"queryorchestration/internal/database/repository"
|
||||
documentdownload "queryorchestration/internal/document/download"
|
||||
"queryorchestration/internal/serviceconfig"
|
||||
"queryorchestration/internal/serviceconfig/objectstore"
|
||||
"queryorchestration/internal/test"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
serviceconfig.BaseConfig
|
||||
objectstore.ObjectStoreConfig
|
||||
}
|
||||
|
||||
// createTestClient creates a client using the client service, which automatically creates the root folder.
|
||||
func createTestClient(t *testing.T, cfg *Config, clientID, clientName string) {
|
||||
t.Helper()
|
||||
clientSvc := client.New(cfg)
|
||||
_, err := clientSvc.Create(t.Context(), client.CreateParams{
|
||||
ID: clientID,
|
||||
Name: clientName,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
// setupTestDocument creates a document in DB, uploads content to S3, and creates the document entry.
|
||||
// Returns the document ID.
|
||||
func setupTestDocument(t *testing.T, cfg *Config, clientID, hash string, filename *string, content []byte) uuid.UUID {
|
||||
t.Helper()
|
||||
|
||||
docID, err := cfg.GetDBQueries().CreateDocument(t.Context(), &repository.CreateDocumentParams{
|
||||
Clientid: clientID,
|
||||
Hash: hash,
|
||||
Filename: filename,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
bucket := cfg.GetBucket()
|
||||
s3Key := "test/download/" + docID.String()
|
||||
|
||||
_, err = cfg.GetStoreClient().PutObject(t.Context(), &s3.PutObjectInput{
|
||||
Bucket: &bucket,
|
||||
Key: &s3Key,
|
||||
Body: bytes.NewReader(content),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
err = cfg.GetDBQueries().AddDocumentEntry(t.Context(), &repository.AddDocumentEntryParams{
|
||||
Documentid: docID,
|
||||
Bucket: bucket,
|
||||
Key: s3Key,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
return docID
|
||||
}
|
||||
|
||||
func TestDownloadDocument_Success(t *testing.T) {
|
||||
t.Parallel()
|
||||
cfg := &Config{}
|
||||
test.CreateDB(t, cfg)
|
||||
test.CreateAWSResources(t, cfg)
|
||||
|
||||
createTestClient(t, cfg, "dl_success_client", "Download Success Client")
|
||||
|
||||
filename := "test-report.pdf"
|
||||
fileContent := []byte("test file content for download verification")
|
||||
docID := setupTestDocument(t, cfg, "dl_success_client", "dl_success_hash", &filename, fileContent)
|
||||
|
||||
svc := documentdownload.New(cfg)
|
||||
result, err := svc.GetDownload(t.Context(), docID)
|
||||
require.NoError(t, err)
|
||||
defer result.Body.Close()
|
||||
|
||||
body, err := io.ReadAll(result.Body)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, fileContent, body)
|
||||
assert.Equal(t, "test-report.pdf", result.Filename)
|
||||
assert.Equal(t, "application/pdf", result.ContentType)
|
||||
}
|
||||
|
||||
func TestDownloadDocument_NotFound(t *testing.T) {
|
||||
t.Parallel()
|
||||
cfg := &Config{}
|
||||
test.CreateDB(t, cfg)
|
||||
test.CreateAWSResources(t, cfg)
|
||||
|
||||
svc := documentdownload.New(cfg)
|
||||
_, err := svc.GetDownload(t.Context(), uuid.New())
|
||||
require.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "document not found")
|
||||
}
|
||||
|
||||
func TestDownloadDocument_NoS3Entry(t *testing.T) {
|
||||
t.Parallel()
|
||||
cfg := &Config{}
|
||||
test.CreateDB(t, cfg)
|
||||
test.CreateAWSResources(t, cfg)
|
||||
|
||||
createTestClient(t, cfg, "dl_noentry_client", "Download NoEntry Client")
|
||||
|
||||
// Create document but do NOT create a document entry or upload to S3
|
||||
docID, err := cfg.GetDBQueries().CreateDocument(t.Context(), &repository.CreateDocumentParams{
|
||||
Clientid: "dl_noentry_client",
|
||||
Hash: "dl_noentry_hash",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
svc := documentdownload.New(cfg)
|
||||
_, err = svc.GetDownload(t.Context(), docID)
|
||||
require.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "no S3 entry")
|
||||
}
|
||||
|
||||
func TestDownloadDocument_MimeTypeDetection(t *testing.T) {
|
||||
t.Parallel()
|
||||
cfg := &Config{}
|
||||
test.CreateDB(t, cfg)
|
||||
test.CreateAWSResources(t, cfg)
|
||||
|
||||
createTestClient(t, cfg, "dl_mime_client", "Download Mime Client")
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
filename *string
|
||||
expectedMime string
|
||||
}{
|
||||
{
|
||||
name: "PDF file",
|
||||
filename: strPtr("report.pdf"),
|
||||
expectedMime: "application/pdf",
|
||||
},
|
||||
{
|
||||
name: "PNG image",
|
||||
filename: strPtr("photo.png"),
|
||||
expectedMime: "image/png",
|
||||
},
|
||||
{
|
||||
name: "CSV file",
|
||||
filename: strPtr("data.csv"),
|
||||
expectedMime: "text/csv; charset=utf-8",
|
||||
},
|
||||
{
|
||||
name: "nil filename defaults to octet-stream",
|
||||
filename: nil,
|
||||
expectedMime: "application/octet-stream",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
hash := "dl_mime_hash_" + uuid.New().String()[:8]
|
||||
content := []byte("file content " + tc.name)
|
||||
|
||||
docID := setupTestDocument(t, cfg, "dl_mime_client", hash, tc.filename, content)
|
||||
|
||||
svc := documentdownload.New(cfg)
|
||||
result, err := svc.GetDownload(t.Context(), docID)
|
||||
require.NoError(t, err)
|
||||
defer result.Body.Close()
|
||||
|
||||
body, err := io.ReadAll(result.Body)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, tc.expectedMime, result.ContentType)
|
||||
assert.Equal(t, content, body)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func strPtr(s string) *string {
|
||||
return &s
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package documentdownload
|
||||
|
||||
import (
|
||||
"queryorchestration/internal/serviceconfig"
|
||||
"queryorchestration/internal/serviceconfig/objectstore"
|
||||
)
|
||||
|
||||
// ConfigProvider combines database and S3 access for download operations.
|
||||
type ConfigProvider interface {
|
||||
serviceconfig.ConfigProvider
|
||||
objectstore.ConfigProvider
|
||||
}
|
||||
|
||||
// Service handles downloading original document files from S3.
|
||||
type Service struct {
|
||||
cfg ConfigProvider
|
||||
}
|
||||
|
||||
// New creates a new download service.
|
||||
func New(cfg ConfigProvider) *Service {
|
||||
return &Service{cfg: cfg}
|
||||
}
|
||||
@@ -1730,6 +1730,9 @@ type ClientInterface interface {
|
||||
// GetDocument request
|
||||
GetDocument(ctx context.Context, id DocumentID, params *GetDocumentParams, reqEditors ...RequestEditorFn) (*http.Response, error)
|
||||
|
||||
// DownloadDocument request
|
||||
DownloadDocument(ctx context.Context, id DocumentID, reqEditors ...RequestEditorFn) (*http.Response, error)
|
||||
|
||||
// GetDocumentLabels request
|
||||
GetDocumentLabels(ctx context.Context, documentId openapi_types.UUID, reqEditors ...RequestEditorFn) (*http.Response, error)
|
||||
|
||||
@@ -2301,6 +2304,18 @@ func (c *Client) GetDocument(ctx context.Context, id DocumentID, params *GetDocu
|
||||
return c.Client.Do(req)
|
||||
}
|
||||
|
||||
func (c *Client) DownloadDocument(ctx context.Context, id DocumentID, reqEditors ...RequestEditorFn) (*http.Response, error) {
|
||||
req, err := NewDownloadDocumentRequest(c.Server, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req = req.WithContext(ctx)
|
||||
if err := c.applyEditors(ctx, req, reqEditors); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return c.Client.Do(req)
|
||||
}
|
||||
|
||||
func (c *Client) GetDocumentLabels(ctx context.Context, documentId openapi_types.UUID, reqEditors ...RequestEditorFn) (*http.Response, error) {
|
||||
req, err := NewGetDocumentLabelsRequest(c.Server, documentId)
|
||||
if err != nil {
|
||||
@@ -4268,6 +4283,40 @@ func NewGetDocumentRequest(server string, id DocumentID, params *GetDocumentPara
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// NewDownloadDocumentRequest generates requests for DownloadDocument
|
||||
func NewDownloadDocumentRequest(server string, id DocumentID) (*http.Request, error) {
|
||||
var err error
|
||||
|
||||
var pathParam0 string
|
||||
|
||||
pathParam0, err = runtime.StyleParamWithLocation("simple", false, "id", runtime.ParamLocationPath, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
serverURL, err := url.Parse(server)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
operationPath := fmt.Sprintf("/document/%s/download", pathParam0)
|
||||
if operationPath[0] == '/' {
|
||||
operationPath = "." + operationPath
|
||||
}
|
||||
|
||||
queryURL, err := serverURL.Parse(operationPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("GET", queryURL.String(), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// NewGetDocumentLabelsRequest generates requests for GetDocumentLabels
|
||||
func NewGetDocumentLabelsRequest(server string, documentId openapi_types.UUID) (*http.Request, error) {
|
||||
var err error
|
||||
@@ -5476,6 +5525,9 @@ type ClientWithResponsesInterface interface {
|
||||
// GetDocumentWithResponse request
|
||||
GetDocumentWithResponse(ctx context.Context, id DocumentID, params *GetDocumentParams, reqEditors ...RequestEditorFn) (*GetDocumentResponse, error)
|
||||
|
||||
// DownloadDocumentWithResponse request
|
||||
DownloadDocumentWithResponse(ctx context.Context, id DocumentID, reqEditors ...RequestEditorFn) (*DownloadDocumentResponse, error)
|
||||
|
||||
// GetDocumentLabelsWithResponse request
|
||||
GetDocumentLabelsWithResponse(ctx context.Context, documentId openapi_types.UUID, reqEditors ...RequestEditorFn) (*GetDocumentLabelsResponse, error)
|
||||
|
||||
@@ -6430,6 +6482,32 @@ func (r GetDocumentResponse) StatusCode() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
type DownloadDocumentResponse struct {
|
||||
Body []byte
|
||||
HTTPResponse *http.Response
|
||||
JSON400 *InvalidRequest
|
||||
JSON401 *Unauthorized
|
||||
JSON404 *NotFound
|
||||
JSON429 *TooManyRequests
|
||||
JSON500 *InternalError
|
||||
}
|
||||
|
||||
// Status returns HTTPResponse.Status
|
||||
func (r DownloadDocumentResponse) Status() string {
|
||||
if r.HTTPResponse != nil {
|
||||
return r.HTTPResponse.Status
|
||||
}
|
||||
return http.StatusText(0)
|
||||
}
|
||||
|
||||
// StatusCode returns HTTPResponse.StatusCode
|
||||
func (r DownloadDocumentResponse) StatusCode() int {
|
||||
if r.HTTPResponse != nil {
|
||||
return r.HTTPResponse.StatusCode
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type GetDocumentLabelsResponse struct {
|
||||
Body []byte
|
||||
HTTPResponse *http.Response
|
||||
@@ -7479,6 +7557,15 @@ func (c *ClientWithResponses) GetDocumentWithResponse(ctx context.Context, id Do
|
||||
return ParseGetDocumentResponse(rsp)
|
||||
}
|
||||
|
||||
// DownloadDocumentWithResponse request returning *DownloadDocumentResponse
|
||||
func (c *ClientWithResponses) DownloadDocumentWithResponse(ctx context.Context, id DocumentID, reqEditors ...RequestEditorFn) (*DownloadDocumentResponse, error) {
|
||||
rsp, err := c.DownloadDocument(ctx, id, reqEditors...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ParseDownloadDocumentResponse(rsp)
|
||||
}
|
||||
|
||||
// GetDocumentLabelsWithResponse request returning *GetDocumentLabelsResponse
|
||||
func (c *ClientWithResponses) GetDocumentLabelsWithResponse(ctx context.Context, documentId openapi_types.UUID, reqEditors ...RequestEditorFn) (*GetDocumentLabelsResponse, error) {
|
||||
rsp, err := c.GetDocumentLabels(ctx, documentId, reqEditors...)
|
||||
@@ -9706,6 +9793,60 @@ func ParseGetDocumentResponse(rsp *http.Response) (*GetDocumentResponse, error)
|
||||
return response, nil
|
||||
}
|
||||
|
||||
// ParseDownloadDocumentResponse parses an HTTP response from a DownloadDocumentWithResponse call
|
||||
func ParseDownloadDocumentResponse(rsp *http.Response) (*DownloadDocumentResponse, error) {
|
||||
bodyBytes, err := io.ReadAll(rsp.Body)
|
||||
defer func() { _ = rsp.Body.Close() }()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
response := &DownloadDocumentResponse{
|
||||
Body: bodyBytes,
|
||||
HTTPResponse: rsp,
|
||||
}
|
||||
|
||||
switch {
|
||||
case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400:
|
||||
var dest InvalidRequest
|
||||
if err := json.Unmarshal(bodyBytes, &dest); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
response.JSON400 = &dest
|
||||
|
||||
case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 401:
|
||||
var dest Unauthorized
|
||||
if err := json.Unmarshal(bodyBytes, &dest); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
response.JSON401 = &dest
|
||||
|
||||
case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404:
|
||||
var dest NotFound
|
||||
if err := json.Unmarshal(bodyBytes, &dest); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
response.JSON404 = &dest
|
||||
|
||||
case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 429:
|
||||
var dest TooManyRequests
|
||||
if err := json.Unmarshal(bodyBytes, &dest); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
response.JSON429 = &dest
|
||||
|
||||
case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500:
|
||||
var dest InternalError
|
||||
if err := json.Unmarshal(bodyBytes, &dest); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
response.JSON500 = &dest
|
||||
|
||||
}
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
// ParseGetDocumentLabelsResponse parses an HTTP response from a GetDocumentLabelsWithResponse call
|
||||
func ParseGetDocumentLabelsResponse(rsp *http.Response) (*GetDocumentLabelsResponse, error) {
|
||||
bodyBytes, err := io.ReadAll(rsp.Body)
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
# - GET /client/{CLIENT_ID}/document/batch - List all batches for client with pagination
|
||||
# - POST /client/{CLIENT_ID}/document/batch (invalid) - Test error handling with non-ZIP file
|
||||
# - DELETE /client/{CLIENT_ID}/document/batch/{BATCH_ID} - Cancel/delete batch processing
|
||||
# - GET /document/{DOCUMENT_ID}/download - Download a processed document
|
||||
# - GET /document/{FAKE_ID}/download - Verify 404 for non-existent document
|
||||
|
||||
set -e # Exit on any error
|
||||
|
||||
@@ -257,6 +259,124 @@ test_invalid_file() {
|
||||
fi
|
||||
}
|
||||
|
||||
# Wait for at least one document in the batch to have a document_id assigned.
|
||||
# Polls the batch status endpoint until a document_id appears or timeout is reached.
|
||||
wait_for_document_id() {
|
||||
log_info "Waiting for documents to be processed (up to 60s)..."
|
||||
|
||||
local max_wait=60
|
||||
local elapsed=0
|
||||
local interval=3
|
||||
|
||||
while [ $elapsed -lt $max_wait ]; do
|
||||
response=$(curl -s "$BASE_URL/client/$CLIENT_ID/document/batch/$BATCH_ID" 2>/dev/null)
|
||||
|
||||
# Extract first non-null document_id from document_outcomes array
|
||||
DOCUMENT_ID=$(echo "$response" | python3 -c "
|
||||
import sys, json
|
||||
data = json.load(sys.stdin)
|
||||
for outcome in data.get('document_outcomes', []):
|
||||
doc_id = outcome.get('document_id')
|
||||
if doc_id:
|
||||
print(doc_id)
|
||||
sys.exit(0)
|
||||
sys.exit(1)
|
||||
" 2>/dev/null)
|
||||
|
||||
if [ $? -eq 0 ] && [ -n "$DOCUMENT_ID" ]; then
|
||||
log_info "Document ready for download: $DOCUMENT_ID"
|
||||
return 0
|
||||
fi
|
||||
|
||||
sleep $interval
|
||||
elapsed=$((elapsed + interval))
|
||||
log_info "Still waiting... ($elapsed/${max_wait}s)"
|
||||
done
|
||||
|
||||
log_error "Timed out waiting for documents to be processed"
|
||||
return 1
|
||||
}
|
||||
|
||||
# Test downloading a document via GET /document/{id}/download.
|
||||
# Verifies HTTP 200, Content-Disposition header, Content-Type, non-empty body, and PDF magic bytes.
|
||||
test_document_download() {
|
||||
log_info "Testing document download: GET /document/$DOCUMENT_ID/download"
|
||||
|
||||
local output_file="downloaded_document.pdf"
|
||||
|
||||
# Download with headers captured
|
||||
curl -s -D headers.txt -o "$output_file" \
|
||||
"$BASE_URL/document/$DOCUMENT_ID/download" 2>/dev/null
|
||||
|
||||
http_code=$(grep -m1 "^HTTP/" headers.txt | awk '{print $2}')
|
||||
|
||||
if [ "$http_code" != "200" ]; then
|
||||
log_error "Download failed (HTTP $http_code)"
|
||||
cat headers.txt 2>/dev/null
|
||||
rm -f "$output_file" headers.txt
|
||||
return 1
|
||||
fi
|
||||
|
||||
log_info "Download returned HTTP 200"
|
||||
|
||||
# Verify Content-Disposition header is present
|
||||
if grep -qi "Content-Disposition" headers.txt; then
|
||||
disposition=$(grep -i "Content-Disposition" headers.txt | tr -d '\r')
|
||||
log_info "$disposition"
|
||||
else
|
||||
log_error "Missing Content-Disposition header"
|
||||
rm -f "$output_file" headers.txt
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Log Content-Type
|
||||
content_type=$(grep -i "Content-Type" headers.txt | head -1 | tr -d '\r')
|
||||
log_info "$content_type"
|
||||
|
||||
# Verify file is non-empty
|
||||
file_size=$(stat -f%z "$output_file" 2>/dev/null || stat -c%s "$output_file" 2>/dev/null || echo "0")
|
||||
if [ "$file_size" -eq 0 ]; then
|
||||
log_error "Downloaded file is empty"
|
||||
rm -f "$output_file" headers.txt
|
||||
return 1
|
||||
fi
|
||||
log_info "Downloaded file size: $file_size bytes"
|
||||
|
||||
# Verify file starts with PDF magic bytes (%PDF)
|
||||
file_header=$(head -c 4 "$output_file")
|
||||
if [ "$file_header" = "%PDF" ]; then
|
||||
log_info "File is a valid PDF (starts with %%PDF header)"
|
||||
else
|
||||
log_warn "File does not start with %%PDF header (got: $file_header)"
|
||||
fi
|
||||
|
||||
# Cleanup
|
||||
rm -f "$output_file" headers.txt
|
||||
|
||||
log_info "Document download test PASSED"
|
||||
return 0
|
||||
}
|
||||
|
||||
# Test that downloading a non-existent document returns 404.
|
||||
test_download_not_found() {
|
||||
log_info "Testing download of non-existent document (should return 404)..."
|
||||
|
||||
local fake_id="00000000-0000-0000-0000-000000000000"
|
||||
|
||||
response=$(curl -s -w "\n%{http_code}" \
|
||||
"$BASE_URL/document/$fake_id/download" 2>/dev/null)
|
||||
|
||||
http_code=$(echo "$response" | tail -n1)
|
||||
|
||||
if [ "$http_code" = "404" ]; then
|
||||
log_info "Non-existent document correctly returned 404"
|
||||
return 0
|
||||
else
|
||||
log_warn "Expected HTTP 404 for non-existent document, got HTTP $http_code"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Cancel batch
|
||||
cancel_batch() {
|
||||
log_info "Canceling batch..."
|
||||
@@ -280,7 +400,7 @@ cancel_batch() {
|
||||
# Cleanup function
|
||||
cleanup() {
|
||||
log_info "Cleaning up..."
|
||||
rm -f "$ZIP_FILE" invalid.txt
|
||||
rm -f "$ZIP_FILE" invalid.txt downloaded_document.pdf headers.txt
|
||||
rm -rf temp_zip_structure
|
||||
log_info "Cleanup complete"
|
||||
}
|
||||
@@ -303,6 +423,15 @@ main() {
|
||||
sleep 1 # Brief pause to let the system process
|
||||
get_batch_status
|
||||
list_batches
|
||||
|
||||
# Document download tests -- must run before cancel_batch
|
||||
if wait_for_document_id; then
|
||||
test_document_download
|
||||
test_download_not_found
|
||||
else
|
||||
log_warn "Skipping download tests - no documents were processed in time"
|
||||
fi
|
||||
|
||||
test_invalid_file
|
||||
cancel_batch
|
||||
|
||||
|
||||
@@ -645,6 +645,48 @@ paths:
|
||||
"500":
|
||||
$ref: "#/components/responses/InternalError"
|
||||
|
||||
/document/{id}/download:
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/DocumentID"
|
||||
get:
|
||||
operationId: downloadDocument
|
||||
tags:
|
||||
- DocumentsService
|
||||
summary: Download the original document file
|
||||
description: |
|
||||
Streams the original uploaded document file. The response Content-Type
|
||||
is auto-detected from the stored filename extension. No query parameters
|
||||
are required; the system resolves the file type automatically.
|
||||
security:
|
||||
- jwtAuth: []
|
||||
responses:
|
||||
"200":
|
||||
description: Document file bytes.
|
||||
headers:
|
||||
RateLimit:
|
||||
$ref: "#/components/headers/RateLimit"
|
||||
Content-Disposition:
|
||||
schema:
|
||||
type: string
|
||||
maxLength: 4096
|
||||
description: 'Attachment header with original filename, e.g. attachment; filename="report.pdf"'
|
||||
content:
|
||||
application/octet-stream:
|
||||
schema:
|
||||
type: string
|
||||
format: binary
|
||||
maxLength: 107374182400
|
||||
"400":
|
||||
$ref: "#/components/responses/InvalidRequest"
|
||||
"401":
|
||||
$ref: "#/components/responses/Unauthorized"
|
||||
"404":
|
||||
$ref: "#/components/responses/NotFound"
|
||||
"429":
|
||||
$ref: "#/components/responses/TooManyRequests"
|
||||
"500":
|
||||
$ref: "#/components/responses/InternalError"
|
||||
|
||||
/folders:
|
||||
post:
|
||||
operationId: createFolder
|
||||
|
||||
Reference in New Issue
Block a user