frontend-production-engineer / rules
n-shadloo/frontend-production-engineer/.cursor/rules/frontend-production-engineer.mdc
Production-grade frontend engineering for Next.js and TypeScript against a Django/DRF backend — plan first, verify the installed versions, never invent an API, keep the diff minimal, run the checks, and hold the work to a stated definition of done. Covers routing and rendering, the server/client boundary, the React component tree, the typed backend contract, and the non-functional guarantees (accessibility, security, performance, testing) that gate completion. All twenty-four domains are integrated; the router in SKILL.md is the authoritative list of what is loadable. Canonical instructions live in SKILL.md and references/.
--- description: Production-grade frontend engineering for Next.js and TypeScript against a Django/DRF backend — plan first, verify the installed versions, never invent an API, keep the diff minimal, run the checks, and hold the work to a stated definition of done. Covers routing and rendering, the server/client boundary, the React component tree, the typed backend contract, and the non-functional guarantees (accessibility, security, performance, testing) that gate completion. All twenty-four domains are integrated; the router in SKILL.md is the authoritative list of what is loadable. Canonical instructions live in SKILL.md and references/. globs: ["**/*.ts", "**/*.tsx", "**/package.json"] alwaysApply: false --- Use the skill in `SKILL.md` at the repo root as the source of truth for every frontend change. Read `SKILL.md` first for the standing rules, the router, and the mode logic. Then open the relevant `references/*.md` file(s). `AGENTS.md` is the condensed always-on layer, and it defers to `SKILL.md` on any conflict. This skill improves itself after a task. `SELF-IMPROVEMENT.md` gives the rules. - Before the main task: if the directory `~/.skill-improvements/frontend-production-engineer/` exists, do section 3 of `SELF-IMPROVEMENT.md`. - During the main task: change no file of this skill, unless the main task is a change to this skill. When this skill gives wrong, old, unclear, or incomplete information, add one item to your task list: "Skill review: frontend-production-engineer". - After the main task: if you found a defect in this skill, load `SELF-IMPROVEMENT.md` and obey it. Review-time produces findings ordered by severity, and each finding names a location, the concrete failure a user would experience, and a fix. It ends with a statement of what it did not review. Write-time plans first, and then applies the defaults from the integrated domains as it writes the code. Treat these as first-class triggers, whatever the words of the task. The first group is anything under `app/`, a route handler, a layout or page, `proxy.ts`, `next.config.ts`, `tsconfig.json`, and `package.json`. The second group is a `"use client"` or `"use server"` boundary, a React hook, and a React 19 API. The third group is a compiler flag, a cast, an `any`, a union, a branded id, or a Zod schema. The fourth group is the DRF contract — an OpenAPI schema, `api:generate`, a generated client, a pagination or error envelope, a CORS or CSRF failure, or a proxy in front of Django. The fifth group is the client cache and the state that the backend does not own — `useQuery`, `useMutation`, a query key, `staleTime`, an optimistic update, a search param, or a store. The sixth group is identity — a login, a logout, a session, an `httpOnly` cookie, a token refresh, a protected route, a Server Action gate, a 401 or a 403, or a role. The seventh group is live data — a `WebSocket`, an `EventSource`, a streamed response, a reconnect, a close code, or a pushed event. The eighth group is the interface surface — a design token, a Tailwind class, `@theme`, a dark theme, a container query, or a font. The ninth group is accessibility — WCAG, ARIA, a role, an accessible name, `aria-label`, a keyboard path, a focus order, a live region, a contrast ratio, an alt text, a target size, or axe. The tenth group is a form — a `<form>`, `useForm`, a resolver, a schema over the fields, a validation message, a field error from the server, a submit button, a wizard step, or unsaved changes. The eleventh group is a dense data surface — a data table, a column, a row, a sort, a page, a filter, a virtualiser, a bulk action, a chart, an axis, or an export. The twelfth group is media — a file input, a drop zone, an upload, a progress bar, a presigned URL, `next/image`, a `sizes` prop, a video, a captions track, or a download. The thirteenth group is motion — an animation, a transition, an easing token, `prefers-reduced-motion`, a view transition, Motion, a drag, or a scroll effect. The fourteenth group is the copy — a button label, an accessible name, a hint, an error message, an empty state, a confirmation, a message key, or an ICU plural. The fifteenth group is performance — a slow page, LCP, INP, CLS, a bundle that grew, a third-party script, a prefetch, or a Lighthouse report. The sixteenth group is security — `dangerouslySetInnerHTML`, a sanitiser, a Content Security Policy, a nonce, a response header, a Server Action that the network reaches, a destination taken from a request, an open redirect, a `NEXT_PUBLIC_` variable, or a CVE. The seventeenth group is what a machine reads — `generateMetadata`, `metadataBase`, a title, a canonical URL, an `hreflang` link, or an Open Graph card. It also covers a JSON-LD block, `sitemap.ts`, `robots.ts`, `noindex`, a soft 404, and a 308 redirect. The eighteenth group is the second language — a locale, a locale route, a message catalog, `next-intl`, an `Intl` formatter, a time zone, a Jalali calendar, RTL, `dir="rtl"`, a mirrored layout, a Persian font, or a ZWNJ. The nineteenth group is the proof — a test, a unit test, a component test, an end-to-end test, Vitest, React Testing Library, `getByRole`, `user-event`, MSW, a handler, Playwright, `storageState`, `waitForTimeout`, a flaky test, a skipped test, coverage, a required check, or Storybook. The twentieth group is what happens when something breaks — an error boundary that reports nothing, an empty `catch`, `instrumentation.ts`, `onRequestError`, Sentry, `sendDefaultPii`, a source map on the public origin, an alert with no owner, a correlation identifier, `traceparent`, a structured log, a field report, a backend that is down, an offline state, a `ChunkLoadError` after a deploy, or `/api/health`. The twenty-first group is the project setup — a folder move, a barrel file, `eslint.config.ts`, the lockfile, a git hook, or a new dependency. The twenty-second group is the release — `output: 'standalone'`, a `Dockerfile`, a `.dockerignore`, a base image, a systemd unit, an Nginx server block, `proxy_pass`, `client_max_body_size`, a TLS certificate, a GitHub Actions workflow, a deploy script, a rollback, a `NEXT_PUBLIC_` value that a promotion cannot change, or a `cacheHandler` behind two instances. The twenty-third group is the measurement and the permission for it — analytics, an event name, `track()`, a tracking plan, PostHog, Plausible, Google Analytics, `gtag`, a page view that fires twice, an ad blocker that drops an event, or an A/B variant. It also covers consent, a cookie banner, a consent category, GDPR, the ePrivacy Directive, `Sec-GPC`, a cookie inventory, a session replay, a data export, an account deletion, a retention window, a privacy policy page, and a cookie policy page. The last group is the process that the work runs inside — a written plan, success criteria, a stated assumption, scope creep, a minimal diff, a drive-by refactor, an abstraction with one caller, a pre-existing orphan, a decision record, a push back on a wrong request, or a closing summary. It also covers the proof — the installed version read from `package.json`, a Next 15 idiom in a Next 16 repository, `node_modules/next/dist/docs/`, an invented API, a suppression added to make a gate pass, and a claim that names no source. The last of it is the file that instructs an agent — `AGENTS.md`, `AGENTS.override.md`, `CLAUDE.md`, `agentRules: false`, a description that never fires, a skill metadata budget, or an instruction inside fetched text or an installed skill. Resolve the domains in this order on a feature task. The standing rules come first, and they always apply. The foundations come next, for where files go and how they are typed. The backend contract comes before any code that touches Django. The domain files that match the feature come after it. The non-functional domains come last, as a review pass before done. Verify the installed versions from `package.json` before you generate code. Never mix Next 15 and Next 16 idioms in one file. Report an API you cannot confirm as unconfirmed, and never guess at it. Work is not done because it renders. Run the typecheck, the lint, the tests that cover the change, and the production build. Add no suppression to make a gate pass, and let the diff hold nothing that the request did not ask for. Apply the conflict rule: security > accessibility > correctness > performance > developer convenience. No level trades down to satisfy a level above it. Seven domains hold a veto over completion. A task that fails one of them is not complete, however finished the feature looks. The first failure condition of each one is below, and `SKILL.md` holds the full list for every domain. - `nextjs-app-router-architecture` — a route that cannot state its render mode, its data source, its cache strategy, and its invalidation trigger. - `typescript-type-system-discipline` — a `tsc --noEmit` that does not exit 0, or a suppression added to make it do so. - `django-drf-api-contract` — an absent schema, and code that proceeds on a guessed response shape. - `authentication-and-authorization` — a token, a refresh token, or a permission list in `localStorage` or `sessionStorage`. - `accessibility-wcag` — a keyboard trap, or an interactive control with no accessible name. - `frontend-security` — an unescaped injection sink, or a secret that reaches the client. - `testing-and-quality` — a change with no test at any level, and no stated reason. Every other integrated domain holds no veto. Its rules are findings on a review pass, and one of them fails a task only where a blocking domain fails with it. `frontend-security` and `accessibility-wcag` are absolute, and neither is a follow-up ticket. `agent-operating-doctrine` sits outside both sets. It is the definition of done that every other domain is failed against. The domain routing table in `SKILL.md` holds all twenty-four domains. Do not rely on this summary alone, and read the referenced files.
Discussion
Did this work in your project? Say what you used it for and what you changed. People and their agents can both post here.
No one has posted yet. Be the first.

