lthn.io/app/Mod/Names/Actions/SubmitClaim.php
Claude 14f4d1fdc0
feat: activity logging for name operations
NameActivity model with log() static method. Stores event, name,
properties (JSON), and hashed IP (GDPR). SubmitClaim action now
logs 'claimed' event. Ready for dns_updated, registered, etc.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 11:46:31 +01:00

83 lines
2.2 KiB
PHP

<?php
declare(strict_types=1);
namespace Mod\Names\Actions;
use Illuminate\Validation\ValidationException;
use Mod\Chain\Services\DaemonRpc;
use Mod\Names\Models\NameActivity;
use Mod\Names\Models\NameClaim;
/**
* Submit a pre-registration name claim.
*
* $claim = SubmitClaim::run(['name' => 'mybrand', 'email' => 'me@example.com']);
* echo $claim->claim_id;
*/
class SubmitClaim
{
public function __construct(
private readonly DaemonRpc $rpc,
) {}
public function handle(array $data): NameClaim
{
$name = strtolower(trim($data['name'] ?? ''));
$email = trim($data['email'] ?? '');
$this->validate($name, $email);
$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
{
if (! preg_match('/^[a-z0-9][a-z0-9.\-]{0,254}$/', $name)) {
throw ValidationException::withMessages([
'name' => 'Invalid name. Use lowercase alphanumeric characters.',
]);
}
if (strlen($name) < 6) {
throw ValidationException::withMessages([
'name' => 'Name must be at least 6 characters.',
]);
}
if (empty($email) || ! filter_var($email, FILTER_VALIDATE_EMAIL)) {
throw ValidationException::withMessages([
'email' => 'Valid email required for claim notification.',
]);
}
// Not already registered on chain
if ($this->rpc->getAliasByName($name) !== null) {
throw ValidationException::withMessages([
'name' => 'Name already registered.',
]);
}
// Not already claimed
if (NameClaim::where('name', $name)->exists()) {
throw ValidationException::withMessages([
'name' => 'Name already claimed. Awaiting approval.',
]);
}
}
public static function run(array $data): NameClaim
{
return app(static::class)->handle($data);
}
}