Skip to content
Apsan Works
In development2026

AdSelf

A self-serve ad platform where advertisers fund and launch their own campaigns, with creative review as the one human checkpoint.

The problem

Two different businesses were on the table before a line of code was written: own a network of sites and take a spread on every campaign, or let publishers run their own instance and license it as SaaS. Committing to either one early would have meant rebuilding the data model the day the answer changed. The actual problem to solve was making that decision reversible.

What we built

  • 01

    Every entity, campaign, placement, creative, is scoped by siteId from day one, even with a single site in use, so a second site is a new row, not a new schema.

  • 02

    A single field, the site's payout split percentage, is the real fork point: under 100% behaves as network mode with the platform taking a spread; 100% behaves as SaaS mode with a separate licence fee modelled outside the split.

  • 03

    Three roles are defined in the schema (platform admin, site admin, advertiser), even though only two have real screens today, so adding multi-tenant site admins later is additive.

  • 04

    Ad types are modelled as data, not branching code: each placement accepts one or more types, and the creative form only asks for the fields that type actually needs.

  • 05

    Payouts route conceptually through Stripe Connect regardless of mode, so wiring real payments later changes one integration, not the domain model.

Decisions worth noting

The business model is a config value

payoutSplitPct is the one field that decides network vs. SaaS mode. Everything else in the schema was written to be indifferent to which one gets chosen, which is what makes the decision safe to defer.

Creative review renders as the real ad

The admin review queue renders each ad type the way it will actually appear (image, native card, plain link, email blurb), so a reviewer is judging the real thing, not a generic file upload.

Validated on mock data, deliberately

No database, auth, or payments are wired up yet. The mechanics and the UI get proven first, against lib/mock-data.ts, before any infrastructure commitment is made.

Tell us what is slowing you down

A short conversation is usually enough to tell whether this is a build, an automation, or something you should not do at all. We will tell you which.