initial commit

This commit is contained in:
2026-02-11 23:37:50 +01:00
commit 908cf42ad9
128 changed files with 17831 additions and 0 deletions

View File

@@ -0,0 +1,37 @@
<?php
declare(strict_types=1);
namespace App\Data\Api;
final class ContactImport
{
public function __construct(
public readonly string $id,
public readonly string $queueAt,
public readonly ?string $startedAt,
public readonly ?string $finishedAt,
public readonly int $totalProcessed,
public readonly int $errors,
public readonly int $duplicates,
public readonly string $state,
) {
}
/**
* @return array<string, mixed>
*/
public function toArray(): array
{
return [
'id' => $this->id,
'queue_at' => $this->queueAt,
'started_at' => $this->startedAt,
'finished_at' => $this->finishedAt,
'total_processed' => $this->totalProcessed,
'errors' => $this->errors,
'duplicates' => $this->duplicates,
'state' => $this->state,
];
}
}

View File

@@ -0,0 +1,15 @@
<?php
declare(strict_types=1);
namespace App\Data\Command;
class BatchResult
{
public function __construct(
public readonly int $fails,
public readonly int $duplicates,
public readonly int $success,
) {
}
}

38
app/Data/Contact.php Normal file
View File

@@ -0,0 +1,38 @@
<?php
declare(strict_types=1);
namespace App\Data;
use Illuminate\Support\Facades\Validator;
use Ramsey\Uuid\UuidInterface;
final readonly class Contact
{
public string $email;
public function __construct(
public UuidInterface $uuid,
string $email,
public ?string $firstName,
public ?string $lastName,
) {
$this->email = strtolower($email);
$validator = Validator::make(['email' => $this->email], [
'email' => ['required', 'email:rfc', 'max:254'],
]);
if ($this->firstName !== null && strlen($this->firstName) > 100) {
throw new InvariantException('First name cannot be longer than 100 characters', ['first_name']);
}
if ($this->lastName !== null && strlen($this->lastName) > 100) {
throw new InvariantException('Last name cannot be longer than 100 characters', ['last_name']);
}
if ($validator->fails()) {
throw new InvariantException($validator->errors()->first('email'), ['email']);
}
}
}

View File

@@ -0,0 +1,23 @@
<?php
declare(strict_types=1);
namespace App\Data;
use Carbon\Carbon;
class ContactImport
{
public function __construct(
public readonly string $id,
public readonly Carbon $queueAt,
public readonly ?Carbon $startedAt,
public readonly ?Carbon $finishedAt,
public readonly int $totalProcessed,
public readonly int $errors,
public readonly int $duplicates,
public readonly string $state,
public readonly ?string $file,
) {
}
}

View File

@@ -0,0 +1,15 @@
<?php
declare(strict_types=1);
namespace App\Data\Intent\Contact;
final class CreateContactIntent
{
public function __construct(
public string $email,
public ?string $firstName,
public ?string $lastName,
) {
}
}

View File

@@ -0,0 +1,15 @@
<?php
declare(strict_types=1);
namespace App\Data\Intent\Contact;
use Ramsey\Uuid\UuidInterface;
final class DeleteContactIntent
{
public function __construct(
public UuidInterface $uuid,
) {
}
}

View File

@@ -0,0 +1,15 @@
<?php
declare(strict_types=1);
namespace App\Data\Intent\Contact\ProcessImport;
final class ImportContactIntent
{
public function __construct(
public ?string $email = null,
public ?string $firstName = null,
public ?string $lastName = null,
) {
}
}

View File

@@ -0,0 +1,27 @@
<?php
declare(strict_types=1);
namespace App\Data\Intent\Contact;
final class SearchContactIntent
{
private const QUERY_ALL = '*';
public readonly string $query;
public readonly int $resultsPerPage;
public function __construct(
string $query,
) {
$this->query = strtolower($query);
$this->resultsPerPage = 20;
}
public static function queryAll(): SearchContactIntent
{
return new SearchContactIntent(
self::QUERY_ALL
);
}
}

View File

@@ -0,0 +1,15 @@
<?php
declare(strict_types=1);
namespace App\Data\Intent\Contact;
use Ramsey\Uuid\UuidInterface;
class SearchContactIntentByUuid
{
public function __construct(
public readonly UuidInterface $uuid,
) {
}
}

View File

@@ -0,0 +1,18 @@
<?php
declare(strict_types=1);
namespace App\Data\Intent\Contact;
use Ramsey\Uuid\UuidInterface;
final class UpdateContactIntent
{
public function __construct(
public UuidInterface $uuid,
public string $email,
public ?string $firstName,
public ?string $lastName,
) {
}
}

View File

@@ -0,0 +1,13 @@
<?php
declare(strict_types=1);
namespace App\Data\Intent\ProcessImport;
class ImportContactsIntent
{
public function __construct(
public readonly string $path
) {
}
}

View File

@@ -0,0 +1,15 @@
<?php
declare(strict_types=1);
namespace App\Data\Intent\ProcessImport;
use Ramsey\Uuid\UuidInterface;
class SearchImportContactsIntent
{
public function __construct(
public readonly UuidInterface $uuid,
) {
}
}

View File

@@ -0,0 +1,18 @@
<?php
declare(strict_types=1);
namespace App\Data;
use Throwable;
class InvariantException extends \InvalidArgumentException
{
/**
* @param array<string> $fields
*/
public function __construct(string $message, public readonly array $fields, int $code = 0, ?Throwable $previous = null)
{
parent::__construct($message, $code, $previous);
}
}