Add onDelete: Cascade to CsvUpload.accountId so deleting an account
cascades to its upload records. Also explicitly delete uploads before
the account in the API route so existing deployed DBs without the
constraint don't error.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Category:
- Add categoryColumn to NormalizerConfig and NormalizedRow
- Map 'Category' column for Discover CC profile
- Write category to Transaction on upload
Budget rules:
- Add BudgetRule model (userId, budgetId, pattern)
- API: GET/POST /api/budget-rules, DELETE /api/budget-rules/:id
- Apply rules during upload (first case-insensitive match wins)
- Budgets page fetches and passes rules per budget
- BudgetCard 'Rules' menu item opens BudgetRulesDialog for add/delete
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Base UI Select.Value renders the raw value prop (cuid) rather than
the item label. Pass the looked-up account name as children to
override it. Falls back to placeholder when no account matches.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Prisma 7 no longer reads the seed command from package.json.
It must be set in prisma.config.ts under migrations.seed.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Unauthenticated requests to /login were hitting the auth gate and
redirecting back to /login?callbackUrl=/login, causing a loop.
Let the login page render for unauthenticated users; only redirect
away from /login when the user is already logged in.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
req.url resolves to the internal hostname in Docker standalone mode.
Read the Host header directly so redirects and CSRF origin checks use
whatever host the browser actually used (IP, hostname, or domain).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
req.nextUrl.origin resolves to localhost inside the container.
Using req.url preserves the Host header the browser sent, so
redirects work when accessing via IP or any external hostname.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
127.0.0.1:3000 only accepted connections from localhost.
DB port intentionally stays on 127.0.0.1.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
NextAuth's Credentials provider pulls in Prisma -> pg -> Node.js crypto,
which crashes in the Edge runtime. Extract an auth.config.ts with only
JWT/session callbacks (no DB, no bcrypt) and use NextAuth(authConfig) in
middleware. auth.ts spreads the config and adds the Credentials provider.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The production runner image has no node_modules, so prisma CLI and tsx
are unavailable. Add a Compose 'setup' profile service that uses the
builder stage (which has all dev tools) to run db push and db seed.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>