Add notification system with Rsx_Throttle utility

Add action log feature, fix Bootstrap variables and DataGrid styling

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
root
2026-01-29 17:44:31 +00:00
parent b8a454bca0
commit f48cda006a
21 changed files with 444 additions and 121 deletions

View File

@@ -381,6 +381,21 @@
"created_at": "2026-01-12T07:36:24+00:00",
"created_by": "root",
"command": "php artisan make:migration:safe add_timezone_to_sites_table"
},
"2026_01_29_070242_create_action_logs_tables.php": {
"created_at": "2026-01-29T07:02:42+00:00",
"created_by": "root",
"command": "php artisan make:migration:safe create_action_logs_tables"
},
"2026_01_29_081808_create_throttle_table.php": {
"created_at": "2026-01-29T08:18:08+00:00",
"created_by": "root",
"command": "php artisan make:migration:safe create_throttle_table"
},
"2026_01_29_081902_create_notifications_table.php": {
"created_at": "2026-01-29T08:19:02+00:00",
"created_by": "root",
"command": "php artisan make:migration:safe create_notifications_table"
}
}
}

View File

@@ -0,0 +1,66 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;
return new class extends Migration
{
/**
* Run the migrations.
*
* IMPORTANT: Use raw MySQL queries for clarity and auditability
* DB::statement() with raw SQL
* Schema::create() with Blueprint
*
* REQUIRED: ALL tables MUST have: id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY
* No exceptions - every table needs this exact ID column (SIGNED for easier migrations)
*
* Integer types: Use BIGINT for all integers, TINYINT(1) for booleans only
* Never use unsigned - all integers should be signed
*
* Migrations must be self-contained - no Model/Service references
*
* @return void
*/
public function up()
{
// Main action log table
DB::statement("
CREATE TABLE action_logs (
id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
site_id BIGINT NOT NULL,
type_id BIGINT NOT NULL,
actor_type BIGINT NULL,
actor_id BIGINT NULL,
subject_type BIGINT NOT NULL,
subject_id BIGINT NOT NULL,
metadata JSON NULL,
created_by BIGINT NULL,
created_at TIMESTAMP(3) NULL DEFAULT CURRENT_TIMESTAMP(3),
updated_at TIMESTAMP(3) NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
updated_by BIGINT NULL,
INDEX idx_action_logs_site_id (site_id),
INDEX idx_action_logs_type_id (type_id),
INDEX idx_action_logs_actor (actor_type, actor_id),
INDEX idx_action_logs_subject (subject_type, subject_id),
INDEX idx_action_logs_created_at (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
");
// Related entities table (one-to-many from action_logs)
DB::statement("
CREATE TABLE action_log_related (
id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
action_log_id BIGINT NOT NULL,
role_id BIGINT NOT NULL,
related_type BIGINT NOT NULL,
related_id BIGINT NOT NULL,
INDEX idx_alr_action_log_id (action_log_id),
INDEX idx_alr_related (related_type, related_id),
FOREIGN KEY (action_log_id) REFERENCES action_logs(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
");
}
};

View File

@@ -0,0 +1,42 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;
return new class extends Migration
{
/**
* Run the migrations.
*
* IMPORTANT: Use raw MySQL queries for clarity and auditability
* DB::statement() with raw SQL
* Schema::create() with Blueprint
*
* REQUIRED: ALL tables MUST have: id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY
* No exceptions - every table needs this exact ID column (SIGNED for easier migrations)
*
* Integer types: Use BIGINT for all integers, TINYINT(1) for booleans only
* Never use unsigned - all integers should be signed
*
* Migrations must be self-contained - no Model/Service references
*
* @return void
*/
public function up()
{
DB::statement("
CREATE TABLE _throttle (
id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
site_id BIGINT NOT NULL,
user_id BIGINT NOT NULL,
action_key VARCHAR(255) NOT NULL,
last_executed_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
created_at TIMESTAMP(3) NULL DEFAULT CURRENT_TIMESTAMP(3),
updated_at TIMESTAMP(3) NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
UNIQUE KEY uk_throttle_site_user_action (site_id, user_id, action_key),
INDEX idx_throttle_last_executed (last_executed_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
");
}
};

View File

@@ -0,0 +1,52 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;
return new class extends Migration
{
/**
* Run the migrations.
*
* IMPORTANT: Use raw MySQL queries for clarity and auditability
* DB::statement() with raw SQL
* Schema::create() with Blueprint
*
* REQUIRED: ALL tables MUST have: id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY
* No exceptions - every table needs this exact ID column (SIGNED for easier migrations)
*
* Integer types: Use BIGINT for all integers, TINYINT(1) for booleans only
* Never use unsigned - all integers should be signed
*
* Migrations must be self-contained - no Model/Service references
*
* @return void
*/
public function up()
{
DB::statement("
CREATE TABLE notifications (
id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
site_id BIGINT NOT NULL,
user_id BIGINT NOT NULL,
type_id BIGINT NOT NULL,
entity_type BIGINT NULL,
entity_id BIGINT NULL,
metadata JSON NULL,
read_at TIMESTAMP(3) NULL,
expires_at TIMESTAMP(3) NOT NULL,
created_by BIGINT NULL,
created_at TIMESTAMP(3) NULL DEFAULT CURRENT_TIMESTAMP(3),
updated_at TIMESTAMP(3) NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
updated_by BIGINT NULL,
INDEX idx_notifications_site_user (site_id, user_id),
INDEX idx_notifications_user_unread (site_id, user_id, read_at),
INDEX idx_notifications_entity (entity_type, entity_id),
INDEX idx_notifications_expires (expires_at),
INDEX idx_notifications_type (type_id),
INDEX idx_notifications_created (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
");
}
};