diff --git a/app/Mod/Names/Actions/SubmitClaim.php b/app/Mod/Names/Actions/SubmitClaim.php index 77a89d9..4a611e3 100644 --- a/app/Mod/Names/Actions/SubmitClaim.php +++ b/app/Mod/Names/Actions/SubmitClaim.php @@ -6,6 +6,7 @@ namespace Mod\Names\Actions; use Illuminate\Validation\ValidationException; use Mod\Chain\Services\DaemonRpc; +use Mod\Names\Models\NameActivity; use Mod\Names\Models\NameClaim; /** @@ -27,10 +28,17 @@ class SubmitClaim $this->validate($name, $email); - return NameClaim::create([ + $claim = NameClaim::create([ 'name' => $name, 'email' => $email, ]); + + NameActivity::log($name, 'claimed', [ + 'claim_id' => $claim->claim_id, + 'email' => $email, + ], request()?->ip()); + + return $claim; } private function validate(string $name, string $email): void diff --git a/app/Mod/Names/Migrations/2026_04_04_create_name_activity_table.php b/app/Mod/Names/Migrations/2026_04_04_create_name_activity_table.php new file mode 100644 index 0000000..5f6d105 --- /dev/null +++ b/app/Mod/Names/Migrations/2026_04_04_create_name_activity_table.php @@ -0,0 +1,25 @@ +id(); + $table->string('name')->index(); + $table->string('event', 50)->index(); + $table->json('properties')->nullable(); + $table->string('ip_hash', 64)->nullable(); + $table->timestamp('created_at')->useCurrent(); + }); + } + + public function down(): void + { + Schema::dropIfExists('name_activity'); + } +}; diff --git a/app/Mod/Names/Models/NameActivity.php b/app/Mod/Names/Models/NameActivity.php new file mode 100644 index 0000000..6b3ff83 --- /dev/null +++ b/app/Mod/Names/Models/NameActivity.php @@ -0,0 +1,55 @@ + '...']); + * NameActivity::log('mybrand', 'dns_updated', ['records' => [...]]); + * $recent = NameActivity::forName('mybrand')->latest()->get(); + */ +class NameActivity extends Model +{ + public $timestamps = false; + + protected $table = 'name_activity'; + + protected $fillable = [ + 'name', + 'event', + 'properties', + 'ip_hash', + 'created_at', + ]; + + protected $casts = [ + 'properties' => 'array', + 'created_at' => 'datetime', + ]; + + public function scopeForName($query, string $name) + { + return $query->where('name', $name); + } + + /** + * Log a name activity event. + * + * NameActivity::log('mybrand', 'claimed', ['email' => 'me@example.com']); + */ + public static function log(string $name, string $event, array $properties = [], ?string $ip = null): self + { + return static::create([ + 'name' => $name, + 'event' => $event, + 'properties' => $properties, + 'ip_hash' => $ip ? hash('sha256', $ip) : null, + 'created_at' => now(), + ]); + } +}