An AI powered college-application workspace with a suite of purpose-built organizational tools. Used by 200+ users, including paying customers who got into top schools like Yale and Berkeley.Founder & Software Engineer · Live · July 10, 2026
Haloway is a writing platform for college applications. Students organize essays
by school, prompt, and deadline, draft them in a version-controlled editor, and
get feedback from AI assistants built to critique and coach rather than
ghostwrite. It runs in production on Next.js 16 and Postgres.It began as a SvelteKit prototype. Once real use exposed the prototype's limits,
I rebuilt it as a Next.js App Router app against the same database — the old
version kept serving traffic throughout the migration, and still shares that
database today.
The product
Application workspace — essays grouped by school and prompt, with
deadlines, status, word limits, a pinned "working on now" document, and search
across everything a student has written.
Version-controlled editor — Tiptap/ProseMirror with local-first autosave, a
version sidebar that snapshots drafts as students revise, and export to
DOCX, PDF, and plain text.
AI writing feedback and admissions guidance. Clara handles drafts through
inline suggestions, a full review pass, and document-aware chat. Chloe answers
admissions questions, with persistent memory and user-set custom instructions.
Both assistants are designed to help students develop their own writing,
with that purpose reflected in their prompts and the product's guidance.
Research and profile tools — school research backed by Google-search
grounding with live citations, a Common App activities organizer (drag
ordering, participation levels, timing), an applicant background form that
feeds a profile-assessment workflow, and AI rewrites for activity
descriptions.
Parent handoff — a student can send a parent an overview of their progress
by invite link or email.
Engineering highlights
Shared AI orchestration. All AI features use an ordered
provider chain (Vertex AI → Google AI Studio, with a Gemini 2.5 tier as a
third entry). Features request a task category (chat, heavy, grounded,
or background), and the shared layer selects the provider. Providers can be
added through configuration. The app can also run without AI keys, with AI
features unavailable and a health endpoint reporting provider availability.
AI execution logs. Multi-step AI flows are recorded across three
tables, so every step, tool call, token count, and latency is inspectable
when investigating an issue.
Fail-closed quotas. Seven per-feature daily counters live on the user row
with atomic consume-or-reject semantics and a UTC reset boundary, and every
consumed unit is appended to a usage log. The prototype's checks were
permissive on error; the current checks reject a request if quota validation
fails, preventing unaccounted usage.
Authorization in one place. The server layer is the security boundary:
every read and mutation passes through session guards and pure ownership
checks that are unit-testable without a database. The Next proxy is an
optimistic redirect and is explicitly documented as not the auth boundary.
Billing as a state machine. Stripe hosted Checkout, webhook-driven
entitlements, a processed-events table for idempotency, and plan expiry
evaluated at read time.
The admin platform
I built a separate Next.js admin app for support, billing, and maintenance,
with its own authentication and mandatory TOTP two-factor authentication.
Postgres enforces database permissions through three roles: read-only,
app-write, and a narrowly scoped role for sensitive operations. Column-level
permissions keep session tokens and credentials inaccessible to all three.
Support — user records organized around the product's navigation, a
contact queue, and billing tools. Refunds and plan changes require additional
verification, valid for 15 minutes.
Content — announcement banners with scheduling and route targeting, and a
markdown blog editor with autosave and publishing, so content ships without a
deploy.
Repairs — destructive operations require a confirmation phrase, a
short-lived signed cookie, and a written reason. The dashboard flags essays
with broken references to their current version and parent emails that
failed to send.
Audit — every mutation of shared data writes a before/after snapshot to an
append-only log. The table is INSERT-only for all three roles at the Postgres
level, so the trail is tamper-evident from the dashboard itself.
Stack
Next.js 16 (App Router) · React 19 · TypeScript · Tailwind v4 · shadcn/Radix ·
PostgreSQL (Supabase, treated as plain Postgres) · Drizzle ORM · Better Auth ·
Stripe · Tiptap · Gemini via Vertex AI & AI Studio (Vercel AI SDK) · Resend ·
Vitest · Vercel
What I learned
Releasing the SvelteKit prototype gave me useful feedback from applicants early
in development. I used their questions and difficulties to decide what to
improve in subsequent releases.The feedback that shaped the product most came from students who went on to
get into numerous Top 20 schools like Yale and Princeton. They wanted feedback that helped them
improve their own essays, which shaped the design of Clara and Chloe. Features
such as version history and parent progress updates also grew out of student
requests. Building Haloway taught me to make user feedback a regular part of
development.