← Back to Projects
Full-StackShipped

Afterthought

Built a deployed personal media archive that separates perceived film quality from personal impact, captures short post-watch reflections, and organizes them into a searchable theme-based knowledge base.

I kept remembering that a movie was an 8/10 and forgetting why it stayed with me. Existing trackers are excellent at logging titles and scores; they lose scenes, questions, and takeaways. I designed Afterthought as a Next.js App Router product with dual-axis ratings (Overall vs Personal Impact), a hard 2–3 minute capture constraint centered on one prompt (“What stuck with you?”), browser voice notes with transcription and AI organization, TMDB-backed media identity, and a persistence boundary that runs on a seeded Zustand demo store or Supabase auth/Postgres/storage. The hard problem was not adding fields. A multi-section journal felt like homework, so I forced capture and organization apart: the user writes the thought; AI may suggest themes afterward, never overwrite the original.

Engineering highlights

  • Modeled Overall Rating and Personal Impact as independent attributes so “best films” and “films that mattered” can diverge in the library
  • Collapsed an 8+ section reflection editor into a 2–3 minute default flow: two scores, one primary prompt, one save; moved structure behind optional expansion and AI post-processing
  • Separated TMDB media identity from user-media records (ratings, reflections, voice transcripts, themes) and kept a demo-first persistence path that runs without cloud credentials
Date
Summer 2026
Focus
Product Systems
Build stage
Deployed MVP
Disciplines
Full-Stack Engineering · Product Design · Data Modeling · API Integration · AI Systems
Next.jsTypeScriptSupabaseTMDBOpenAIZustandZodProduct Design
Product entry
Afterthought landing page with dual-axis rating promise

Public landing: dual-axis promise and one-click path into the seeded demo journal.

Full write-up below. The hero is the short version. This is the build story: what I designed, what broke, and why I made the calls I did.

Motivation

Why I started this

What pulled me in, and what I wanted to get better at.

Why I built it

I could remember whether a movie was an 8/10. What disappeared was why it stayed with me: a scene, a decision, a technique, or a question I wanted to keep.

What interested me

Trackers answer “what did you watch and how much did you like it?” I wanted something that could also answer “what did you take away from it?”

What I wanted to learn

How to model personal impact, how much structure helps before it becomes homework, where AI should organize instead of rewrite, and how to ship a local demo with a clean path to real cloud services.

System Overview

How the system fits together

A Next.js film journal: search real titles, score Overall vs Personal Impact, capture one primary reflection (“What stuck with you?”), optionally speak a voice note for AI organization, and browse the archive by themes like ambition or identity. TMDB owns media identity; Afterthought owns the user’s relationship to it. Demo mode runs on a seeded Zustand store when credentials are missing.

01

Discovery

TMDB search / seeded catalog → normalized media page.

02

Dual-axis ratings

Overall quality and Personal Impact as independent fields.

03

Reflection capture

2–3 minute default: two scores + one free reflection + save.

04

Voice + AI organize

Browser recording → transcript → cleaned copy / summary / themes; original stays ground truth.

05

Theme library

Retrieve by ideas (ambition, mentorship, sacrifice) not only title or date.

06

Persistence boundary

Zustand demo store locally; Supabase auth/DB/storage when configured.

Data flow

Search → TMDB media object → Overall + Personal Impact → write or voice → optional AI organization → themes / lists / library.

Control flow

External metadata answers what the title is. Private ratings, reflections, voice notes, and themes live on user-media records so they never get tangled into the catalog object.

Architecture
Afterthought architecture: user to Next.js to TMDB, OpenAI, and Supabase

Client owns search, detail, and reflection. App routes talk to TMDB for identity, OpenAI for organize/transcribe, Supabase for cloud persistence, or the local demo store when keys are absent.

Engineering Breakdown

Broken down by discipline

Each block covers the goal, the design, what broke, what changed, and what shipped.

01Full-Stack Application Architecture

Full-Stack Application Architecture

Goal

Ship a real multi-page product, not a static movie-review mock.

Design

Next.js App Router + TypeScript. Landing, dashboard, discover, media detail, reflection editor, library, lists, themes, voice notes, auth/onboarding. UI behavior stays separated from persistence and external APIs so demo content can exercise the product without mandatory credentials.

Challenges

  • Portfolio demos die when every click requires TMDB + Supabase + OpenAI keys.
  • Cloud multi-user paths still needed a clean migration story.

