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:
@@ -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 = [
|
||||
|
||||
+40
@@ -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
@@ -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
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user