Case StudyFact sheet

Product design · UX · Full-stack development

The Founders League — a private reading league that runs itself.

A closed, invitation-only web application where four founders each read a book every month, present it in a structured monthly meeting, get evaluated by an AI judge, and progress through levels, honours and a shared fund. I designed and built the product, the interface and the entire back end.

Problem
A reading group that dies after month three
Users
Four founders, one super admin
What I did
Product, UX, interface, back end, data & security
Shape
Bilingual web app, automated monthly cycle

Context & problem

Reading groups fail for reasons software can actually address.

Four founders wanted a serious monthly reading commitment. In practice such groups collapse for a short list of reasons: choosing a book takes longer than reading one, nobody schedules the meeting, discussion stays polite and shallow, effort is invisible, and there is no consequence to skipping a month.

The group is also deliberately private and francophone, which rules out public communities and English-only tools.

  • Book selection paralysis
  • Meetings that never get scheduled
  • Discussion with no structure or stakes
  • Invisible effort, no sense of progress
  • No membership control in a private group

The solution

One product that turns a good intention into a monthly ritual with rules.

01

Decide

A reader profile and a scored monthly shortlist replace the endless debate — the member still confirms the final choice.

02

Meet

Meetings are generated, scheduled across time zones, reminded without duplicates, and hosted in a video room with a calendar invite.

03

Prove

A structured question round, AI evaluation, experience points, honours, tokens and a shared fund make the effort visible and comparable.

Key features

Each capability, the problem it solves, and what it is worth.

Invitation-only membership

01

Problem

The league is deliberately limited to four members, so open sign-up would break the concept.

What I built

An approved-email whitelist enforced at the database level, hashed single-use invitation tokens, an accept-invitation flow, admin roles, member suspension and replacement, and an audit log of admin actions.

Value

Access is closed by design and every membership change is traceable.

Member dashboard & progression

02

Problem

Members had no single place to see where they stand in the season.

What I built

Level ring with experience points, current month's book with page progress, honours grid, season leaderboard, shared adventure fund, and a live countdown to the next gathering.

Value

The full state of a member's month is readable in one screen.

Automated monthly meetings

03

Problem

Scheduling a recurring meeting across time zones by hand is fragile and easy to forget.

What I built

Server-side generation of upcoming monthly meetings, IANA time-zone handling, member slot suggestions with admin resolution, an idempotent reminder ledger so no email is ever sent twice, calendar (.ics) export, a video room per meeting, and a public scheduling endpoint that a scheduled job can call.

Value

The ritual runs itself; the admin only arbitrates.

Knowledge Arena

04

Problem

Book discussions drift and stay passive.

What I built

A structured question/answer round per meeting: members submit questions, answers are revealed and scored, a token currency is earned and spent, special abilities are limited per meeting, and results are persisted. The rules are versioned and must be accepted.

Value

Discussion becomes a fair, repeatable, competitive format.

AI Chief Judge

05

Problem

Peer scoring alone is inconsistent and socially loaded.

What I built

Server-side AI evaluation of submitted questions and answers through a hosted model gateway, stored per meeting, feeding a meeting report and an end-of-meeting cinematic recap.

Value

Neutral, consistent feedback that no member has to police.

Reader profile & recommendation engine

06

Problem

Choosing the right monthly book is the hardest recurring decision.

What I built

A ten-step reader profile questionnaire, a compatibility score computed from goals, obstacles, difficulty, language and discussion value, a monthly shortlist with reasons, side-by-side comparison, save / not-interested feedback that feeds back into scoring, and an explicit final confirmation (never auto-selected).

Value

A defensible recommendation instead of a coin flip — and the member always decides.

Reading paths

07

Problem

One good book a month does not build a direction.

What I built

Thematic multi-stage paths mapped from the reader profile, with per-step state and progress, plus a dedicated path screen.

Value

Monthly reading becomes a sequence with a visible destination.

Curated book catalogue (admin)

08

Problem

Public book data is noisy, duplicated and inconsistently described.

What I built

External search and import of book metadata and covers, deduplication by identifier, editions, difficulty and discussion-value assignment, approval/blocking, and promotion of a single Book of the Month enforced by a unique database index.

Value

Recommendations only ever draw from data a human approved.

Bilingual interface (EN / FR)

09

Problem

The members are francophone; the product had to read naturally in both languages.

What I built

Full interface translation with a per-user language preference persisted to their profile.

Value

No English-only compromise for a bilingual group.

Architecture & integrations

How the pieces fit — and why each one is there.

Shape of the system

  • Typed server functions hold the business logic. Each one validates its input and, when it touches member data, runs behind authentication middleware.
  • The database is the last line of defence. Row-level security scopes every table to its owner, with admin access granted only through role-checking functions.
  • Public HTTP endpoints exist only for machine callers (scheduled meeting generation, calendar files) and verify the caller themselves.
  • Reads go through a query cache keyed per resource, so a mutation invalidates exactly what it changed.

