Work makorefinery
web

Mako Refinery

Regulated 21+ storefront — passkey-only auth, a sourced federal/state/county restriction engine enforced at checkout, COA-gated publishing, scheduled local pickup, and camera-to-catalog AI intake on a Go + PostgreSQL backend.

Mako Refinery is a content-and-commerce platform for a regulated, age-restricted (21+) storefront: passkey-only auth (there are no passwords, and a lost passkey is recovered through a confirmed email link, never a password), AI product intake that turns a phone photo — or a whole batch of them, with barcode decode, OCR, and UPC enrichment — into drafted catalog entries, a faceted catalog (price, brand, stock) with search-as-you-type suggestions, products / orders / coupons / tax groups, a staff-facing customer directory (order history, lifetime value, notes, and the ability to block an account), a public Certificate-of-Analysis library with a database trigger that refuses to publish any product without a linked lab report, a versioned restriction ruleset at federal, state, and county level — with per-product purchase caps — that fails closed at checkout, per-product fulfillment methods (scheduled local pickup, carrier shipping for eligible goods, never for vapor), third-party age verification, first-party analytics, an articles / news CMS, and a maintenance-mode kill switch with auto-reopen. A Go backend (chi + pgx + PostgreSQL) serves a JSON API and WebAuthn ceremonies behind nginx and Cloudflare; the front end is a React 19 + Vite single-page app.

Last updateSep 1, 2026 PrimaryGo
  • Go
  • chi
  • PostgreSQL
  • pgx
  • WebAuthn
  • React
  • React Router
  • Vite
  • JavaScript
  • Tailwind CSS
  • OpenRouter
  • Google Cloud Storage
  • USPS API
  • Postmark
  • Twilio
  • Cloudflare
  • Playwright
  • Lighthouse
  • nginx
  • systemd
Mako Refinery — Regulated 21+ storefront — passkey-only auth, a sourced federal/state/county restriction engine enforced at checkout, COA-gated publishing, scheduled local pickup, and camera-to-catalog AI intake on a Go + PostgreSQL backend.
Mako Refinery media
Mako Refinery media
Mako Refinery media
Mako Refinery media

Mako Refinery is a content-and-commerce platform built for a regulated, age-restricted storefront that needs more than a Shopify theme — passkey-only auth on the customer side, OpenRouter-driven AI product intake, a public Certificate-of-Analysis library that gates what can be published, a restriction engine that knows which categories can be sold, shipped, or picked up where — down to the county — scheduled local pickup, third-party age verification, and a full articles CMS, so the same instance ships the storefront, the marketing site, and the back-office tooling.

Customer-facing

  • Passkey-only auth. WebAuthn is the only login path — there are no passwords to phish (server-side go-webauthn, browser @simplewebauthn); the autofill ceremony surfaces saved credentials on supported browsers, customers are nudged to enroll a backup passkey, and guests can still look up an order from the confirmation pair. A lost device is recovered by registering a new passkey from a link sent to an optional, confirmed account email — the address is a contact fact, never a credential, and the link never signs anyone in on its own.
  • Storefront with category browsing — All Products, sub-categories, faceted filtering by price, brand, and stock, search-as-you-type suggestions, age-gated detail pages, product images, per-product lab reports and batch numbers, and guest carts that survive hard reloads.
  • Public COA library. Every published product links to a publicly visible Certificate of Analysis at /lab-reports; lot coverage is derived at render time by comparing the product's batch to the report's, so a mismatch shows a visible "may not cover this lot" chip rather than a status column that rots.
  • Restriction engine, enforced where it counts. A versioned ruleset of federal, state, and county-level rules — each sourced against fetched primary law — decides per product whether it can be sold, shipped, delivered, or picked up for a given destination, and fails closed at checkout. The buyer sees the restriction at address entry, not after submitting; full state names normalize to codes so spelling a state out never bypasses the block; a public restrictions API drives the storefront's "sales ended" badges. Category-level sales cutoffs can be armed ahead of a regulatory deadline, so a product line switches itself off at the stroke of the effective date. Per-product purchase caps — a maximum quantity per customer per rolling day — are a rule in the same ruleset, evaluated inside the order transaction's own locks.
  • Per-product fulfillment. Each product carries its own fulfillment methods: scheduled local pickup with a pickup window, carrier shipping for eligible goods (USPS cubic pricing, adult signature on age-restricted parcels), and a permanent never-ship rule for vapor products. Quotes compute the pickup-address tax and the combined Florida rate; the money path runs paid → pickup completion → stock restore on cancellation.
  • Age verification — third-party identity checks wired into checkout on top of the site-wide 21+ gate.
  • Back-in-stock alerts. A shopper on a sold-out product page can ask to be told once it's purchasable again — a confirmed account email or a double-opt-in guest address — and is emailed exactly once per restock, never twice for the same window.

