Problem
A community project at A2SV needed a real product, not another tutorial app: somewhere users could rate, review and discover restaurants, with auth, image uploads, and a moderation surface.
My role
Back-end developer. I owned the Express + MongoDB API, the deployment pipeline, and most of the AWS infrastructure work. Frontend work was done with the team in Vue.
Architecture
┌─────────┐ HTTPS ┌────────────┐ ┌──────────────┐
│ Vue SPA │────────────▶│ Express │───▶│ MongoDB │
└─────────┘ │ API (Node)│ │ (Atlas) │
└────┬───────┘ └──────────────┘
│
▼
┌────────────────┐
│ AWS S3 │
│ (image uploads)│
└────────────────┘Everything ran inside Docker containers, orchestrated on AWS, with infra defined in Terraform so any teammate could terraform apply to a fresh environment.
Key decisions
- MongoDB for review/rating data — flexible schema fit the iteration speed at the start, and the relational pressure never grew enough to justify migrating
- S3 for uploads, signed URLs from the API — no large blobs through Node
- GitHub Actions for CI/CD — test on PR, build + push image on merge, deploy on tag
- Terraform from day one — no "click in the AWS console" steps ever in the runbook
Results
- Live product used by real users in the A2SV community
- Reproducible environments (dev / staging / prod) entirely from code
- Deploy time from merge to running in production: a few minutes, fully automated
What I would do differently
- Use TypeScript on the API from the start — the JS-only Express layer slowed refactors
- Move uploads to direct browser → S3 via presigned URLs to remove API bandwidth as a bottleneck