Case study · 2026

Creativin — an influencer marketplace built on numbers you can verify

A two-sided KOL marketplace with end-to-end campaign management: find creators, run the campaign, review drafts, close with an invoice. React, NestJS, and Supabase.

The anon key sitting in the frontend bundle cannot read a single row from a data table.

Brands pick influencers based on claims. Creators send rate cards full of numbers nobody can check. Both sides lose, and the ones who lose most are small brands with no team to verify anything.

Numbers pulled from the source

Creators connect their Instagram and TikTok accounts through OAuth. Follower counts and engagement rates are pulled straight from the platforms and fed into a credibility score. The numbers on a creator profile are not numbers they typed themselves.

Two sides of the table in one product

For brands: search by niche, platform, city, followers, and engagement rate. Create a campaign, invite creators at an offered rate, or open it for applications. Review drafts with approve or request-changes, and every revision stays on record. Close with an invoice that exports to PDF.

For creators: manage invitations and applications, submit drafts and proof of posting, keep a portfolio and a rate card per content type. A planner syncs both ways with Google Calendar, plus per-post analytics and an ER/CPM calculator.

The architecture decision: the frontend never touches a data table

The Supabase anon key ships inside the JavaScript bundle every visitor downloads. Anyone can lift it and hit the API directly. The usual answer is to lean on Row Level Security, but that turns every new table into a potential hole if a policy is missed.

Here the frontend gets exactly two permissions: authentication and storage. Zero queries against data tables. All data access goes through NestJS, which connects to Postgres as a BYPASSRLS role, with RLS still enabled on every table as a second layer. A leaked key reads nothing.

Identity comes from the token subject, not the email

The backend verifies JWTs against the public JWKS using asymmetric ES256 keys, and resolves users only from the sub claim. It looks like a small detail, but emails change and can be reused after an account is deleted. Anchoring identity to an email is a bug that surfaces a year later, the first time someone updates their address.

A free server that falls asleep

The API runs on Render free tier, which sleeps after fifteen idle minutes and takes about thirty seconds to wake. Instead of a spinner that makes people think the site is broken, the frontend shows a waiting screen that explains what is happening. A cost constraint does not always have to be hidden from users; sometimes it just needs to be explained.

Also shipped

Admin verification of social accounts, tiered sanctions and blacklisting, two-way reviews, favourites with folders, notifications, campaign reports, educational content, and a Premium tier. Global rate limiting, strict DTO validation, and security headers through helmet.

One small thing I kept: when there is not enough data to score a creator, the profile says so plainly instead of showing an empty five stars or a zero. A thin portfolio should look honest, not bad.