# POST-CHECKs — Compact Reference

> **Referenced by:** step-04-examine.md (section 6b)
> **Execution:** Run .sh scripts from `references/checks/`. Each script outputs BLOCKING/WARNING/OK per check.

## Run MCP Tools FIRST

1. `mcp__smartstack__validate_conventions()` — naming, routes, NavRoute kebab-case
2. `mcp__smartstack__validate_security()` — tenant isolation, TenantId, authorization
3. `mcp__smartstack__validate_frontend_routes()` — lazy loading, route alignment

---

## Execution Commands

```bash
# Run all checks by category
bash references/checks/security-checks.sh
bash references/checks/backend-checks.sh
bash references/checks/frontend-checks.sh
bash references/checks/seed-checks.sh
bash references/checks/architecture-checks.sh
bash references/checks/infrastructure-checks.sh
```

## Check Index

### Security — Tenant Isolation & Authorization (S1-S9)

| ID | Severity | Description | Script |
|----|----------|-------------|--------|
| S1 | BLOCKING | Services must filter by TenantId (OWASP A01) — MCP overlap | security-checks.sh |
| S2 | BLOCKING | Controllers must use [RequirePermission], not [Authorize] — MCP overlap | security-checks.sh |
| S3 | BLOCKING | Services must inject ICurrentTenantService (tenant isolation) | security-checks.sh |
| S4 | BLOCKING | HasQueryFilter must not use Guid.Empty (OWASP A01) — MCP overlap | security-checks.sh |
| S5 | BLOCKING | Services must NOT use TenantId!.Value (null-forgiving crash pattern) — MCP overlap | security-checks.sh |
| S6 | BLOCKING | Pages must use lazy loading (no static page imports in routes) — MCP overlap | security-checks.sh |
| S7 | BLOCKING | Controllers must NOT use Guid.Empty for tenantId/userId (OWASP A01) — MCP overlap | security-checks.sh |
| S8 | BLOCKING | Write endpoints must NOT use Read permissions | security-checks.sh |
| S9 | BLOCKING | FK relationships must enforce tenant isolation | security-checks.sh |

### Backend — Entity, Service & Controller Checks (V1-V2, C8, C12, C14, C28-C31, C54, C62)

| ID | Severity | Description | Script |
|----|----------|-------------|--------|
| V1 | BLOCKING | Controllers with POST/PUT must have corresponding Validators | backend-checks.sh |
| V2 | WARNING | Validators must be registered in DI | backend-checks.sh |
| C8 | BLOCKING | Backend APIs must support search parameter for EntityLookup | backend-checks.sh |
| C12 | WARNING | GetAll methods must return PaginatedResult<T> | backend-checks.sh |
| C14 | WARNING | Entities must implement IAuditableEntity + Create/Update validator pairs | backend-checks.sh |
| C28 | WARNING | Pagination type must be PaginatedResult<T> — no aliases | backend-checks.sh |
| C29 | BLOCKING | Code generation — ICodeGenerator must be registered for auto-generated entities | backend-checks.sh |
| C30 | BLOCKING | Code regex must support hyphens | backend-checks.sh |
| C31 | WARNING | CreateDto must NOT have Code field when service uses ICodeGenerator | backend-checks.sh |
| C54 | BLOCKING | No helper method calls inside .Select() on IQueryable | backend-checks.sh |
| C62 | WARNING | Services must use TenantContextRequiredException for tenant check, NOT InvalidOperationException | backend-checks.sh |

### Frontend — CSS, Forms, Components, I18n (C3a, C3-C7, C9, C11, C24-C27, C36-C37, C49, C52)