Admin / operator surface

  • Auto Inventory — camera to catalog. Point a phone camera at a product and two vision models read the label in parallel, with a third model breaking ties; brand, name, unit size, flavor, and category land as a drafted product with the photos attached. Intake refuses forbidden compounds by name, alias, SKU, or tag before a row ever exists.
  • Inventory Fill — bulk intake. Shoot a whole shelf: photos are grouped into batches, barcodes decoded server-side, labels OCR'd, UPCs enriched from external catalogs with retryable outages, and scale readings parsed for shipping-safe weights; a correction loop lets the operator split, merge, or link a scan to an existing product before one shared review submits the lot.
  • Product research — comparable-price and COA lookups per product, with every AI call cost-logged into a spend dashboard and a cleanup loop reaping abandoned scans.
  • Dashboard, products, orders, articles, lab reports, tax groups, coupons — full CRUD on every merchandising primitive, decimal-precise pricing, a COA coverage chip on the product grid, staff notes and tags on every order, a pick-slip rendering of the receipt for the counter, and the operator alerted the moment an order exists.
  • Customer accounts. Order history, lifetime value net of refunds, an append-only note thread per account, and a block flag that refuses a future order without touching the account's session or cart.
  • Shipping and pickup configurator — carriers, services, geographical zones, pricing markup, USPS credential management, and the pickup schedule.
  • Payment methods — bank wire, card, custom payment instructions, per-method enable/disable.
  • Site controls — basic info + branding, maintenance-mode toggle with custom message and auto-reopen schedule, registration toggles, contact email.
  • Mail and voice — Postmark send + inbound webhook, templated transactional email; inbound lab-report emails sync straight into the compliance paper trail; a Twilio number handles the regulator-mandated order line.
  • First-party analytics — traffic and retention recorded in Postgres, no third-party tag.

How it's wired

The backend is Go (chi router + CORS) exposing a JSON API and WebAuthn ceremonies, backed by PostgreSQL via pgx (numbered migrations, a generated schema.sql snapshot that deploy refuses to drift from, and PL/pgSQL triggers as the authority no import path can bypass). Media and nightly backups land in Google Cloud Storage with Postgres as the object index; secrets are read from files at startup, never from the repo or the environment. QR codes and lab-report label images are generated server-side. The front end is a React 19 + Vite single-page app (JavaScript, Tailwind, React Router). In production the Go binary runs as a systemd service bound to localhost behind nginx (TLS 1.2+, per-route rate-limit zones, nonce-based CSP, HSTS, SameSite=Strict CSRF cookies) with Cloudflare in front, and a Playwright suite plus a seeded launch rehearsal — catalog to picked-up order — must pass before a deploy counts as done. Lighthouse mobile scores are checked read-only against the live pages.

Why "Mako Refinery"

