- Add transactions_dirty table and zero-tolerance cleansing action - Implement bookkeeping workbench (/bookkeeping) with searchable Combobox channel selector and card suffix / account identifier - Implement transaction ledger (/transactions) with date groupings, multi-currency metrics, and filters - Update AGENTS.md guidelines for Base UI Select and Combobox bindings
4.1 KiB
4.1 KiB
This is NOT the Next.js you know
This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in node_modules/next/dist/docs/ before writing any code. Heed deprecation notices.
Fluxent Web
Commands
- Use
pnpm. Primary checks arepnpm lint,pnpm typecheck, andpnpm build; runpnpm typecheck && pnpm buildto verify changes. There is no committed test suite. - Add UI primitives only via
pnpm dlx shadcn@latest add <component> --yes. Read the referenced docs viapnpm dlx shadcn@latest docs <component>before using. - Format with
pnpm format(Prettier + Tailwind plugin: double quotes, no semicolons, 2 spaces, LF, 80-column wrap).
App And Auth
- Next.js 16 App Router application under
app/. Authenticated pages composeSidebarProvider,AppSidebar, andSidebarInsetthemselves. - Next.js 16 uses
proxy.ts, NOTmiddleware.ts. Keepproxy.tsedge-safe: import onlylib/auth/config.ts, never database or password-hashing code. - Public routes:
/login,/register,/api/auth/*. All other routes are protected byproxy.ts; server pages and server actions must still validate sessions viaauth(). lib/auth/index.tsowns Node-side Auth.js providers and database operations. OIDC is disabled unlessAUTH_OIDC_ENABLED=truewith full issuer/client credentials configured.- Sidebar active state must derive from
usePathname()(/exact match, child routes prefix match). Do not add navigation links until their route exists.
Database And Ledger Architecture
- PostgreSQL access via Drizzle ORM +
postgres; schema truth islib/db/schema.ts. Drizzle Kit loadsDATABASE_URLfrom.env.localviadrizzle.config.ts. - Schema sync:
pnpm drizzle-kit push --force. Never executepnpm tsx lib/db/reset.tsunless explicitly instructed (drops all data tables). - Multi-tenancy & safety: Every action in
lib/actions/must enforceuserId = session.user.idand filter out soft-deleted records withisNull(table.deletedAt). Verify that referenced accounts or channels belong to the same user. - Two-tier transaction ledger:
- Fast/draft entry stores records in
transactions_dirty. - Cleansing action (
cleanseTransactionsActioninlib/actions/bookkeeping.ts) performs atomic zero-tolerance validation before moving items intotransactions.
- Fast/draft entry stores records in
- Card brands: Stored as lowercase machine keys (
visa,mastercard,unionpay,amex,diners,discover,jcb). Always usenormalizeCardBrand()fromlib/payment/card-brand.tsand local SVGs under/payment-logos/.
UI And Copy
- Tech stack: shadcn
base-novaon@base-ui/react, Lucide icons, Tailwind v4, semantic CSS variables fromapp/globals.css. - Base UI Select & Combobox:
<SelectValue />: When<SelectItem>contains complex JSX/icons and no plain string children, Base UI falls back to rendering raw values (e.g. UUIDs). Provide plain textchildrenor explicit formatting logic.<Combobox>: Whenitemsis an array of objects, always provide bothitemToStringValue(string serialization for search matching and value keying) anditemToStringLabel(input display string) to avoid[object Object]display bugs.
- Form composition: Use
FieldGroup,Field, andFieldLabel. PutSelectIteminsideSelectGroup. UseFieldSet/FieldLegendonly when grouping adds visible user meaning. - Dialog composition: Follow standard structure (
DialogHeader, form/content,DialogFooterdirectly insideDialogContent). Do not addp-0, negative margins, sticky footers, or manual scroll wrappers without a verified requirement. - Styling: Use
gap-*, NEVERspace-x-*orspace-y-*. Use semantic color tokens, avoid hardcoded palettes or manualdark:overrides. Buttons with icons usedata-icon="inline-start"ordata-icon="inline-end". - Product copy is Chinese only: Do not add English parentheticals to labels, menus, options, or headings (e.g., no "账户 (Accounts)"). Retain user-entered values and standard business tokens (e.g., currency codes
CNY, card brand namesVisa) verbatim.