Work

Jan 12, 2026 - May 1, 2026
Vue 3
TypeScript
FastAPI
Python
PostgreSQL
Cloudflare R2
SSE
Gemini AI

A full-stack e-commerce automation platform independently designed and developed for Temu cross-border sellers. Covers four core workflows: batch Excel generation, concurrent image upload, end-to-end order processing, and AI image batch editing. Built with FastAPI + PostgreSQL on the backend with SSE real-time streaming for all long-running tasks, and Vue 3 + TypeScript + Naive UI on the frontend, integrated with Google Gemini multimodal API and Playwright browser automation.

Temu E-commerce Automation Platform screenshot

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

Vue 3TypeScriptFastAPIPython 3.12PostgreSQLSQLModelCloudflare R2Gemini 2.5 FlashPlaywrightPiniaNaive UISSE

Background

Day-to-day operations on the Temu platform involve a large volume of repetitive manual work: filling product Excel sheets according to category-specific rules, uploading product images one by one to cloud storage, parsing SKUs from order export files and matching them to image assets, manually removing watermarks from product images — these workflows are tedious, error-prone, and have no reusable engineering foundation.

This project is the full-pipeline automation system I built independently after taking over these workflows as an engineer. The core goal is simple: turn repetitive manual operations into a single click.

Project Info
RoleSolo Full-Stack Dev
Timeline2026.01 — Present
TypeFrontend/Backend · Production
Scale10 Routers · 6 Pages · 3 DBs
48
Concurrent Threads
SSE
Real-time Streaming
AI
Gemini Integration
YAML
Config-driven Tasks

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/sse/config+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


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 calls
Storage Layer
  • PostgreSQL — structured metadata
  • SQLite — lightweight local history
  • JSON — high-read low-write
  • 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

10
Router Modules
6
Frontend Pages
48
Concurrent Threads
4
Composables
3
Datasources
SSE Streams