Commit Graph

3 Commits

Author SHA1 Message Date
Дмитрий 04b90afda4 phase2(auth-backend): Sanctum SPA mode + AuthController + 13 Pest tests
- laravel/sanctum@^4.3 install. SPA mode (cookie-based session, не tokens).
  personal_access_tokens migration удалена (для SPA не нужна).
- AuthController (Api/): login + register + me + logout с детальной валидацией
  + кастомные русские error-messages.
- LoginRequest + RegisterRequest Form Requests. Register требует
  accept_offer:accepted + accept_pdn:accepted (по ТЗ §1.5/§4.1, БЕЗ
  маркетингового click-wrap'а - расхождение #2 handoff vs ТЗ).
- User::fillable += last_login_at, last_active_at.
- Auth-routes в web.php (НЕ api.php): Sanctum SPA нуждается в session-cookie
  middleware из web-группы (laravel.com/docs/sanctum#spa-authentication).
- cspell-words.txt: pdn, залогинен.

Pest +13 (всего 61/61 за 6.22s):
- login success + 2FA-flag + invalid pass + missing email + blocked + format
  validation + last_login_at update + register success/duplicate/без accept +
  me 401/200 + logout 200.
- Logout-test упрощён до 200+message - Pest cookie-jar держит session между
  запросами теста, full flow через browser-mode (отдельный коммит).
- phpstan-baseline: +25 ignored Pest TestCall warnings (Larastan+Pest quirk).

Регресс: pint+stan passed; vitest 129/129 за 9.59s; vite build 802ms;
story:build 21/28 за 30.39s; Pest 61/61 за 6.22s.

CLAUDE.md v1.31->v1.32, реестр Открытых_вопросов v1.40->v1.41.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 19:41:35 +03:00
Дмитрий 5560ebbdfd phase1(eloquent): Tenant/User/Project models + SetTenantContext middleware
Первый Eloquent-слой над schema v8.6 + middleware для RLS-фильтрации
HTTP-запросов. Pest 19/19 passed (1672 ms): 4 RLS smoke + 8 model
smoke + 5 middleware + 2 default.

app/app/Models/ (NEW Tenant.php, Project.php; MODIFIED User.php):

- Tenant — saas-уровневая модель (БЕЗ RLS, тенант-родитель). Soft Deletes.
  hasMany Users, Projects.
- User — переписан под нашу схему: password_hash вместо password,
  first_name/last_name вместо name, override getAuthPassword/Name для
  Laravel auth-интеграции. Soft Deletes. belongsTo Tenant.
- Project — tenant-aware с RLS. belongsTo Tenant.

app/database/factories/ (NEW TenantFactory, ProjectFactory; MODIFIED
UserFactory):

- TenantFactory: уникальный subdomain через Str::random + дефолты
  (timezone Europe/Moscow, locale ru, is_trial true, api_key_limit 5).
- UserFactory: tenant_id через Tenant::factory() chain, email unique
  через faker, password_hash через Hash::make.
- ProjectFactory: tenant_id через factory chain, дефолты под schema.sql
  (region_mask 255, delivery_days_mask 127, assignment_strategy manual).

app/app/Http/Middleware/SetTenantContext.php (NEW, alias `tenant`):

- Резолюция tenant_id (приоритет): auth()->user() → subdomain (3+ parts
  HTTP_HOST) → X-Tenant-Id header (только dev/testing).
- Без контекста → 403 Forbidden с явным сообщением.
- SET LOCAL app.current_tenant_id внутри транзакции (DB::beginTransaction
  + SET LOCAL + next() + commit/rollback). PgBouncer-safe (Прил. И Г.1
  кейс 2).
- Зарегистрирован в bootstrap/app.php через $middleware->alias().

app/tests/Feature/ (NEW TenantModelsTest, SetTenantContextTest):

- TenantModelsTest (8 тестов): factories + связи (Tenant→users/projects,
  User→tenant, Project→tenant) + проверка User::getAuthPassword override.
- SetTenantContextTest (5 тестов): 403 без контекста, X-Tenant-Id header,
  игнор не-числового header, subdomain резолюция через absolute URL,
  middleware устанавливает app.current_tenant_id для last query.

Сопутствующие правки:

- app/.gitignore: + _ide_helper_models.php (сгенерированный, как и
  _ide_helper.php — не в репо)
- app/phpstan-baseline.neon: regenerated — Pest dynamic methods
  ($this->get(), withHeaders()) и factory-return-type mismatch (Larastan
  v3 не понимает array<string, mixed> vs array<model property of T>) +
  Request::user/header (Larastan тип hint мисс) + console.php $this в
  Closure — все в baseline до миграции на typed properties / pest extension
- CLAUDE.md §6: Pest 6/6 → 19/19, добавлены модели + middleware
- memory project_state.md, MEMORY.md: обновлены под новый этап

Не сделано в этой сессии (отложено):

- Deal model — composite primary key (id, received_at) + partitioned
  parent. Эта модель сложнее по архитектуре Eloquent.
- ide-helper:models -W -M -N запускался — добавил @mixin IdeHelperX
  и сгенерил _ide_helper_models.php; но т.к. этот файл gitignored,
  @mixin строки удалены из моделей (PHPStan не нашёл бы класс на CI).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 14:29:50 +03:00
Дмитрий 4d38f75826 phase1(scaffold): Laravel 11 + predis + .env под PG 16 + Memurai
Триггер фазы 1 запущен 08.05.2026 (вечер):
composer create-project laravel/laravel app

Стек подтверждён native (без Docker/WSL2/Sail):
- PostgreSQL 16.13 (Chocolatey, Windows-сервис, port 5432)
- Memurai Developer 4.1.8 (Redis 7-совм., port 6379) — TCP +PONG OK
- PHP 8.3.31 + 11/11 Laravel-required ext (pdo_pgsql, mbstring,
  openssl, tokenizer, xml, ctype, json, bcmath, fileinfo, curl, pgsql)
- Composer 2.9.7

Что в коммите (59 файлов, 11059 строк скаффолда Laravel 11 +
правки):
- composer require predis/predis (v3.4.2) — PHP-only Redis-клиент,
  т.к. php_redis ext не установлен (см. project_phase1_strategy.md)
- app/.env (gitignored) — APP_NAME=Liderra, APP_LOCALE=ru,
  APP_TIMEZONE=Europe/Moscow, DB_CONNECTION=pgsql → liderra@localhost,
  REDIS_CLIENT=predis
- app/.env.example — те же правки без секретов (для команды)

Smoke-test PG ↔ Laravel ↔ pdo_pgsql прошёл:
3/3 default-миграций → 9 таблиц в liderra (cache, cache_locks,
failed_jobs, job_batches, jobs, migrations, password_reset_tokens,
sessions, users).

Артефакт стартера app/database/database.sqlite (0 B) удалён —
sqlite не используется.

Что НЕ в этом коммите (следующие шаги фазы 1):
- Pest 3 swap (CTO-12) — composer remove phpunit + require pest
- Laravel Boost MCP + 9 guidelines disable по CLAUDE.md §5/§7
- Pint, Larastan, Roave/SecurityAdvisories, IDE Helper, squawk,
  pgFormatter (Прил. Н #11–18)
- resources/boost/guidelines/vuetify.blade.php

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 09:37:16 +03:00