Lab Portal Module¶
Files: lab_portal_routes.py (45k lines), lab_print_upload_routes.py (58k lines), lab_portal_async.py, lab_portal_id_utils.py
Architecture Overview¶
flowchart TD
A[Photographer] --> B[Create print order
with client details]
B --> C[Upload album files
to lab storage]
C --> D[Lab receives order
PIN + Lab ID login]
D --> E[Lab updates status
Pending → Delivered]
E --> F[Client checks status
via public link]
Lab Access Model¶
- Labs are granted access by admin via
async_set_lab_portal_access() - Each lab gets a unique
lab_id(e.g.,LNZ-LAB-XXXX) and 4-digitlab_pin - Login: POST to
/lab/loginwithlab_id+lab_pin→ sets lab session - Lab session is separate from user session
Print Order Lifecycle¶
| Status | Set By | Meaning |
|---|---|---|
pending |
Photographer | Order created, files not yet downloaded |
files_downloaded |
Lab | Lab has downloaded the album files |
print_ready |
Lab | Printing complete |
out_for_delivery |
Lab | Courier dispatched or pickup ready |
delivered |
Lab | Client confirmed receipt |
Each transition is timestamped (files_downloaded_at, print_ready_at, etc.).
Key Routes (lab_portal_routes.py)¶
| Route | Method | Description |
|---|---|---|
/lab/login |
POST | Authenticate lab with lab_id + PIN |
/lab/dashboard |
GET | Lab dashboard — all incoming orders |
/lab/order/<print_id> |
GET | View individual order details |
/lab/order/<print_id>/update-status |
POST | Update order status |
/lab/order/<print_id>/download-files |
GET | Generate download link for album files |
/lab/logout |
POST | Clear lab session |
Photographer Print Upload (lab_print_upload_routes.py)¶
| Route | Method | Description |
|---|---|---|
/print/create-order |
POST | Create print order with full details |
/print/upload-initiate |
POST | Initiate S3 multipart upload for album |
/print/upload-presigned-url |
GET | Get presigned URL for each part |
/print/upload-complete |
POST | Complete multipart upload |
/print/orders |
GET | List all orders submitted by this photographer |
/print/order/<print_id>/cancel |
POST | Cancel pending order |
Public Order Status Link¶
Every order generates a status_link token:
- Stored in
PrintOrdersPublicLinktable - Accessible via
/print/status/<status_link>— no auth required - Shows: order status, estimated delivery, studio name, lab name
- Does NOT show file download links or sensitive data
Lab ID Generation (lab_portal_id_utils.py)¶
python
def generate_lab_id() -> str:
return f"LNZ-LAB-{secrets.token_hex(4).upper()}"
- 8-character hex suffix → 4 billion unique IDs
- Collision checked against DB before assignment
Async Operations (lab_portal_async.py)¶
python
def async_set_lab_portal_access(user_email, grant=True):
# Runs in background thread
# Creates LabPortal row in DB
# Sends email notification to lab
- Runs in a
threading.Threadto avoid blocking admin dashboard - Creates
LabPortalDB row with generatedlab_idandlab_pin - Sends confirmation email to lab owner
TL;DR¶
What it does: Digital print order workflow. Photographer creates orders, uploads files. Lab logs in with PIN, manages orders, updates status. Client tracks via public link.
Key techniques: PIN-based lab auth (separate session), status state machine with timestamps, public status link (no auth), async lab access grant via background thread, S3 multipart upload for album files.