Skip to main content
Manyi Life — M Monogram
/

Architecture Decisions

The fork we took, and why

Seven public architecture decisions — what we chose, what we gave up, and when we'd revisit each.

"We use Logto" is an answer; "why not Auth0" is the useful content. Each ADR below (Architecture Decision Record) is something we actually weighed, shipped, and wrote down. The full versions live in GitHub at docs/adr/ — this page is the short-form index for teams about to make similar calls.

  1. ADR-001

    2026-05-03

    Logto for cross-brand SSO

    Four domains, one reader identity, solo-team budget, embedded sign-in needed. After weighing NextAuth / Auth0 / Clerk, we chose Logto Cloud: pricing curve survives 10× growth, Experience SDK is first-class, OSS escape hatch.

  2. ADR-002

    2026-04-01

    OpenNext on Cloudflare Workers (not Vercel)

    Single-vendor strategy for a multi-site portfolio: Workers + D1 + KV + R2 + Queues on one bill. Cost: working around a few Next.js features like ISR (see ADR-006). Vercel DX is better, but at 4 sites the math doesn't.

  3. ADR-003

    2026-05-06

    Single Resend audience, brand-tagged

    Per-brand audiences look clean, but you can never answer "how many readers are active in ≥2 brands." We chose shared audience with brand tags — cross-brand queries are one JOIN. Cost: strict scoping on broadcasts.

  4. ADR-004

    2026-05-06

    D1 for cross-brand analytics (not KV, not external warehouse)

    Ad-hoc analytics needs SQL. KV can't, external warehouses cost too much at our scale, Workers Analytics Engine query surface is too narrow. D1 flat table + JSON metadata is the sweet spot; trade-off is no multi-region replication.

  5. ADR-005

    2026-05-03

    Per-brand cookies, no shared session across brands

    Different TLDs fundamentally can't share cookies; we use OIDC redirect for "sign in once, use any brand." Costs ~300ms on first cross-brand visit. Buys brand independence and security isolation.

  6. ADR-006

    2026-05-08

    No ISR on OpenNext until Queues are wired

    Learned via PR #60: next.revalidate on Workers needs Cloudflare Queues or it 500s in production. Until Queues are set up, use Suspense islands + worker-local caches instead.

  7. ADR-007

    2026-04-15

    One repo per sub-brand, group repo for shared admin

    Rejected monorepo: a broken build in one brand shouldn't block another. Cost: code duplication, but 6 months in it's been manageable. Revisit when team grows past 3 engineers.

For the full versions (including options we rejected and revisit triggers), the complete ADR set is public at docs/adr/.

See Advisory services