144d4cbb98
Schema delta (1 правка в db/schema.sql):
- projects + archived_at TIMESTAMPTZ NULL — soft archive flow (отличие от
is_active=false который = pause).
Метрики: 62 базовых таблицы / 117 индексов / 39 RLS (без изменений).
Сопутствующие правки:
- db/CHANGELOG_schema.md — v8.20 entry.
- app/Models/Project — fillable+casts: archived_at datetime + scopeActive +
scopeArchived (whereNull/whereNotNull archived_at).
- Migration guard: Schema::hasColumn() проверка перед ALTER TABLE — предотвращает
"duplicate column" после migrate:fresh (schema.sql v8.20 уже содержит колонку).
Tests:
- ArchivedAtTest.php — 2 it() блоков: archived_at колонка timestamptz + fillable/casts.
- pest --filter=ArchivedAtTest: 2/2 PASS (4 assertions, 485 ms).
- Full suite: 689/686+3 skipped/0 failed (2094 assertions, 84638 ms).
Quirk зафиксирован: Schema::getColumnType('projects', 'archived_at') → 'timestamptz'
(не 'timestamp') — PostgreSQL TIMESTAMPTZ → Doctrine/Laravel native type string.
План spec ожидал 'timestamp', скорректировано в тесте с комментарием.
Spec: docs/superpowers/specs/2026-05-10-claude-brain-extraction-design.md (Plan 5).
Plan: docs/superpowers/plans/2026-05-10-claude-brain-extraction.md Task 1.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
26 lines
1.0 KiB
PHP
26 lines
1.0 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use App\Models\Project;
|
|
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
|
use Illuminate\Support\Facades\Schema;
|
|
|
|
// NOTE: \Tests\TestCase auto-binds via tests/Pest.php (->in('Feature')); explicit
|
|
// uses(\Tests\TestCase::class) conflicts ("already uses the test case").
|
|
// DatabaseTransactions — изоляция; also ensures DB connection is bootstrapped.
|
|
uses(DatabaseTransactions::class);
|
|
|
|
it('projects table has archived_at column nullable timestamp', function () {
|
|
expect(Schema::hasColumn('projects', 'archived_at'))->toBeTrue();
|
|
$type = Schema::getColumnType('projects', 'archived_at');
|
|
// PostgreSQL TIMESTAMPTZ → Doctrine/Laravel reports 'timestamptz' (not 'timestamp').
|
|
expect($type)->toBe('timestamptz');
|
|
});
|
|
|
|
it('Project model has archived_at in fillable and casts it to datetime', function () {
|
|
$project = new Project;
|
|
expect(in_array('archived_at', $project->getFillable(), true))->toBeTrue();
|
|
expect($project->getCasts()['archived_at'] ?? null)->toBe('datetime');
|
|
});
|