Work

Jan 12, 2026 - Jun 8, 2026
Vue 3
TypeScript
FastAPI
Python
PostgreSQL
Cloudflare R2
SSE
Gemini AI
Playwright
PLC

A full-stack e-commerce operations automation platform independently designed and developed for Temu POD cross-border sellers. It covers product template management, batch Excel generation, concurrent image upload, AI image processing, end-to-end order processing, ERP integration, campaign management, mockup batch rendering, production nodes, and PLC control. The backend is built with FastAPI + PostgreSQL, with SSE real-time streaming for long-running tasks; the frontend is built with Vue 3 + TypeScript + Naive UI, integrating Google Gemini multimodal API, Cloudflare R2, Playwright browser automation, and local production-device orchestration.

Temu E-commerce Automation Platform screenshot

Automation-driven operations — freeing sellers from repetitive manual work.

Vue 3TypeScriptFastAPIPython 3.12PostgreSQLSQLModelCloudflare R2Gemini 2.5 FlashPlaywrightNaive UISSEPLC

Background

Day-to-day POD operations on Temu involve a large amount of manual work: filling product Excel sheets according to category-specific rules, maintaining template SKUs with colors and sizes, uploading product images to cloud storage, parsing exported orders and matching customer-customized images, removing watermarks, generating mockups in batches, and finally handing orders to local production equipment. These workflows are tedious, error-prone, and had little reusable engineering foundation.

This project is the full-pipeline automation system I designed and continuously expanded after taking over these workflows as an engineer. The goal is not only to reduce clicks, but to bring products, assets, orders, production actions, and status reporting into one configurable, traceable, and extensible toolchain.

Project Info
RoleSolo Full-Stack Dev
Timeline2026.01 — 2026.06
TypeOperations + Production Platform
Scale15 Pages · Multi-service · Node
15
Operation Pages
SSE
Real-time Streaming
PLC
Device Control
R2
Cloud Asset Library

System Architecture
Frontend · Vue 3 SPA

Vue 3 Composition API
TypeScript · Vite
Naive UI · Pinia
Vue Router · ofetch

useSSETaskuseOrderTaskusePlanEditor
HTTP · SSE
Backend · FastAPI

Python 3.12 · Uvicorn
Pydantic · SQLModel
Alembic · boto3
google-genai · Playwright

/excel/upload/order/ai-generate/mockup-render/nodes+4 more
ORM · S3 API
Storage · Multi-datasource

PostgreSQL — Image library metadata
SQLite — Order history
JSON — SKU mapping · Resource index
Cloudflare R2 — Image CDN

Each datasource chosen for its access pattern


Business Loop

Product & Assets

Template management, SKU/color/size metadata, title libraries, print libraries, tag imports, PSD assets, and image-status checks.

TemplatesPrint LibraryTitle Library
Listing & Operations

Plan multi-store upload tasks, generate Temu / Miaoshou Excel files, upload assets to R2, and support campaign and price-related operations.

ExcelR2 UploadCampaigns
Orders & Production

Parse exported orders, validate customer-customized images, generate production assets, and sync tasks to local production nodes for printing and PLC dispensing.

OrdersProduction NodePLC

After this expansion, the platform is no longer just an “Excel generation + image upload” tool. It has become a workspace for the full POD operation lifecycle: order processing, order management, ERP integration, campaign management, template management, Excel generation, image upload, AI watermark removal, print library, print tags, batch rendering, render jobs, log analytics, MCP integration, and production-node management. Long-running operations share one task interface and one SSE log-stream pattern, so operators no longer need to jump between spreadsheets, terminals, browsers, and local devices.

Technical Depth

01SSE · ASYNC
SSE Real-time Log Stream Architecture
Server-Sent Events · StreamingResponse · Composable Pattern

All long-running tasks share the same problem: they take seconds to minutes, and users need real-time progress feedback. I chose SSE over WebSocket — pure HTTP unidirectional push, no protocol upgrade required, and a natural fit for FastAPI’s StreamingResponse. The backend assigns a UUID to each task; the frontend useSSETask composable manages connection lifecycle, giving all modules zero-boilerplate integration.

SSE FLOW
POST /processTrigger task
uuid4()Assign task ID
GET /sse/{id}Frontend subscribes
StreamingResponsePush line by line
LogStream.vueRender in real time
@router.get("/sse/{task_id}")
async def sse_stream(task_id: str):
  async def event_generator():
      queue = task_queues.get(task_id)
      while True:
          msg = await queue.get()
          if msg is None: break       # task done signal
          yield f"data: {msg}\n\n"
  return StreamingResponse(event_generator(), media_type="text/event-stream")
02CONCURRENCY
48-Thread Concurrent Upload Pipeline
ThreadPoolExecutor · boto3 · Cloudflare R2 · Resource Index Rebuild

Image upload is I/O-bound — network transfer dominates over CPU time. Using ThreadPoolExecutor(max_workers=48) compresses serial upload time to roughly 1/48. The value 48 was determined empirically as the optimal balance between R2 API rate limits and local bandwidth. After upload completes, the system automatically rebuilds the data.json resource index — the single data contract between the upload and order modules.

