Skip to main content
In the previous lesson we produced a technical specification that covered many components and integrations. That spec was comprehensive, but it included services and infrastructure we don’t plan to implement for this project. This lesson shows how to:
  • generate a component diagram quickly (we used Mermaid),
  • read and prune the diagram to match an MVP scope, and
  • convert the simplified design into an implementable architecture using Flask + OpenCV for on-demand image processing.
Generate a quick diagram (Mermaid) We started by prompting a diagram generator with a short prompt:
The tool returned a fairly complete component diagram in Mermaid. The original graph included user authentication, MongoDB, S3, and more: When translated into a visual sketch (for example in Excalidraw or draw.io), it becomes a fairly large diagram. Below is an Excalidraw screenshot of a similar image upload/retrieval pipeline showing the components above.
A screenshot of a hand-drawn system architecture diagram in Excalidraw showing an image upload/retrieval pipeline with components like User Interface, Authentication Service, Database (MongoDB), Image Upload/Processing, Cloud Storage (AWS S3) and Image Retrieval connected by arrows for metadata and image flows. The Excalidraw toolbar and style panel are visible along the top and left edges.
Interpreting the original flow
  • User uploads an image via the User Interface to the Image Upload Service.
  • The Image Upload Service forwards the image to the Image Processing Service.
  • The Image Processing Service stores the optimized image in Cloud Storage (AWS S3) and writes metadata to the Database (MongoDB).
  • The Image Retrieval Service queries metadata and object storage to return the image to the user.
  • An Authentication Service handles login/signup and validates users against the database.
Tip: Start with a broad diagram to capture ideas, then prune components that aren’t required for your MVP. This keeps the design accurate and actionable.
Why simplify? For our current scope we only need an on-demand image optimization endpoint that processes uploads and returns an optimized image directly. The following subsystems are out-of-scope for the MVP. Planned removals and simplifications Target implementation constraints Simplified architecture With those constraints, the simplified data-flow looks like this: Design notes for the simplified flow
  • No persistent storage: images are processed in-memory (or temporary ephemeral files) and streamed back to the client.
  • Single Flask app can handle both upload and retrieval endpoints; separate services are unnecessary for the MVP.
  • OpenCV handles decoding, minimal transformations, and re-encoding with tuned JPEG quality.
Minimal Flask + OpenCV example Below is a minimal Flask endpoint that:
  • accepts an uploaded image,
  • decodes and validates it with OpenCV,
  • re-encodes it as a compressed JPEG buffer, and
  • returns the optimized image directly to the browser.
Implementation tips and production notes
  • Validate uploads: check Content-Type and attempt to decode with OpenCV before processing.
  • Upload size: configure Flask and the front-end to limit request size (e.g., Nginx/gunicorn client_max_body_size equivalents).
  • Temporary storage: if handling very large images, write to a secure temporary directory and ensure cleanup.
  • WSGI server: run Flask under gunicorn or another production server rather than Flask’s dev server.
  • Multipart/form-data: clients should send files under the image field (as shown in the example).
  • Security: if the service is public, consider rate limiting and authentication later.
Tooling and references Further reading This approach — start broad, then prune to an MVP — helps you avoid building unnecessary infrastructure while keeping the architecture clear and implementable.

Watch Video