Imported from rradic/TenderAI-next.js (
AGENTS.md). Install upstream withnpx skills add rradic/TenderAI-next.js. Copyright stays with the author.
Frontend Engineering Rules (CLAUDE.md)
Framework- and library-independent rules for any component-based frontend
(React, Vue, Angular, Svelte). Apply proactively. Full rationale, patterns, and
examples: read ./docs/architecture-frontend.md on demand (plain path on
purpose — an @import loads it every session and wastes context).
Architecture style
Clean / layered + ports & adapters. Dependencies point inward only: Components → Presentation logic → Use Cases → Domain ← Infrastructure. Components are the thin edge; business rules live in a framework-free core; everything external (data, storage, navigation) is reached through interfaces the core owns. Collapse layers when the app is small; separate per feature when it grows.
Non-negotiables
- Dependency rule — inward only. Components/Infrastructure (edge) depend on inner abstractions; Domain depends on nothing — no React/Vue/Angular/Svelte types, no fetch/axios/GraphQL, no storage or router. A domain import from the UI framework or a data client is a bug.
- Business & validation rules live in the Domain, never in components, JSX/templates, hooks, or store reducers.
- No I/O in components. Never call
fetch/axios/GraphQL,localStorage, the router, or analytics directly from a component. Go through a port (Repository/Gateway) supplied by a hook/use case. - Inject, don't import singletons. Get API clients and adapters from the composition root (provider/context/factory); never construct them inside business logic.
- Keep components dumb. Presentational components take props and emit events; hooks/ containers own state, call use cases, and map domain → view models.
- State management is view state. Redux/Zustand/Pinia/signals hold UI state, not business rules.
Precedence (resolve top-down, don't guess)
- Dependency rule — inner never depends on outer.
- KISS / YAGNI — simplest thing that meets today's requirement.
- GRASP / SOLID — responsibility, cohesion, low coupling.
- DRY — last; it over-fires. Accept duplication over coupling.
Principles, one line each
- Clean / Hexagonal — keep the layers; thin components; map to view models at the boundary.
- GRASP — Information Expert; the hook/presenter is the Controller; low coupling + high
cohesion; Polymorphism over
switch(type)in rendering; Indirection / Pure Fabrication (repository, mapper) when no component is a natural home. - SOLID — SRP (render OR fetch OR decide, not all three); OCP (add a variant/strategy, don't grow a conditional); LSP; ISP (small prop/port interfaces); DIP (inject clients).
- TDD — test behavior, not markup; domain + use cases testable with no DOM/network; components tested against fake ports; hard to test = design smell.
- KISS — simplest solution; readable duplication > clever abstraction.
- YAGNI — build only today's requirement; no premature global store or speculative config.
- DRY — dedupe rules/knowledge, not look-alike markup. Rule of Three; keep duplication over coupling.
Before extracting a shared component/abstraction — all must be true
- Same rule/behavior (not markup that merely looks alike)
- Seen 3+ times
- Simpler than the duplication it removes
- Not speculative (YAGNI)
Definition of done
- Domain imports no framework/data-client/storage code
- Components thin; rules in domain, state in hooks/stores
- Data & external access behind ports, wired at the composition root
- Dependencies point inward only
- Tests cover behavior with fake ports, not markup detail
- No speculative flexibility added
Project specifics — FILL IN per repo
- Stack: Next.js v16
Skill usage
- When writing a feature or fixing a bug, use the
tddskill (red-green-refactor). - When investigating a hard bug or perf regression, use
diagnosing-bugs. - Before finishing a change, run
code-reviewon the diff. - When a task touches domain terms, use
domain-modelingand keep CONTEXT.md current.
Agent skills
Issue tracker
Issues and PRDs live as local markdown files under .scratch/<feature>/ (this repo has no git remote). See docs/agents/issue-tracker.md.
Triage labels
Five canonical labels, used as-is: needs-triage, needs-info, ready-for-agent, ready-for-human, wontfix. See docs/agents/triage-labels.md.
Domain docs
Single-context: one CONTEXT.md + docs/adr/ at the repo root. See docs/agents/domain.md.