NestJS
React
AI
bullMQ
Redis
PostgreSQL
During a routine medical appointment, the practitioner mentioned needing subtitles for over 1 000 training videos, each in five languages. It was considered a months-long manual task. I left that day thinking: how long would it take to automate this?
Ten days later, Titro was live.
This project was built almost entirely through a structured, prompt-driven workflow — but not in a magical “AI builds the app” way. It was more like pairing with a tireless technical co-pilot.
The loop began with ChatGPT. Before writing any code, I used it to pressure-test the concept: asking architecture questions, exploring infrastructure tradeoffs, and clarifying feature boundaries. This back-and-forth helped me refine the scope, spot edge cases early, and converge on a solid plan.
Once confident in direction, I had ChatGPT generate .mdc files — technical, step-by-step prompts tailored for Cursor, my primary development environment. These weren’t vague user stories or acceptance criteria; they were precise instructions on how to implement backend services, database migrations, cron jobs, and React components in my stack. Each file mapped to one atomic feature or update, and I would feed it directly into Cursor to generate compliant, context-aware code.
For both backend and frontend, I also had ChatGPT produce a linear step-by-step roadmap. These roadmaps lived as reference .mdc files and guided my progress: I’d pick the next step, clarify it with ChatGPT if needed, and then prompt Cursor to implement it — keeping business logic clean and structure consistent.
Frontend work added another layer. Before coding, I asked ChatGPT to generate prompts for Vercel’s v0, which created UI components matching my needs. Sometimes I’d take the raw design output as-is; other times I used the screenshots and structure as references in my Cursor prompts. It was fast, iterative, and always aligned with the stack and component library I’d chosen.
The end result? A project built systematically, with each feature distilled down to a clear, testable unit of work — and a dev experience that felt more like orchestration than brute-force building.
Most indie devs default to Vercel, Railway, or Coolify. I wanted the opposite: total ownership. I run a single VPS and use Docker + GitHub Actions for zero-downtime deployments. All containers run behind a central nginx reverse proxy, with logs, environment separation, and HTTPS managed via compose.
Subtitle translations happen in the background. I used NestJS with BullMQ for job orchestration, Redis for state tracking, and a dedicated worker process to run translations. Jobs are resilient (retries, backoff, timeout-aware), and once completed, a zip job collects results for the user. Bull Board provides a live UI for monitoring.
Users don't need long-term storage. I added a scheduled task (NestJS cron) to run every night, deleting old uploads and zip files based on a deletionDate column in Postgres. Redis keys for those batches are also cleaned. This avoids disk bloat while keeping historical data for analytics.
I configured nginx and letsencrypt-nginx-proxy-companion to act as aroot reverse proxy across all my apps — each deployed as a container with its own domain/subdomain. New apps get auto-generated SSL certs and routing with zero config.
Looking to bring your web ideas to life?
Reach out to me on Linkedin or Twitter
jeanrobertou.com
Apps