@schafevormfenster/eslint-plugin
v0.0.23
Published
This package contains **Custom ESLint Rules** that enforce logging, architectural, REST, testing, and other domain-specific patterns for the `@schafevormfenster` platform. It translates our internal guidelines into automated checks that run before code is
Readme
@schafevormfenster/eslint-plugin
This package contains Custom ESLint Rules that enforce logging, architectural, REST, testing, and other domain-specific patterns for the @schafevormfenster platform. It translates our internal guidelines into automated checks that run before code is committed or deployed.
Purpose
This custom ESLint plugin serves three key functions:
- Enforcement: Automates the verification of internal coding guides (e.g., "Always log before throwing," "Include required API route files").
- Education: Provides helpful error messages to guide developers towards correct patterns during development.
- Safety: Prevents common domain-specific mistakes (e.g., logging sensitive keys, missing cache headers in GET handlers).
Integration
This plugin is designed to be used via @schafevormfenster/eslint-config, which provides pre-configured rule sets for different project types. The plugin integrates seamlessly into your development workflow, running checks during:
- Local development (IDE integration)
- Pre-commit hooks
- CI/CD pipelines
Documentation Structure
This plugin provides two types of documentation:
📚 Coding Instructions (docs/instructions/)
Living guidelines for engineers and AI coding agents. These documents describe how to write code that complies with our architectural patterns:
- logging-guide.md - Structured logging with pino
- rest-service-design-guide.md - REST API design patterns
- client-service-coordinator-guide.md - Layered architecture with clients, services, and coordinators
- caching-guide.md - Caching strategies and limitations
- testing-standards-guide.md - Unified testing architecture and best practices
- component-test-guide.md - Component testing patterns for services and coordinators
- integration-test-guide.md - Integration testing patterns for clients
- rest-api-e2e-testing-guide.md - E2E testing patterns
- unit-test-env-vars-guide.md - Environment variable handling in tests
- And more...
For Engineers and AI Agents: Consult these instruction documents as your primary coding guidelines. See INSTRUCTIONS.md for details on how to use these guides.
For Consuming Applications: Maintain an AGENTS.md file in your project root that references these instruction documents so AI coding agents know to follow them before ESLint enforcement runs. See INSTRUCTIONS.md for the recommended pattern.
📋 Rule Catalog (docs/rules/)
Technical documentation for each ESLint rule, including examples of correct and incorrect code:
- enforce-api-route-structure.md - Required files for API routes
- enforce-log-before-throw.md - Logging before throwing errors
- no-sensitive-log-keys.md - Prevent logging sensitive data
- And 21+ more rules...
See the full rule catalog below for a complete list organized by domain.
Semantic Module Architecture
We use a "Logical Monolith" structure. All custom rules live in this single package but are organized into semantic modules (domains). You can enable rules for specific domains without enabling everything.
Domains
- Logging: Enforces structured logging, pino usage, and error handling.
- Architecture: Enforces file naming conventions (kebab-case) and folder structures.
- Caching: Enforces correct caching headers and HTTP method usage.
- REST: Enforces API route structure, schema exports, and path conventions.
- Stack: Enforces technology choices and prevents forbidden imports.
- Testing: Enforces testing best practices (env vars, error matching, file naming, test tier separation).
- Testing-E2E: Rules specific to end-to-end tests (Playwright).
- Testing-Unit: Rules specific to unit tests (Vitest).
- Testing-Component: Rules specific to component tests (Vitest,
*.component.test.ts). - Testing-Integration: Rules specific to integration tests (Vitest,
*.integration.test.ts). - Testing-Coverage: Rules for source files to enforce test coverage per architectural layer.
- Security: (Planned) Prevents usage of insecure patterns.
- Queue: (Planned) Enforces correct retry behavior for queue handlers.
Usage
Typically, you will use this via @schafevormfenster/eslint-config. However, if you need to use it directly or want to understand the available modular configs:
import svfPlugin from "@schafevormfenster/eslint-plugin";
export default [
{
plugins: {
"@schafevormfenster": svfPlugin
},
// Option A: Use a preset (Recommended)
...svfPlugin.configs.logging.rules,
// Option B: Configure manually
rules: {
"@schafevormfenster/enforce-log-before-throw": "error",
"@schafevormfenster/no-sensitive-log-keys": "error"
}
},
// Example: Apply E2E testing rules to e2e directory
{
files: ["**/e2e/**/*.spec.ts"],
rules: {
...svfPlugin.configs["testing-e2e"].rules
}
},
// Example: Apply Unit testing rules to unit test files
{
files: ["**/*.test.ts"],
ignores: ["**/*.component.test.ts", "**/*.integration.test.ts"],
rules: {
...svfPlugin.configs["testing-unit"].rules
}
},
// Example: Apply Component testing rules to component test files
{
files: ["**/*.component.test.ts"],
rules: {
...svfPlugin.configs["testing-component"].rules
}
},
// Example: Apply Integration testing rules to integration test files
{
files: ["**/*.integration.test.ts"],
rules: {
...svfPlugin.configs["testing-integration"].rules
}
},
// Example: Apply test coverage rules to source files
{
files: ["**/services/**/*.ts", "**/coordinators/**/*.ts", "**/clients/**/*.ts"],
ignores: ["**/*.test.*", "**/*.spec.*"],
rules: {
...svfPlugin.configs["testing-coverage"].rules
}
}
];Rules
💼 Configurations enabled in.
⚠️ Configurations set to warn in.
🔧 Automatically fixable by the --fix CLI option.
| Name | Description | 💼 | ⚠️ | 🔧 |
| :------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------ | :----------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------- | :- |
| enforce-api-route-structure | Enforce presence of required files for API routes (route.test.ts, *.contract.ts, *.schema.ts) | | | |
| enforce-apitest-env-vars | Forbid process.env access in e2e/ unless variable starts with APITEST_ or is TEST_ENV |
| | |
| enforce-file-naming | Enforce kebab-case file naming with semantic suffixes | |
| |
| enforce-folder-structure | Enforce src/ folders: app, clients, lib, types, test, services, coordinators | |
| |
| enforce-get-logger-category | Enforce getLogger to be called with a category string |
| | |
| enforce-layer-dependencies | Enforce architectural layer dependency rules between clients, services, and coordinators |
| | |
| enforce-log-before-throw | Enforce logging before throwing an error (skipped in test files) |
| | |
| enforce-log-level-before-throw | Enforce log level before throwing an error (skipped in test files) | |
| |
| enforce-schema-type-export | Every exported Zod schema must have a corresponding exported TypeScript type using z.infer |
| | |
| enforce-semantic-cache-headers | Ensure Cache-Control header is set in GET route handlers | |
| |
| enforce-structured-logging | Enforce structured logging (context object + message) |
| | |
| enforce-test-file-naming | Enforce *.spec.ts for Playwright and *.test.ts / *.component.test.ts / *.integration.test.ts for Vitest |
| | |
| enforce-token-in-path | Enforce that API routes either include [token] in path or validate params.token in handler |
| | |
| no-env-preservation-in-tests | Forbid preserving and restoring process.env values in tests - tests should set their own env vars |
| | 🔧 |
| no-env-vars-in-component-tests | Forbid process.env access in component tests — component tests must not depend on environment variables |
| | |
| no-forbidden-imports | Forbid libraries that have preferred alternatives per tech stack | |
| |
| no-mocks-in-integration-tests | Forbid vi.mock(), vi.spyOn(), and vi.fn() in integration tests — must use real API calls |
| | |
| no-raw-logging | Prevent logging raw objects without a message | |
| |
| no-redundant-normalize-error | Detect and forbid calls to normalizeError() inside log.error(), as the logger handles this internally |
| | |
| no-reexport-files | Prevent files that primarily re-export from other modules | |
| |
| no-sensitive-log-keys | Prevent logging of sensitive keys |
| | |
| no-skip-in-integration-tests | Forbid .skip, .skipIf, and .todo in integration tests — integration tests must always run to validate external contracts |
| | |
| no-unsafe-log-property-access | Prevent unsafe property access in log context | |
| |
| no-use-cache-in-post | Forbid "use cache" directive in POST request handlers |
| | |
| one-function-per-file | Warn if a file defines multiple top-level functions (exported or internal) | |
| |
| one-function-per-file-strict | Error if a file defines more than 4 top-level functions (high priority when file is larger than 250 lines) |
| | |
| prefer-custom-logger | Enforce use of custom logger instead of console | |
| |
| prefer-loose-error-matching | Prefer regex matching over exact string matching for error messages | |
| |
| prefer-schema-extension | Warn if a Zod object is defined from scratch without using .extend() or .merge() when it could reuse common schemas | |
| |
| require-component-test | Require *.component.test.ts files for services and coordinators | |
| |
| require-describe-wrapper | Require test cases to be wrapped in describe() blocks for better organization | |
| |
| require-env-setup-in-tests | Require beforeEach to initialize env vars when tests access process.env | |
| 🔧 |
| require-error-in-log-error | Ensure log.error includes an error object | |
| |
| require-integration-test | Require *.integration.test.ts files for client files that call external APIs | |
| |
| require-meaningful-descriptions | Require meaningful descriptions for describe() and it()/test() blocks | |
| |
| require-mock-data-source-comment | Require a provenance comment documenting the data source before mockResolvedValue, mockReturnValue, and related mock calls in unit tests | |
| |
| suggest-test-categorization | Suggest organizing tests into categories for better structure | |
| |
