Skip to content

wcz-layout

general

137 linesSource

Use ALWAYS, before any other skill here, for every code change in this project. Defines the approved stack (TanStack, Vite+, MUI), TypeScript and naming conventions, date formatting, light/dark theming, testing and the validation command, and the src/ and tests/ folder layout that decides where each new file goes.

This is the default skill. Reference it in combination with more specific skills (e.g., forms, table, dialogs, etc.) for targeted tasks. For the full catalogue of every wcz-layout import subpath and what it exports, read references/exports.md. For access control, permissions, scopes, the signed-in user or downstream API tokens, read references/auth.md.

Preferred Technology Stack

Favor the established platform before introducing custom code or a new dependency:

  • TanStack ecosystem: Reach for the TanStack library that owns the problem instead of hand-rolling it — Start for the full-stack app and server functions, Router for routing and route-level data loading, DB for client-side collections and live queries, AI for LLM-backed chat and streaming, Form for form state and validation, Hotkeys for keyboard shortcuts, Virtual for long lists and grids, Pacer for debouncing, throttling, rate limiting and queueing or Charts for data visualization.
  • Vite+: Use Vite+ for the development server, formatting, linting and testing.
  • Material UI: Use Material UI for interface components and icons.

When the requirement is not covered above, look for an existing library before writing any logic. Prefer a well-maintained, widely adopted, typed library over custom implementations, even for seemingly simple functionality where a library can reduce edge cases and bugs. If a suitable library exists, install it and use it. Only implement the functionality yourself when it takes a few lines or no suitable library exists.

Coding Conventions

  • Write strict ES2023 TypeScript. Preserve local inference, type public boundaries and never use explicit any.
  • Stick to double quotes, semicolons, and the ~/ alias for src/ imports.
  • Avoid useMemo / useCallback; the React Compiler handles memoization.
  • Keep code self-documenting; only add comments to clarify non-obvious intent.
  • Run the narrow relevant test, then vp check --fix. It formats, lints and type-checks.

User Interface

  • Translate every user-facing string via useTranslation (or t outside components).
  • Format all client-side dates with "L LT" or "L".
  • When building UI, always design for both light and dark mode; this app uses colorSchemeSelector: "data-mui-color-scheme", so prefer theme.applyStyles("dark", ...) for mode-specific styling.
  • Always design for desktop and mobile, using responsive layouts and breakpoints to keep the UI usable on any screen.
  • Build skeletons for loading states.
  • Components fetching their own data with useQuery should wait until visible using useInView({ triggerOnce: true }) from wcz-layout/hooks and enabled: inView. Attach ref to a wrapper showing the skeleton. Data preloaded in route loaders stays eager.
  • For infinite scroll, attach ref from useInView() (without triggerOnce) to a sentinel after the last item.
  • Wrap content that must fill the rest of the viewport in Fullscreen from wcz-layout/components. It takes Box props and scrolls inside.
  • Success has no message. Animate the changed item where it lives: created enters, deleted collapses out, edited briefly tints. If the change isn't visible (e.g. before navigating), morph the trigger button to a check for ~400ms.

Utils

  • Generate every id on the client with uuidv7() from wcz-layout/utils.
  • Detect the OS with Platform.isAndroid / isIOS / isWindows / isMacOS from wcz-layout/utils.

Testing

  • vp test runs tests/unit and tests/integration; import the test API from vite-plus/test.
  • Server functions need a request context to run, so integration tests cover what they build on: the schema and constraints against the DATABASE_URL Postgres, and collections with the server function mocked.
  • npm run test:e2e runs Playwright against the dev server, signed in as admin by tests/e2e/auth.setup.ts.
  • Add or update tests for any new functionality or bug fixes where it matters, don't write tests just for the sake of having them.

File Organization

Use this ownership model for new application code. Keep feature-specific code close to its route; promote it to a root directory only when it is shared across multiple features.

plaintext
src/                               # client-first architecture
├── components/                    # shared components across multiple routes
├── db/                            # TanStack DB
│   ├── collections/               # collection descriptors
│   │   └── <table>.ts
│   └── queries/                   # live query option objects
│       └── <table>.ts
├── env.ts                         # clientEnv + serverEnv via createEnv
├── hooks/                         # shared hooks across multiple routes
│   └── useTheme.ts                # MUI theme + color schemes
├── lib/                           # isomorphic/shared logic usable by client and server
│   ├── auth/
│   │   ├── permissions.ts         # as const satisfies Permissions
│   │   └── scopes.ts              # as const satisfies Scopes
│   ├── locales/
│   │   ├── cs.json
│   │   └── en.json
│   └── schemas/                   # shared Zod schemas
│       └── <table>.ts
├── router.tsx                     # QueryClient, DbClient, router options
├── routes/                        # TanStack Router file-based routing
│   ├── __root.tsx
│   ├── index.tsx
│   ├── login.tsx                  # required by requireAuth
│   ├── health.ts                  # Docker HEALTHCHECK, pings the database
│   ├── auth/                      # OAuth handlers
│   │   ├── login.ts
│   │   ├── callback.ts
│   │   └── logout.ts
│   ├── api/                       # REST API routes (only when a public API is required)
│   │   └── features/
│   │       ├── index.ts
│   │       └── $id.ts
│   └── features/                  # feature folder with multiple routes (kebab-case, plural)
│       ├── -components/           # route-specific components
│       ├── -hooks/                # route-specific hooks
│       ├── index.tsx
│       ├── create.tsx
│       ├── $id.tsx
│       └── edit.$id.tsx
├── server/                        # server-only code, never imported from a component
│   ├── actions/
│   │   └── <table>.ts
│   ├── db/
│   │   ├── migrations/
│   │   ├── schemas/               # Drizzle schemas
│   │   │   ├── <table>.ts
│   │   │   └── relations.ts
│   │   └── index.ts               # pool, search_path, auto-migrate
│   └── middleware/
│       └── databaseMiddleware.ts  # app-local, not a library export
├── types/
│   ├── i18next.d.ts               # types t() against en.json
│   └── wcz-layout.d.ts            # declares virtual:wcz-layout
tests/
├── unit/
│   ├── lib/
│   │   └── schemas/
│   │       └── <table>.test.ts
│   ├── hooks/
│   │   └── useX.test.ts
│   └── routes/
│       └── features/
│           └── -components/
│               └── XCard.test.tsx
├── integration/
│   ├── server/
│   │   └── db/                    # real Postgres from DATABASE_URL
│   │       └── <table>.test.ts
│   └── db/
│       └── collections/           # server function mocked
│           └── <table>.test.ts
└── e2e/                           # Playwright
    ├── auth.setup.ts              # signs in as admin, no Microsoft login
    ├── utils.ts                   # gotoHydrated
    └── features/
        └── crud.spec.ts