№ IV · MMXXVI projects

№ X · 2026 · parked, not buried

Mintly

An approval-grade shell for a crypto-only get-paid-to site. 50 commits, 38 backend tests, 12 Playwright E2Es, all green. Built in five days end-to-end as a discipline study — and deliberately never launched. The code is clean. The market wasn't.

What it is

Mintly is the public-facing shell of a get-paid-to (GPT) site — landing, sign-up, verify, dashboard, withdraw, offer browse, the legal shelf. Real auth, real append-only ledger, a dev-only "complete this offer" button that exercises the full credit/release/confirm/withdraw lifecycle through a background scheduler. If an offerwall partner ever connected, the data shape on the dashboard would not change — only the source would flip from a JSON seed to a live API.

Mintly landing page — asymmetric hero with live preview panel showing top offers and balance card.
Landing — asymmetric hero with a live preview panel.

Why it exists

I wanted to find out how far I could push a discipline I'd been sketching for months: brainstorm to spec to plan to execution, with everything written down, every change reviewed, every test green. Crypto GPT was the test bed — a domain I understood, a market I knew was hard, a scope I could bound to one sub-project of seven without pretending I was launching a real business.

The output is the most production-ready unlaunched code I've ever written, and a clear answer to the implicit question: is the bottleneck building this, or distributing it? The bottleneck was never the build.

How it was built

Five days, one operator, one terminal session per phase. Process was rigid and deliberately so — the goal was as much "see if this loop scales" as "ship the site."

  1. Brainstorm. Niche, scope, stack, visual direction, brand placeholder — locked through a guided multiple-choice flow. No premature code.
  2. Spec. A single design document — architecture, data model, auth flows, ledger invariants, dev-complete mechanics, copy direction, testing strategy, deployment runbook, explicit out-of-scope. Reviewed and approved before any task was written.
  3. Plan. 46 tasks across 11 phases, each with exact files, exact code, exact commands, an explicit failing test before any implementation. Self-reviewed against the spec for placeholders, contradictions, and ambiguity.
  4. Execution. A controller dispatched a fresh subagent per task. Two-stage review after each: spec compliance first, then code quality. Implementer fixed, reviewer re-checked, and only then did the next task start. ~50 commits, no batching, no shortcuts.
  5. Polish. A second pass after the functional build, this time on visual quality — typography overhaul, asymmetric hero, refined offer grid with category tabs, split-context auth pages with a faux-dashboard preview, custom accordion, trimmed footer. The shell stopped reading as generic AI MVP and started reading as real product.
Mintly earn page — stats bar, category tabs, featured row of top-payout offers, refined offer cards.
Earn — featured row + category tabs over 40 stub offers.

Architecture

┌──────────────┐    ┌──────────────────┐    ┌──────────────────┐
│ Astro 4 SSR  │ ←→ │ FastAPI 0.110+   │ ←→ │ Postgres 16      │
│ React islands│    │ async SQLAlchemy │    │ user_balances    │
│ Tailwind 3   │    │ JWT-free sessions│    │ (SQL view)       │
└──────────────┘    └────────┬─────────┘    └──────────────────┘
                             │
                             ▼
                    ┌──────────────────┐
                    │ APScheduler      │
                    │ (hold release    │
                    │  every 30s)      │
                    └──────────────────┘

Single-VPS docker-compose: postgres + api + web behind nginx. Sessions are opaque cookies stored as sha256(token) server-side, not JWTs — simpler revocation, no parsing surface. The ledger is append-only; balance is a VIEW, never a stored counter. Every dollar that enters the system traverses production code paths, even in dev — the only thing the dev-complete button does is shortcut which dollar.

The ledger invariants

The most load-bearing decision in the spec is that the ledger is append-only and the balance is derived. Three rules, non-negotiable:

The withdraw endpoint refuses negative available_balance at the application layer; a property test asserts no user-reachable code path can drive it negative. The endpoint exercises the full hold→reverse round trip even though payouts aren't wired — when they are, the only change is replacing the immediate reverse with a real settlement marker.

Why it isn't live

The shell is the easy 30% of "make this work." The hard 70% is operational and external:

None of these are technical problems. All of them are real ones. With Receptiv as the active income grind and no warm crypto distribution to leverage, the opportunity cost was clear. The right move was to bank the polish as a study, write down what would have come next, and not pretend a partial answer was the whole one.

Mintly signup page — left side shows live activity feed and trust stats, right side has the form.
Sign-up — split layout with a live activity feed as social proof.

Stack

What's actually here

The repo is a self-contained reference for solo full-stack work at a quality bar I'd be willing to ship. Spec, plan, runbook, and acceptance template all live in docs/. Every commit message is a complete sentence. No TODOs, no placeholder TODOs, no "Add error handling" in any handler. The five post-build polish commits are explicitly labelled — Header logout fix, dev-tools env-source fix, pytest baked into Dockerfile, Resend bypass logging, password reset E2E coverage — so future-me knows exactly what was punted and why.

If the conditions ever change — a warm distribution channel appears, an influencer asks the right question, the regulatory picture shifts — the shell is already there. Until then it's a study in shipping discipline more than a study in get-paid-to.