Files
SkinbaseNova/app/Services/Academy/AcademyChallengeService.php

71 lines
2.4 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Services\Academy;
use App\Models\AcademyChallenge;
use App\Models\AcademyChallengeSubmission;
use App\Models\Artwork;
use App\Models\User;
use Illuminate\Support\Collection;
final class AcademyChallengeService
{
public function __construct(
private readonly AcademyAccessService $access,
private readonly AcademyBadgeService $badges,
) {
}
public function eligibleArtworkOptions(User $user): Collection
{
return Artwork::query()
->where('user_id', $user->id)
->public()
->latest('published_at')
->limit(50)
->get(['id', 'title', 'slug', 'hash', 'thumb_ext', 'published_at']);
}
/**
* @param array<string, mixed> $attributes
*/
public function submit(User $user, AcademyChallenge $challenge, Artwork $artwork, array $attributes): AcademyChallengeSubmission
{
abort_unless((bool) config('academy.challenges_enabled', true), 404);
abort_unless($this->access->canAccessChallenge($user, $challenge), 403);
abort_unless($artwork->user_id === $user->id, 403);
abort_unless($challenge->active && $challenge->status === AcademyChallenge::STATUS_ACTIVE, 422, 'Challenge is not accepting submissions.');
$submission = AcademyChallengeSubmission::query()->updateOrCreate(
[
'challenge_id' => $challenge->id,
'user_id' => $user->id,
'artwork_id' => $artwork->id,
],
[
'prompt_used' => $attributes['prompt_used'] ?? null,
'workflow_notes' => $attributes['workflow_notes'] ?? null,
'ai_tool_used' => $attributes['ai_tool_used'] ?? null,
'is_ai_generated' => (bool) ($attributes['is_ai_generated'] ?? false),
'is_ai_assisted' => (bool) ($attributes['is_ai_assisted'] ?? true),
'moderation_status' => 'pending',
'submitted_at' => now(),
],
);
$this->badges->syncForUser($user);
return $submission;
}
public function setModerationStatus(AcademyChallengeSubmission $submission, string $status): AcademyChallengeSubmission
{
$submission->forceFill([
'moderation_status' => $status,
])->save();
return $submission;
}
}