01
Public application
- Discover businesses
- Browse products and services
- Favorites
- Reviews
- Public business pages
Independent product · Engineering retrospective
Building a local discovery platform from idea to production.
Or-by is a local business discovery platform that I took from idea to production. I worked across the frontend, backend, database, infrastructure, and deployment.

The idea came from comparing how people discover stores and services in large and small cities. Smaller cities often lack a single place to see what local businesses offer.
I built Or-by to help people find nearby businesses, products, and services, while giving business owners a structured place to publish what they offer.
I used AI to speed up implementation. I remained responsible for product, architecture, review, debugging, infrastructure, and production decisions.
I started working on Or-by when I was still learning Node.js, before generative AI tools became part of my development workflow.
I later added AI coding agents to my development workflow. They helped me explore solutions and implement interfaces faster, while I continued to review the output and make the technical decisions.
Using these tools with a component library reduced the time I spent moving from a Figma design to an implemented interface and helped me complete the MVP.
01
02
03
04
The public app, owner hub, and admin are Next.js applications. API requests reach NGINX on EC2, which forwards them to the Node.js and Express service. The API persists data in private RDS PostgreSQL through TypeORM, while media uploads use presigned URLs for direct PUT requests to Cloudflare R2 outside AWS.
The public app, owner hub, and admin are Next.js applications. Their API requests enter an AWS VPC through NGINX on a public EC2 instance and reach a Node.js and Express container. The API accesses PostgreSQL in private RDS subnets through TypeORM. For media, the API issues a presigned URL and the browser uploads directly to Cloudflare R2 outside AWS. ECR stores the API image, and Terraform provisions the AWS resources without participating in request processing.
Product interfaces used by visitors, business owners, and platform administrators.
API request flow
AWS production boundary
A VPC with the EC2 runtime in a public subnet and PostgreSQL in private database subnets.
Receives HTTPS traffic and forwards API requests to the application container.
Approximately 110 endpoints running as the application service.
Persistent data with database access restricted to the EC2 security group.
Direct media flow
Direct PUT upload from the application, outside the AWS boundary.
Provisioning layer · outside the request flow
Terraform · Defines the VPC, subnets, security groups, IAM, EC2, RDS, ECR, and optional alarms.
05.1
Early in the project, image uploads passed through the backend. That approach increased coupling and made the application server process file transfers outside the core business flow.
The current flow uses presigned URLs: the client requests an authorized URL and uploads directly to Cloudflare R2 with PUT. File type, extension and a 5 MB size limit are validated across the client and server boundaries, keeping the file transfer separate from the API.
The next iteration should add retry strategies, clearer upload state tracking, and stronger failure recovery.
05.2
As the backend grew to approximately 110 REST endpoints, consistent module and request-handling patterns became more important.
I use shared conventions for validation, services, controllers, errors, and persistence so that the API remains easier to follow as its scope grows.
05.3
Or-by gave me practical experience with application security through concrete safeguards: Zod schemas for body and query validation, authentication and authorization rules, Helmet headers, a CORS allowlist, targeted rate limiting, and request payload limits.
These controls reduce common risks but do not make the application absolutely secure. I treat this work as part of the architecture rather than something to add after development.
Deploying and operating the application was the most difficult part of the project.
My first AWS deployment took around four hours just to configure and connect the required pieces. I had to understand EC2, a private RDS PostgreSQL instance, VPCs, subnets, networking, ECR, containers, domains, and how the application components would communicate.
NGINX was configured as a reverse proxy, routing incoming requests to the Node.js application and avoiding direct exposure of the application process. TLS is managed through Certbot, and NGINX enforces the configured 5 MB request body limit. Docker Compose runs the application containers, Terraform describes the AWS infrastructure, and Cloudflare R2 stores media outside AWS.
The deployment made the operational work concrete: the application needs logging, monitoring, recovery plans, maintenance, and a clear way to release changes.
Or-by taught me to evaluate features as parts of a system running in production, not only as code that works locally.
That means considering failure, bottlenecks, coupling, recovery, infrastructure costs, and availability while making technical decisions.
I now account for that operational work earlier in development.



Private repository