Mako Refinery exists because regulated storefronts (the "lab-report-required, age-gated, ships-here-but-not-there" pattern) keep needing the same integrations — passkeys, per-product fulfillment rules, COA attachments, jurisdiction- by-jurisdiction compliance gating, AI product intake, and an articles CMS — and none of the off-the-shelf cart frameworks ship them all cleanly. Mako Refinery is what we point at that pattern when a client shows up needing the whole stack.

Straight from the source

The project's own README.

Rendered in place — every link, image, and code block carried over from the repo. The page below is what a contributor would see opening the project for the first time.

Mako Refinery

Storefront for Mako Refinery, a registered fictitious name of MEIUX MEIUX LLC (Florida). Lab-tested CBD and hemp products, kratom, kava and accessories, sold to adults 21+ only.

This repository is private and must stay private. It is not open source and carries no licence. HANDOFF.md contains the Florida sales-tax certificate and DOR business-partner numbers, both marked confidential — see the note in .gitignore for what has to happen before this could ever be made public.

Stack

Layer What
Backend Go 1.25, chi router, pgx/v5
Database PostgreSQL (makorefinery, owned by makouser)
Frontend React 19 + Vite + Tailwind, built into backend/web/
Auth WebAuthn / passkeys only — there are no passwords
Edge nginx on the box, Cloudflare in front

The Go service listens on 127.0.0.1:8080 only; nginx is the sole way in.

Where things are

backend/internal/     the application, one package per domain
backend/database/     schema.sql (generated) + migrations/
frontend/src/         React app; `npm run build` outputs to backend/web/
nginx/                the live vhost, mirrored from /etc/nginx
scripts/              verify-schema.sh, browser tests, ops helpers
docs/                 subsystem documentation — start at docs/README.md
legal/                the published policy texts
HANDOFF.md            running project record; read this first

Common commands

just handoff-status  # begin/end a session with production context
just check           # formatting, vet, and full hermetic Go suite
just exposure-check  # served files, listener, sandbox, nginx, closed store
just preflight       # check + schema + exposure + production build
just deploy          # clean, pushed master only; deploy + live verification
just status          # health and production diagnostics
just logs            # recent backend service logs

# Lower-level commands remain available behind the recipes:
./deploy.sh deploy
./scripts/verify-schema.sh
./backup-database.sh       # see --help; 'schema-snapshot' regenerates schema.sql

node scripts/browser-test/edge-check.mjs   # what Cloudflare changes about our responses
sudo ./scripts/cloudflare-edge-fix.sh      # ...and turn those off over the API

deploy blocks if the migrations no longer reproduce schema.sql. Fix the drift, or --skip-schema-check to assert you have read the diff and it is harmless.

This directory is the live production checkout on a VPS shared with unrelated projects. Read AGENTS.md before operating it. GitHub is private, but only the Mako nginx/API/static-file surface is intended to be public; secrets remain in /var/keys and must never enter Git, logs, or backend/web.

Backend tests are hermetic and run in CI-style with go test ./.... Tests that need external resources are behind build tags, so they are opt-in:

go test -tags dbtest ./internal/analytics   # needs ANALYTICS_TEST_DSN
go test -tags gcslive ./internal/gcs        # costs real GCS operations

Two rules that bite

Schema changes need a migration, and schema.sql is generated. Never edit backend/database/schema.sql by hand — it is a pg_dump of production, regenerated by ./backup-database.sh schema-snapshot. Write a numbered migration, apply it, regenerate the snapshot, and confirm ./scripts/verify-schema.sh is still green. It compares the two and will tell you when they disagree.

Secrets live in /var/keys, never in the repo or the environment file. backend/.env holds tuning values only; the database password, the PII encryption key and the age-gate key are read from files at startup. See docs/backup.md for what is backed up where.

Documentation

docs/README.md is the index. docs/quick-start.md is the fastest way in. HANDOFF.md is the chronological record of what was done and why, and is usually the answer to "why is this like this".

Gallery

The full set.

Build something like this

Want a tool like this for your shop?

We've shipped this kind of thing before. Twenty-minute intro call, no slides.