docs: consolidate documentation into organized structure

- Move 12 markdown files from root to docs/ subdirectories
- Organize documentation by category:
  • docs/troubleshooting/ (1 file)  - Technical troubleshooting guides
  • docs/deployment/      (4 files) - Deployment and security documentation
  • docs/guides/          (3 files) - Feature-specific guides
  • docs/planning/        (4 files) - Planning and improvement proposals

Root directory cleanup:
- Reduced from 16 to 4 markdown files in root
- Only essential project files remain:
  • CLAUDE.md (AI instructions)
  • README.md (Main project readme)
  • CLEANUP_PLAN.md (Current cleanup plan)
  • SRC_STRUCTURE_IMPROVEMENTS.md (Structure improvements)

This improves:
 Documentation discoverability
 Logical organization by purpose
 Clean root directory
 Better maintainability
This commit is contained in:
2025-10-05 11:05:04 +02:00
parent 887847dde6
commit 5050c7d73a
36686 changed files with 196456 additions and 12398919 deletions

View File

@@ -0,0 +1,104 @@
<?php
declare(strict_types=1);
namespace App\Application\Campaign\ValueObjects;
/**
* Campaign Value Object
*
* Represents a pre-save campaign with all metadata
*/
final readonly class Campaign
{
/**
* @param array<CampaignTrack>|null $tracks
*/
public function __construct(
public string $id,
public string $slug,
public string $artist_name,
public string $album_title,
public ?string $description,
public ?string $artwork_url,
public ?\DateTimeImmutable $release_date,
public int $total_saves,
public ?int $track_count,
public bool $spotify_enabled,
public bool $apple_music_enabled,
public ?string $spotify_uri,
public ?string $apple_music_id,
public ?array $tracks = null,
public string $status = 'active',
public ?\DateTimeImmutable $created_at = null,
public ?\DateTimeImmutable $updated_at = null,
) {}
public static function fromArray(array $data): self
{
return new self(
id: $data['id'],
slug: $data['slug'],
artist_name: $data['artist_name'],
album_title: $data['album_title'],
description: $data['description'] ?? null,
artwork_url: $data['artwork_url'] ?? null,
release_date: isset($data['release_date'])
? new \DateTimeImmutable($data['release_date'])
: null,
total_saves: (int) ($data['total_saves'] ?? 0),
track_count: isset($data['track_count']) ? (int) $data['track_count'] : null,
spotify_enabled: (bool) ($data['spotify_enabled'] ?? false),
apple_music_enabled: (bool) ($data['apple_music_enabled'] ?? false),
spotify_uri: $data['spotify_uri'] ?? null,
apple_music_id: $data['apple_music_id'] ?? null,
tracks: isset($data['tracks']) ? array_map(
fn($track) => CampaignTrack::fromArray($track),
$data['tracks']
) : null,
status: $data['status'] ?? 'active',
created_at: isset($data['created_at'])
? new \DateTimeImmutable($data['created_at'])
: null,
updated_at: isset($data['updated_at'])
? new \DateTimeImmutable($data['updated_at'])
: null,
);
}
public function toArray(): array
{
return [
'id' => $this->id,
'slug' => $this->slug,
'artist_name' => $this->artist_name,
'album_title' => $this->album_title,
'description' => $this->description,
'artwork_url' => $this->artwork_url,
'release_date' => $this->release_date?->format('Y-m-d'),
'total_saves' => $this->total_saves,
'track_count' => $this->track_count,
'spotify_enabled' => $this->spotify_enabled,
'apple_music_enabled' => $this->apple_music_enabled,
'spotify_uri' => $this->spotify_uri,
'apple_music_id' => $this->apple_music_id,
'status' => $this->status,
'created_at' => $this->created_at?->format('Y-m-d H:i:s'),
'updated_at' => $this->updated_at?->format('Y-m-d H:i:s'),
];
}
public function isActive(): bool
{
return $this->status === 'active';
}
public function hasReleased(): bool
{
if (!$this->release_date) {
return false;
}
return $this->release_date <= new \DateTimeImmutable();
}
}

View File

@@ -0,0 +1,54 @@
<?php
declare(strict_types=1);
namespace App\Application\Campaign\ValueObjects;
/**
* Campaign Track Value Object
*
* Represents a track within a campaign
*/
final readonly class CampaignTrack
{
public function __construct(
public string $id,
public int $position,
public string $title,
public ?int $duration,
public ?string $preview_url,
public ?string $spotify_id = null,
public ?string $apple_music_id = null,
) {}
public static function fromArray(array $data): self
{
return new self(
id: $data['id'],
position: (int) $data['position'],
title: $data['title'],
duration: isset($data['duration']) ? (int) $data['duration'] : null,
preview_url: $data['preview_url'] ?? null,
spotify_id: $data['spotify_id'] ?? null,
apple_music_id: $data['apple_music_id'] ?? null,
);
}
public function toArray(): array
{
return [
'id' => $this->id,
'position' => $this->position,
'title' => $this->title,
'duration' => $this->duration,
'preview_url' => $this->preview_url,
'spotify_id' => $this->spotify_id,
'apple_music_id' => $this->apple_music_id,
];
}
public function hasPreview(): bool
{
return $this->preview_url !== null;
}
}