Repository navigation
ci: phase i.2, architecture guardrails - #75
Merged
Merged
Conversation
…ncy-cruiser pnpm check:boundaries runs dependency-cruiser over apps and packages with six rules: no-cross-module-import, pure-domain-and-application, domain-imports-only-the-kernel (ddd-kit, events, zod and its own module), domain-does-not-depend-on-application, packages-never-import-apps and app-never-imports-api (the front may only import api/client). It runs in the pre-push hook and as a CI step right after install. Import rules live here only: the cruiser reads the AST, so re-exports, side-effect imports, dynamic imports and require are all seen. Measured with every rule at error: 0 violations (1046 modules, 4463 dependencies cruised), so no baseline file is needed. dependency-cruiser cannot parse with typescript 7 and silently falls back to cruising nothing, so a package extension gives it typescript 6 as its own dependency without touching the workspace compiler. The dist exclusion is anchored to workspace packages: a bare /dist/ pattern also dropped every npm package whose entry lives in dist, which made the framework part of pure-domain-and-application match nothing.
Three scans over apps/api/src, one per rule already written in apps/api/CLAUDE.md that no import graph can see: domain and application never throw, routes never write to the database, and the environment is read only through shared/env. Import rules belong to dependency-cruiser. First run found one hit: migrate.ts read process.env.MIGRATIONS_FOLDER directly while already loading shared/env through the logger. MIGRATIONS_FOLDER now lives in the env schema with the same ./migrations default. No throw in any application layer and no write in any route file. The only remaining env reader is cron/sweep.ts, a standalone script that cannot import shared/env, listed with its reason.
Scans every non-test source file of apps/api/src and packages/*/src, the catalog package itself excluded, for references to EventTypes.<NAME>, dotted literals passed to an emit* or addEvent call and classes declaring eventType = "<type>", then compares them with the @packages/events catalog both ways. Any EventTypes reference counts as an emit site, so types routed through a lookup (cookie consent through ConsentService.append, billing subscription updates through subscriptionEventType, scim user changes through the change-kind map of auth.ts) are seen without an allowlist, and every catalog type has a reference today. Retention, visibility and description coverage is already enforced by their Record<EventType, ...> types and the events package tests, so no third test duplicates it.
|
🎉 This PR is included in version 2.0.0 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
pnpm check:boundaries(dependency-cruiser, pre-push and CI): no cross-module import, pure application layer, domain imports only the kernel, packages never import apps, app never imports api; 0 violation on 1046 modules@packages/test/source-scan: comment and string aware lexer, scans throws, writes and env readsshared/env(cron script allowlisted with its reason)EventTypesentry needs a reference outside the catalog that is not anonEventsubscription; no emit site uses a type outside the catalogMIGRATIONS_FOLDERmoved into the env schema (only violation found); dependency-cruiser gets TypeScript 6 viapackageExtensionssince TS 7 makes it parse nothingnoImportCyclesalready covers the repo