updates to UI and add archiving option

This commit is contained in:
Simon Pocrnjič
2025-10-05 19:45:49 +02:00
parent fe91c7e4bc
commit bab9d6561f
50 changed files with 3337 additions and 416 deletions
@@ -0,0 +1,61 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('archive_settings', function (Blueprint $table): void {
$table->id();
// Contextual foreign keys (nullable allows broader global rules)
$table->foreignId('action_id')->nullable()->constrained()->nullOnDelete();
$table->foreignId('decision_id')->nullable()->constrained()->nullOnDelete();
$table->foreignId('segment_id')->nullable()->constrained()->nullOnDelete();
// JSON describing entities (tables/models) impacted
// Example shape: [{"table":"documents","conditions":{"older_than_days":180},"columns":["id","deleted_at"]}]
$table->json('entities');
// Optional descriptive metadata
$table->string('name')->nullable();
$table->text('description')->nullable();
$table->boolean('enabled')->default(true);
// Execution strategy: immediate | scheduled | queued
$table->string('strategy')->default('immediate');
// Whether to perform a soft archive (flag / soft delete) instead of permanent removal
$table->boolean('soft')->default(true);
// Additional arbitrary options (thresholds, flags, custom logic parameters)
$table->json('options')->nullable();
// Auditing foreign keys for who created / last updated the rule
$table->foreignId('created_by')->nullable()->constrained('users')->nullOnDelete();
$table->foreignId('updated_by')->nullable()->constrained('users')->nullOnDelete();
$table->timestamps();
$table->softDeletes();
// Useful indexes
$table->index(['action_id', 'decision_id', 'segment_id']);
$table->index('enabled');
$table->index('strategy');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('archive_settings');
}
};
@@ -0,0 +1,33 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('archive_entities', function (Blueprint $table): void {
$table->id();
$table->string('focus')->unique(); // e.g. contracts, client_cases
$table->json('related'); // JSON array of related table names
$table->string('name')->nullable();
$table->text('description')->nullable();
$table->boolean('enabled')->default(true);
$table->timestamps();
$table->index('enabled');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('archive_entities');
}
};
@@ -0,0 +1,63 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
// Add active column to bookings if missing
if (Schema::hasTable('bookings') && ! Schema::hasColumn('bookings', 'active')) {
Schema::table('bookings', function (Blueprint $table): void {
$table->unsignedTinyInteger('active')->default(1)->after('description');
$table->index('active');
});
}
// Add active column to activities if missing
if (Schema::hasTable('activities') && ! Schema::hasColumn('activities', 'active')) {
Schema::table('activities', function (Blueprint $table): void {
$table->unsignedTinyInteger('active')->default(1)->after('note');
$table->index('active');
});
}
// Add active column to documents if missing
if (Schema::hasTable('documents') && ! Schema::hasColumn('documents', 'active')) {
Schema::table('documents', function (Blueprint $table): void {
$table->unsignedTinyInteger('active')->default(1)->after('is_public');
$table->index('active');
});
}
}
/**
* Reverse the migrations.
*/
public function down(): void
{
if (Schema::hasTable('bookings') && Schema::hasColumn('bookings', 'active')) {
Schema::table('bookings', function (Blueprint $table): void {
$table->dropIndex(['active']);
$table->dropColumn('active');
});
}
if (Schema::hasTable('activities') && Schema::hasColumn('activities', 'active')) {
Schema::table('activities', function (Blueprint $table): void {
$table->dropIndex(['active']);
$table->dropColumn('active');
});
}
if (Schema::hasTable('documents') && Schema::hasColumn('documents', 'active')) {
Schema::table('documents', function (Blueprint $table): void {
$table->dropIndex(['active']);
$table->dropColumn('active');
});
}
}
};
@@ -0,0 +1,28 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
if (Schema::hasTable('payments') && ! Schema::hasColumn('payments', 'active')) {
Schema::table('payments', function (Blueprint $table): void {
$table->unsignedTinyInteger('active')->default(1)->after('type_id');
$table->index('active');
});
}
}
public function down(): void
{
if (Schema::hasTable('payments') && Schema::hasColumn('payments', 'active')) {
Schema::table('payments', function (Blueprint $table): void {
$table->dropIndex(['active']);
$table->dropColumn('active');
});
}
}
};
@@ -0,0 +1,31 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('archive_runs', function (Blueprint $table): void {
$table->id();
$table->foreignId('archive_setting_id')->constrained()->cascadeOnDelete();
$table->foreignId('user_id')->nullable()->constrained()->nullOnDelete();
$table->string('status', 30)->default('running'); // running|success|error
$table->json('counts')->nullable(); // per-table affected counts
$table->json('context')->nullable(); // manual context scope
$table->timestamp('started_at')->nullable();
$table->timestamp('finished_at')->nullable();
$table->unsignedInteger('duration_ms')->nullable();
$table->text('message')->nullable();
$table->timestamps();
$table->index(['archive_setting_id', 'status']);
});
}
public function down(): void
{
Schema::dropIfExists('archive_runs');
}
};
@@ -0,0 +1,28 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
if (Schema::hasTable('archive_settings') && ! Schema::hasColumn('archive_settings', 'reactivate')) {
Schema::table('archive_settings', function (Blueprint $table): void {
$table->boolean('reactivate')->default(false)->after('soft');
$table->index('reactivate');
});
}
}
public function down(): void
{
if (Schema::hasTable('archive_settings') && Schema::hasColumn('archive_settings', 'reactivate')) {
Schema::table('archive_settings', function (Blueprint $table): void {
$table->dropIndex(['reactivate']);
$table->dropColumn('reactivate');
});
}
}
};
@@ -0,0 +1,36 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::table('import_templates', function (Blueprint $table) {
if (! Schema::hasColumn('import_templates', 'reactivate')) {
$table->boolean('reactivate')->default(false)->after('is_active');
}
});
Schema::table('imports', function (Blueprint $table) {
if (! Schema::hasColumn('imports', 'reactivate')) {
$table->boolean('reactivate')->default(false)->after('status');
}
});
}
public function down(): void
{
Schema::table('import_templates', function (Blueprint $table) {
if (Schema::hasColumn('import_templates', 'reactivate')) {
$table->dropColumn('reactivate');
}
});
Schema::table('imports', function (Blueprint $table) {
if (Schema::hasColumn('imports', 'reactivate')) {
$table->dropColumn('reactivate');
}
});
}
};
@@ -0,0 +1,35 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::table('accounts', function (Blueprint $table) {
// Drop existing unique index if present (contract_id, reference, deleted_at)
try {
$table->dropUnique('accounts_reference_unique');
} catch (\Throwable $e) {
// ignore if it does not exist
}
// Recreate including active flag so archived/inactive accounts can reuse reference
$table->unique(['contract_id', 'reference', 'active', 'deleted_at'], 'accounts_reference_unique');
});
}
public function down(): void
{
Schema::table('accounts', function (Blueprint $table) {
try {
$table->dropUnique('accounts_reference_unique');
} catch (\Throwable $e) {
// ignore
}
// Restore previous definition without active
$table->unique(['contract_id', 'reference', 'deleted_at'], 'accounts_reference_unique');
});
}
};