Studio17Designs

Our Work

Real projects, real outcomes. Here is a look at what we have built, rescued, and maintained for our clients.

SaaS Build

Building a B2B Expense Management Platform from Scratch

Fintech / B2B SaaS

Problem

A two-person fintech startup had raised a small friends-and-family round and needed to turn their validated idea into a shippable product — fast. They had a detailed spec, a design file in Figma, and a hard deadline tied to a pilot with three paying customers. What they did not have was engineering capacity.

The product needed multi-tenancy from day one: each company that signed up needed isolated data, role-based permissions, and the ability to invite team members. They also needed Stripe billing wired up before the pilot, because free trials were not part of the deal.

They had tried hiring a freelancer who disappeared after two weeks with a partially-working prototype. They needed someone who could take ownership of the full technical execution, not just write code to a ticket.

Approach

We started with a two-day architecture session to nail the data model and auth strategy before writing any application code. Multi-tenancy via a tenant_id foreign key pattern on every table, combined with Supabase row-level security policies, gave us data isolation without a complex microservices setup.

Authentication was built on Supabase Auth with custom middleware for role checking (owner, admin, member). The billing integration used Stripe Checkout for subscriptions and Stripe webhooks to provision/deprovision seats in real time. We set up a CI/CD pipeline on day three so every push was tested and deployed to a staging environment automatically.

The frontend was a Next.js app router project with a shared component library built on shadcn/ui. We wrote enough tests to cover the billing and permissions logic — the two areas where bugs would have been most damaging to the pilot relationship.

Outcome

We shipped the product in six weeks. All three pilot customers were onboarded on day one of the pilot period. The founders were able to run the demo calls themselves without needing us on standby because the product was stable.

After the pilot, both founders reported that investor confidence had increased significantly — having a production-grade product rather than a prototype changed how those conversations went. The product has been running in production without incident since launch.

The handover documentation meant the founders could onboard a part-time developer to handle minor changes without needing to come back to us for every small request.

Next.js
TypeScript
Supabase
PostgreSQL
Stripe
Vercel
Tailwind CSS
shadcn/ui
Vitest
Vibe Code Rescue

Stabilising a Marketplace Built with AI Coding Tools

Marketplace / Creator Economy

Problem

A solo founder had built a creator marketplace using Cursor and Claude. In three months of evenings and weekends, they had shipped something real — listings, user profiles, bookings, and a basic Stripe integration. It was live. People were using it. Then it started breaking.

Bookings were occasionally double-confirming, sending two confirmation emails and charging users twice. Profile images were loading for some users and not for others depending on the browser. The checkout flow worked on desktop but failed silently on mobile Safari. Deploys were manual, nerve-wracking, and usually done late at night when traffic was lowest.

The founder knew the codebase was fragile but did not know where to start. They did not want to rebuild — the product worked well enough to have paying users, and a full rebuild would take months they did not have.

Approach

We started with a two-week audit before touching any code. We mapped every user-facing flow, identified all the places where errors were swallowed silently, and traced the double-booking bug to a race condition in the Stripe webhook handler — two concurrent requests were both updating booking status before either had finished.

The fixes went in order of severity: the payment race condition first (a database transaction and an idempotency key on the Stripe event), then the image loading inconsistency (a misconfigured Next.js image domain whitelist), then the mobile Safari checkout failure (a missing HTTPS redirect that worked on Chrome but not Safari's stricter handling).

We then added a test suite covering the booking and payment flows — not full coverage, but enough to catch the class of bugs that had been causing production incidents. The final step was setting up a GitHub Actions CI/CD pipeline so deploys became a pull request merge, not a manual SSH session.

Outcome

The double-billing issue was resolved within the first week. In the month after we finished the engagement, there were no production incidents requiring the founder to intervene outside business hours — compared to roughly one per week before.

The founder described the biggest change as "being able to sleep again." Deploys went from something they dreaded to something they did several times a week without thinking about it. New features that had been sitting in a backlog for months started shipping because the codebase was stable enough to change.

The test suite caught two regressions during the engagement itself — both before they reached production. That alone justified the time spent writing them.

Next.js
TypeScript
Prisma
PostgreSQL
Stripe
Vercel
Cloudinary
GitHub Actions
Vitest
Ongoing Maintenance

Ongoing Engineering Partner for a Bootstrapped Project Management Tool

Productivity / SMB SaaS

Problem

A bootstrapped SaaS founder had been running a project management tool for small construction companies for two years. The product had paying customers, solid retention, and a clear roadmap of features their customers kept asking for. The problem was time.

Every week, some portion of the founder's attention was pulled away from sales calls and customer conversations to deal with a broken report export, a user who could not log in, or a dependency that had gone out of date and was causing warnings in the console. None of it was catastrophic, but all of it was constant.

They had tried hiring a part-time developer but the onboarding cost was high and the person had left after four months. They needed a reliable engineering presence that did not require them to manage someone week to week.

Approach

We started with a two-week onboarding period to get familiar with the codebase, document the parts that were not documented, and set up proper error monitoring with Sentry. That first look also surfaced three security issues that needed fixing before we could confidently add new features — an exposed API route that did not check authentication, outdated packages with known CVEs, and a missing rate limit on the login endpoint.

Once the foundation was stable, the engagement settled into a monthly cadence: the founder would send through a prioritised list of bugs and feature requests, we would scope them, build them, test them, and deploy them. Response time for production-breaking bugs was same-day. Non-urgent requests were batched into the monthly cycle.

After six months we added automated dependency updates via Renovate with a weekly review window, which removed the need for manual patch management entirely.

Outcome

Within the first three months, the founder reported that their week had changed meaningfully — the technical interruptions that had been a regular drain on their attention had largely stopped. They were spending more time on customer calls and less time explaining to users why something was broken.

Seven new features shipped across the first year of the engagement — more than had shipped in the previous twelve months combined. The founder attributed this partly to having reliable engineering capacity and partly to not being mentally occupied with firefighting.

The three security issues fixed in onboarding were particularly significant — one of them was in the authentication flow, and the founder had not known it existed.

Next.js
TypeScript
Supabase
PostgreSQL
Vercel
Sentry
Renovate
GitHub Actions

Ready to start?

Book a free discovery call and let's talk about your project.