# Mustafa Erhan Portakal — Full-Stack Developer Full-stack developer who ships production systems end to end — NestJS APIs, Next.js and React interfaces, PostgreSQL and MongoDB data layers, Docker-based deployment. ## Summary Mustafa Erhan Portakal is a full-stack developer based in Bursa, Türkiye who builds and ships production web systems end to end. He works primarily in TypeScript with NestJS on the backend, Next.js and React on the frontend, PostgreSQL and MongoDB for data, and Docker for deployment. Since July 2025 he has been co-founder and full-stack developer at Vimof Studios, where he built Auraly-AI, a mood-based music recommendation product. Since November 2025 he has worked as a freelance full-stack developer, delivering an on-premise union management platform for Demokratik Sağlık-Sen and, from April 2026, the live e-commerce platform maisonmeda.com. He holds a BSc in Computer Engineering from Bursa Technical University. ## Contact and identity Name: Mustafa Erhan Portakal Job title: Full-Stack Developer Location: Bursa, Türkiye Relocation: Open to relocation to İstanbul, İzmir or Ankara, and to remote work. Email: portakalm11@gmail.com Phone: +90 507 413 1160 Website: https://mustafaerhanportakal.com LinkedIn: https://www.linkedin.com/in/mustafa-erhan-portakal-2142101ba/ GitHub: https://github.com/mustafaep Spoken languages: Turkish — native; English — B2 reading and writing, B1 speaking ## Experience ### Full-Stack Developer — Freelance Bursa, Türkiye (Remote) · November 2025 – present - Built the Union Management Platform for Demokratik Sağlık-Sen (November 2025 – July 2026): 30 backend modules and 40 relational data models covering member records, dues and deduction documents, approval flows, accounting, content and reporting. - Built maisonmeda.com from April 2026 onward: a live e-commerce platform for a boutique, as a Turborepo monorepo holding a Next.js 16 storefront, an admin panel and a NestJS API. ### Co-Founder & Full-Stack Developer — Vimof Studios Remote · July 2025 – present A two-person independent software studio. I handle development; my partner handles QA and testing. - Built Auraly-AI, a mood-based music recommendation product, as a TypeScript monorepo of four applications: a NestJS 11 API, a Next.js 15 web app, an admin panel and a React Native (Expo) mobile app sharing a typed DTO package. - Implemented 102 REST endpoints across 17 controllers and 27 MongoDB schemas with Mongoose 8. - Integrated the Spotify Web API (OAuth, token refresh, library access, Connect playback control) and Google Gemini (mood interpretation, playlist generation). - Rewrote the recommendation pipeline after the Spotify Recommendations endpoint was deprecated, designing and documenting a new algorithm behind a feature flag with variant positioning. - Shipped the mobile app with Expo Router: audio playback, push notifications, deep linking, i18next and expo-localization. - Deployed with Docker Compose and Nginx, CI/CD on GitHub Actions, with the admin panel behind Cloudflare Access. 241 commits over 13 months; iOS and Android release targeted for August 2026. - Also built menu/UI flows and data-saving logic in Unreal Engine 5 Blueprint for a game project. ### Software Developer Intern — BRM Bilgisayar Bursa, Türkiye · September 2024 – February 2025 İMEP vocational training programme plus a summer internship — six months of industry experience inside a 20-person development team. - Built desktop applications with .NET 8 and web applications with ASP.NET Core, using Entity Framework and Microsoft SQL Server. - Built push notification infrastructure with a OneSignal integration and real-time communication features over WebSocket. - Worked on database design and third-party API integrations within a layered enterprise architecture and a code review process. - Closing project: SoccerApp, an ASP.NET Core 8 football team management panel. ## Projects ### Auraly-AI Auraly-AI is a mood-based music recommendation product built by Mustafa Erhan Portakal at Vimof Studios, which interprets a listener's mood with Google Gemini and turns it into a playable Spotify playlist. It runs as a TypeScript monorepo of four applications — a NestJS API, a Next.js web app, an admin panel and a React Native mobile app — and is live at auraly-ai.com. Role: Co-Founder & Full-Stack Developer Period: July 2025 – present Status: Live · iOS and Android release targeted for August 2026 Tech stack: TypeScript, NestJS 11, Next.js 15, React Native (Expo), MongoDB, Mongoose 8, Spotify Web API, Google Gemini, Docker Compose, Nginx, GitHub Actions, Cloudflare Access Live: https://auraly-ai.com Page: https://mustafaerhanportakal.com/projects/auraly-ai What Auraly-AI does Auraly-AI takes a description of how someone feels and returns music they can play immediately. Google Gemini interprets the mood and generates a playlist concept; the Spotify Web API resolves it into real tracks and plays them on the listener's own Spotify session. It is the product behind Vimof Studios, the two-person studio I co-founded in July 2025, and it was also my graduation project at Bursa Technical University. How the system is put together The whole product lives in one TypeScript monorepo containing four applications that share a single typed DTO package, so a change to an API contract is a compile error in the web app and the mobile app rather than a runtime surprise. - API — NestJS 11, with 102 REST endpoints across 17 controllers and 27 MongoDB schemas modelled in Mongoose 8. - Web — Next.js 15. - Admin panel — an internal application, kept off the public internet behind Cloudflare Access. - Mobile — React Native on Expo, routed with Expo Router, covering audio playback, push notifications, deep linking and localisation through i18next and expo-localization. Two external services carry the product's core behaviour. Spotify handles identity and playback: OAuth, token refresh, library access and Connect playback control. Gemini handles interpretation: reading a mood and generating a playlist. Deployment is Docker Compose behind Nginx, with CI/CD on GitHub Actions. Why the recommendation pipeline had to be rewritten Spotify deprecated its Recommendations endpoint, which removed the single API call the entire feature had been built on. Recommendation was not a side feature of Auraly-AI — it was the product — so this was not something that could be patched around. I rebuilt the pipeline rather than looking for a drop-in replacement. The new algorithm was designed and documented as a deliberate piece of work, then put behind a feature flag with variant positioning so the replacement could be introduced and compared without a hard cutover. Writing the design down first mattered here: the constraint was permanent and external, so the reasoning needed to survive past the moment of the outage. What is still open Playback synchronisation between Spotify and YouTube is in progress. Keeping a single listening session coherent across two providers with different playback models and different notions of session state is the current problem. Where it stands Auraly-AI is live at auraly-ai.com, with 241 commits over 13 months of development. The iOS and Android release is targeted for August 2026. I handle development; my partner at Vimof Studios handles QA and testing. ### maisonmeda.com maisonmeda.com is a live e-commerce platform Mustafa Erhan Portakal built for a boutique client, covering a customer storefront, an admin panel and the API behind them. It is a Turborepo monorepo holding a Next.js 16 storefront and a NestJS API, with Trendyol marketplace synchronisation and iyzico payments, and has been in production since April 2026. Role: Freelance Full-Stack Developer Period: April 2026 – present Status: Live · real client, in production Tech stack: TypeScript, Turborepo, Next.js 16, NestJS, Prisma, PostgreSQL, iyzico, Trendyol Marketplace API, Zod, Docker Compose, Nginx, Resend, sharp Live: https://maisonmeda.com Page: https://mustafaerhanportakal.com/projects/maisonmeda What the platform does maisonmeda.com sells a boutique's products online and keeps that catalogue in step with the same products listed on Trendyol. It is a real commercial system with real customers and real payments, not a demonstration build. The repository is a Turborepo monorepo with three applications: a Next.js 16 storefront, an admin panel, and a NestJS API serving both. Behind the API sit 13 Prisma models and roughly 58 REST endpoints, with 18 migrations to date. How marketplace synchronisation works A scheduled job runs every 30 minutes, importing and reconciling more than 100 products against Trendyol. Reconciliation is the harder half of that sentence: two systems each believe they own the product catalogue, so the job has to decide what has genuinely changed rather than blindly overwriting one side with the other. Why authorisation moved out of Next.js middleware CVE-2025-29927 made it possible to bypass Next.js middleware, and the platform's authorisation checks were running in exactly that middleware. Because the bypass defeats the middleware layer itself, no amount of additional logic inside that layer would have fixed it — the check had to move somewhere the request could not skip. I moved authorisation down into NestJS guards at the API layer. Customer sessions and admin sessions now sit behind separate guards, so the storefront and the admin panel do not share an authorisation path. Sessions are JWTs carried in httpOnly cookies, with bcrypt for password hashing and Zod for input validation. I recorded the change as an Architecture Decision Record, including the alternatives I rejected and why. A decision made under a live CVE is exactly the kind that gets misremembered later as arbitrary, and the client's team needed the reasoning to be legible without me in the room. The rest of the infrastructure Deployment is Docker Compose behind Nginx. Transactional email goes through Resend, and product images are processed with sharp. The order lifecycle runs through iyzico for payment. Where it stands The platform is live at maisonmeda.com and has been in production since April 2026. Work on it is ongoing. ### Union Management Platform The Union Management Platform is a management system Mustafa Erhan Portakal built for Demokratik Sağlık-Sen, a health workers' union, covering member records, dues and deduction documents, approval flows, accounting, content and reporting. It comprises 30 backend modules over 40 relational data models, and was packaged with Docker Compose and installed on-premise on the client's own infrastructure. Role: Freelance Full-Stack Developer Period: November 2025 – July 2026 Status: Delivered · installed on-premise, no public URL Tech stack: TypeScript, NestJS 11, Prisma 6, PostgreSQL 16, Redis, BullMQ, React 19, Vite 7, Material-UI 7, TanStack Query, Recharts, Puppeteer, AWS SES, Docker Compose, Nginx Proxy Manager Live: no public link Page: https://mustafaerhanportakal.com/projects/union-management-platform What the platform does The Union Management Platform runs the administrative work of a health workers' union: member records, dues and deduction documents, approval processes, accounting, content and reporting. It is the largest system I have built — 30 backend modules over 40 relational data models — and it is the reason the project has no link on this page: it was installed on the client's own infrastructure and is not exposed to the public internet. How it is structured The backend is NestJS 11 with Prisma 6 over PostgreSQL 16. The administrative interface is React 19 on Vite 7, using Material-UI 7 and TanStack Query, with Recharts for the reporting dashboards. The API is documented with Swagger/OpenAPI. Regional structure is modelled explicitly as a province / district / branch hierarchy, and every record change is written to an audit log. For an organisation whose decisions have to be defensible after the fact, knowing who changed what is part of the product rather than a debugging aid. Why work moved onto queues Notification delivery and PDF generation were moved onto Redis and BullMQ queues. Both are slow and both are bursty — a notification run or a batch of documents affects many members at once — so leaving them in the request path would have meant a request whose duration depended on how many people it touched. Queued, the request returns immediately and the work drains at its own pace. PDF generation itself runs through Puppeteer, with Excel export alongside it. Notifications go out over three channels: AWS SES, WhatsApp and SMS. How permissions work Role-based access control is dynamic rather than fixed in code: an administrator can create their own roles and assign permissions to them. A union's internal structure is not something an outside developer can enumerate correctly in advance, and it changes without warning — so the system had to let the organisation describe its own hierarchy instead of asking me to hard-code one. Deployment and migration The platform was packaged with Docker Compose and Nginx Proxy Manager and installed on-premise, on infrastructure the client controls. Over the life of the project the schema went through 82 Prisma migrations while the system was in active use, which meant every migration had to be applied against live data rather than a clean database. Where it stands The platform was delivered and is in use. There is no public link — it runs on the client's own infrastructure. ### Letter to Stars Letter to Stars is an English diary and learning platform built by Mustafa Erhan Portakal, where a user writes a diary entry in English and Gemini rewrites it at a chosen IELTS level from 6 to 9. It also extracts the new vocabulary with Turkish meanings, and marks each day with a star on a visual progress map. It is live at lettertostars.mustafaerhanportakal.com. Role: Full-Stack Developer Status: Live Tech stack: React, Vite, Tailwind CSS, NestJS, Prisma, PostgreSQL, FastAPI, Google Gemini, Django, Docker Compose Live: https://lettertostars.mustafaerhanportakal.com Page: https://mustafaerhanportakal.com/projects/letter-to-stars What it does A user writes a diary entry in English, and the platform returns the same entry rewritten at the IELTS level they are aiming for — 6, 7, 8 or 9. Alongside the rewrite it extracts the vocabulary that was new to that entry, with Turkish meanings. Each day of writing earns a star, which builds into a visual progress map over time. The AI response is structured JSON rather than free text: the rewritten entry, grammar corrections, new words, writing tips, strengths and weaknesses, and overall feedback. Asking for a fixed shape means the interface can render each part in its own place, instead of showing the learner a wall of prose and hoping they find the correction inside it. How it is built The system is split across four services, each in the language that suited it: - Frontend — React with Vite and Tailwind CSS. - Backend — NestJS with Prisma over PostgreSQL. - AI service — FastAPI, wrapping Google Gemini. - Admin and analytics — Django. Deployment is Docker Compose. Where it stands Letter to Stars is live at lettertostars.mustafaerhanportakal.com. ### MoodWeave MoodWeave is a polyglot microservice system Mustafa Erhan Portakal built to learn gateway architecture, routing traffic through an Nginx reverse proxy to a NestJS API gateway that fronts a Django service and a FastAPI service. The internal services are closed to the internet, and every merge to main deploys to a VPS over SSH through GitHub Actions. The source is on GitHub; it is not currently running live. Role: Full-Stack Developer Period: January – March 2026 Status: Not currently live · source on GitHub Tech stack: Nginx, NestJS, Django, FastAPI, React, Vite, Docker, GitHub Actions, Let's Encrypt Live: no public link Source: https://github.com/MustafaEP/moodweave Page: https://mustafaerhanportakal.com/projects/moodweave Why it exists I built MoodWeave to understand gateway architecture by running into its actual problems rather than reading about them. The brief I set myself was to make several services in different languages behave as one system from the outside. How requests flow An Nginx reverse proxy sits at the edge. Behind it, a NestJS API gateway fronts two services: a Django service handling Spotify, and a FastAPI service handling mood analysis. A React client built with Vite sits in front of the gateway. The internal services are closed to the internet — the gateway is the only way in. Docker healthchecks restart containers automatically when a service stops responding. Deployment Every merge to main deploys to a VPS over SSH through GitHub Actions, without touching the server by hand. HTTPS is handled by Let's Encrypt, alongside rate limiting and structured logging. Where it stands MoodWeave has 119 commits and is not currently running live. The source is on GitHub. ### wchatapi wchatapi is a self-hosted WhatsApp messaging API built by Mustafa Erhan Portakal on Node.js, Express 5 and Baileys, with a Next.js panel for monitoring sessions. It covers API key validation, HMAC-signed webhooks, rate limiting and graceful shutdown, and runs in Docker. Role: Full-Stack Developer Period: April 2026 Status: Self-hosted Tech stack: Node.js, Express 5, Baileys, Next.js, Docker Live: no public link Page: https://mustafaerhanportakal.com/projects/wchatapi What it does wchatapi sends and receives WhatsApp messages from a service you host yourself, rather than through a third-party provider. A Next.js panel sits alongside it for monitoring session state. What it handles The parts that matter in a messaging API are the boring ones, so those are what the project covers: - API key validation on inbound requests. - HMAC-signed webhooks, so a receiver can verify a callback genuinely came from this service. - Rate limiting, because the upstream will not tolerate an unbounded send loop. - Graceful shutdown, so a restart does not drop an in-flight session. It runs in Docker. ### SoccerApp SoccerApp is a football team management panel built in ASP.NET Core 8 by Mustafa Erhan Portakal as the closing project of his software developer internship at BRM Bilgisayar in Bursa. The source is on GitHub. Role: Software Developer Intern Status: Closing project · source on GitHub Tech stack: C#, ASP.NET Core 8, Entity Framework, Microsoft SQL Server Live: no public link Source: https://github.com/mustafaep/SoccerApp Page: https://mustafaerhanportakal.com/projects/soccerapp What it is SoccerApp is a football team management panel written in ASP.NET Core 8. It was the closing project of my internship at BRM Bilgisayar in Bursa — the İMEP vocational training programme plus a summer internship, six months inside a 20-person development team. Context The internship was where I worked in .NET properly: desktop applications with .NET 8, web applications with ASP.NET Core, and Entity Framework over Microsoft SQL Server. It was also my first exposure to a layered enterprise architecture and a real code review process, which shaped how I structure services now. The source is on GitHub. ## Education BSc Computer Engineering — Bursa Technical University, Bursa, Türkiye (2020 – 2025) Graduation project: Auraly-AI. ## Award TÜBİTAK 2209-A Research Support — "Rover Wheel Design with an Anti-Skid System" (2022 – November 2024) Supported and successfully completed under the 2022/1 term of the TÜBİTAK 2209-A University Students Research Projects Support Programme. The project addressed skidding and entrapment on the fine, sandy terrain of the Martian surface. As the only computer engineer on a four-person team I was responsible for all software and electronics: an Arduino control loop that read distance and motion sensors to detect entrapment and drove servo-steered DC motors. Project repository: https://github.com/Rover-Anti-Skid-System ## Certificate IBM Full Stack Software Developer — Coursera Professional Certificate, January 2026 A 15-course programme covering cloud-native development, microservices, Docker, Kubernetes, OpenShift, CI/CD, React, Node.js, Django, databases and application security. Verification: https://coursera.org/verify/professional-cert/ZA0GJFIPNUUT ## Technical skills Languages: TypeScript, JavaScript, Python, C#, SQL Backend: NestJS, Node.js, Express, ASP.NET Core, Django, FastAPI Frontend: React 19, Next.js 15/16 (App Router), Tailwind CSS 4, Material-UI, TanStack Query, Vite Mobile: React Native (Expo), Expo Router Databases: PostgreSQL, MongoDB, Microsoft SQL Server, Redis ORM: Prisma, Mongoose, Entity Framework DevOps: Docker, Docker Compose, Nginx, GitHub Actions, Turborepo, pnpm, VPS, Let's Encrypt Integrations: Spotify Web API, Google Gemini, iyzico, Trendyol Marketplace API, AWS SES, Resend, OneSignal, Baileys Practices: REST API design, JWT authentication, Role-based access control, Background queues (BullMQ), Swagger/OpenAPI, Architecture Decision Records (ADR), Monorepo ## Notes A full Turkish translation of this site is available under https://mustafaerhanportakal.com/tr. A machine-readable résumé in the JSON Resume schema is at https://mustafaerhanportakal.com/api/resume.json.