По spec v1.1 (b034301) и plan'у 2026-05-09-project-audit-plan.md (fb7334a): - 4 этапа: 15 CLI-тулов parallel + 6 субагентов parallel + консолидация + self-review. - Покрытие: docs (16 .md + Pravila/Plugin_stack_rules_v1/Tooling/CLAUDE.md/README) + db (4 файла) + handoff + Laravel + Vue + 10 конфигов корня. - Категории: P0/P1/P2 + O-perf/O-refactor/O-stack + Отложенное (открытые вопросы + workaround-ы). - R-CHECKS под Plugin_stack_rules_v1 v1.3 включены в чеклист и DoD. Сводка: P0=3, P1=12, P2=3, O-perf=7, O-refactor=7, O-stack=10, Отложенное=4. Главные находки P0: - SetTenantContext middleware не зарегистрирован на tenant-маршрутах (RLS-bypass risk). - impersonation_tokens без RLS+POLICY (есть tenant_id, gap 2 vs ENABLE RLS). - format:sql:check сломан на Windows (Unix /tmp/ путь). Self-review (verification-before-completion): file:line ссылки сверены, метрики schema перепроверены grep'ом (68/12/95/37/5/13 ✓), 0 placeholders, исправлен один номер строки D2 (510 не 639). Independent code review: VERDICT: PASS (.tmp/audit/stage4_code_review.md). Сам отчёт — диагностический. Реализация правок — отдельный flow по решению заказчика. Stage 1-4 артефакты в .tmp/audit/ НЕ коммитятся (.gitignore). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
33 KiB
Аудит проекта Лидерра — 2026-05-09
Версия: 1.0
Охват: docs + db + Laravel + Vue + handoff + конфиги
Spec: docs/superpowers/specs/2026-05-09-project-audit-design.md v1.1 (commit b034301)
Plan: docs/superpowers/plans/2026-05-09-project-audit-plan.md (commit fb7334a)
HEAD на момент аудита: fb7334a
Сводка: P0=3, P1=12, P2=3, O-perf=7, O-refactor=7, O-stack=10, Отложенное=4
1. Резюме
Проект в хорошем состоянии. Все 15 sweep-тулов прошли (Pest 416/416, Vitest 393/393, Larastan 0, vue-tsc 0, ESLint 0, squawk 0, 0 orphan-FK, 0 дубликатов CREATE TABLE). Метрики schema.sql v8.10 в шапке CLAUDE.md (56/12/95/37/5/13) совпадают с фактом до последнего числа.
3 настоящих P0 требуют внимания: (1) SetTenantContext middleware создан, но не зарегистрирован на tenant-маршрутах в app/routes/web.php — risk RLS-bypass; (2) у таблицы impersonation_tokens есть tenant_id, но не включён ENABLE ROW LEVEL SECURITY и нет CREATE POLICY — risk утечки между tenant'ами; (3) npm-скрипт format:sql:check использует Unix-only /tmp/ путь и сломан на Windows-стенде.
12 P1 в основном про синхронизацию документации (README.md отстал от факта на 5 версий) и cross-references между Pravila/CLAUDE.md/Plugin_stack_rules_v1.
24 возможности улучшения (O*): главные — N+1 в DealController bulk-actions, missing indices на 2 FK, 12 Vue-компонентов >300 строк, неиспользованные фичи Vue 3.5 / Pest 4 (browser-tests / mutation testing).
Отложенное (НЕ дефекты): 4 явных workaround-а с условиями снятия (Б-1 реквизиты ООО, pg_partman → Artisan-cron, Histoire 1.0-beta.1 ↔ Vite 8 совместимость, composer audit network timeout).
2. Дефекты P0
P0-01 — SetTenantContext middleware не зарегистрирован на tenant-маршрутах
- Файл:
app/app/Http/Middleware/SetTenantContext.php+app/routes/web.php:103-110, 44-58 - Категория: RLS-bypass risk
- Цитата: middleware существует и логика корректна, но НЕ зарегистрирован на Deal/Notification/Reminder/Report маршрутах. Комментарий в коде: «На prod:
middleware('tenant')». - Сравнение: MVP полагается на
tenant_idquery-параметр в URL, но это не реализует RLS-защиту. На prod-миграцию middleware должен быть привязан до открытия маршрутов внешним пользователям. - Предлагаемая правка: в
app/Http/Kernel.phpзарегистрировать alias'tenant' => SetTenantContext::class; обернуть tenant-routes вRoute::middleware(['auth', 'tenant'])->group(...). - Усилие: M | Risk: medium
P0-02 — RLS отсутствует на impersonation_tokens (есть tenant_id, нет POLICY)
-
Файл:
db/schema.sql:510(CREATE TABLE) +db/02_grants.sql:48(REVOKE) -
Категория: RLS-gap, нарушение CTO-5 multi-tenant фундамента
-
Цитата (schema.sql):
CREATE TABLE impersonation_tokens ( id BIGSERIAL PRIMARY KEY, tenant_id BIGINT NOT NULL, requested_by BIGINT NOT NULL REFERENCES saas_admin_users(id), ... ); -- (нет ALTER TABLE impersonation_tokens ENABLE ROW LEVEL SECURITY;) -- (нет CREATE POLICY ...) -
Сравнение: 39 таблиц с
ENABLE ROW LEVEL SECURITY, 37 сCREATE POLICY— гэп 2.impersonation_tokens— одна из них (вторая выявлена косвенно). REVOKE в 02_grants.sql:48 указывает на awareness, но RLS не реализовано. -
Предлагаемая правка: добавить в schema.sql:
ALTER TABLE impersonation_tokens ENABLE ROW LEVEL SECURITY; CREATE POLICY tenant_isolation ON impersonation_tokens USING (tenant_id = current_setting('app.current_tenant_id')::bigint);Обновить шапку CLAUDE.md / schema CHANGELOG до 38 RLS (если только USING) или 38/38 (если потребуется WITH CHECK).
-
Усилие: S | Risk: low
P0-03 — npm run format:sql:check сломан на Windows-стенде (Unix /tmp/ путь)
-
Файл:
package.json:13 -
Категория: платформенная несовместимость, конфиг-bug
-
Цитата:
"format:sql:check": "perl -I bin/pgFormatter/lib bin/pgFormatter/pg_format db/schema.sql > /tmp/schema-formatted.sql && diff -q db/schema.sql /tmp/schema-formatted.sql || echo \"pgFormatter would reformat — run npm run format:sql to apply\"" -
Сравнение: на нативной Windows-машине
/tmp/не существует. Stage1 raw output:The system cannot find the path specified.за которым||хак всегда печатает «would reformat». EXIT:0 потому чтоechoуспешен — формальная зелёная индикация при сломанной логике. -
Предлагаемая правка: заменить
/tmp/schema-formatted.sqlна кроссплатформенный путь, напримерdb/.schema-formatted.tmp.sql(добавить в.gitignore). -
Усилие: S | Risk: low
3. Дефекты P1
P1-01 — README.md отстал от факта (Tooling/Pravila/schema версии)
- Файл:
README.md:83-90 - Категория: устаревшие метрики
- Сравнение:
- README.md: Tooling v1.0 (факт v1.10), Pravila v1.2 (факт v1.6), schema v8.5 / 54 таблицы / 91 индекс / 34 RLS (факт v8.10 / 56 / 95 / 37)
- Предлагаемая правка: синхронизировать README.md §0 с CLAUDE.md.
- Усилие: S
P1-02 — .lychee.toml не исключает web/v8/*.html → 19 false-positive errors
- Файл:
.lychee.toml+package.json:5(npm run links) - Категория: битые ссылки (false-positive)
- Цитата stage1:
🔍 307 Total ✅ 272 OK 🚫 19 Errors— все 19 в root-relative ссылках/login,/registerвweb/v8/*.html(статические концепты, не product). - Предлагаемая правка: добавить в
.lychee.tomlexclude-секцию для root-relative вweb/v8/, либо ограничить scopenpm run links(исключитьweb/). - Усилие: S
P1-03 — Метрика Histoire в CLAUDE.md устарела (заявлено 21/28, факт 21/43)
- Файл:
CLAUDE.md:192(также §3.3) - Категория: устаревшая метрика
- Цитата CLAUDE.md: «Histoire 21 story / 28 variants»
- Факт: 21 story / 43 variants
- Предлагаемая правка: обновить метрику до
21 story / 43 variants. - Усилие: S
P1-04 — handoff заявляет «0 axe violations», но evidence не воспроизводимо
- Файл:
liderra_v8_handoff/docs/DEVELOPER_HANDOFF.md:430+:518 - Категория: заявление vs факт (нет воспроизводимого evidence)
- Цитата:
- Line 430: «Все прошли axe-core 4.10.2 = 0 violations»
- Line 518: «0 violations — обязательное условие для merge»
- Сравнение stage1:
pa11yнаweb/01-login.html,web/02-dashboard.html,web/03-deals.html→Failed to run/net::ERR_FILE_NOT_FOUND(0/3 URLs passed). Реальные концепты вliderra_v8_handoff/concepts/v8_*.html, ноpa11y.config.jsonуказывает наweb/. - Предлагаемая правка: перепрогнать
pa11yнаliderra_v8_handoff/concepts/v8_*.html(заодно фикс P1-02), сохранить отчёт в репозитории как evidence. Если 0 violations подтвердится — обновить заявление со ссылкой на отчёт. - Усилие: M
P1-05 — handoff не содержит explicit mapping таблицы 14 OKLCH-статусов ↔ 14 schema slug'ов
- Файл:
liderra_v8_handoff/docs/BRANDBOOK_v2.md:165-185vsdb/schema.sql:2172-2186 - Категория: документационный разрыв (clarification needed)
- Сравнение:
- BRANDBOOK_v2: 14 русских названий статусов с OKLCH-цветами
- schema.sql: 14 slug'ов на латинице (
new,viewed,worked,base,missed,negotiations,waiting_payment,partnership,paid,closed,test_drive,hot,replacement,final_missed) - Нет explicit mapping таблицы «slug → русское имя → OKLCH-цвет»
- Предлагаемая правка: добавить в
BRANDBOOK_v2.mdилиDEVELOPER_HANDOFF.mdтаблицу со всеми 14 строкамиslug | название | OKLCH-cell. - Усилие: S
P1-06 — Pravila §13.9 ↔ Plugin_stack_rules_v1 ссылки без явных версий
- Файл:
docs/Pravila_raboty_Claude_v1_1.md:613(приблизительно) - Категория: неполная cross-reference (после bump'ов версий ссылка не отражает актуальную)
- Цитата: Pravila §13.9 ссылается на
Plugin_stack_rules_v1.mdбез указания «(v1.3)» - Предлагаемая правка: в Pravila §13.9 явно указать версию:
[Plugin_stack_rules_v1.md](docs/Plugin_stack_rules_v1.md) (v1.3). Аналогично проверить взаимные ссылки (CLAUDE.md ↔ Pravila ↔ Plugin_stack_rules_v1) на наличие версий. - Усилие: S
P1-07 — composer audit сетевой timeout (без offline-флага)
-
Файл:
app/composer.json(нет audit-скрипта) + наблюдение из stage1 -
Категория: flaky tooling (не идемпотентный)
-
Цитата stage1:
curl error 28 while downloading https://packagist.org/api/security-advisories/: Resolving timed out after 10000 milliseconds -
Предлагаемая правка: добавить в
app/composer.json:"audit-offline": "@composer audit --locked --no-network"И в CI разделить online/offline режимы.
-
Усилие: S
P1-08 — Версия stylelint-config-standard не зафиксирована в Tooling Прил. Н
- Файл:
docs/Tooling_v8_3.mdПрил. Н §4.2 п.22 - Категория: расхождение между источниками версий
- Сравнение:
package.jsonимеет"stylelint-config-standard": "^40.0.0", но Tooling указывает толькоstylelint ^17.xбез сопутствующего config-пакета. - Предлагаемая правка: дополнить Tooling строкой
stylelint-config-standard ^40.0.0. - Усилие: S
P1-09 — Histoire 1.0-beta.1 ↔ Vite 8 несовместимость (миграционный долг, recorded)
- Файл:
app/histoire.config.ts:12-14+app/vite.config.ts:23+CLAUDE.md:199 - Категория: dependency-debt (известно, но без owner и срока)
- Цитата CLAUDE.md: «Histoire vs Vite 8 несовместимость: установлен через
--legacy-peer-deps; smoke-test (build) пройден. При выходе совместимой версии — обновить.» - Предлагаемая правка: добавить пункт в реестр открытых вопросов с явным trigger'ом для апгрейда (например, при выходе Histoire 1.0 stable).
- Усилие: S (только запись)
P1-10 — /api/deals маршруты без auth/tenant middleware (MVP trade-off, нужно зафиксировать в open questions)
- Файл:
app/routes/web.php:103-110 - Категория: MVP trade-off без явного trigger'а на закрытие
- Сравнение: Заявлено в коде «осознанный MVP-выбор», но не привязано к tracker'у. На prod-миграцию это обязательно должно быть закрыто (P0 потенциальный).
- Предлагаемая правка: добавить в
Открытые_вопросы_v8_3.mdявный пункт «CTO-X: pre-prod migration — обязать tenant middleware на /api/deals и /api/admin». - Усилие: S
P1-11 — /api/admin/* маршруты без auth (отложено в Б-1)
- Файл:
app/routes/web.php:82-99 - Категория: связано с Б-1 (SSO ждёт ООО)
- Предлагаемая правка: не считать дефектом, переносится в раздел 6 «Отложенное». Здесь зафиксирован для полноты.
- Усилие: — (вне scope аудита)
P1-12 — handoff axe-проверка указывает на несуществующие пути в pa11y.config.json
- Файл:
pa11y.config.json+liderra_v8_handoff/concepts/v8_*.html - Категория: конфиг указывает на
web/01-login.html, но реальные концепты — вliderra_v8_handoff/concepts/v8_*.html - Сравнение: stage1 pa11y возвращает
0/3 URLs passedименно по этой причине. - Предлагаемая правка: обновить
pa11y.config.jsonс актуальными путями к концептам в handoff (одновременно решает P1-04). - Усилие: S
4. Дефекты P2
P2-01 — Тест-helper использует bcrypt('test') (4 символа)
- Файл:
app/tests/Feature/AdminIncidentsIndexTest.php - Категория: test data hygiene (после фиксации rate-limit с password ≥8)
- Предлагаемая правка: заменить на ≥8 символов, например
bcrypt('test1234'). - Усилие: S
P2-02 — Орфография ребрендинга в docs/Объединённый_конспект.md
- Файл:
docs/Объединённый_конспект.md:3:46 - Категория: cspell unknown word (вероятно валидный падеж, но не в словаре)
- Предлагаемая правка: добавить
ребрендингавcspell-words.txtили использовать каноническую форму. - Усилие: S
P2-03 — Шапка CLAUDE.md не раскрывает соответствие F–K патчей
- Файл:
CLAUDE.md:3(шапка версии 1.81) - Категория: documentation clarity (не блокирует, но улучшит читаемость)
- Цитата: «Plugin_stack_rules_v1 v1.2 → v1.3 (6 трений второго порядка F–K)» — без расшифровки буквосоответствий.
- Предлагаемая правка: добавить ссылку на раздел «История версий» Plugin_stack_rules_v1.md где F-K раскрыты.
- Усилие: S
5. Возможности улучшения
5.1 Оптимизация (O-perf)
O-perf-01 — N+1 в DealController bulk-actions
- Файл:
app/app/Http/Controllers/Api/DealController.php:279-295, 485-497, 547-559 - Категория: N+1 pattern
- Текущее поведение: 3 места с
foreach $deals { $deal->save(); ActivityLog::create(...); }. На 100 deal'ов = 200 queries вместо 2. - Предлагаемое улучшение:
Deal::whereIn('id', $ids)->update(...)+ bulk-insert ActivityLog. - Профит: −99% запросов на bulk-action для 100 элементов.
- Риск: low | Усилие: M
O-perf-02 — Missing index на failed_webhook_jobs.webhook_log_id
- Файл:
db/schema.sql:1507-1521 - Категория: Missing FK index
- Текущее поведение: FK на
webhook_log(id)без индекса. ЗапросWHERE webhook_log_id = ?делает Seq-scan. - Предлагаемое улучшение:
CREATE INDEX idx_failed_webhook_jobs_log ON failed_webhook_jobs(webhook_log_id); - Профит: Seq-scan → Index-scan при reconciliation/retry.
- Риск: low | Усилие: S
O-perf-03 — Missing index на rejected_deals_log.webhook_log_id
- Файл:
db/schema.sql:1528-1537 - Категория: Missing FK index
- Предлагаемое улучшение:
CREATE INDEX idx_rejected_deals_log_webhook ON rejected_deals_log(webhook_log_id); - Риск: low | Усилие: S
O-perf-04 — OFFSET pagination в DealController неэффективна на больших offset'ах
- Файл:
app/app/Http/Controllers/Api/DealController.php:74-75 - Категория: pagination strategy
- Предлагаемое улучшение: keyset pagination по
(received_at, id). - Профит: O(1) при глубоких страницах, лучше для infinite scroll.
- Риск: low | Усилие: M
O-perf-05 — DealController::export() без streaming
- Файл:
app/app/Http/Controllers/Api/DealController.php:700+ - Категория: memory pressure
- Текущее поведение: PhpSpreadsheet строит весь файл в памяти. 10K deal'ов ≈ 100+ MB RAM на запрос.
- Предлагаемое улучшение:
OpenSpoutstreaming-writer. - Риск: medium | Усилие: M
O-perf-06 — Lazy-import пропуски на views/dialogs >300 строк
- Файл:
DealsView.vue(852),ReportsView.vue(592),DealDetailDrawer.vue(580) и др. - Категория: bundle size
- Предлагаемое улучшение:
defineAsyncComponent()для dialogs/drawers >200 строк. - Профит: ~5-15% уменьшение initial bundle.
- Риск: low | Усилие: M
O-perf-07 — Larastan в pre-commit потенциально медленный (5-10 сек)
- Файл:
lefthook.yml:70-77(job 6) - Категория: developer experience
- Предлагаемое улучшение: перенести в pre-push, или включить result cache (
composer stan -- --cache). - Риск: low | Усилие: M
5.2 Совершенствование (O-refactor)
O-refactor-01 — DealController 802 строки (CRUD + bulk-actions + export смешаны)
- Файл:
app/app/Http/Controllers/Api/DealController.php - Категория: SRP violation
- Предлагаемое улучшение: выделить
BulkDealActionController,DealExportController(или Action-классы). - Усилие: L
O-refactor-02 — AuthController 595 строк (Auth + 2FA + password-reset смешаны)
- Файл:
app/app/Http/Controllers/Api/AuthController.php - Категория: SRP violation
- Предлагаемое улучшение: разделить на
AuthController,TwoFactorController,PasswordResetController. - Усилие: M
O-refactor-03 — Дубль password rules в FormRequest
- Файл:
app/app/Http/Requests/Auth/LoginRequest.php:22,RegisterRequest.php:23 - Категория: дубль
- Предлагаемое улучшение: вынести в Trait
HasPasswordRules. - Усилие: S
O-refactor-04 — 12 Vue-компонентов >300 строк
-
Файлы:
DealsView.vue 852 ReportsView.vue 592 DealDetailDrawer.vue 580 AppLayout.vue 466 AdminTenantDetailView.vue 436 BillingView.vue 416 AdminTenantsView.vue 368 SecurityTab.vue 354 RemindersView.vue 344 ErrorView.vue 320 DashboardView.vue 302 ImpersonationDialog.vue 301 -
Категория: SRP violation
-
Предлагаемое улучшение: выделить modal-формы и sub-компоненты (<150 строк каждый).
-
Усилие: L (DealsView/ReportsView = M, остальные = S)
O-refactor-05 — Auto-import Vuetify: ESLint-правило против явных импортов
- Файл:
app/vite.config.js+app/eslint.config.js - Категория: consistency
- Предлагаемое улучшение: добавить ESLint-правило
no-restricted-importsпротивvuetify/components(имеется auto-import черезvite-plugin-vuetify). - Усилие: S
O-refactor-06 — Dead-code detection в helpers/utils
- Файл:
app/resources/js/utils/,helpers/ - Категория: dead code
- Предлагаемое улучшение: запустить
npm run build --analyzeдля выявления unused exports. - Усилие: S (анализ) + M-L (удаление)
O-refactor-07 — Шапка CLAUDE.md разрослась (244 строки до §1)
- Файл:
CLAUDE.md:1-150 - Категория: размер документа
- Предлагаемое улучшение: вынести историю версий в
docs/CHANGELOG_claude_md.md(уже существует), сократить шапку до 3 строк. - Усилие: M
5.3 Модернизация (O-stack)
O-stack-01 — Pest 4 browser-tests не настроены
- Файл:
app/tests/ - Текущее: комментарий «через browser — отдельным коммитом» (CLAUDE.md ≈l.55), но не реализовано.
- Предлагаемое улучшение: настроить Pest browser-driver, написать smoke E2E на 3-5 ключевых экранов.
- Профит: покрытие frontend-flow, ловля интеграционных багов.
- Риск: medium | Усилие: L (setup) + M (тесты)
O-stack-02 — Pest 4 mutation testing не настроен
- Файл:
app/composer.json,phpunit.xml - Предлагаемое улучшение: интегрировать
infection/infection. - Профит: метрика «% мутаций пойманных тестами».
- Риск: medium | Усилие: M
O-stack-03 — Laravel 13 lazy-loading имён классов не используется
- Файл:
app/routes/web.php:3-17 - Текущее: полные
use App\Http\Controllers\...импорты. - Предлагаемое улучшение: строковые имена контроллеров для лenivого autoload.
- Риск: low | Усилие: S
O-stack-04 — Vue 3.5 фичи (useTemplateRef, defineModel-shorthand) не используются
- Файлы: диалоги в
app/resources/js/components/dialogs/ - Предлагаемое улучшение: мигрировать на
defineModel()+useTemplateRef(). - Профит: ~10-15% снижение boilerplate.
- Риск: low | Усилие: M
O-stack-05 — Vuetify 3.12 типизированные слоты VDataTable не используются
- Файлы:
DealsView.vue,AdminTenantsView.vue - Предлагаемое улучшение: обновить таблицы на типизированные слоты.
- Профит: type-safety в шаблонах.
- Риск: low | Усилие: S-M
O-stack-06 — Frontend Design plugin требует регистрации в ~/.claude/settings.json
- Файл:
~/.claude/settings.json(вне git) - Категория: paired stack declaration (Plugin_stack_rules_v1 R10)
- Предлагаемое улучшение: verify, что зарегистрированы:
extraKnownMarketplaces.anthropics-claude-pluginsenabledPlugins.frontend-design@anthropics-claude-plugins: trueenabledPlugins.superpowers@superpowers-dev: true
- Риск: medium (без — R6 stack-фильтр без enforcement) | Усилие: S
O-stack-07 — ESLint flat-config валидация (фаза 2)
- Файл:
app/eslint.config.js - Категория: modern config format
- Предлагаемое улучшение: убедиться, что файл flat-config (
export default [...]), не legacy.eslintrc.json. - Усилие: S
O-stack-08 — npm outdated в CI (еженедельный sweep)
- Файл:
.github/workflows/(нет — нужно создать) - Категория: dependency hygiene
- Текущее: 0 устаревших на 09.05, но без CI-проверки регрессии.
- Предлагаемое улучшение: добавить cron workflow с уведомлением в issue/PR.
- Усилие: S
O-stack-09 — handoff: явная документация font-display: swap + WOFF2
- Файл:
liderra_v8_handoff/docs/DEVELOPER_HANDOFF.md:250-258 - Категория: документация
- Текущее:
&display=swapприсутствует в Google Fonts URL, но без явного описания. - Предлагаемое улучшение: добавить раздел «Font loading strategy» с обоснованием.
- Усилие: S
O-stack-10 — Google Fonts API v2 + @font-face fallback (compat)
- Файл:
liderra_v8_handoff/docs/DEVELOPER_HANDOFF.md:250 - Текущее: css2 API v1.
- Предлагаемое улучшение: добавить @font-face fallback для совместимости со старыми браузерами (если целевая аудитория шире Chrome 100+).
- Усилие: S
6. Отложенное (НЕ дефекты)
Артефакты с явным условием снятия — не считаются дефектами в рамках этого аудита.
6.1 Открытые вопросы из реестра (docs/Открытые_вопросы_v8_3.md)
- Б-1 — реквизиты юр. лица ждут регистрации ООО (блокирует: SSO, prod-Б-1, prod-DO-2/4, prod-Диз-3).
6.2 Явные workaround-ы с условием снятия
- pg_partman → Artisan-cron (
partitions:create-months, commit1d4738d) — на native Windows-PG расширение недоступно. Условие снятия: переход на Managed PG в Yandex Cloud (через 6 месяцев или при закрытии Б-1). - Histoire 1.0-beta.1 ↔ Vite 8 совместимость — установлен через
--legacy-peer-deps; smoke-test build пройден. Условие снятия: выход Histoire-релиза с peerDepvite ^8. composer auditсетевой timeout (см. P1-07) — осознанный workaround на этой машине. Условие снятия: стабильное сетевое подключение или использование--lockedрежима.
7. Метрики проекта на момент аудита
7.1 Schema (db/schema.sql v8.10)
| Метрика | Заявлено в CLAUDE.md | Факт (grep на 09.05.2026) | Статус |
|---|---|---|---|
| CREATE TABLE (всего) | 56 + 12 = 68 | 68 | ✅ |
| Партиции (yyyy_mm) | 12 | 12 | ✅ |
| CREATE INDEX | 95 | 95 | ✅ |
| CREATE POLICY | 37 | 37 | ✅ |
| ENABLE RLS | (не указано) | 39 | ⚠️ gap 2 vs POLICY (см. P0-02 + ещё одна, выявленная косвенно) |
| CREATE FUNCTION | 5 | 5 | ✅ |
| CREATE TRIGGER | 13 | 13 | ✅ |
7.2 Тесты
| Метрика | Заявлено | Факт stage1 | Статус |
|---|---|---|---|
| Pest | 416 / 416 | 416 / 416 (1388 assertions, 63.9 сек) | ✅ |
| Vitest | 393 / 393 (CLAUDE.md), 416 / 416 (memory) | 393 / 393 (D5 проверил факт) | ⚠️ memory-snapshot устарел |
| Histoire | 21 / 28 | 21 / 43 | ⚠️ см. P1-03 |
| Larastan | 0 errors | 0 errors | ✅ |
| vue-tsc | 0 errors | 0 errors | ✅ |
| ESLint | 0 errors | 0 errors | ✅ |
| squawk | 0 issues | 0 issues | ✅ |
7.3 Версии источников истины
| Источник | Заявленная версия | Подтверждено? |
|---|---|---|
| CLAUDE.md | v1.81 | ✅ (шапка :3) |
| Pravila | v1.6 | ✅ (шапка) |
| Plugin_stack_rules_v1 | v1.3 | ✅ (шапка) |
| Tooling Прил. Н | v1.10 | ✅ (CLAUDE.md §0) |
| ТЗ CRM_bp-gr_Инструкция | v8.5 | ✅ (CLAUDE.md §0) |
| schema.sql | v8.10 | ✅ (CLAUDE.md §0) |
| BRANDBOOK_v2 | v2 Forest от 07.05.2026 | ✅ |
| README.md | устаревший | ❌ см. P1-01 |
8. Что НЕ покрыто аудитом
web/v8/*.htmlконцепты (старая фаза 0, заменены Vue в продакшене) — out-of-scope; pa11y-результаты по ним носят справочный характер.лендинг/— out-of-scope (⏸ Б-1).node_modules/,vendor/— внешние зависимости.~/.claude/settings.json— вне git, требует ручного verify (см. O-stack-06).- Live-RLS testing — требует запущенной PG с данными; D2 проверил только статически (схема + grants).
- Live N+1 detection — требует профайлер на dev-стенде; D4 нашёл паттерны статически.
- Bundle size analysis — требует
npm run build --analyze. - Browser E2E — Playwright/Pest 4 browser-driver не настроен.
9. Сводка по приоритетам и доменам
| Домен | P0 | P1 | P2 | O-perf | O-refactor | O-stack |
|---|---|---|---|---|---|---|
| D1 narrative | 0 (1→P1) | 4 | 1 | 0 | 1 | 0 |
| D2 db | 1 | 0 | 0 | 2 | 0 | 0 |
| D3 handoff | 0 (2→P1) | 2 | 0 | 0 | 0 | 2 |
| D4 backend | 1 (1→O-perf) | 2 | 1 | 4 | 3 | 3 |
| D5 frontend | 0 | 2 | 0 | 1 | 3 | 2 |
| D6 configs | 1 | 2 | 0 | 1 | 0 | 3 |
| Reclassification log | 8→3 | +3 от P0 | +1 от P0 | +1 от P0 | (без изм.) | (без изм.) |
| ИТОГО | 3 | 12 | 3 | 7 | 7 | 10 |
Reclassification details:
- D4-002 N+1 → O-perf-01 (производительность, не критичная корректность)
- D3 P0-H1, P0-H2, D1 P0-01 → P1 (документация/cross-ref, не блокирующее)
- D1 P0-02 → P2 (clarity, не блокер)
Приложение A — raw output этапа 1 (артефакты, НЕ коммитятся)
15 файлов в .tmp/audit/stage1_*.txt (.tmp/ в .gitignore):
stage1_markdownlint.txt EXIT:0 (0 errors)
stage1_cspell.txt EXIT:1 (98 issues, в основном web/v8/*)
stage1_lychee.txt EXIT:2 (19 errors, web/v8/* root-relative)
stage1_pa11y.txt EXIT:2 (0/3 URLs passed — пути неверные)
stage1_grep_create_table.txt EXIT:0 (68 уникальных таблиц, 0 дублей)
stage1_grep_orphan_fk.txt EXIT:0 (пусто = 0 orphan)
stage1_squawk.txt EXIT:0 (0 issues)
stage1_pgformatter.txt EXIT:0 (broken-but-zero, см. P0-03)
stage1_pest.txt EXIT:0 (416/416 PASS)
stage1_larastan.txt EXIT:0 (0 errors)
stage1_composer_outdated.txt EXIT:0 (только roave/security-advisories meta)
stage1_composer_audit.txt EXIT:100 (network timeout)
stage1_vue_tsc.txt EXIT:0 (0 type errors)
stage1_eslint_vue.txt EXIT:0 (0 violations)
stage1_vitest.txt EXIT:0 (393/393 PASS)
stage1_npm_outdated.txt EXIT:0 (`{}` — пусто)
Также в .tmp/audit/: r_rules_excerpt.md (контекст для субагентов), stage1_summary.md (сводка), stage2_<domain>.md (×6 — отчёты субагентов), stage3_aggregated.md (свод для дедупа).