Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
26 / 26
100.00% covered (success)
100.00%
3 / 3
CRAP
100.00% covered (success)
100.00%
1 / 1
CurrentUserView
100.00% covered (success)
100.00%
26 / 26
100.00% covered (success)
100.00%
3 / 3
3
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 fromUser
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
1 / 1
1
 toArray
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3declare(strict_types=1);
4
5namespace App\Identity\Application\Query;
6
7use App\Identity\Domain\User;
8
9/**
10 * Safe read model for the authenticated user. Never carries the password hash.
11 */
12final class CurrentUserView
13{
14    public function __construct(
15        public readonly string $id,
16        public readonly string $email,
17        public readonly string $preferredCurrency,
18        public readonly string $name,
19        public readonly string $surnames,
20        public readonly ?string $birthDate,
21        public readonly ?int $age,
22        // Lets the SPA gate its admin nav/guard off /users/me, which it already loads,
23        // instead of decoding the JWT. Cosmetic only — the API is the real gate.
24        public readonly bool $isAdmin = false,
25        // Short-lived signed URL, minted by the handler: the view never touches
26        // the stored file name, the same way it never carries the hash.
27        public readonly ?string $avatarUrl = null,
28        // False for a provider-only account: without it the profile kebab would
29        // offer a "change password" action that can never succeed.
30        public readonly bool $hasPassword = true,
31    ) {
32    }
33
34    public static function fromUser(User $user, ?string $avatarUrl = null): self
35    {
36        $birthDate = $user->birthDate();
37
38        return new self(
39            $user->id()->value(),
40            $user->email()->value(),
41            $user->preferredCurrency()->code(),
42            $user->name(),
43            $user->surnames(),
44            $birthDate?->value(),
45            $birthDate?->age(),
46            $user->isAdmin(),
47            $avatarUrl,
48            $user->hasPassword(),
49        );
50    }
51
52    /**
53     * @return array<string, string|int|bool|null>
54     */
55    public function toArray(): array
56    {
57        return [
58            'id' => $this->id,
59            'email' => $this->email,
60            'preferredCurrency' => $this->preferredCurrency,
61            'name' => $this->name,
62            'surnames' => $this->surnames,
63            'birthDate' => $this->birthDate,
64            'age' => $this->age,
65            'isAdmin' => $this->isAdmin,
66            'avatarUrl' => $this->avatarUrl,
67            'hasPassword' => $this->hasPassword,
68        ];
69    }
70}