Smoke Test App
Todo List Display — render all persisted todos ordered by creation time with completion styling and an empty-state message
Todo List Display — render all persisted todos ordered by creation time with completion styling and an empty-state message
- Fetch and render todos from GET /api/todos on page loadFetch and render todos from GET /api/todos on page load
- Display each todo with a checkbox and title textDisplay each todo with a checkbox and title text
- Apply strikethrough + muted style to completed todosApply strikethrough + muted style to completed todos
- Show empty-state message when no todos existShow empty-state message when no todos exist
Add Todo — input field and Add button to create new todos
Add Todo — input field and Add button to create new todos
- Text input with placeholder and Add buttonText input with placeholder and Add button
- Submit on Enter key pressSubmit on Enter key press
- Client-side validation: reject empty/whitespace inputClient-side validation: reject empty/whitespace input
- Append new todo to list without full page reloadAppend new todo to list without full page reload
- Clear and re-focus input after successful addClear and re-focus input after successful add
Toggle Todo Completion — checkbox interaction to mark todos complete or incomplete
Toggle Todo Completion — checkbox interaction to mark todos complete or incomplete
- Clicking checkbox toggles completed state via PATCH /api/todos/:idClicking checkbox toggles completed state via PATCH /api/todos/:id
- UI updates to reflect new completion state immediatelyUI updates to reflect new completion state immediately
- Strikethrough added on complete, removed on incompleteStrikethrough added on complete, removed on incomplete
Remaining Count Display — live count of incomplete todos
Remaining Count Display — live count of incomplete todos
- Display count of incomplete todos formatted as 'N left'Display count of incomplete todos formatted as 'N left'
- Count updates on every add or toggle actionCount updates on every add or toggle action
- Shows '0 left' when all todos are complete or list is emptyShows '0 left' when all todos are complete or list is empty
Data Persistence via PostgreSQL — all todos stored and retrieved from a PostgreSQL database
Data Persistence via PostgreSQL — all todos stored and retrieved from a PostgreSQL database
- todos table with id, title, completed, created_at columnstodos table with id, title, completed, created_at columns
- Auto-create table on app startup if not existsAuto-create table on app startup if not exists
- Database connection via DATABASE_URL environment variableDatabase connection via DATABASE_URL environment variable
REST API — Next.js Route Handlers exposing todo CRUD endpoints
REST API — Next.js Route Handlers exposing todo CRUD endpoints
- GET /api/todos — return all todos ordered by created_at ASCGET /api/todos — return all todos ordered by created_at ASC
- POST /api/todos — create todo, returns 201 with todo objectPOST /api/todos — create todo, returns 201 with todo object
- PATCH /api/todos/:id — toggle completed, returns 200 with updated todoPATCH /api/todos/:id — toggle completed, returns 200 with updated todo
- 400 on invalid input, 404 on missing resource, 500 on server error400 on invalid input, 404 on missing resource, 500 on server error
Basic Styling — clean, readable UI with CSS Modules
Basic Styling — clean, readable UI with CSS Modules
- Centered single-column layoutCentered single-column layout
- Visual distinction between complete and incomplete todosVisual distinction between complete and incomplete todos
- User-visible error message on API failureUser-visible error message on API failure