# Code Conventions

> Code style, logging, and testing conventions for SkillHub backend (Java) and frontend (TypeScript). Use when writing or reviewing code.

- Skill: `iflytek/code-conventions` (Agent Skill)
- Install (CLI): `npx skillmds@latest add iflytek/code-conventions`
- Raw SKILL.md: https://api.skillmd.com/api/skills/iflytek/code-conventions/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- License: Apache-2.0
- Author: iflytek (https://skillmd.com/u/iflytek)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/iflytek/code-conventions

---


# Code Conventions Skill

## Java / Backend Conventions

### User Identity Type

User identity is **always `String`** throughout the codebase. This covers:
- Authentication and authorization
- API parameters and responses
- Permission checks
- Audit logs
- Resource owner, creator, reviewer, actor, submittedBy fields

Never introduce `int`, `long`, or `bigint` as user identifiers. The platform needs to support
external SSO/OIDC/SCIM identity sources whose UIDs are typically stable strings.

### Exception Handling

- Use `LocalizedDomainException` for user-facing error messages (supports i18n)
- Use `DomainBadRequestException` for invalid client input
- Use `DomainNotFoundException` for missing resources
- Use `DomainForbiddenException` for authorization failures
- Exception classes live in `skillhub-domain/shared/exception/`

### Domain Services

- Return domain objects, not DTOs
- Contain business rules and state transitions
- Use domain events for cross-cutting side effects (publishing, notifications)
- Located in `domain/{submodule}/service/`

### Controllers

- Transport only: extract auth context, bind request params, wrap responses
- No business logic in controllers
- Located in `com.iflytek.skillhub.controller/`

### Query Repositories

- Handle read-model joins and presentation projection
- Return DTOs or presentation models
- Located in `com.iflytek.skillhub.repository/`
- Named like `*QueryRepository` (e.g., `GovernanceQueryRepository`, `MySkillQueryRepository`)

### App Services

- Workflow orchestration: coordinate domain services and query repositories
- Should express "what this endpoint does", not "how it assembles DTOs"
- Located in `com.iflytek.skillhub.service/`

### Logging

- Use SLF4J with structured logging
- Use MDC for request tracing
- Log at appropriate levels: INFO for business events, DEBUG for troubleshooting, ERROR for failures

## TypeScript / Frontend Conventions

### Type Safety

- Strict TypeScript mode. No `any` types.
- Use generated OpenAPI types from `web/src/api/generated/schema.d.ts` for all API interactions.
- Additional types in `web/src/types/`

### Data Fetching

- **Always use TanStack Query** (`@tanstack/react-query`) for server state
- **Never use `useEffect`** for data fetching
- Use `openapi-fetch` client for type-safe API calls

### Component Composition

- **Radix UI** primitives: `@radix-ui/react-dropdown-menu`, `@radix-ui/react-select`
- **class-variance-authority** (cva) for component variants
- **clsx** + **tailwind-merge** for class merging
- **`cn()` utility**: `web/src/shared/lib/utils.ts`
- shadcn/ui is NOT used as a library

### State Management

- **TanStack Query** for server state (API data, caching, invalidation)
- **Zustand** for local/UI state (theme, sidebar, modals, form state)

### Feature-Sliced Design

| Layer | Path | Purpose |
|-------|------|---------|
| Pages | `web/src/pages/` | Route-level page components |
| Features | `web/src/features/` | Self-contained business features |
| Entities | `web/src/entities/` | Domain entity display logic |
| Shared | `web/src/shared/` | Reusable UI components, hooks, utilities |

Place code at the lowest appropriate layer. Do not put page-level logic in shared.

### Styling

- Tailwind CSS for all styling
- Follow existing component patterns
- Use `cn()` for conditional class merging

### Internationalization

- Use i18next + react-i18next
- All user-facing text must be translatable
- Translation keys in `web/src/i18n/`

## Testing Philosophy

### Backend

- JUnit 5 + Mockito + AssertJ
- Use Spring Boot test slices where possible (`@WebMvcTest`, `@DataJpaTest`)
- Test behaviors, not implementations
- Use `make test-backend-app` (includes `-am` for dependent modules)
- Never run `./mvnw -pl skillhub-app clean test` directly — stale Maven cache causes misleading errors

### Frontend

- Vitest for unit tests
- Playwright for E2E tests
- Test component behavior and user interactions

## Common Pitfalls

- **Maven multi-module**: Always use `-am` flag or Makefile targets to include dependent modules
- **OpenAPI types**: Must regenerate and commit after API contract changes
- **String identity**: Never use numeric types for user identifiers
- **Controller business logic**: Move to domain service or app service
- **Complex read-models in app service**: Extract to query repository