THROUGHPUT COMPARISON
Serial upload1 image/request
Concurrent ×48~48× faster
with ThreadPoolExecutor(max_workers=48) as executor:
  futures = {executor.submit(upload_single, p, bucket): p for p in paths}
  for future in as_completed(futures):
      try:
          future.result()
          task_queue.put(f"✓ {futures[future].name}")  # SSE push
      except Exception as e:
          failed.append((futures[future], str(e)))
rebuild_index(bucket)   # rebuild resource index
03VUE 3 · TS
Vue 3 Composition API Frontend Architecture
Composable · Pinia · TypeScript · Separation of Concerns

Core principle: the view layer only renders; business logic lives in Composables. Four Composables each own their domain and compose with each other — useOrderTask internally composes useSSETask, reusing log-stream logic without duplication. TypeScript unified request/response types across 10 API modules, catching field-rename errors at compile time during multiple refactors.

useSSETaskgeneric

Manages SSE connection lifecycle, exposes logs / isRunning — reused by all modules

useOrderTaskorders

Order selection, pre-processing, batch submission, failedImages state — composes useSSETask

usePlanEditorconfig

YAML Plan CRUD: GET load → local edit → POST persist

useUploadEditorupload

Upload task config management, same pattern as usePlanEditor with added field validation

04FASTAPI · DB
FastAPI Modular Backend · Multi-datasource Design
Router · Service Layer · Pydantic · SQLModel · Alembic
Router Layer
  • Exposes HTTP endpoints only
  • Pydantic input validation
  • Calls Service, no business logic
  • 10+ domain-split routers
Service Layer
  • Core business logic
  • Independently unit-testable
  • Cross-router logic reuse
  • Encapsulates external API / device calls
Storage Layer
  • PostgreSQL — structured metadata
  • SQLite — lightweight local history
  • JSON/YAML — config and indexes
  • R2 — image object storage

SQLModel (SQLAlchemy + Pydantic fusion) lets the same Model class serve as both ORM mapping and API schema, eliminating redundant definitions. Alembic manages PostgreSQL migration history so every schema change is versioned. The three datasources were chosen for their access patterns — not over-engineering, but the right tool for each job.

05AI · GEMINI
Google Gemini Multimodal AI Integration
Gemini 2.5 Flash · Multimodal Reasoning · Batch Processing · Prompt Engineering

Traditional watermark removal relies on fixed-position masks, but product image watermarks vary in position, font, and opacity. By integrating Gemini 2.5 Flash multimodal, the system feeds the image together with natural language instructions, letting the model semantically understand and execute the edit.

The engineering focus was prompt engineering: a template structure of “describe task + constrain format + provide example”, with separate strategies for solid-color vs. complex backgrounds. Failed images enter a retry queue, with full SSE progress streaming throughout.

AI PIPELINE
InputProduct image + prompt template
InferGemini 2.5 Flash multimodal
OutputProcessed image base64
WriteSave result + SSE notify
RetryFailed images → retry queue
06NODE · PLC
Production Node and PLC Control
FastAPI Node · CUPS Printer · Siemens S7-200 SMART · snap7

Once an order enters production, the master system is responsible for distribution and status recording, while a local production node runs on the machine connected to the printer and production line. The node syncs published orders, claims the next task, prints shipping labels through the local CUPS printer, executes SKU-ordered production actions, and reports key states such as claimed, running, printed, done, or failed back to the master system.

PRODUCTION FLOW
MasterPublishes production-ready orders
NodeSyncs and claims the next job
PrinterSubmits labels through CUPS
PLCSends SKU-based output pulses
ReportWrites status and errors back

The PLC layer uses python-snap7 to connect to a Siemens S7-200 SMART controller. It supports connection testing, output-point testing, and order-line-based pulse signals. The device-communication layer is separated from the order model so future integrations can swap in serial, Modbus, or HTTP device interfaces without changing the master system.

07CONFIG · PLAN
Config-driven Multi-store Task Orchestration
YAML · upload_plan.json · catalog merge · CLI / API dual entry

Early scripts had parameters scattered through code: changing a store, template, or output directory meant editing scripts. The current system extracts task definition from execution logic. settings.yaml describes default paths and globals, catalog.yaml merges product catalog metadata, and upload_plan.json orchestrates date-based batch tasks. The same backend pipeline exposes both CLI and HTTP APIs: command line for development/debugging, frontend buttons for operations.

Config Loading
› settings.yaml defaults
› settings.local.yaml overrides
› catalog.yaml product merge
Task Planning
› Filter by date
› Skip done=true entries
› Single-task and plan modes
Execution
› Typer CLI debugging
› FastAPI HTTP calls
› Unified SSE log streaming
08RENDER · ASSET
Template, Print Library, and Batch Rendering Pipeline
PSD import · OpenCV · print tags · render jobs · resource cleanup

POD product imagery is not just image upload. It depends on base mockups, prints, colors, customization type, and output format. The platform separates template configuration, print tags, PSD import, region configuration, and rendering jobs into dedicated modules. Template pages manage product metadata, the print library manages assets and labels, batch rendering composites prints into mockups, and the render-job page tracks asynchronous task state.

ASSET PIPELINE
TemplateSKU / color / size / PSD metadata
PrintName, prefix, tags, combination ID
RegionPSD import or manual print regions
RenderNormal / image custom / text custom
CleanupCascade-preview R2 and local resources

15
Frontend Pages
10+
Router Modules
48
Concurrent Threads
3
Datasources
PLC
Device Control
SSE Streams