Delivery & Export Flow¶
This document describes how generated images flow through review, approval, and export to external systems.
Overview¶
After images are generated, they go through a delivery flow:
- Review - Users inspect generated images
- Approve/Reject - Quality control decisions
- Export - Deliver to external systems
flowchart LR
subgraph Review["Review"]
View[View Images]
Compare[Compare Variations]
Annotate[Add Notes]
end
subgraph Decision["Decision"]
Approve[Approve]
Reject[Reject]
Revise[Request Revision]
end
subgraph Export["Export"]
Select[Select Images]
Config[Configure Export]
Deliver[Deliver]
end
View --> Compare
Compare --> Annotate
Annotate --> Approve
Annotate --> Reject
Annotate --> Revise
Approve --> Select
Select --> Config
Config --> Deliver
Review Phase¶
Gallery Interface¶
The Gallery provides tools for reviewing generated images:
| Feature | Description |
|---|---|
| Grid View | Overview of all generated images |
| Detail View | Full-resolution single image |
| Compare Mode | Side-by-side comparison of variations |
| Zoom | Inspect details at pixel level |
| Filters | Filter by status, date, shooting, etc. |
Review Workflow¶
sequenceDiagram
participant User
participant Webapp
participant Backend
User->>Webapp: Open Gallery
Webapp->>Backend: GET /gallery?shooting_id=...
Backend-->>Webapp: Image list with metadata
User->>Webapp: Select image for detail view
Webapp->>Webapp: Display full resolution
User->>Webapp: Compare with variations
Webapp->>Backend: GET /predictions?shot_id=...
Backend-->>Webapp: All predictions for shot
User->>Webapp: Add annotation
Webapp->>Backend: POST /annotations
Backend-->>Webapp: Annotation saved
Image States¶
| State | Description | Actions Available |
|---|---|---|
| Pending Review | Newly generated | Approve, Reject, Revise |
| Approved | Accepted for delivery | Export, Unapprove |
| Rejected | Not suitable | Delete, Regenerate |
| Exported | Delivered to external | View export history |
Decision Phase¶
Approval Flow¶
sequenceDiagram
participant User
participant Webapp
participant Backend
participant DB
User->>Webapp: Click Approve
Webapp->>Backend: PUT /shots/{id}/approve
Backend->>Backend: Validate permissions
Backend->>DB: Update Shot status
Backend->>DB: Update Prediction status
Backend-->>Webapp: Approval confirmed
Note over Webapp: Update UI state
Approval API¶
PUT /api/v1/shots/{shot_id}/approve
Content-Type: application/json
{
"prediction_id": "uuid", // Which prediction to use as final
"notes": "Optional approval notes"
}
Rejection Flow¶
PUT /api/v1/shots/{shot_id}/reject
Content-Type: application/json
{
"reason": "QUALITY_ISSUE", // Enum value
"notes": "Details about the issue"
}
Rejection reasons:
| Reason | Description |
|---|---|
QUALITY_ISSUE |
Image quality not acceptable |
WRONG_STYLING |
Style doesn't match requirements |
PRODUCT_ISSUE |
Product not displayed correctly |
SUBJECT_ISSUE |
Subject appearance problem |
OTHER |
Other reason (requires notes) |
Revision Request¶
When an image needs adjustments:
POST /api/v1/shots/{shot_id}/revisions
Content-Type: application/json
{
"changes_requested": [
"Adjust lighting on product",
"Fix background color"
],
"regenerate": true, // Trigger new generation
"config_overrides": {
"guidance_scale": 8.0 // Optional parameter tweaks
}
}
Export Phase¶
Export Options¶
| Export Type | Description | Destination |
|---|---|---|
| Download | Direct file download | User's device |
| DAM Export | Push to DAM system | Client's DAM |
| API Delivery | Webhook notification | Client's systems |
| Batch Export | Multiple images at once | ZIP file or DAM |
Export Configuration¶
flowchart TB
subgraph Selection
S1[Select approved images]
S2[Choose export format]
end
subgraph Format["Format Options"]
F1[Resolution]
F2[File format]
F3[Color profile]
F4[Naming convention]
end
subgraph Destination["Destination"]
D1[Download]
D2[DAM Integration]
D3[Webhook]
end
S1 --> S2
S2 --> F1
F1 --> F2
F2 --> F3
F3 --> F4
F4 --> D1
F4 --> D2
F4 --> D3
Export Request¶
POST /api/v1/exports
Content-Type: application/json
{
"shots": ["uuid1", "uuid2", "uuid3"],
"format": {
"resolution": "original", // or "2048", "1024"
"file_format": "png", // or "jpg", "webp"
"color_profile": "sRGB", // or "AdobeRGB"
"quality": 95 // for lossy formats
},
"naming": {
"pattern": "{sku}_{shot_type}_{index}",
"start_index": 1
},
"destination": {
"type": "download" // or "dam", "webhook"
}
}
Export Sequence¶
Download Export¶
sequenceDiagram
participant User
participant Webapp
participant Backend
participant Storage
participant Worker
User->>Webapp: Configure export
Webapp->>Backend: POST /exports
Backend->>Backend: Create Export record
Backend->>Worker: Queue export job
Backend-->>Webapp: Export ID + status URL
Worker->>Storage: Fetch images
Worker->>Worker: Process (resize, convert)
Worker->>Storage: Create ZIP
Worker->>Backend: Update Export status
Webapp->>Backend: GET /exports/{id}
Backend-->>Webapp: Export complete + download URL
Webapp-->>User: Download ready notification
User->>Storage: Download ZIP
DAM Export¶
sequenceDiagram
participant Backend
participant Worker
participant Storage
participant DAM as Client DAM
Backend->>Worker: Queue DAM export
Worker->>Storage: Fetch images
Worker->>Worker: Process for DAM format
loop For each image
Worker->>DAM: Upload image
DAM-->>Worker: Asset ID
Worker->>Backend: Update with asset ID
end
Worker->>Backend: Export complete
Backend->>Backend: Store DAM references
Webhook Delivery¶
sequenceDiagram
participant Backend
participant Worker
participant Client as Client System
Backend->>Worker: Queue webhook delivery
Worker->>Client: POST webhook_url
Note over Worker,Client: Send event payload
alt Success
Client-->>Worker: 200 OK
Worker->>Backend: Mark delivered
else Failure
Client-->>Worker: Error
Worker->>Worker: Retry with backoff
end
Export Processing¶
Image Processing Options¶
| Option | Values | Description |
|---|---|---|
| Resolution | original, 4096, 2048, 1024, 512 | Output size |
| Format | PNG, JPG, WebP, TIFF | File format |
| Quality | 1-100 | Compression quality (lossy) |
| Color Profile | sRGB, AdobeRGB, ProPhoto | Color space |
| Background | transparent, white, black | For PNG exports |
Processing Pipeline¶
async def process_export_image(
source_url: str,
config: ExportFormat,
) -> bytes:
# Load image
image = await fetch_image(source_url)
# Resize if needed
if config.resolution != "original":
image = resize_to_max(image, int(config.resolution))
# Convert color profile
if config.color_profile != get_profile(image):
image = convert_profile(image, config.color_profile)
# Handle background (for PNG)
if config.file_format == "png" and config.background:
image = apply_background(image, config.background)
# Encode to target format
return encode_image(
image,
format=config.file_format,
quality=config.quality,
)
File Naming¶
Naming patterns support variables:
| Variable | Description | Example |
|---|---|---|
{sku} |
Product SKU | ABC123 |
{product_name} |
Product name | Summer_Dress |
{shot_type} |
Shot type name | full_body |
{subject} |
Subject name | Model_A |
{shooting} |
Shooting name | Summer_2024 |
{index} |
Sequential number | 001 |
{date} |
Export date | 2024-01-15 |
Example pattern: {sku}_{shot_type}_{index}.png → ABC123_full_body_001.png
DAM Integration¶
Supported DAM Systems¶
| System | Integration Type | Features |
|---|---|---|
| Generic | REST API | Upload, metadata |
| Custom | Configurable | Brand-specific |
DAM Configuration¶
class DAMConfig:
endpoint: str # DAM API endpoint
auth_type: str # "api_key", "oauth"
credentials: dict # Auth credentials
metadata_mapping: dict # Map Sartiq fields to DAM fields
folder_structure: str # Path pattern in DAM
Metadata Mapping¶
Map Sartiq metadata to DAM fields:
{
"metadata_mapping": {
"title": "{product_name} - {shot_type}",
"description": "Generated by Sartiq",
"keywords": ["product_category", "style_name"],
"custom_fields": {
"sartiq_sku": "product_sku",
"sartiq_shooting": "shooting_name"
}
}
}
Export Status¶
Status Tracking¶
| Status | Description |
|---|---|
PENDING |
Export created, not started |
PROCESSING |
Images being processed |
UPLOADING |
Uploading to destination |
COMPLETED |
All images delivered |
PARTIAL |
Some images failed |
FAILED |
Export failed |
Status API¶
Response:
{
"id": "uuid",
"status": "PROCESSING",
"progress": {
"total": 10,
"completed": 4,
"failed": 0,
"percent": 40
},
"images": [
{
"shot_id": "uuid",
"status": "completed",
"download_url": "...",
"dam_asset_id": "..."
}
],
"created_at": "2024-01-15T10:00:00Z",
"completed_at": null,
"download_url": null // Set when complete
}
Error Handling¶
Export Errors¶
| Error | Handling |
|---|---|
| Image fetch failed | Skip image, mark partial |
| Processing error | Skip image, mark partial |
| DAM auth failure | Fail export, alert user |
| DAM upload failed | Retry 3x, then fail |
| Webhook delivery failed | Retry with backoff |
Partial Export¶
When some images fail:
{
"status": "PARTIAL",
"progress": {
"total": 10,
"completed": 8,
"failed": 2
},
"errors": [
{
"shot_id": "uuid",
"error": "Image processing failed",
"details": "Corrupted source file"
}
]
}
Batch Operations¶
Bulk Approval¶
POST /api/v1/shots/bulk-approve
Content-Type: application/json
{
"shots": [
{"shot_id": "uuid1", "prediction_id": "pred1"},
{"shot_id": "uuid2", "prediction_id": "pred2"}
]
}
Bulk Export¶
POST /api/v1/exports/bulk
Content-Type: application/json
{
"shooting_id": "uuid", // Export entire shooting
"status_filter": "approved",
"format": { ... },
"destination": { ... }
}
Monitoring¶
Key Metrics¶
| Metric | Description | Alert |
|---|---|---|
approval_rate |
% images approved | Informational |
export_success_rate |
% successful exports | < 95% |
dam_sync_latency |
Time to DAM delivery | > 5min |
download_size_avg |
Average export size | Informational |
Export Analytics¶
Track export patterns:
- Most exported shot types
- Average images per export
- Popular export formats
- DAM vs download ratio
Related Documentation¶
- Generation Pipeline - How images are created
- Gallery Interface - Review UI details
- API Reference - Export endpoints