External services, and what each does

  • AI gateway (Gemini Flash) — evaluates meeting questions and answers server-side.
  • Google Books + Open Library — book metadata and covers, with a fallback between the two.
  • Resend — invitations and meeting reminders, tracked in a delivery ledger.
  • Jitsi Meet — a video room per meeting, restricted to active members.
  • iCalendar export — so the meeting lands in each member's own calendar.
  • Scheduled database jobs — call the public scheduling endpoint monthly.

Front end

  • React
  • TanStack Router (file-based)
  • TanStack Query
  • TypeScript
  • Tailwind CSS
  • Radix / shadcn components
  • i18next
  • Motion

Back end

  • TanStack Start server functions
  • Zod validation
  • Auth middleware per server function
  • Public HTTP endpoints for webhooks / scheduling

Data

  • PostgreSQL
  • Row-level security policies
  • Role helper functions (security definer)
  • SQL migrations
  • Scheduled database jobs

Services

  • Hosted AI gateway (Gemini Flash model)
  • Google Books API
  • Open Library API
  • Resend (transactional email)
  • Jitsi Meet (video rooms)
  • iCalendar (.ics) generation

Challenges & decisions

The trade-offs I had to take a position on.

Security enforced in the database, not in the UI

Every table carries row-level security and explicit grants, and admin checks run through security-definer functions rather than client-side flags. Execute rights on sensitive functions were revoked from anonymous and standard roles, a recursive policy on meeting participants was replaced by a dedicated helper function, and member email addresses were removed from the readable profile columns and exposed only through a self-scoped function.

The AI advises, it never decides

The AI judge produces evaluations and signals; it never selects a member's book and never awards membership or roles. Recommendation selection always ends on an explicit human confirmation step.

No invented data

Book prices could not be sourced reliably, so instead of faking them the interface states that the price is unavailable and links to a search by identifier, with the data model left ready for a real provider. Missing covers fall back to a placeholder rather than a guess.

Idempotency over cron optimism

Meeting reminders and monthly generation are keyed so a repeated or retried job cannot duplicate emails or shortlists — the correctness constraint lives in the schema, not in the scheduler.

Extend, never delete

The reading-recommendation system was layered alongside the original book tables instead of replacing them, so no historical member data was lost during the migration.

Impact & value

What the product changes — stated without invented numbers.

This is a private application for four people and no analytics were collected, so I make no claims about retention, engagement or growth. What can be shown is the work itself:

Recurring manual work removed

Meeting creation, scheduling, reminders and calendar invites no longer depend on anyone remembering.

A decision made defensible

Book choice moved from opinion to an explainable score, with the reason shown next to each recommendation.

Discussion given a format

A repeatable question round with neutral evaluation replaces unstructured conversation.

Privacy held as a hard constraint

Membership is closed at the database level and email addresses are not readable by other members.

Bilingual by default

Every screen exists in French and English with a persisted per-user preference.

Security findings closed

Permissive policies, mutable function search paths, recursive policies and over-broad execute rights were identified and fixed.

Project visuals

Real screens from the application, anonymised.

Member dashboard — screen from The Founders League application

Member dashboard

Level and experience ring, current month's book, honours, season leaderboard, token balance and shared fund. Member names anonymised; captured in a development environment, so counters read zero.

Book discovery — screen from The Founders League application

Book discovery

Entry point to the monthly shortlist: the engine scores approved catalogue books against the reader profile — goals, obstacles, difficulty, language and discussion value.

Monthly gatherings — screen from The Founders League application

Monthly gatherings

Meetings generated automatically per month with status (upcoming, reviews open, finalised) and admin scheduling. Each meeting carries its calendar export and video room.

Skills demonstrated

Product, engineering, UX and judgement.

Product

  • Scoping a system from a vague ritual
  • Feature sequencing in phases
  • Deciding what not to build

Engineering

  • Full-stack TypeScript
  • Relational modelling & migrations
  • Third-party API integration
  • Automation & idempotency

Security

  • Row-level security design
  • Role separation & least privilege
  • Closing audit findings

UX & design

  • Editorial dark design system
  • Progressive disclosure in a 10-step flow
  • Bilingual copy
  • Purposeful motion, reduced-motion respected

Summary

Fact sheet.

Project
The Founders League — private reading & accountability league
Type
Personal product, designed and built end to end
My role
Product definition, UX, interface design, full-stack development, database & security
Users
A closed group of four members, one of whom is a super admin
Surface
Bilingual web app (EN / FR), dark editorial design system
Core stack
React · TanStack Start / Router / Query · TypeScript · Tailwind · PostgreSQL with row-level security
Integrations
AI gateway · Google Books · Open Library · Resend · Jitsi · iCalendar · scheduled jobs
Metrics
No usage statistics are claimed — the app runs for a private group and no analytics were collected

Every statement on this page is drawn from the application's own code, database schema and integrations. Where information could not be verified — usage metrics, book pricing, project timeline — it is marked as unavailable rather than estimated.