Projects

Haloway

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
Next.js
TypeScript
PostgreSQL
Stripe
LLM orchestration
The Haloway essay workspace, showing a student's essays grouped by school and prompt alongside the drafting editor.
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.
  • 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.
  • 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.
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.
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 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.