| ID | Severity | Description | Script |
|----|----------|-------------|--------|
| C3a | BLOCKING | Frontend must not be empty if Layer 3 was planned | frontend-checks.sh |
| C3 | WARNING | Translation files must exist for all 4 languages (if frontend) | frontend-checks.sh |
| C4 | WARNING | Forms must be full pages with routes — ZERO modals/popups/drawers/slide-overs | frontend-checks.sh |
| C5 | CRITICAL | Create/Edit pages must exist as separate route pages | frontend-checks.sh |
| C6 | WARNING | Form pages must have companion test files | frontend-checks.sh |
| C7 | WARNING | FK fields must use EntityLookup — NO <input>, NO <select> | frontend-checks.sh |
| C9 | WARNING | No hardcoded Tailwind colors in generated pages | frontend-checks.sh |
| C11 | BLOCKING | Frontend routes must use kebab-case | frontend-checks.sh |
| C24 | WARNING | i18n must use separate JSON files per language (not embedded in index.ts) | frontend-checks.sh |
| C25 | WARNING | Pages must use useTranslation hook (no hardcoded user-facing strings) | frontend-checks.sh |
| C26 | WARNING | List/Detail pages must include DocToggleButton (documentation panel) | frontend-checks.sh |
| C27 | WARNING | Module documentation must be generated (doc-data.ts) | frontend-checks.sh |
| C36 | CRITICAL | Frontend navigate() calls must have matching route definitions | frontend-checks.sh |
| C37 | CRITICAL | Detail page tabs must NOT navigate() — content switches locally | frontend-checks.sh |
| C49 | BLOCKING | Route Ordering in App.tsx — static before dynamic | frontend-checks.sh |
| C52 | BLOCKING | Frontend route paths must include module segment | frontend-checks.sh |
| C64 | BLOCKING | ListPages must have Create/New button (navigate to create route) | frontend-checks.sh |

### Seed Data — Navigation, Roles, Permissions (C1-C2, C10, C15-C23, C32-C35, C44-C48, C53)

