>jose_sosa_
Back to projects
My product

Quizpato

A bilingual trivia game about what's happening now

Read the story behind a topic → answer timed questions → challenge a friend with a link, no sign-up → climb the weekly league → come back tomorrow for the daily trivia.

Quizpato duck mascot

// how it works

The core loop

Built for a habit and for sharing: every topic is a short story you can learn from, and every result is one link away from a friend.

1

Discover

Fresh stories on what people are reading this week — plus sports, science, history and more.

2

Play

The daily trivia, a category, or Pato's dial. 30 seconds per question, graded on the server.

3

Learn

Every answer links to the story behind it, so a miss still teaches something.

4

Challenge

7 questions, one link, 48 hours to beat you. Nobody needs an account.

5

Compete

Streaks, XP, weekly leagues and a medal per category.

6

Come back

Push and in-app notifications: a rival answered, someone passed you, new questions landed.

// architecture

Two systems, one HTTP contract

Quizpato is built on the architecture I designed for Skillpato. I wanted a similar platform — questions, scoring, leagues, an AI content engine — but with different features for a different audience: casual trivia players in English and Spanish instead of developers preparing for interviews. So it keeps the same split: a Next.js platform and a Python content engine that only talk over a versioned HTTP API. The engine never touches the database or user data — it researches, writes and checks content, and the platform decides what goes live. Reusing that foundation is what took it from design doc to production in three days.

quizpato-web
Next.js · Supabase · Vercel
◀── /api/v1 (HTTP) ──▶no shared DB · scoped keys + SSM
quizpato-generator
Python · AWS Lambda · SAM

quizpato-web

The game · Next.js on Vercel

  • Next.js 16 (App Router), React 19, TypeScript, Tailwind v4.
  • Supabase (Postgres + Auth) with Prisma 7; row-level security locks the public API, so every read and write goes through the server.
  • Bilingual by design: EN at the root, ES under /es (next-intl), and the home remembers your language.
  • Installable PWA with Web Push plus an in-app inbox, both fed by one notification producer.
  • Admin for the topic queue, per-category generation plans, player reports, and a weekly metrics report compared week over week.

quizpato-generator

The AI newsroom · Python on AWS Lambda

  • Python 3.12 packaged with AWS SAM — five Lambdas on EventBridge schedules.
  • Daily content run per category: pick a topic, write a story and EN/ES question twins with OpenAI, then verify every answer against the source.
  • Topic sourcing: Wikipedia's most-read pages daily, a ~3,300-topic backlog from its monthly charts since 2015, Search Console queries, and manual picks.
  • Quality passes: answer check, EN/ES twin check, interest scoring, and triage of player reports into proposed rewrites.
  • Also runs the league rollover, season reset, hourly push fan-out and a weekly report (Search Console + GA4 + Mixpanel + DB).
  • Zero database access — its only contract is the HTTP API + secrets in SSM Parameter Store.

// the hard part

AI-written trivia that doesn't make things up

A trivia game lives or dies on correct answers and fresh topics. An LLM gives you volume; these three rules are what make it trustworthy, fair across languages, and current.

Fact-first

Every answer has a receipt

Each question is built from a verbatim excerpt of its source (Wikipedia), and the excerpt is checked programmatically against the real page before anything is posted. If the answer can't be quoted, the question doesn't exist.

Twins, not translations

Fair across languages

English and Spanish questions are written as linked twins with the same facts and answer, then checked as a pair. That's what lets a player in Spanish challenge a friend playing in English on the exact same seven questions.

Always current

A prioritized topic queue

Manual picks beat trending topics, which beat search-driven and backlog ones. Trending topics jump the category rotation and expire after a week, so the site talks about this week — not just the evergreen classics.

// engineering decisions

How I built it to be fair and shareable

A leaderboard and a challenge link are only fun if nobody can cheat them and anyone can open them. These are the decisions behind that.

Challenges with zero sign-up

A guest gets a random browser id, the server fixes the seven questions, and the link (/reto/<code>) is all a rival needs. If either player signs up later, their challenges move to the account.

Server-authoritative clock

Each served question carries an HMAC-signed token with the serve time, and the 30 seconds are enforced on submit; in a challenge, reloading re-serves the same question with the same clock. The correct answer never reaches the browser before you commit.

Notifications with manners

One producer feeds the inbox and Web Push. Push never fires between 22:00 and 08:00 local, sends at most one per kind per day, respects per-kind opt-outs, and only delivers to an allowlist of real push services. Permission is asked at a useful moment, never on arrival.

Metrics as a feature

A weekly Lambda compiles Search Console, GA4, Mixpanel and database numbers into one stored report, staff accounts excluded. The admin compares any week with the previous one, with the change in amount and percent.

Same engine, different product

Quizpato started from Skillpato's codebase. Kept: scoring, leagues, streaks, push and the content pipeline. Removed: skill scores, jobs and the recruiter side. Added for a casual audience: daily trivia, challenge links, stories, trending topics and a fully bilingual game. Each product has its own repos, database and keys — nothing shared at runtime.

Locked down before launch

Row-level security on every table with no public grants, timing-safe secrets on internal routes, scoped API keys, and a pre-launch security review across the app, the AWS account and the live site.

// what's in it

Feature set

  • Daily trivia — the same questions for everyone, with a daily ranking
  • Challenge a friend by link: 7 questions, 30s each, 48h to answer, no account needed
  • Six categories with sub-topics, plus Pato's dial to pick one at random
  • A short story behind every topic, linked from each answer
  • Streaks, XP, weekly leagues with promotion and relegation, medals and trophies
  • Public player profiles, private with one toggle
  • Installable PWA with Web Push and an in-app notification inbox
  • Fully bilingual (EN/ES) with linked question twins
  • Admin: topic queue, generation plans, player reports, weekly metrics

// tech stack

Built with

Platform

Next.js 16TypeScriptReact 19Tailwind v4next-intlPWA

Data

SupabasePostgreSQLPrisma 7Zod

AI engine

Python 3.12AWS LambdaAWS SAMEventBridgeOpenAIWikipedia APIs

Ops & infra

VercelWeb Push (VAPID)SSM Parameter StoreMixpanelGA4Search Console API

My role

Creator & sole engineer — product, design, architecture, full-stack, cloud & AI content pipeline