Files
crewli/api/app/FormBuilder/Purposes/Resolvers/PostEventEvaluationSubjectResolver.php
bert.hausmans 16a9265430 feat(form-builder): add PurposeSubjectResolver per purpose (WS-6)
Parallel interface to PurposeGuardProvider for runtime subject
resolution. Seven concrete resolvers, one per v1.0 purpose. Wired
through purposes.php via subject_resolver_class key.

EventRegistration uses PersonProvisioner (may create). Other purposes
resolve from existing context (portal token, production request, auth).
IncidentReport is the only purpose allowed to return null (anonymous-
allowed configurations); the others return concrete model types
(narrowed via PHP covariance) for caller convenience.

Refs: RFC-WS-6.md §3 (Q9)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 12:57:21 +02:00

64 lines
2.0 KiB
PHP

<?php
declare(strict_types=1);
namespace App\FormBuilder\Purposes\Resolvers;
use App\Exceptions\FormBuilder\PurposeSubjectResolutionException;
use App\FormBuilder\Purposes\PurposeSubjectResolver;
use App\Models\FormBuilder\FormSubmission;
use App\Models\Person;
use App\Models\User;
use Illuminate\Database\Eloquent\Model;
/**
* RFC §3 Q9 — post_event_evaluation: subject is a Person resolved via
* the authenticated User → linked Person. Throws if no auth or no
* Person link.
*/
final readonly class PostEventEvaluationSubjectResolver implements PurposeSubjectResolver
{
public function resolveOrProvision(FormSubmission $submission): Model
{
if ($submission->subject_type === 'person' && $submission->subject_id !== null) {
$subject = $submission->subject;
if ($subject instanceof Person) {
return $subject;
}
}
$user = $this->resolveUser($submission);
$person = Person::query()->withoutGlobalScopes()->where('user_id', $user->id)
->where('event_id', $submission->event_id)
->first();
if ($person === null) {
throw new PurposeSubjectResolutionException(
'post_event_evaluation',
'no_person_for_user',
(string) $submission->id,
"user {$user->id} has no Person linked for event {$submission->event_id}",
);
}
return $person;
}
private function resolveUser(FormSubmission $submission): User
{
if ($submission->submitted_by_user_id !== null) {
$user = User::query()->find($submission->submitted_by_user_id);
if ($user instanceof User) {
return $user;
}
}
throw new PurposeSubjectResolutionException(
'post_event_evaluation',
'no_auth',
(string) $submission->id,
'post_event_evaluation submission has no authenticated User',
);
}
}