chore(template): clean-slate template snapshot from bb4a0c7
Curated, product-agnostic snapshot of the post-story-04 tree: demo content deleted, auth-only reference feature, web-next shell, all gates green. Product-specific docs, ADRs 027-029, PRDs/epics/archive, editor library traces, and product naming are curated out; generic template repairs (coverage provider devDeps, root test:coverage script, live lint fixes, root-only release-please) are kept. See TEMPLATE.md for provenance, curation list, and usage. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016j8z4VHjedXDTjEDNg7qHK
This commit is contained in:
195
packages/core-eslint/base.js
Normal file
195
packages/core-eslint/base.js
Normal file
@@ -0,0 +1,195 @@
|
||||
import js from "@eslint/js";
|
||||
import eslintConfigPrettier from "eslint-config-prettier";
|
||||
import tseslint from "typescript-eslint";
|
||||
import turboPlugin from "eslint-plugin-turbo";
|
||||
import boundaries from "eslint-plugin-boundaries";
|
||||
import globals from "globals";
|
||||
import conformancePlugin from "./plugin.js";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
// <gen:realtime-rules-imports>
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
const repoRoot = path.resolve(__dirname, "..", "..");
|
||||
|
||||
export default [
|
||||
{
|
||||
ignores: [
|
||||
"dist/**",
|
||||
"node_modules/**",
|
||||
".next/**",
|
||||
".turbo/**",
|
||||
"storybook-static/**",
|
||||
],
|
||||
},
|
||||
js.configs.recommended,
|
||||
{
|
||||
files: ["**/*.{mjs,cjs,js}", "**/*.config.{ts,tsx}"],
|
||||
languageOptions: {
|
||||
globals: { ...globals.node },
|
||||
},
|
||||
},
|
||||
...tseslint.configs.recommended,
|
||||
eslintConfigPrettier,
|
||||
{
|
||||
plugins: { turbo: turboPlugin },
|
||||
rules: {
|
||||
"turbo/no-undeclared-env-vars": "warn",
|
||||
},
|
||||
},
|
||||
{
|
||||
plugins: { conformance: conformancePlugin },
|
||||
rules: {
|
||||
// Structural conformance rules (milestone iii.a).
|
||||
// All 5 features now have manifests; promoted to ERROR.
|
||||
"conformance/feature-must-have-manifest": ["error", { repoRoot }],
|
||||
"conformance/usecase-must-have-test-file": "error",
|
||||
"conformance/required-cores-installed": ["error", { repoRoot }],
|
||||
"conformance/no-undeclared-event-publish": ["warn", { repoRoot }],
|
||||
"conformance/no-undeclared-audit": ["warn", { repoRoot }],
|
||||
"conformance/no-undeclared-analytics-event": ["warn", { repoRoot }],
|
||||
"conformance/usecase-must-be-wired": ["error", { repoRoot }],
|
||||
"conformance/component-must-have-story": "warn",
|
||||
"conformance/component-must-have-test": "warn",
|
||||
"conformance/atomic-tier-import-direction": "warn",
|
||||
"conformance/pii-declaration-must-be-complete": "warn",
|
||||
"conformance/no-undeclared-consent-check": ["warn", { repoRoot }],
|
||||
"conformance/no-undeclared-rate-limit": ["warn", { repoRoot }],
|
||||
"conformance/entity-must-have-test": "warn",
|
||||
"conformance/no-relative-parent-import-in-tests": "warn",
|
||||
},
|
||||
},
|
||||
{
|
||||
rules: {
|
||||
// Honour the leading-underscore convention for intentionally-unused params/vars.
|
||||
"@typescript-eslint/no-unused-vars": [
|
||||
"error",
|
||||
{
|
||||
argsIgnorePattern: "^_",
|
||||
varsIgnorePattern: "^_",
|
||||
caughtErrorsIgnorePattern: "^_",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
plugins: { boundaries },
|
||||
settings: {
|
||||
"boundaries/elements": [
|
||||
{ type: "app", pattern: "apps/*" },
|
||||
{ type: "tooling", pattern: "packages/core-eslint" },
|
||||
{ type: "tooling", pattern: "packages/core-typescript" },
|
||||
{ type: "tooling", pattern: "packages/core-testing" },
|
||||
{ type: "core-composition", pattern: "packages/core-api" },
|
||||
{ type: "core-composition", pattern: "packages/core-cms" },
|
||||
{ type: "core", pattern: "packages/core-*" },
|
||||
{ type: "feature", pattern: "packages/!(core-*)" },
|
||||
],
|
||||
},
|
||||
rules: {
|
||||
"boundaries/element-types": [
|
||||
2,
|
||||
{
|
||||
default: "disallow",
|
||||
rules: [
|
||||
{
|
||||
from: "app",
|
||||
allow: ["app", "core", "core-composition", "feature", "tooling"],
|
||||
},
|
||||
{ from: "feature", allow: ["core", "feature", "tooling"] },
|
||||
{ from: "core", allow: ["core", "tooling"] },
|
||||
{ from: "core-composition", allow: ["core", "feature", "tooling"] },
|
||||
{ from: "tooling", allow: ["tooling"] },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
// Block direct @sentry/* imports outside the allowlisted instrumentation paths.
|
||||
{
|
||||
files: ["**/*.{ts,tsx,mjs,cjs,js}"],
|
||||
rules: {
|
||||
"no-restricted-imports": [
|
||||
"error",
|
||||
{
|
||||
patterns: [
|
||||
{
|
||||
group: ["@sentry/*"],
|
||||
message:
|
||||
"Import from @repo/core-shared/instrumentation instead — feature packages must not depend on Sentry directly.",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
// Allowlist — the only paths permitted to import @sentry/*.
|
||||
// Per ADR-017, server-side Sentry SDK usage is limited to the OTel bridge
|
||||
// and browser/client init files. Patterns are double-star prefixed so they
|
||||
// match whether eslint runs from the repo root or from inside a sub-package.
|
||||
{
|
||||
files: [
|
||||
// OTel bridge — the only server-side file that may import @sentry/opentelemetry
|
||||
"**/instrumentation/otel/sentry-bridge.{ts,js}",
|
||||
"**/instrumentation/otel/sentry-bridge.test.{ts,js}",
|
||||
// OTel DI binder — may import @sentry/opentelemetry via sentry-bridge
|
||||
"**/instrumentation/di/bind-otel-instrumentation.{ts,js}",
|
||||
"**/instrumentation/di/bind-otel-instrumentation.test.{ts,js}",
|
||||
// Browser-side Sentry init helpers (server-only migration — browser keeps Sentry SDK directly)
|
||||
"**/instrumentation/sentry/init-client.{ts,js}",
|
||||
"**/instrumentation/sentry/init-client.test.{ts,js}",
|
||||
"**/instrumentation/sentry/init-client-react.{ts,js}",
|
||||
"**/instrumentation/sentry/init-client-react.test.{ts,js}",
|
||||
// Server-side Sentry SDK init still used by apps (calls Sentry.init with DSN)
|
||||
"**/instrumentation/sentry/init-server.{ts,js}",
|
||||
"**/instrumentation/sentry/init-server.test.{ts,js}",
|
||||
"**/instrumentation/sentry/init-server-node.{ts,js}",
|
||||
"**/instrumentation/sentry/init-server-node.test.{ts,js}",
|
||||
// Test guard — mocks Sentry + OTel SDKs to prevent real init in test processes
|
||||
"**/setup/no-instrumentation.{ts,js}",
|
||||
"**/setup/no-instrumentation.test.{ts,js}",
|
||||
// Legacy alias for one release cycle
|
||||
"**/setup/no-sentry.{ts,js}",
|
||||
"**/setup/no-sentry.test.{ts,js}",
|
||||
// App-level instrumentation entry points and build config
|
||||
"**/instrumentation.{ts,js,mjs}",
|
||||
"**/instrumentation-client.{ts,js,mjs}",
|
||||
"**/next.config.{mjs,ts,js}",
|
||||
"**/vite.config.{ts,mjs,js}",
|
||||
"**/sentry.*.config.{ts,mjs,js}",
|
||||
],
|
||||
rules: {
|
||||
"no-restricted-imports": "off",
|
||||
},
|
||||
},
|
||||
// OTel SDK packages (@opentelemetry/sdk-*, @opentelemetry/resources,
|
||||
// @opentelemetry/semantic-conventions, @opentelemetry/instrumentation-*,
|
||||
// @sentry/opentelemetry) are restricted to core-shared/instrumentation/otel/
|
||||
// and app-level init paths.
|
||||
// The vendor-neutral API packages (@opentelemetry/api, @opentelemetry/api-logs)
|
||||
// are unrestricted within core-shared/instrumentation/ — features use them for
|
||||
// advanced tracing without coupling to the SDK.
|
||||
{
|
||||
files: [
|
||||
"**/instrumentation/otel/**/*.{ts,tsx,mjs,cjs,js}",
|
||||
// App-level init and build config also allowed to import OTel SDK packages
|
||||
"**/instrumentation.{ts,js,mjs}",
|
||||
"**/next.config.{mjs,ts,js}",
|
||||
"**/vite.config.{ts,mjs,js}",
|
||||
],
|
||||
rules: {
|
||||
"no-restricted-imports": "off",
|
||||
},
|
||||
},
|
||||
// E1 — Event handlers must not be re-exported. Wire them only inside the
|
||||
// consumer feature's bind-production / bind-dev-seed (spec § 2.2 Rule E1).
|
||||
// J — Direct `payload.jobs.*` access is forbidden outside the integration
|
||||
// layer. Use IJobQueue (from @repo/core-shared/jobs) instead.
|
||||
// Events + jobs rules are added here when @repo/core-events is scaffolded
|
||||
// via `pnpm turbo gen core-package events`.
|
||||
// <gen:events-rules>
|
||||
// R2 / R1 (ADR-016) — realtime-specific ESLint rules (no-direct-socket-io,
|
||||
// no-realtime-handler-reexport) are added here when @repo/core-realtime is
|
||||
// scaffolded via `pnpm turbo gen core-package realtime`.
|
||||
// <gen:realtime-rules>
|
||||
];
|
||||
Reference in New Issue
Block a user