Iterations

  • Coupled UI and credentials
  • Persistence abstraction + seeded demo store
  • Deployed MVP with production integration boundaries

Final implementation

Deployed app that can show the full flow in demo mode and swap in TMDB / Supabase / OpenAI when configured.

Dashboard
Afterthought dashboard after entering demo mode

Authenticated demo shell: Home / Discover / Library / Lists / Voice Notes / Themes. Guest session with seeded onboarding preferences driving recommendations.

02Product & Interaction Design

Product & Interaction Design

Goal

Make meaningful reflection fast enough that someone would actually do it after a movie.

Design

Early editor exposed lessons, scenes, characters, quotes, techniques, applications, themes, tags, and voice. It felt like homework. Hard constraint: normal reflection ≤ 2–3 minutes. Default flow became two ratings + one primary field + save; deeper organization moved behind optional expansion or AI post-processing.

Challenges

  • Richer data models made capture cognitively expensive.
  • A journal that asks more than a star rating has to stay aggressively short.

Iterations

  • Feature-rich multi-section editor
  • 2–3 minute product constraint
  • Capture first, organize second

Final implementation

“What stuck with you?” as the primary surface; structure and AI help after the thought exists.

Reflection flow
Reflection editor with Overall and Personal Impact scores

After the credits: Overall and Personal Impact as separate sliders, then the primary prompt. Draft/save path stays short on purpose.

03Dual-Axis Rating Model

Dual-Axis Rating Model

Goal

Represent perceived quality and personal meaning separately.

Design

Store Overall Rating and Personal Impact as independent attributes. Optional dimension ratings exist but are not forced, and they do not auto-collapse into a single score unless the user chooses that.

Challenges

  • Two values add a little input friction.
  • A single 1–10 erases the distinction the product is built on.

Iterations

  • Traditional single score
  • Weighted rubric experiments
  • Two required scores only

Final implementation

Library can sort “best movies I watched” apart from “movies that mattered most to me.”

Media detail
Movie detail showing Overall and Personal Impact fields

Interstellar detail: YOUR OVERALL and YOUR IMPACT as separate slots, with community ratings as a secondary reference, not the product’s core.

04Movie Metadata / TMDB Integration

Movie Metadata / TMDB Integration

Goal

Reflect on real films without maintaining a hand-built movie database.

Design

Media records key off external TMDB identifiers (title, year, poster, overview, genres, cast, director). Personal state lives on separate user-media rows.

Challenges

  • External metadata and private data have different ownership and update lifecycles.
  • Duplicating subjective data into the catalog object would poison both sides.

Iterations

  • Manual seed-only catalog
  • Normalized TMDB objects + user-media records
  • Demo catalog fallback when the token is unset

Final implementation

Search → normalized media → personal ratings/reflections without stuffing the user’s thinking into the TMDB-shaped row.

Discover
Discover / search surface for films

Discovery path into real (or seeded) titles before reflection. Catalog identity stays separate from the journal entry.

05Voice Reflection + AI Organization

Voice Reflection + AI Organization

Goal

Capture messy post-movie thoughts without forcing structured forms up front.

Design

Browser recording → transcription → AI cleaned reflection, takeaway, suggested themes, optional follow-up. Original transcript is never overwritten; AI outputs are secondary, editable, and dismissible.

Challenges

  • Generative rewrite can sound polished and wrong.
  • If AI is treated as authoritative, the archive stops being personal.

Iterations

  • AI as writer
  • AI as organizer on top of user text
  • Approval step before themes stick

Final implementation

AI organizes the user’s thinking. It does not replace it.

Voice notes
Voice notes interface for spoken reflections

Speak-first capture surface. Transcription and theme suggestions are post-processing; the raw thought remains the source of truth.

06Theme-Based Information Architecture

Theme-Based Information Architecture

Goal

Make old reflections useful again months later.

Design

Associate reflections with themes such as ambition, identity, mentorship, leadership, sacrifice, grief, purpose, family, courage. Retrieval sits beside title, genre, year, and date watched.

Challenges

  • A chronological journal gets hard to search as it grows.
  • Theme value is weak on a cold-start empty account.

Iterations

  • Date-ordered log only
  • Manual categories
  • Theme browsing as a first-class axis

Final implementation

Closer to a personal knowledge base for media than a conventional watch tracker.

Themes
Theme browsing for reflections by idea

Browse by what the film taught you, not only by title. This is where the dual-axis journal pays rent after the fact.

Key Design Decisions

Calls I actually made

