Skip to content

Add Habit Tracker example: Next.js, Drizzle ORM and ClickHouse Managed Postgres - #504

Merged
sdairs merged 1 commit into
mainfrom
app/habit-tracker
Oct 23, 2026
Merged

sdairs merged 1 commit into
mainfrom
app/habit-tracker

Conversation

@sdairs

@sdairs sdairs commented Oct 21, 2026

Copy link
Copy Markdown
Member

Adds applications/habit-tracker: a Next.js 16 habit tracker (App Router, Server Components, Server Actions, Click UI) using Drizzle ORM with node-postgres on ClickHouse Managed Postgres, provisioned with clickhousectl.

Database lesson: one check-in per habit per day. check_ins has a (habit_id, day) primary key. The checkbox sends its desired state rather than a toggle, and checking a day is a single INSERT … SELECT … ON CONFLICT DO NOTHING, so double clicks, retries and concurrent requests leave one row. Streaks are computed in SQL with a gaps-and-islands window query.

Included: the app, src/db.ts with verify-full TLS from the service CA (it refuses a remote host without a CA), drizzle-kit migrations, SQL for roles, grants, seed and cleanup, unit and integration tests, a README with every clickhousectl and psql step, a CI workflow (install, typecheck and unit tests, build), and one line in the root README.

Verified against ClickHouse Managed Postgres 18.6:

  • 8 unit and 8 integration tests pass as the app role. These cover 20 concurrent check-ins leaving exactly one row, a raw duplicate failing with 23505, idempotent unchecking, streaks across gaps, ownership and archive checks, app-role DDL failing with 42501, and pg_stat_ssl reporting TLS.
  • The README's schema steps ran twice from scratch, the cleanup block ran as written, and the "Try it" steps were checked in the UI.

Walkthrough article (production URL): https://clickhouse.com/resources/engineering/build-habit-tracker-nextjs-drizzle-postgres

🤖 Generated with Claude Code

…d Postgres

A Next.js 16 habit tracker (Server Components, Server Actions, Click UI)
using Drizzle ORM with node-postgres on ClickHouse Managed Postgres,
provisioned with clickhousectl. A (habit_id, day) primary key and
INSERT ... ON CONFLICT DO NOTHING keep one check-in per habit per day
under retries and concurrency; streaks use a gaps-and-islands query.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sdairs
sdairs requested a review from lio-p October 21, 2026 16:58
@sdairs
sdairs merged commit 537b081 into main Oct 23, 2026
1 check passed
@sdairs
sdairs deleted the app/habit-tracker branch October 23, 2026 14:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants