4.0 KiB
4.0 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. The available checks arepnpm lint,pnpm typecheck, andpnpm build; runpnpm typecheck && pnpm buildafter application changes. There is no committed test suite or CI workflow. - Add UI primitives only through
pnpm dlx shadcn@latest add <component> --yes. Before using a shadcn component, runpnpm dlx shadcn@latest docs <component>and read the referenced docs. - Formatting is Prettier with Tailwind sorting (
pnpm format). It uses double quotes, no semicolons, 2 spaces, LF, and 80-column wrapping.
App And Auth
- This is a single Next.js App Router application; routes live under
app/. Authenticated pages composeSidebarProvider,AppSidebar, andSidebarInsetthemselves. - Next.js 16 uses
proxy.ts, notmiddleware.ts. Keepproxy.tsedge-safe: it imports onlylib/auth/config.ts, never database or password-hashing code. - Login, registration, and
/api/authare public. All other routes are protected byauthConfig; server pages and actions must still validate the session themselves. lib/auth/index.tsowns Node-side Auth.js providers and database work. OIDC is configuration-driven and disabled unlessAUTH_OIDC_ENABLED=truewith a complete issuer/client configuration.
Database
- PostgreSQL access is Drizzle +
postgres; the schema source of truth islib/db/schema.ts. Drizzle Kit loadsDATABASE_URLfrom.env.localand usesdrizzle.config.ts. - Use
pnpm drizzle-kit push --forceonly when a schema change is intended; it can apply destructive changes.pnpm tsx lib/db/reset.tsdropstransactions,channels,accounts,user_accounts, andusersand must never be run casually. - Business tables are user-scoped. Every read, update, or delete in
lib/actions/must obtainauth().user.idand constrain the query with thatuser_id; validate that referenced account/channel IDs belong to the same user. - Keep soft deletion (
deleted_at) semantics in reads and mutations. Account and channel management actions already follow this model.
UI And Copy
- The project uses shadcn
base-novaon@base-ui/react, Lucide icons, Tailwind v4, and semantic CSS variables fromapp/globals.css. - Prefer stock shadcn composition and variants over custom styling. Use
classNameonly for necessary layout, responsiveness, truncation, or stable dimensions; do not override component padding, margins, colors, typography, or default Dialog/Footer behavior without a verified need. - Forms use
FieldGroup,Field, andFieldLabel; useFieldSet/FieldLegendonly when the grouping adds user-facing meaning. PutSelectIteminsideSelectGroup. - Errors and callouts use
Alert; destructive errors useAlert variant="destructive"withAlertTitleandAlertDescription, never a hand-styleddiv. - Follow the default Dialog composition:
DialogHeader, form/content, thenDialogFooteras a directDialogContentchild. Do not addp-0, custom negative margins, fixed heights, sticky footers, or isolated scroll containers unless the task explicitly requires them. - Use
Button,Badge,Empty,Separator,Tooltip, and other installed primitives instead of recreating them. Usedata-icon="inline-start"ordata-icon="inline-end"for icons in buttons. - Use
gap-*, neverspace-x-*orspace-y-*; use semantic tokens instead of raw color palettes or manualdark:overrides. - Product-facing UI copy is Chinese only. Do not add English parentheticals to menus, labels, options, or headings; retain user-entered business values such as currency codes and card brands verbatim.
- Sidebar active state must derive from
usePathname()with exact matching for/and route-boundary matching for child paths. Do not add navigation links until their route exists.