feat(billing-v2): add BalanceTransaction::TYPE_MIGRATION + extend CHECK

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Дмитрий
2026-05-23 12:29:55 +03:00
parent 53f61dda19
commit 8e05486083
5 changed files with 95 additions and 4 deletions
+2
View File
@@ -40,6 +40,8 @@ class BalanceTransaction extends Model
public const TYPE_CHARGEBACK_REPAYMENT = 'chargeback_repayment';
public const TYPE_MIGRATION = 'migration';
public $timestamps = false;
protected $fillable = [
@@ -0,0 +1,40 @@
<?php
declare(strict_types=1);
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;
return new class extends Migration
{
public function up(): void
{
DB::statement(
'ALTER TABLE balance_transactions DROP CONSTRAINT IF EXISTS balance_transactions_type_check'
);
DB::statement(
'ALTER TABLE balance_transactions ADD CONSTRAINT balance_transactions_type_check '.
'CHECK (type IN ('.
"'trial_bonus','topup','lead_charge','refund',".
"'manual_adjustment','historical_import',".
"'chargeback_writedown','chargeback_repayment',".
"'migration'".
'))'
);
}
public function down(): void
{
DB::statement(
'ALTER TABLE balance_transactions DROP CONSTRAINT IF EXISTS balance_transactions_type_check'
);
DB::statement(
'ALTER TABLE balance_transactions ADD CONSTRAINT balance_transactions_type_check '.
'CHECK (type IN ('.
"'trial_bonus','topup','lead_charge','refund',".
"'manual_adjustment','historical_import',".
"'chargeback_writedown','chargeback_repayment'".
'))'
);
}
};
@@ -0,0 +1,31 @@
<?php
declare(strict_types=1);
use App\Models\BalanceTransaction;
use App\Models\Tenant;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Tests\TestCase;
uses(TestCase::class, DatabaseTransactions::class);
it('accepts type=migration after CHECK constraint extension', function () {
/** @var Tenant $tenant */
$tenant = Tenant::factory()->create(['balance_rub' => '1000.00']);
$tx = BalanceTransaction::create([
'tenant_id' => $tenant->id,
'type' => BalanceTransaction::TYPE_MIGRATION,
'amount_leads' => -5,
'amount_rub' => '600.00',
'balance_leads_after' => 0,
'balance_rub_after' => '1600.00',
'description' => 'test migration',
]);
expect($tx->type)->toBe('migration');
});
it('exposes TYPE_MIGRATION constant', function () {
expect(BalanceTransaction::TYPE_MIGRATION)->toBe('migration');
});
+18 -2
View File
@@ -1,11 +1,27 @@
# CHANGELOG schema.sql — Лидерра
**Назначение:** консолидированный журнал изменений `schema.sql`. Содержит двадцать восемь записей в обратном хронологическом порядке (v8.31 → v8.30 → v8.29 → v8.28 → v8.27 → v8.26 → v8.25 → v8.24 → v8.23 → v8.22 → v8.21 → v8.20 → v8.19 → v8.18 → v8.17 → v8.16 → v8.15 → v8.14 → v8.13 → v8.12 → v8.11 → v8.10 → v8.9 → v8.8 → v8.7 → v8.6 → v8.5 → v8.4 → v8.3 → v8.2), как принято в keep-a-changelog.
**Назначение:** консолидированный журнал изменений `schema.sql`. Содержит двадцать девять записей в обратном хронологическом порядке (v8.32 → v8.31 → v8.30 → v8.29 → v8.28 → v8.27 → v8.26 → v8.25 → v8.24 → v8.23 → v8.22 → v8.21 → v8.20 → v8.19 → v8.18 → v8.17 → v8.16 → v8.15 → v8.14 → v8.13 → v8.12 → v8.11 → v8.10 → v8.9 → v8.8 → v8.7 → v8.6 → v8.5 → v8.4 → v8.3 → v8.2), как принято в keep-a-changelog.
**Файл схемы:** `schema.sql` (текущая версия — v8.31, консолидированная — разворачивает БД с нуля).
**Файл схемы:** `schema.sql` (текущая версия — v8.32, консолидированная — разворачивает БД с нуля).
**История записей:**
## v8.32 — 2026-05-23 — balance_transactions.type +'migration'
Расширение CHECK-ограничения `balance_transactions_type_check` девятым значением `'migration'`
— технический тип для одноразовой Billing v2 Spec A конвертации legacy `tenants.balance_leads`
в `tenants.balance_rub` по цене ступени 1 (artisan-команда `billing:migrate-leads-to-rub`).
Без `down()` потери данных: миграция переоткрывает CHECK с тем же набором, минус `'migration'`.
Совместимо с партиционированием `balance_transactions` (v8.31): ADD/DROP CONSTRAINT на
partitioned parent распространяется на партиции.
**Применение:**
- Миграция: `2026_05_23_100001_extend_balance_transactions_type_for_migration`
- Константа: `App\Models\BalanceTransaction::TYPE_MIGRATION`
- План: `docs/superpowers/plans/2026-05-23-billing-v2-spec-a-balance-rub-plan.md` (Task A.1)
- Спек: `docs/superpowers/specs/2026-05-23-billing-v2-spec-a-balance-rub-design.md` §3.2.3
## v8.31 — 2026-05-23 — партиционирование 7 audit-таблиц (hole #2)
Закрывает дыру #2 аудита журналирования: все 7 audit-таблиц переведены на
+4 -2
View File
@@ -1,6 +1,7 @@
-- =============================================================================
-- schema.sql — единая схема БД для SaaS-аналога crm.bp-gr.ru («Лидерра»)
-- Версия: v8.31 (23.05.2026 — партиционирование 7 audit-таблиц помесячно (hole #2): auth_log / activity_log / tenant_operations_log / webhook_log / balance_transactions / pd_processing_log / saas_admin_audit_log; PK → (id, created_at|received_at); FK на webhook_log удалены (W1); retention defaults в system_settings)
-- Версия: v8.32 (23.05.2026 — balance_transactions.type +'migration' для Billing v2 Spec A конвертации balance_leads → balance_rub)
-- Базовая версия: v8.31 (23.05.2026 — партиционирование 7 audit-таблиц помесячно (hole #2): auth_log / activity_log / tenant_operations_log / webhook_log / balance_transactions / pd_processing_log / saas_admin_audit_log; PK → (id, created_at|received_at); FK на webhook_log удалены (W1); retention defaults в system_settings)
-- Базовая версия: v8.30 (23.05.2026 — scheduler_heartbeats: пульс планировщика, SaaS-level без RLS, 11 cron-задач, hole #6)
-- Базовая версия: v8.29 (22.05.2026 — webhook_log: supplier audit columns)
-- Базовая версия: v8.28 (22.05.2026 — tenant_operations_log: журнал тенант-уровневых операций вне сделок (проекты, API-ключи, webhook URL), append-only hash-chain, P2 operational journaling closure)
@@ -2333,7 +2334,8 @@ CREATE TABLE balance_transactions (
CHECK (type IN ('trial_bonus','topup','lead_charge','refund',
'manual_adjustment','historical_import',
'chargeback_writedown', -- Ю-3: списание непокрытой части chargeback в долг тенанта
'chargeback_repayment' -- Ю-3: погашение долга через /billing
'chargeback_repayment', -- Ю-3: погашение долга через /billing
'migration' -- Billing v2 Spec A: конвертация balance_leads → balance_rub
)),
amount_rub DECIMAL(12,2) DEFAULT 0,
amount_leads INT DEFAULT 0,