|
| 1 | +# Architecture compliance audit |
| 2 | + |
| 3 | +Дата аудита: 2026-06-18 |
| 4 | + |
| 5 | +Источник требований: [ProverCoderAI/architecture-skills#1](https://github.com/ProverCoderAI/architecture-skills/issues/1). |
| 6 | + |
| 7 | +## Summary |
| 8 | + |
| 9 | +Текущая кодовая база частично соответствует требованиям. В проекте уже есть сильная |
| 10 | +база: monorepo, CI с build/typecheck/lint/test/e2e, Effect lint profile, |
| 11 | +property-based tests и jscpd в части пакетов. По строгой трактовке issue |
| 12 | +репозиторий пока нельзя считать соответствующим: есть крупные нарушения по |
| 13 | +размеру модулей, файлов и функций; OpenAPI/generated client отсутствует; |
| 14 | +mutation testing отсутствует; coverage не enforced в CI; API `lint:effect` не |
| 15 | +подключён в CI; остаются прямые `fetch`, `unknown` и casts. |
| 16 | + |
| 17 | +Строгость оценки: strict with documented exceptions. Boundary `unknown` |
| 18 | +допустим только при явном schema decoding и без утечки в domain API. |
| 19 | + |
| 20 | +## Audit matrix |
| 21 | + |
| 22 | +| Требование | Статус | Evidence | |
| 23 | +| --- | --- | --- | |
| 24 | +| File size <= 400 lines | Fail | 33 tracked TS code files exceed 400 lines. Largest: `packages/api/src/http.ts` 2121, `packages/api/src/services/federation.ts` 1916, `packages/api/src/services/terminal-sessions.ts` 1836. | |
| 25 | +| Function size <= 50 lines | Fail | 270 functions exceed 50 lines. Largest: `makeRouter` in `packages/api/src/http.ts` starts at line 942 and spans about 1179 lines. | |
| 26 | +| Parameters <= 5 | Partial | 7 functions exceed the limit. Worst: `packages/api/src/services/terminal-sessions.ts:1203` has 7 params. | |
| 27 | +| Nesting depth <= 4 | Partial | 2 functions exceed the limit: `packages/api/src/services/auth-menu.ts:114` depth 7 and `packages/api/src/services/auth-menu.ts:165` depth 5. | |
| 28 | +| Cyclomatic complexity <= 8 | Fail | 35 functions exceed the limit. Worst: `packages/api/src/services/projects.ts:449` complexity 36. | |
| 29 | +| Suppression comments blocked | Partial | Only 4 `eslint-disable` / TS suppression hits, but they are config-level comments allowing test disables. jscpd suppression is broad: 40 `jscpd:ignore-start` blocks. | |
| 30 | +| `any`, `unknown`, dynamic blocked | Partial | Explicit `any`: 0 AST occurrences. `unknown`: 163 AST occurrences; some are legitimate boundary values, but literal policy is not globally enforced. | |
| 31 | +| Casts / `as` blocked | Fail | 59 TypeScript casts/type assertions in TS-only audit; broader JS/TS scope found 74. | |
| 32 | +| Monorepo modules <= 5000 LOC | Fail | Top packages exceed the limit: app about 48k lines, lib about 28k, api about 26k, terminal about 10k, container about 8k. | |
| 33 | +| Folder <= 10 code files | Fail | Top flat folders: `packages/app/src/web` 149 files, `packages/app/src/docker-git` 100, `packages/lib/src/usecases` 77, `packages/api/src/services` 42. | |
| 34 | +| No unused dependencies | Partial | `dist-deps-prune` exists for packaged app dependency pruning, but there is no workspace-wide `knip`, `depcheck`, or equivalent unused dependency gate. | |
| 35 | +| No unused modules | Partial | TypeScript and ESLint catch local unused symbols, but no workspace-wide unused export/module gate such as `knip` or `ts-prune` was found. | |
| 36 | +| No duplicate code | Partial | `.jscpd.json` exists for app/lib/terminal and jscpd dependencies exist in app/lib/terminal/container. API and session-sync lack jscpd config, and many files use `jscpd:ignore`. | |
| 37 | +| ORM or typed query layer for DB | Fail / not currently applicable | No Prisma/Drizzle/Kysely/TypeORM/Knex/Effect SqlClient usage was found. Existing DB-related code mainly handles typed database profile/proxy configuration, not database persistence. | |
| 38 | +| Swagger/OpenAPI generated client | Fail | No OpenAPI/Swagger files or generated API client pipeline found. API schemas and clients appear handwritten with Effect Schema. | |
| 39 | +| CI safe `lint --fix` bot flow | Fail | CI runs lint, but no deterministic auto-fix commit/fixed-point workflow was found. | |
| 40 | +| Test coverage >= 10% | Partial | Vitest coverage thresholds exist in app/lib/container/terminal configs, but package test scripts and CI run plain `vitest run` without `--coverage`; API and session-sync lack coverage thresholds. | |
| 41 | +| Property-based testing for invariants | Pass | `fast-check` is used broadly: 42 files and 77 `fc.property` usages were found. | |
| 42 | +| E2E testing | Pass | CI runs 7 E2E jobs in `.github/workflows/check.yml`: local package, browser command, opencode, clone cache, login context, runtime volumes + SSH, clone auto-open SSH. | |
| 43 | +| 100% changed code covered in PR | Fail | No diff coverage gate was found. | |
| 44 | +| Mutation testing on PR changes | Fail | No Stryker or equivalent mutation testing config/tooling was found. | |
| 45 | + |
| 46 | +## Top blockers |
| 47 | + |
| 48 | +1. `packages/api` is the biggest architectural risk: large files, large functions, |
| 49 | + direct `fetch`, remaining Effect migration warnings, and weak regular ESLint |
| 50 | + enforcement compared with app/lib/container/terminal. |
| 51 | +2. OpenAPI/generated-client workflow is absent. |
| 52 | +3. Mutation testing and diff coverage are absent. |
| 53 | +4. Coverage thresholds exist only partially and are not enforced by CI. |
| 54 | +5. Module and folder size limits are not satisfied by current package/folder |
| 55 | + boundaries. |
| 56 | +6. Duplication checks are partial and heavily bypassed in copied frontend-lib |
| 57 | + code. |
| 58 | + |
| 59 | +## Recommended PR sequence |
| 60 | + |
| 61 | +1. Enforcement PR: add a read-only architecture audit script for LOC, folder |
| 62 | + width, function size, params, nesting, complexity, casts and direct `fetch`; |
| 63 | + connect API `lint:effect` to CI. |
| 64 | +2. Coverage PR: add `test:coverage` scripts, thresholds for API/session-sync, |
| 65 | + and a CI coverage job. |
| 66 | +3. Duplication and unused-code PR: add workspace-wide jscpd coverage plus a |
| 67 | + `knip` or equivalent unused dependency/export gate. |
| 68 | +4. API contract PR: choose and introduce OpenAPI as source of truth, then |
| 69 | + generate client/types and block handwritten internal API access. |
| 70 | +5. Refactor PR series: split the largest API files first: |
| 71 | + `http.ts`, `federation.ts`, `terminal-sessions.ts`, `skiller.ts`. |
| 72 | +6. Mutation PR: add mutation testing on changed files after the test/coverage |
| 73 | + baseline is stable. |
| 74 | + |
| 75 | +## Verification commands |
| 76 | + |
| 77 | +The audit used read-only checks only: |
| 78 | + |
| 79 | +```bash |
| 80 | +rtk gh issue view 1 --repo ProverCoderAI/architecture-skills --json title,body,comments |
| 81 | +rtk rg --files -g 'package.json' -g '*eslint*' -g '*biome*' -g '*jscpd*' -g '*openapi*' -g '*swagger*' -g '*stryker*' -g '*vitest*' |
| 82 | +rtk bun run lint:effect |
| 83 | +rtk rg -n 'fast-check|fc\\.property|fc\\.assert' packages -g '*.ts' -g '*.tsx' |
| 84 | +rtk rg -n '\\bfetch\\(|\\.fetch\\(' packages scripts -g '*.ts' -g '*.tsx' -g '*.mjs' |
| 85 | +``` |
| 86 | + |
| 87 | +The AST metrics were computed with the TypeScript compiler API against tracked |
| 88 | +files under `packages/` and `scripts/`, excluding generated build output. |
0 commit comments