| ID | Severity | Description | Script |
|----|----------|-------------|--------|
| C1 | WARNING | Navigation routes must be full paths starting with / | seed-checks.sh |
| C2 | WARNING | Seed data must not use deterministic/sequential/fixed GUIDs | seed-checks.sh |
| C10 | CRITICAL | Routes seed data must match frontend application routes | seed-checks.sh |
| C15 | WARNING | RolePermission seed data must NOT use deterministic role GUIDs | seed-checks.sh |
| C16 | CRITICAL | Cross-tenant entities must use Guid? TenantId | seed-checks.sh |
| C17 | CRITICAL | Scoped entities must have EntityScope property | seed-checks.sh |
| C18 | BLOCKING | Permissions.cs static constants must exist | seed-checks.sh |
| C19 | BLOCKING | ApplicationRolesSeedData.cs must exist | seed-checks.sh |
| C20 | WARNING | Section route completeness (NavigationSection → frontend route + permissions) | seed-checks.sh |
| C21 | WARNING | FORBIDDEN route patterns — /detail/:id | seed-checks.sh |
| C22 | WARNING | Permission path segment count (2-4 dots expected) | seed-checks.sh |
| C23 | BLOCKING | IClientSeedDataProvider must have 4 methods with real implementation (not stubs) + DI registration | seed-checks.sh |
| C32 | CRITICAL | Translation seed data must have idempotency guard | seed-checks.sh |
| C33 | CRITICAL | Resource seed data must use actual section IDs from DB | seed-checks.sh |
| C34 | BLOCKING | NavRoute segments must use kebab-case for multi-word codes — MCP overlap | seed-checks.sh |
| C35 | BLOCKING | Permission codes must use kebab-case matching NavRoute codes — MCP overlap | seed-checks.sh |
| C44 | CRITICAL | RolesSeedData must map standard role-permission matrix | seed-checks.sh |
| C45 | BLOCKING | PermissionAction enum must use valid typed values only | seed-checks.sh |
| C46 | WARNING | Navigation translation completeness — 4 languages per level | seed-checks.sh |
| C47 | WARNING | Person Extension entities must not duplicate User fields | seed-checks.sh |
| C48 | CRITICAL | Person Extension service must Include(User) | seed-checks.sh |
| C53 | BLOCKING | Enum serialization — JsonStringEnumConverter required | seed-checks.sh |
| C57 | BLOCKING | SeedDataProvider Seed*Async methods must NOT be `return Task.CompletedTask` or empty body — stubs cause empty menu | seed-checks.sh |
| C58 | BLOCKING | File paths in filesToCreate must be valid C# identifiers — no spaces, apostrophes, or accents | seed-checks.sh |
| C63 | BLOCKING | Reserved section codes (detail/create/edit/*-detail) must NOT be seeded as menu items | seed-checks.sh |

### Architecture — Clean Architecture Layer Isolation (A1-A8)

| ID | Severity | Description | Script |
|----|----------|-------------|--------|
| A1 | BLOCKING | Domain must not import other layers | architecture-checks.sh |
| A2 | BLOCKING | Application must not import Infrastructure or Api | architecture-checks.sh |
| A3 | BLOCKING | Controllers must not inject DbContext | architecture-checks.sh |
| A4 | WARNING | API must return DTOs, not Domain entities | architecture-checks.sh |
| A5 | WARNING | Service interfaces in Application, implementations in Infrastructure | architecture-checks.sh |
| A6 | BLOCKING | No EF Core attributes in Domain entities | architecture-checks.sh |
| A7 | WARNING | No direct repository usage in controllers | architecture-checks.sh |
| A8 | BLOCKING | API endpoints must match handoff apiEndpointSummary | architecture-checks.sh |

### Infrastructure — Migration & Build (C13, C38-C43, C50-C51, C56, C60-C61)

| ID | Severity | Description | Script |
|----|----------|-------------|--------|
| C13 | WARNING | i18n files must contain required structural keys | infrastructure-checks.sh |
| C38 | BLOCKING | Migration ModelSnapshot must contain ALL entities registered in DbContext | infrastructure-checks.sh |
| C39 | CRITICAL | I18n namespace files must be registered in i18n config | infrastructure-checks.sh |
| C40 | BLOCKING | FluentValidation validators must be registered via DI | infrastructure-checks.sh |
| C41 | WARNING | Date/date properties in DTOs must use DateOnly, not string | infrastructure-checks.sh |
| C42 | BLOCKING | Every module with entities must have a migration covering them | infrastructure-checks.sh |
| C43 | BLOCKING | Controllers must NOT have both [Route] and [NavRoute] attributes | infrastructure-checks.sh |
| C50 | BLOCKING | NavRoute Uniqueness — no duplicate NavRoute values | infrastructure-checks.sh |
| C51 | WARNING | NavRoute Segments vs Controller Hierarchy (depth matching) | infrastructure-checks.sh |
| C56 | BLOCKING | Hierarchy Artifact Completeness — current run only (entities + sections) | infrastructure-checks.sh |
| C60 | BLOCKING | Controllers must inject ISender _mediator, NOT direct business services | infrastructure-checks.sh |
| C61 | BLOCKING | Controllers with [NavRoute] must have [Authorize] attribute | infrastructure-checks.sh |

### PRD Compliance — Delegate Mode Only (PC-1 to PC-6)

> **These checks run ONLY in delegate mode** (when `/apex -d` is used with companion spec files).
> They validate that generated code matches the PRD specifications from `.ralph/` companion files.
> Implemented in `step-04-examine.md` section 6d — no separate .sh script needed.

| ID | Severity | Description | Source |
|----|----------|-------------|--------|
| PC-1 | BLOCKING | All columns from screens.json SmartTable resources must exist in generated ListPage | step-04 §6d |
| PC-2 | BLOCKING | All actions from screens.json (create, edit, delete, approve, reject, export) must have handlers in pages | step-04 §6d |
| PC-3 | WARNING | I18n labels must have correct UTF-8 accents (FR: Employés not Employes, DE: Übersicht not Ubersicht) | step-04 §6d |
| PC-4 | BLOCKING | All permissionPaths from permissions.json must exist in PermissionsSeedData.cs and Permissions.cs | step-04 §6d |
| PC-5 | WARNING | Every primary/functional section in screens.json must have a corresponding page file | step-04 §6d |
| PC-6 | WARNING | Module i18n namespace must be registered in i18n config (prevents raw key display) | step-04 §6d |

---

## Summary

After running all checks above, report the total count:
- **N BLOCKING** issues must be fixed before committing
- **M WARNING** issues should be reviewed but are non-blocking
- **K CRITICAL** issues must be fixed immediately