What else was on the table, what I picked, and why it still made sense once the hardware was real.

01

One rating or two?

The problem

Can a single rating accurately represent what I want to remember?

Alternatives considered

  • Traditional 5-star
  • Single 1–10
  • Detailed weighted rubric
  • Overall + Personal Impact

Tradeoffs

Two ratings add a little friction. One rating deletes the distinction the product exists to keep.

Why I chose this

Overall Rating + Personal Impact. Enough structure to preserve meaning without a rubric tax.

02

Structured form or free reflection?

The problem

How much structure should capture impose?

Alternatives considered

  • Separate inputs for lessons, scenes, characters, quotes, techniques, applications
  • One primary “What stuck with you?” field

Tradeoffs

Comprehensive forms are slow and cognitively expensive right after a movie.

Why I chose this

One primary field. Capture should be frictionless; organization can happen afterward.

03

AI writer or AI organizer?

The problem

What should AI actually do?

Alternatives considered

  • Generate an interpretation
  • Rewrite the user automatically
  • Organize the user’s original reflection

Tradeoffs

More generative behavior sounds polished while drifting from the user’s meaning.

Why I chose this

Original reflection is ground truth. AI proposes structure the user can accept or discard.

04

Cloud-only or demo-first?

The problem

Should the prototype require full infrastructure to run?

Alternatives considered

  • Require auth, DB, metadata API, and AI credentials for all behavior
  • Seeded demo mode alongside production integrations

Tradeoffs

Cloud-only is a fragile portfolio demo. Demo-first must not fake a production architecture that does not exist.

Why I chose this

Demo store + mocked AI/TMDB paths, with real Supabase/TMDB/OpenAI boundaries when keys are present.

Evolution

How it got here

Bench bring-up, CAD fits, soldering, and the demos in between. Not just the final photo.

  1. V0–V1

    Concept → feature-rich editor

    Started from Movie → Rating → Review, then exploded into lessons, profound moments, characters, scenes, techniques, quotes, applications, and voice. Powerful data model. Felt like a questionnaire.

    Organization surfaces
    Lists surface showing organizational structure

    Lists and structured organization were always part of the ambition. Early versions put too much of that structure in the first capture step.

  2. V2–V3

    Under three minutes, then AI as post-processing

    Asked a blunt question: can someone log a movie in under three minutes? Required path became two ratings + one reflection + save. Voice and AI routes summarize and suggest themes after the thought exists. Capture first, organize second.

    Library
    Library view of logged films

    After the constraint, the library is an archive of short captures, not a graveyard of unfinished multi-section forms.

  3. V4

    Deployed MVP

    Landing, library, detail, simplified reflection, voice architecture, theme retrieval, and demo/production boundaries shipped as one product at afterthought-phi.vercel.app.

    Landing
    Afterthought marketing landing page

    Public entry: brand, dual-axis promise, and a one-click path into the demo journal.

Results & Validation

What held up

What worked in the end, what I can show for it, and where it's still limited.

Functional MVP

Live demo

Landing, dashboard, library, detail, dual-axis ratings, written reflection, voice UI, themes, lists, seeded demo data, and external-service integration seams.

Reflection-time target

0 scores + 1 field

Standard flow minimized to two ratings + one reflection. Design target under three minutes; not yet a timed usability study.

Demo / production boundary

Zustand demo store

App remains demonstrable without credentials while preserving paths to TMDB, Supabase, and OpenAI.

Limitations

  • Real multi-user production behavior depends on completed TMDB, Supabase, and OpenAI configuration.
  • AI organization can distort nuance if treated as authoritative.
  • Theme retrieval is weak on a cold-start archive.
  • MVP validates implementation and interaction flow, not long-term retention.

Reflection

Looking back

What surprised me, what I'd redo, and questions I'm still chewing on.

What surprised me

  • The hardest product problem was deciding what not to ask. More structure made a richer schema and a worse experience.
  • Separating capture from organization fixed more than any new AI feature.

What I would redesign

  • Lean harder into retrieval: rediscovery across the last hundred watches, not more logging fields.
  • Stronger cloud persistence and unified movie + TV search (TV support is already starting to land).

Future improvements

  • Semantic search across reflections
  • Connections between reflections from different titles
  • Theme evolution over time and “you wrote this six months ago” resurfacing
  • Exportable personal film journal
  • Embedding-based similarity between reflections

Questions that emerged

  • How should software help people remember experiences without turning the experience itself into data entry?