SIDE PROJECT · CURRENT
ScooScoo.homes
A production pipeline that turns an address list into house portraits, while uncertain matches stop for review.
Charged before any work starts. If the imagery is the wrong building, the job ends in a refund.
The whole pipeline parks an uncertain match. The customer decides.
A refresh or a second visit resumes the paid job instead of buying another one.
A failed or refunded job draws its own screen instead of spinning.
THE REASONING
The live application runs at scooscoo.homes →
Batching pipeline: processing address lists instead of single homes
Custom home illustrations are traditionally commissioned one address at a time through manual illustration workflows. For holiday cards or client closing gifts, buyers require processing full address lists simultaneously.
ScooScoo executes that workflow as an automated batch pipeline: geocoding, street imagery extraction, candidate verification, style transfer, and packaging run across each address sequentially without human intervention.
Street imagery must be fetched automatically because customers do not photograph every address on their recipient list. When automated matching cannot confirm the correct building, the job halts for review.
Upfront payment state machine and refund handling
ScooScoo charges upfront per job, making candidate misidentification a financial liability rather than an iterative artifact. The pipeline enforces strict address verification gates before committing paid style transfer runs, and issues programmatic refunds when confidence thresholds fail.
Checkout persists the job record first. The address, selected style, and uploaded reference photo are saved before the payment form loads, holding the job in pending_payment. Once Stripe webhook confirmation returns, the worker transitions the job to queued.
Page refreshes or duplicate submissions resume the paid job rather than creating redundant charges. A client debounce flag handles rapid repeated clicks.
Presigned URL storage uploads and fallback failure modes
The upload path requests a presigned storage URL and falls back to streaming through the API server if the direct upload fails.
Maintaining dual ingestion paths masks primary upload errors when storage failures fall back to the API server. Consolidating on a single upload contract simplifies error tracking.
The 60-second selection gate and timeout behavior
When ranking confidence falls below threshold, the job transitions to waiting_for_selection. The web interface presents ranked candidates with the highest-scoring image preselected.
If unconfirmed after sixty seconds, the pipeline commits the top-ranked candidate and proceeds, preventing abandoned web sessions from stalling the background processing queue.
Streaming real-time candidate filtering and curation
The delivery interface polls job state every three seconds, rendering discovered images, rejected angles, and worker status directly from the database record without synthetic progress animations.
The pipeline executes five discrete stages: Initializing loads the paid record; Scanning streams candidate views onto the page as discovered; Curating filters out occluded or mismatched angles; Painting renders the confirmed reference in watercolor; Finalizing generates image derivatives and delivers download links via email.
Because candidate filtering is recorded and rendered in real time, customers see why specific views were rejected if human confirmation is requested.
Content-addressable storage and derivative image generation
Clean original renders are stored under unguessable UUIDs to prevent directory enumeration. Watermarked gallery previews derive their object keys from input hashes, ensuring repeated requests for identical inputs share storage assets. Thumbnail and display sizes are generated once during the finalize step.
Captions are stored independently from background artwork. Changing a label re-renders only the text overlay layer, generating a new variant without re-running the neural style model.
Client-side validation before pipeline execution
Inbound addresses are validated for street numbers and minimum character length before initiating geocoding queries. Reference image uploads are restricted to JPEG and PNG formats under ten megabytes, validated in the browser before transfer.
Terminal job states halt client polling immediately and display explanatory resolution views, preventing redundant status checks on finished or refunded tasks.