Files
query-orchestration/internal/document/download/download.go
T
Jay Brown 2eff52877b Merged in feature/download-pdf (pull request #216)
retrieve document by id and tests

* working

* missing files
2026-03-17 17:06:57 +00:00

78 lines
2.1 KiB
Go

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
}