# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project

TextIQ User Portal Frontend — Next.js 16 + React 19 + TypeScript app. Frontend-only repo; backend is a separate Python/FastAPI BFF in `textiq-user-portal-api`.

## Commands

```bash
pnpm dev              # Dev server (port 3000)
pnpm build            # Production build
pnpm lint             # ESLint (cached)
pnpm lint:fix         # ESLint fix + Prettier
pnpm check-types      # TypeScript validation (tsc --noEmit)
pnpm knip             # Detect unused code/exports
pnpm commit           # Interactive conventional commit (commitizen)
```

Validation before PR: `pnpm lint && pnpm check-types && pnpm build`

## Architecture

### Stack

Next.js 16 (App Router, React Compiler enabled), React 19, Tailwind CSS 4, shadcn/ui (new-york style, Radix UI), TanStack Query v5 (server state), Zustand 5 (client UI state), Zod 4 (validation), React Hook Form 7, next-intl 4 (i18n), Axios (HTTP), next-themes (dark/light).

### Routing

All routes under `src/app/[locale]/` — next-intl handles locale prefix. Next.js 16 middleware at `src/proxy.ts` currently handles locale routing via next-intl. Auth redirect and CSP nonce are planned but not yet implemented.

### Feature Module Pattern

Each feature is self-contained under `src/features/{name}/`:

```
features/{name}/
├── api/            # TanStack Query key factories + API calls (Zod-validated)
├── components/     # Feature-specific UI
├── hooks/          # Feature-specific hooks
├── schemas/        # Zod schemas (types inferred via z.infer)
├── stores/         # Zustand stores (if needed)
├── types/          # Feature types
├── helpers/        # Feature utils
└── index.ts        # Barrel export (public API)
```

**Isolation rules:**
- Features import from `@/components/`, `@/hooks/`, `@/stores/`, `@/lib/`, `@/types/`. Features must NEVER import from other features.
- **Rule of Three:** All logic starts inside `features/{name}/`. Promote to `src/` shared layer only when used by 2+ features.
- **Cross-feature communication:** Only via shared layer or prop-drilling at Page level.

**Folder semantics within features:**
- `helpers/` — Pure TS functions, no package imports (e.g., `isBrowser()`)
- `data/` — Feature-specific static data (lists, config objects)
- `schemas/` — Single source of Zod schemas for both API validation and UI forms
- `api/` — TanStack Query hooks + API calls. UI layer must NEVER use `axios`/`fetch` directly.

**Global `src/lib/` vs `src/helpers/`:** Files with package imports (date-fns, js-cookie, etc.) go in `lib/`. Pure TS without imports go in `helpers/`.

### API Layer

1. **Global client** (`src/lib/api.ts`): Axios instance with base URL from `env.NEXT_PUBLIC_API_URL`, typed helpers (`get`, `post`, `put`, `del`)
2. **Feature API** (`src/features/{name}/api/`): Query key factories + API functions that validate responses with Zod
3. **Query client** (`src/lib/query-client.ts`): staleTime 60s, gcTime 5min, retry 1

### Provider Hierarchy

`ThemeProvider` → `IntlProvider` → `QueryProvider` → `ActiveThemeProvider` → children (in `src/providers/Providers.tsx`)

### Environment Variables

Validated at runtime via `@t3-oss/env-nextjs` + Zod in `src/env.ts`:
- `NEXT_PUBLIC_SITE_URL` (required URL)
- `NEXT_PUBLIC_API_URL` (required URL — BFF endpoint)
- `NEXT_PUBLIC_GA_ID` (optional)

### i18n

next-intl with locale segment `[locale]`. Languages: `en`, `ja`. Translation files in `src/messages/{locale}.json`. Default locale: `en`. Locale config in `src/constants/i18n.constants.ts`.

## Key Path Aliases

`@/*` → `src/*`, `@/ui` → `src/components/ui`, `@/features/*` → `src/features/*`. Full list in `tsconfig.json` paths.

## Code Conventions

- **Path aliases mandatory** — parent-relative imports (`../`, `../../`) are FORBIDDEN. Use `@/` aliases.
- **Import order** (enforced by Prettier): React → Next → TanStack → Zustand → Lucide → third-party → types/schemas/config → i18n/assets → lib → providers/stores/hooks → components → tailwind
- **No HTTP in UI** — UI components must never call `axios`/`fetch` directly. Consume only `features/{name}/api/` functions.
- **Styling**: `cn()` from `src/lib/utils.ts` (clsx + tailwind-merge) for className composition
- **Commits**: Conventional Commits enforced via commitlint + Husky pre-commit hooks. Do NOT include `Co-Authored-By` in commit messages.
- **Lint-staged**: ESLint + Prettier on `*.{ts,tsx,js,jsx}`, Prettier on `*.{css,md,json}`
- **shadcn/ui**: Add components via `npx shadcn@latest add {component}` — outputs to `src/components/ui/`
- **Chat language**: Vietnamese or English. Code/types/naming always in English

## Key Documentation

- `docs/planning-artifacts/architecture.md` — Frontend architecture decisions
- `docs/api-contract.md` — REST endpoints, Socket.IO events, response formats for BFF integration
- `docs/references/textiq-user-portal-api/architecture.md` — BFF internals reference
- `AGENTS.md` — AI agent persona and operational guardrails
