Files
michaelschiemer/src/Application/Campaign/ShowCampaign.php
Michael Schiemer fc3d7e6357 feat(Production): Complete production deployment infrastructure
- Add comprehensive health check system with multiple endpoints
- Add Prometheus metrics endpoint
- Add production logging configurations (5 strategies)
- Add complete deployment documentation suite:
  * QUICKSTART.md - 30-minute deployment guide
  * DEPLOYMENT_CHECKLIST.md - Printable verification checklist
  * DEPLOYMENT_WORKFLOW.md - Complete deployment lifecycle
  * PRODUCTION_DEPLOYMENT.md - Comprehensive technical reference
  * production-logging.md - Logging configuration guide
  * ANSIBLE_DEPLOYMENT.md - Infrastructure as Code automation
  * README.md - Navigation hub
  * DEPLOYMENT_SUMMARY.md - Executive summary
- Add deployment scripts and automation
- Add DEPLOYMENT_PLAN.md - Concrete plan for immediate deployment
- Update README with production-ready features

All production infrastructure is now complete and ready for deployment.
2025-10-25 19:18:37 +02:00

86 lines
2.8 KiB
PHP
Executable File

<?php
declare(strict_types=1);
namespace App\Application\Campaign;
use App\Framework\Attributes\Route;
use App\Framework\Http\Method;
use App\Framework\Http\Session\Session;
use App\Framework\Meta\MetaData;
use App\Framework\Router\Result\ViewResult;
/**
* Show Campaign Landing Page
*
* Displays public campaign landing page with pre-save functionality
*/
final readonly class ShowCampaign
{
public function __construct(
private CampaignService $campaignService
) {
}
#[Route(path: '/campaign/{slug}', method: Method::GET)]
public function __invoke(string $slug, Session $session): ViewResult
{
// Fetch campaign data
$campaign = $this->campaignService->findBySlug($slug);
if (! $campaign) {
throw new \RuntimeException("Campaign not found: {$slug}");
}
// Check if user has already saved
$userHasSaved = $this->campaignService->hasUserSaved(
$campaign->id,
$session->getId()
);
// Prepare campaign data for view
$campaignData = [
'slug' => $campaign->slug,
'artist_name' => $campaign->artist_name,
'album_title' => $campaign->album_title,
'description' => $campaign->description,
'artwork_url' => $campaign->artwork_url,
'release_date' => $campaign->release_date?->format('F j, Y'),
'total_saves' => $campaign->total_saves,
'track_count' => $campaign->track_count,
'spotify_enabled' => (bool) $campaign->spotify_enabled,
'apple_music_enabled' => (bool) $campaign->apple_music_enabled,
'tracks' => $campaign->tracks ? array_map(
fn ($track) => [
'position' => $track->position,
'title' => $track->title,
'duration' => $track->duration ? $this->formatDuration($track->duration) : null,
'preview_url' => $track->preview_url,
],
$campaign->tracks
) : null,
];
return new ViewResult(
'campaign-landing',
new MetaData(
title: $campaign->artist_name . ' - ' . $campaign->album_title,
description: $campaign->description ?? 'Pre-save this album on Spotify',
),
data: [
'campaign' => $campaignData,
'user_has_saved' => $userHasSaved,
'csrf_token' => $session->csrf->generateToken('campaign-landing')->toString(),
]
);
}
private function formatDuration(int $seconds): string
{
$minutes = floor($seconds / 60);
$remainingSeconds = $seconds % 60;
return sprintf('%d:%02d', $minutes, $remainingSeconds);
}
}