Cadence Redesign Build Guide
From Broken to Working in One Session
Overview
This guide documents the process of redesigning and fixing the Cadence task management app. The session focused on simplifying the data model, fixing broken features, and streamlining the deployment workflow.
Time: ~5 hours (including recurring tasks) Result: Fully functional app with unified tasks, time blocking, goals, calendar views, and recurring tasks
What Made This Build Smoother
1. Git Credentials Embedded in Remote URL
The key improvement: storing the GitHub token directly in the remote URL.
git remote set-url origin https://YOUR-TOKEN@github.com/USERNAME/REPO.git
Why this matters:
- No password prompts on every push
- No credential caching issues
- Push fails? Just update the token in the URL
To set this up:
- Create a Personal Access Token at https://github.com/settings/tokens/new
- Check repo scope
- Run the command above with your token
- All future pushes "just work"
2. Auto-Deploy Already Configured
Railway and Vercel were already connected to GitHub from the original build:
- Push to
master→ Railway auto-deploys backend - Push to
master→ Vercel auto-deploys frontend
No manual deploys needed. Just push and wait 2-3 minutes.
3. Fix → Push → Test Live (Not Local)
Instead of wrestling with local database setup, we:
- Made code changes with Claude Code
- Pushed directly to GitHub
- Tested on the live site
- Read error messages from browser console + Railway logs
- Fixed and repeated
This avoided the entire "set up local PostgreSQL" rabbit hole.
4. Database Fixes Direct to Production
When the production database was missing columns, we fixed it directly:
# In Claude Code, with the DATABASE_URL:
psql "postgresql://postgres:xxx@xxx.proxy.rlwy.net:xxx/railway"
Then ran ALTER TABLE commands. No migrations, no downtime.
The Redesign Process
Phase 1: Planning (This Chat)
Before touching code, we designed:
- Unified task model (one table instead of two)
- Simplified date handling (one
datefield, notscheduleddate+duedate) - Sprint colors for visual distinction
- Goals as leading indicators with manual increment
- View structure (Today, Tasks, Sprints, Cycles)
Output: cadence-redesign-spec.md — a complete spec to hand to Claude Code
Phase 2: Database Migration
Claude Code created a migration script that:
- Renamed old tables (
tasksold,sprinttasks_old) - Created new unified
taskstable - Migrated data from both old tables
- Added new columns (
coloron sprints,outcomeon cycles) - Simplified goals (renamed columns)
Key insight: The migration ran locally but NOT on production. We had to manually add missing columns to the Railway database.
Phase 3: Backend Updates
- Rewrote Task model for unified schema
- Updated all routes to use new table
- Removed old routes (
/api/week,/api/today) - Removed old models (
SprintTask,DailyTask)
Phase 4: Frontend Updates
Built/updated views in order:
- Tasks list view (grouped by Today/Tomorrow/This Week/Later)
- Tasks calendar view (side-by-side with day panel)
- Today view (time blocking grid)
- Sprint view (with colors, explicit completion)
- Cycle view (with goals and [+] increment)
Phase 5: Bug Fixes
Most bugs were database schema mismatches:
| Error | Cause | Fix |
|---|---|---|
| 500 on create cycle | Missing outcome column | ALTER TABLE cycles ADD COLUMN outcome TEXT |
| 500 on create goal | Columns named wrong | Renamed targetvalue → target, currentvalue → current |
| 500 on create task | Missing columns | Added starttime, estimatedminutes, sprint_id |
| Sprint dropdown empty | Promise.all failing | Separated fetches into independent try/catch |
Debugging pattern:
- Try action in browser
- Check browser console for error code (500, 404, etc.)
- Check Railway logs for actual error message
- Fix database or code
- Push and retest
Key Commands Reference
Git (with embedded token)
# Set up once
git remote set-url origin https://TOKEN@github.com/USERNAME/REPO.git
# Then just push
git add .
git commit -m "Description"
git push origin master
Database Fixes (via Claude Code)
# Connect to Railway Postgres
psql "DATABASE_URL_HERE"
# Common fixes
ALTER TABLE tablename ADD COLUMN IF NOT EXISTS columnname TYPE;
ALTER TABLE tablename RENAME COLUMN old TO new;
\d tablename -- show table structure
\q -- quit
Debugging Stubborn Bugs
When a fix doesn't work, add logging at every step:
// Client - before API call
console.log('[Action] Sending:', { data, options });
// Client - after API response
console.log('[Action] Server response:', response);
// Server - in route handler
console.log('[ROUTE] Params:', { id, mode, data });
console.log('[ROUTE] Branch:', 'which code path executed');
// Client - in data processing
console.log('[Process] Input:', rawData);
console.log('[Process] Output:', processedData);
Then trace the data flow to find where it breaks.
Check Deployment Status
- Railway: https://railway.app/dashboard → your project → Deployments
- Vercel: https://vercel.com/dashboard → your project → Deployments
What's Different from Original Cadence Build
| Original Build | This Redesign |
|---|---|
| Built features incrementally | Started with complete spec |
| Local testing with SQLite | Test directly on production |
| Manual Vercel deploys | Auto-deploy on push |
| Credential prompts every push | Token embedded in remote URL |
| Two task tables | One unified table |
| Complex date fields | Single date field |
| Goals with "points" | Goals as leading indicators |
Final App Structure
Cadence
├── Dashboard (summary counts)
├── Today (time blocking)
│ ├── Time grid (15-min increments)
│ └── Unscheduled tasks panel
├── Tasks
│ ├── List view (grouped by date)
│ └── Calendar view (side-by-side with day panel)
├── Sprints
│ ├── Active / Upcoming / Completed sections
│ ├── Sprint detail with tasks
│ └── Explicit "Mark Complete" button
├── Cycles
│ ├── Current / Past sections
│ ├── Goals with progress bars and [+] increment
│ └── Linked sprints
└── Issues (existing feature)
Lessons Learned
- Spec first, code second — The planning conversation caught UX issues before writing code
- Production database ≠local database — Migrations don't auto-run on Railway. Check Railway logs for "column does not exist" errors.
- 500 errors = check server logs — Browser console shows the error code, Railway logs show the actual message
- Embed git credentials — Saves 5 minutes of frustration on every push
- Test live, not local — Faster feedback loop when you skip local database setup
- Fix one bug at a time — Verify each fix before moving to the next
- Database columns must match code — When you get 500 errors on create/update, it's often a mismatch between what the code expects and what the database has. Fix with ALTER TABLE directly on Railway.
- Console.log is your friend — When a bug is stubborn, add logging at each step of the flow (client → server → back to client) to pinpoint exactly where it breaks.
- Timezone bugs are sneaky —
new Date("2026-01-29")parses as UTC midnight, which shifts to the previous day in western timezones. Use local date parsing helpers when comparing dates.
- Clean URLs matter —
/todayis better than/cadence?tab=today. Use React Router for clean routes.
- Recurring tasks are deceptively complex — They need: instance generation, exclusions for completed/deleted, proper date passing for each instance, and special handling for the first occurrence (which comes from the original task, not generated instances).
- When porting features between apps, bring the bug fixes — We fixed recurring task bugs in Rapport, then applied the same patterns to Cadence. Document what you learn so you don't re-discover bugs.
- Test the specific instance, not just the feature — "Delete works" isn't enough. Test: delete today's instance, delete a future instance, delete all. Each path can break differently.
- Use the app for real — Building is one thing. Using it daily will reveal what's actually missing or broken.
Next Steps (Future Sessions)
- [ ] Google Calendar integration (read events, write time-blocked tasks)
- [ ] Design polish pass (match Rapport styling exactly)
- [ ] Sprint visibility on calendar view
- [x] Add recurring tasks — done
- [x] Clean up URL structure — done:
/today,/tasks,/sprints,/cycles - [x] Calendar side-by-side layout with drag-drop — done
- [x] Dashboard counts fixed — done
- [x] Explicit sprint completion — done
Guide created: January 29, 2026