---
name: eslint-validator
description: Static validation of SmartStack React conventions (5 architecture rules)
group: V
cli: cli
allowed-tools: [Read, Glob, Grep, Bash]  # Bash: CLI invocation
---

# Skill: ESLint SmartStack Validator

> Static analysis of React/TypeScript files to validate SmartStack
> architecture conventions (5 layers, PermissionGuard, DTO naming, hooks, feature-folder).

## When to use

- After frontend file generation (scaffold-routes, scaffold-component)
- Before a merge or PR
- To audit an existing React codebase

## The 5 Rules

| Code | Description |
|------|-------------|
| `ss/no-direct-fetch` | No direct `fetch()` or `axios` in `components/` and `pages/` — use the API service |
| `ss/permission-guard` | Sensitive actions (delete, approve, execute) wrapped in `<PermissionGuard>` or protected by `usePermission` |
| `ss/dto-naming` | Interfaces exported in `types/*.types.ts` follow pattern `{Resource}ResponseDto`, `Create{Resource}Dto`, `Update{Resource}Dto` |
| `ss/service-hook-structure` | Custom hooks in `hooks/` use `useQuery` or `useMutation` from React Query |
| `ss/feature-folder` | Files organized in `features/{module}/{resource}/{layer}/` where layer = pages, components, hooks, services, types |

## CLI Invocation

```bash
npx --prefer-offline tsx skills/validation/eslint/cli/index.ts --src <directory>
```

## JSON Output

```json
{
  "timestamp": "2026-03-31T...",
  "checks": [
    { "code": "ss/no-direct-fetch", "status": "ok", "count": 0 },
    { "code": "ss/permission-guard", "status": "error", "file": "StockTable.tsx", "line": 12, "message": "Button 'delete' without PermissionGuard" }
  ],
  "errors": 1,
  "warnings": 0
}
```

## Workflow

1. User mentions "validate frontend" or "eslint"
2. Request the source directory (`--src`)
3. Call the CLI
4. Present results explaining each violation and how to fix it

## Typical Corrections

| Violation | Correction |
|-----------|-----------|
| `ss/no-direct-fetch` | Move call to `services/{resource}Api.ts` and use React Query hook |
| `ss/permission-guard` | Wrap button in `<PermissionGuard permission={...}>` |
| `ss/dto-naming` | Rename interface to follow `{Resource}ResponseDto` / `Create{Resource}Dto` / `Update{Resource}Dto` |
| `ss/service-hook-structure` | Add `useQuery` or `useMutation` to the hook |
| `ss/feature-folder` | Move file to `features/{module}/{resource}/{layer}/` |
