
The idea
Streaming broke the deal music used to have. An artist earns roughly a third of a cent per stream, so you need hundreds of thousands of plays to make rent. A fan pays a monthly fee and owns nothing, the moment they stop paying their whole library is gone. The value pools in the middle, at the platform and the labels, and the two groups who actually matter, the people making the music and the people who love it, both get the thin end.
FIRSTPRESS is a direct-to-fan music marketplace built to undo that. A fan buys a record and owns it, lossless, for good, even if the platform vanishes. The artist keeps 90 percent of every sale and the money hits their bank fast, not on some quarterly royalty statement. No label gate, no algorithm deciding who gets heard, no exclusivity contract. Direct, the way it should have stayed.
It is a two-sided thing on purpose. Fans get discovery, ownership, and a real line to the artists they back. Artists get a storefront, fast money, and the customer relationship that labels normally rent back to them. The whole technical build exists to serve that one sentence. Music deserves a better deal.
What it actually is
The product has a few sides that share a spine.
Fan side. Browse and discover releases, buy them, download lossless or stream, a real library and player, follow artists, a wishlist, order history. Buying once means owning it, no subscription that repossesses your collection.
Artist side. A full self-service dashboard. Release editor, audio and video upload with quality handling, thumbnail and artwork, profile and theme, payout setup, promo codes, marketing and link tools, analytics on real sales and fans, not vanity numbers.
[ New product screenshots go here, provided by Clive. ]
Community. Every artist gets a free fanclub. Posts, comments, a real moderation pipeline running on an automated content-moderation model. Free to join, no paywall, the gate is membership not money.
Site Builder. The one paid product, a monthly subscription. A drag-and-drop page editor and a custom domain with automatic TLS, so an artist can run their own site on top of the same commerce engine.
Admin. An internal dashboard for the operations side. Orders, payouts, disputes, refunds, entitlement overrides, moderation queues, reconciliation. Everything that has to be auditable.
The stack
API is NestJS on TypeORM and Postgres. Web is Next.js 15 on the App Router with Tailwind. iOS is native SwiftUI, deliberately not cross-platform, because playback and the purchase flow need to feel native. Payments and payouts run on Stripe Connect. Email is transactional through Resend. Content moderation runs on an omni-moderation model. The whole thing started on a process manager and moved to containers.
How the backend is organized
It is a modular monolith, and the modules are kept honest. Commerce, entitlements, payouts, and community are separate concerns that do not bleed into each other.
Access is entitlement-based. Every purchase produces an entitlement, and every access check asks the entitlement layer, not the payment provider. That keeps the playback and download logic from getting welded to Stripe specifics, which matters when you have both web and iOS reading the same rights.
Money is append-only. The finance and event logs are write-only ledgers, so refunds, payout changes, entitlement overrides, and moderation actions all leave a trail you can replay. The payout balance is a ledger computation, credits minus debits, not a mutable number someone can fat-finger.
The payout model took real thought. It runs on Stripe Connect with the platform as merchant of record, daily automatic payouts once an artist clears a minimum, a short hold from their first sale as fraud protection, and dispute clawbacks that pull from the next payout. The artist keeps 90 percent, the platform takes 10, and the per-payout fee math is designed so the platform never pays out at a loss on a tiny balance.
The infrastructure
FIRSTPRESS runs on a self-managed Hetzner footprint, not a managed cloud. Bare-metal and cloud VMs run the containers, with my own load balancing on HAProxy, my own monitoring, and my own autoscaling. More operational work, far less cost than the hyperscalers at this scale, and the savings go into the build instead of an AWS invoice.
The shape is straightforward. Cloudflare sits at the edge for CDN, WAF, DDoS, and a tunnel, so the origin has zero open ports. HAProxy on Hetzner does health-checked L4 and L7 load balancing across the VM pool. Web (Next.js SSR), API (NestJS, blue/green deploys), and workers (video transcode, email, async jobs) each run as autoscaled container pools. Postgres is self-hosted with a primary and read replicas, point-in-time recovery via WAL-G to R2, and automated backups across zones. Media lives in Cloudflare R2, S3-compatible with zero egress fees. Secrets sit in self-hosted Vault. There are separate dev and production environments with their own databases, so I can break things on dev without touching anyone real. Fonts are self-hosted rather than pulled from a CDN, for privacy and to dodge a content-security headache.
Observability is a self-hosted Grafana stack. Prometheus for metrics, Loki for logs, Tempo for traces, and Sentry for errors tagged to the exact commit SHA, so every exception resolves back to a line of code and a deploy. The architecture is deliberately portable. Standard Postgres, Linux, and OCI containers mean it can move to any hyperscaler in a weekend if a contract or regulation ever demands it.
The domain setup keeps a staging family and a production apex separate, so the path is local to dev to production, and the same build promotes up the chain.

The CI/CD pipeline and the devops
This is the part a sloppy AI build would die on, so it is locked down.
It runs on GitHub Actions with self-hosted runners. The pipeline runs lint and typecheck, then end-to-end tests, then a build stage that produces the web image and runs browser tests and an audit, then deploy. Around the deploy itself are the things that keep you employed. A database backup before anything ships, migrations, then a smoke test and a schema verification after, and an automatic rollback if any of that comes back wrong.
The workflow is trunk-based on main. Squash merge only so the history stays linear and every commit on main is revertible on its own. Branches live less than a day. Anything not ready hides behind a feature flag. Main is protected with required status checks, and merges are serialized, because the self-hosted runners share ports and a test database, so two deploys racing each other is a real way to corrupt state. Capacity is deliberately kept at one for that reason.
AI engineering, not vibe coding
The codebase is largely AI-written, orchestrated as a multi-agent pipeline with enforced gates, not a single chat assistant. Roles are separated. A test-writer agent emits a failing test for each unit of work, frontend and backend agents implement against it, a reviewer agent checks the diff, and a security-auditor agent runs on anything touching money or auth, configured to block by default.
Test-first is enforced, not suggested. An implementation cannot merge until its red test passes, which closes the failure mode where AI output reads correct and is quietly wrong. Agents run in isolated git worktrees so parallel work does not collide on the index, open PRs with structured handoff notes, and a separate stage owns the merge. The loop runs unattended against a work queue and returns reviewed PRs.
Worked example from the payout path. The auditor blocked the PR twice on a guaranteed double-pay. A column type mismatch let the Stripe Connect transfer fire while the ledger insert failed silently, so the next daily payout run would have re-paid every artist. The unit suite was green because it mocked the database, which is the exact seam the mismatch lived in. The catch came from an agent instructed to attack the path, not from the passing tests.
What is worth stealing from this
Test first is not optional once an AI is writing the code. Adversarial review catches the plausible-but-wrong failure mode that crashes nothing. The real engineering is the orchestration, the worktrees and the gate and the rollback and the recovery path, not the prompts. And steering is still a human job, because the agents are fast and literal and someone has to own the taste and the direction.
See it live: firstpress.audio