Files
portal/app/database/seeders/DatabaseSeeder.php
T
Дмитрий a907fea031 feat(db): Plan 4 Task 1 — schema delta v8.18 → v8.19 + models/seeder
Schema delta (4 правки в db/schema.sql):
- tenants + delivered_in_month INT NOT NULL DEFAULT 0 CHECK (>=0) — month
  counter для PricingTierResolver O(1) lookup на горячем пути.
- lead_charges + charge_source VARCHAR(8) DEFAULT 'rub' CHECK IN ('prepaid','rub')
  + ALTER ADD CONSTRAINT chk_lead_charges_prepaid_zero_price (prepaid → price=0).
- supplier_leads + recovered_from_csv_at TIMESTAMPTZ + partial index
  WHERE recovered_from_csv_at IS NOT NULL.
- Новая таблица supplier_csv_reconcile_log (SaaS-level, без RLS) + 2 индекса
  (started_at DESC, partial status WHERE status IN ('drift_alert','failed')).

Метрики: 61 → 62 базовых таблиц / 114 → 117 индексов / 39 RLS (без изменений).

Сопутствующие правки:
- db/CHANGELOG_schema.md — v8.19 entry (18 записей).
- db/02_grants.sql — GRANT SELECT,INSERT,UPDATE on supplier_csv_reconcile_log
  + GRANT USAGE,SELECT on sequence для crm_supplier_worker.
- app/Models/Tenant — fillable+casts: delivered_in_month integer.
- app/Models/LeadCharge — fillable+casts: charge_source string.
- app/Models/SupplierLead — fillable+casts: recovered_from_csv_at datetime.
- LeadChargeFactory — defaults charge_source='rub' + prepaid() state.
- PricingTierSeeder (новый) — 7 ступеней дефолтного тарифа (placeholder,
  Plan 4 Открытый вопрос #1: 100/200/400/800/1500/3000/∞ leads at
  50000/45000/40000/35000/30000/27000/25000 копеек).
- DatabaseSeeder — call PricingTierSeeder; убран broken Laravel scaffold
  User::factory(['name' => ...]) (наша схема first_name/last_name).

Tests (Plan 4 surface):
- SchemaDeltaTest.php — 5 it() блоков: delivered_in_month CHECK, charge_source
  CHECK на prepaid+zero-price, recovered_from_csv_at колонка, reconcile_log
  таблица+status CHECK, migrate:fresh idempotency (skip in parallel).
- pest --filter=SchemaDeltaTest: 5/5 PASS (9 assertions, 2076 ms).
- pest --filter='Tenant|LeadCharge|SupplierLead|Plan4': 111/111 PASS.

CI gates:
- composer pint: passed.
- composer stan: passed (0 errors above baseline — @phpstan-ignore-next-line
  на $this->markTestSkipped в Pest closure rebound context).

Verify:
- migrate:fresh --seed на DB_DATABASE=liderra_testing: 0 errors, 754 ms.
- PricingTier::count() = 7.

Концерны (НЕ блокируют Task 1):
- pest --parallel: 617/622 PASS + 4 skipped + 1 flaky FAIL — flaky test
  колеблется между ProjectExtensionsTest::supplierB1_B2_B3_relations
  (SupplierProjectFactory race: closure пикает signal_type=sms до override
  platform=B1 → CHECK chk_supplier_projects_b1_not_for_sms violation)
  и NewLeadNotificationTest::webhook_дубль_Биз_19 (известный microsecond
  precision quirk в anti-spam exclusion, memory feedback_environment.md).
  Оба теста существуют на main (HEAD 0802f7c = plan4-billing branch HEAD
  до этого commit'а), Plan 4 их не трогает. Фиксы — вне Task 1 scope.

Spec: docs/superpowers/specs/2026-05-11-plan4-billing-csv-admin-design.md §2.
Plan: docs/superpowers/plans/2026-05-11-plan4-billing-csv-admin-plan.md Task 1.

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

25 lines
732 B
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
namespace Database\Seeders;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
use WithoutModelEvents;
/**
* Seed the application's database.
*
* Note: the Laravel scaffold default User::factory() seed was removed —
* наша схема использует first_name/last_name (а не "name"), и заранее
* не было сценария, где этот seed реально вызывался. PricingTierSeeder
* (Plan 4) — единственный текущий seed для dev/testing.
*/
public function run(): void
{
$this->call(PricingTierSeeder::class);
}
}