{#- Context variables:
   - company: str (e.g., "ACME Bank")
   - industry: str (e.g., "fsi")
   - catalog: str (e.g., "acme_fsi_demo")
   - bundle_name: str (e.g., "acme-bank-fsi-demo")
   - app_name: str (e.g., "acme-bank-fsi-app")
   - warehouse_id: str
   - workspace_host: str
   - databricks_profile: str | None
   - lakebase_url: str | None
   - notification_email: str
-#}
# Coding Standards -- {{ company }} {{ industry | upper }} Demo

## General Principles

1. **Library-first**: Check existing libraries before writing custom code.
2. **Production quality**: No "we'll fix it later." Every wave ships production-ready code.
3. **DRY**: Extract at three copies. Premature abstraction is worse than repetition.
4. **Composition over inheritance**: Combine small pieces. No deep hierarchies.
5. **Simple over clever**: If it needs explanation, it is too clever.
6. **No dead code**: Delete unused code, do not comment it out.
7. **300-line file limit**: Split if a source file exceeds this.

## Python Standards

### Style
- **Line length**: 100 characters (Ruff enforced)
- **Imports**: Sorted by Ruff (isort rules)
- **Type hints**: Required on all function signatures
- **Docstrings**: Required on all public functions and classes

### Quality Commands
```bash
uv run ruff check src/ --fix      # Lint
uv run ruff format src/            # Format
uv run mypy src/                   # Type check
uv run pytest tests/ -v            # Test
```

### Patterns
- Use `from __future__ import annotations` in all modules
- Use Pydantic v2 for data validation
- Use structlog for logging (JSON output)
- Use `Path` objects, not string paths

## SQL Standards (DLT)

### Naming Conventions
- Bronze tables: `bronze_{entity}` (e.g., `bronze_customers`)
- Silver tables: `silver_{entity}` (e.g., `silver_customers`)
- Gold tables: `gold_{metric}` (e.g., `gold_customer_health`)
- File names: `{entity}_{tier}.sql` (e.g., `customers_bronze.sql`)

### Table Properties
- Always set `TBLPROPERTIES ("quality" = "{tier}")`
- Gold tables: add `"pipelines.autoOptimize.zOrderCols"` for key columns

### Quality Constraints (Silver)
- Always add `EXPECT` constraints for NOT NULL on primary keys
- Always add `EXPECT` constraints for valid enum values
- Use `ON VIOLATION DROP ROW` for data quality

### Fully Qualified Names
- Always use `{{ catalog }}.{schema}.{table}` format
- Never use unqualified table names in DLT SQL

## Frontend Standards (Companion App)

### TypeScript
- Strict mode ON (`"strict": true` in tsconfig.json)
- No `any` types -- use proper typing or `unknown`
- Discriminated unions for variant types
- Zod for runtime validation + `z.infer<>` for type derivation

### React
- Functional components only (no class components)
- TanStack Query for ALL server state (never raw `fetch` + `useState`)
- Zustand for UI-only client state
- React Hook Form + Zod for forms
- Handle all states: default, loading, error, empty

### Styling
- Tailwind CSS utilities only -- no custom CSS classes
- shadcn/ui for all standard UI components
- `cn()` utility for conditional class merging (clsx + tailwind-merge)
- CVA (class-variance-authority) for component variants

### Quality Commands
```bash
npx tsc --noEmit        # Type check
npx vitest run           # Test
npm run build            # Build
```

## Commit Standards

- One logical change per commit
- Descriptive commit messages: `feat:`, `fix:`, `refactor:`, `docs:`, `test:`
- Run quality gates before every commit
