# Portal Full Audit — Summary Report (2026-05-12 ночь)

> **Связано:** план `2026-05-12-portal-full-audit.md`, findings `2026-05-12-portal-full-audit-findings.md`, blocked `2026-05-12-portal-full-audit-blocked.md`
> **Триггер:** заказчик ушёл спать, попросил «полный аудит всего портала, исправь всё что сможешь в моё отсутствие, вопросы фиксируй и продолжай»
> **Режим:** экономия 0% (full reads, full test output, ≥3 гипотезы на debug, verify-before-completion)
> **Ветка:** `plan5-frontend-projects` (HEAD `b5849bb` → audit-final HEAD `57f0b8e+`)

---

## TL;DR

- **Findings:** 393 (P0: 1, P1: 47, P2: 339, P3: 6)
- **Fixed:** 8 fix-commits + 1 finalization commit (см. ниже Commits таблицу)
- **Deferred / known:** 18 cspell mixed-script artifacts (typo'ы в исходниках, requires manual review), 6284-line pgFormatter diff (style-only, не auto-apply), 1 markdownlint в untracked design.md от прошлой сессии, 3 Pest sequential failures (квирк 62 cumulative state в `liderra_testing`, fix через test-DB hygiene)
- **BLOCKED на вопрос заказчика:** 4 (Q.HARD.001 admin role-guard ⏸ Б-1, Q.INFO.001 Semgrep CI, Q.INFO.002 dev vs prod schema metrics, Q.HARD.002 schema.sql pgFormatter swap) — см. `2026-05-12-portal-full-audit-blocked.md`

---

## По phase'ам

### Phase 0 — Pre-flight (✅ closed)

- git sync OK: HEAD=`b5849bb` == origin/plan5-frontend-projects.
- 32 untracked PNG из workdir → перемещены в `audit-screens/legacy/`.
- DemoSeeder.php (untracked) Read, безопасен — использован для UI smoke seed.
- Skeletons artefacts созданы (findings.md, blocked.md).

### Phase 1 — Static analysis (✅ closed via subagent dispatch ×4 parallel)

- **Backend (Subagent A):** Pint 0 issues (после auto-fix DemoSeeder); Larastan 0 above baseline; composer audit 0 advisories.
- **Frontend (Subagent B):** **17 ESLint errors** (test-mocks any, vitest/no-disabled-tests rule-not-found, unused beforeEach); **9 vue-tsc errors** (AppSidebar countKey, duplicate Project interface); **48 prettier --check fails**; knip 0 issues.
- **Docs (Subagent C):** **165 markdownlint violations** (untracked plans/specs); **103 cspell unknown** (78% lorem ipsum + бренд-нейминг в web/v8/*.html); lychee 0 broken (339 URLs / 141 unique).
- **SQL (Subagent D):** squawk 0 issues; pgFormatter 6284-line style-only diff (P3 defer).

### Phase 2 — Test suites (✅ closed)

- **Pest sequential:** 736 passed / 3 failed (квирк 62 cumulative state) / 3 skipped (Browser ext-sockets blocker).
- **Pest --parallel:** **739 passed / 0 failed / 3 skipped** (clean per-worker test-DBs).
- **Vitest:** 79 files / 614 passed / 3 skipped / 56s.
- **Histoire build:** **EXIT 1** — `getActivePinia()` без app.use(pinia) в `BulkActionsBar.story.vue` валит весь build (regression от baseline 24 stories / 31 variants).
- **Vite build:** exit 0, 1.80s, 688 modules, без warnings. Top JS: VBtn 184 kB, KanbanView 182 kB, app.js 131 kB, ProjectsView 47 kB.

### Phase 3 — Schema integrity (✅ closed)

- RLS 39 = 39 ✅, orphan FK = 0 ✅, user funcs = 5 ✅.
- Tables baseline 62 vs dev factual **75** (+13), partitions 12 vs **102** children (+90 от `partitions:create-months` accumulation), indexes 117 vs **289** (+172), triggers 13 vs **19** (+6), DB roles 0 на dev (by design, 5 на prod).
- **Drift = stale baseline в CLAUDE.md метриках**, не data integrity. → §8 audit-fix Phase 9.

### Phase 4 — Security (✅ closed)

- gitleaks полная история: 0 leaks, 333 commits scanned, 11.14 MB.
- Semgrep SAST: tool unavailable (Python пакет, install blocked Pravila §13.10) → blocked.md Q.INFO.001.
- composer audit --locked: 0 advisories.

### Phase 5 — UI smoke (✅ closed) — 24 views via Playwright MCP

- 7 auth views: 5 ✅ + 1 router-guard redirect (2fa→login expected) + 1 false-positive (`/reset` query-style vs path-param `/reset/:token`).
- 8 main views: все ✅ после login (admin@demo.local / password).
- 8 admin views: все доступны обычному tenant-admin — **documented MVP defer** ⏸ Б-1 (TODO в router/index.ts:128, /api/admin/* без middleware в routes/web.php:75-87,90,93,97,105,115).
- 1 error view: 404 catch-all `/no-such-path` ✅.
- 1 interactive flow: login + logout via avatar dropdown ✅.
- DevIndexOverlay fragment-root inheritance Vue warns (повторяющийся pattern; dev-only artifact).

### Phase 6 — Cross-doc integrity (✅ closed)

- Vue Router имеет `/reset/:token` (line 74), не query-style — false-positive Phase 5 P1 → P2/defer.
- Admin role-guard TODO (line 128) + backend `/api/admin/*` без middleware — documented ⏸ Б-1.
- routes/web.php inconsistent: `/reminders, /projects, /admin/*` отсутствуют в explicit `Route::view` list (нарушает test-isolation rationale) → fixed Phase 8 commit `b9038bc`.
- memory `reference_archive.md` description forward-stale (заявляет v1.88/v1.11/v2.0/v1.16/v1.78 — факт v1.87/v1.10/v1.7/v1.15/v1.73) → fixed in Phase 8 (memory edit, не git-tracked).
- CLAUDE.md §0/§2/§6/§8 schema метрики застряли на baseline v8.19 — fixed Phase 9 (commit `57f0b8e` v1.88).

### Phase 7 — Categorize (✅ closed)

- Severity rollup в findings.md `## Phase 7 — Fix Queue`.

### Phase 8 — Fix loop (✅ closed — 8 atomic commits)

| # | Commit | Scope | Findings closed |
|---|---|---|---|
| 1 | `3a8229a` | `fix(histoire): register Pinia in setup file + add missing routes` | P0 Histoire build broken |
| 2 | `55a9d3f` | `fix(types): unify Project interface + NavItem.countKey + drop legacy Record` | P1 vue-tsc 9 errors |
| 3 | `245b76e` | `test(frontend): fix 17 ESLint errors + TwoFactorView router stub` | P1 ESLint 17 + P2 Vue Router warn |
| 4 | `6988e80` | `chore(cspell): add 79 project + lorem-ipsum + brand-naming + test-fixture words` | P2 cspell 103 → 18 |
| 5 | `cb05657` | `chore(format): prettier --write across 37 .vue/.ts files` | P2 prettier 48 → 0 |
| 6 | `b9038bc` | `chore(routes): add explicit Route::view for /projects, /reminders, /admin/*` | P2 routes inconsistent |
| 7 | `57f0b8e` | `docs(claude.md): v1.87 → v1.88 audit-driven sync §0/§2/§6/§8` | P2 doc-drift schema/registry/phase |
| 8 | (TBD) | `chore(audit): finalize 2026-05-12 portal full audit — findings + blocked + report + DemoSeeder + screens` | All audit artefacts |

### Phase 9 — Final verification (см. ниже Метрики до/после)

---

## Метрики до/после

| Метрика | Phase 1+2 baseline | Phase 9 final | Delta |
|---|---|---|---|
| Pest tests (--parallel) | 739 passed / 0 failed / 3 skipped | unchanged | 0 |
| Pest sequential | 736 / 3 failed / 3 skipped | unchanged (квирк 62) | 0 |
| Vitest | 79 files / 614 passed / 3 skipped | 79 / 614 / 3 | 0 (regression-free) |
| Histoire build | **EXIT 1 BROKEN** | **35 stories / 63 variants** | **+35 stories** ✅ FIXED |
| Vite build | exit 0, 1.80s, 688 modules | exit 0, similar | 0 |
| Larastan | 0 above baseline | 0 | 0 |
| ESLint errors | **17** | **0** | **-17** ✅ FIXED |
| vue-tsc errors | **9** | **0** | **-9** ✅ FIXED |
| Prettier issues | **48 files** | **0** | **-48** ✅ FIXED |
| markdownlint issues | **165** | **1** (untracked design.md) | **-164** ✅ FIXED |
| cspell unknown | **103** in 12 files | **18** mixed-script artifacts | **-85** ✅ FIXED |
| lychee broken | 0 | 0 | 0 |
| gitleaks leaks | 0 (333 commits) | 0 | 0 |

---

## Blocked questions for user (см. blocked.md)

1. **Q.HARD.001 Admin role-guard** — frontend + backend `/api/admin/*` middleware. Documented MVP defer ⏸ Б-1. Решение: (A) ждать Б-1 / (B) добавить временный frontend guard / (C) ничего.
2. **Q.INFO.001 Semgrep SAST** — tool unavailable, требует `pip install semgrep` или CI job ubuntu-latest. Решение: (A) install local / (B) добавить в CI (рекомендую) / (C) пропустить.
3. **Q.INFO.002 schema metrics dev vs prod** — фактический dev `liderra` отличается от schema.sql baseline (накопленные partitions). CLAUDE.md §0/§2/§6/§8 теперь содержат оба числа после v1.88 bump. Подтвердить корректность формата ИЛИ откатить.
4. **Q.HARD.002 schema.sql pgFormatter swap** — 6284-line cosmetic diff. Не трогать (recommend defer).
5. **Q.DEFER.001 memory reference_archive description** — был forward-stale, обновлён в этой сессии до фактического. Confirm OK.

---

## Что НЕ зафиксировано в коде

- Phase 5 admin role-guard (документированный MVP defer ⏸ Б-1 — не fix без явного «закрываем»).
- pgFormatter 6284-line diff (style-only, hard-stop convention).
- 3 Pest sequential failures (квирк 62 — fix требует test-DB hygiene `DROP+CREATE+ICU+migrate --env=testing`).
- 18 cspell mixed-script artifacts в исходниках — typo finding'и (импersonator, fonetика, proverено, бо́льшей) сохранены как P3 в findings.md для manual review.

---

## Verdict

🟢 **GREEN** — все P0 + P1 (eligible под decision-tree) закрыты. 0 регрессий. Tests + builds + lints — все clean (acceptable known issues явно отмечены).

---

## Commits made в этой сессии (8 + 1 finalize)

```
57f0b8e docs(claude.md): v1.87 → v1.88 audit-driven sync §0/§2/§6/§8
b9038bc chore(routes): add explicit Route::view for /projects, /reminders, /admin/*
cb05657 chore(format): prettier --write across 37 .vue/.ts files
6988e80 chore(cspell): add 79 project + lorem-ipsum + brand-naming + test-fixture words
245b76e test(frontend): fix 17 ESLint errors + TwoFactorView router stub
55a9d3f fix(types): unify Project interface + NavItem.countKey + drop legacy Record
3a8229a fix(histoire): register Pinia in setup file + add missing routes
(TBD)  chore(audit): finalize 2026-05-12 portal full audit — findings + blocked + report + DemoSeeder + screens
```

Push на `origin/plan5-frontend-projects` (НЕ main; НЕ PR — заказчик утром решит сам).

---

## Память сессии — quirks для будущих сессий

- **Quirk 63:** Composer absorbs `--test` flag перед passing to script. Каноническое `composer pint:test` (alias) вместо `composer pint --test` (silently runs WRITE mode).
- **Quirk 64:** `dev-indices.json` авто-генерируется vite watcher при frontend изменениях. Включать в logical commits; не отдельным atomic commit.
- **Quirk 65:** Histoire `setup.ts` нужно явно регистрировать Pinia (как Vuetify + vue-router) — иначе любая story с `useXxxStore()` на top-level setup валит весь build (P0).
- **Quirk 66:** Vue Router `/reset/:token` (path-param), не `/reset?token=...` (query-style). Email reset link format соответственно.
- **Quirk 67:** Playwright MCP `browser_fill_form` с label-based locators ломается на CSS escape issues с кириллицей. Использовать `#input-v-N` id-based ИЛИ `mcp__playwright__browser_type` с element ref после `browser_snapshot`.
- **Quirk 68:** routes/web.php `Route::view('/reset', 'welcome')` ловит ТОЛЬКО literal `/reset`; для `/reset/{token}` срабатывает `Route::fallback`. Это ОК для SPA-shell, но комментарий line 195 «рендерит ResetPasswordView для /reset/{token}» misleading — Vue Router сам ловит через catch-all.
