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,123 @@
<?php
declare(strict_types=1);
use App\Domain\Media\Image;
use App\Domain\Media\ImageRepository;
use App\Framework\Filesystem\FilePath;
use App\Framework\Http\MimeType;
use App\Framework\Core\ValueObjects\FileSize;
use App\Framework\Core\ValueObjects\Hash;
use App\Framework\Ulid\Ulid;
use App\Framework\DateTime\SystemClock;
beforeEach(function () {
// Create test directory structure
$this->testDir = '/tmp/test_images';
if (!is_dir($this->testDir)) {
mkdir($this->testDir, 0755, true);
}
// Create test image file
$this->testImagePath = $this->testDir . '/test.jpg';
file_put_contents($this->testImagePath, 'fake-image-content');
// Create Clock instance
$clock = new SystemClock();
$this->testImage = new Image(
ulid: Ulid::fromString($clock, '00MF9VW9R36NJN3VCFSTS2CK6R'),
filename: 'test.jpg',
originalFilename: 'original-test.jpg',
mimeType: MimeType::fromString('image/jpeg'),
fileSize: FileSize::fromBytes(strlen('fake-image-content')),
width: 100,
height: 200,
hash: Hash::fromString('2f36ee4cde5b43e02c118f4b21e5a4904d0c13597b5c2f1127097b808080622d'),
path: FilePath::create($this->testDir),
altText: 'Test image'
);
});
afterEach(function () {
// Clean up test files
if (file_exists($this->testImagePath)) {
unlink($this->testImagePath);
}
if (is_dir($this->testDir)) {
rmdir($this->testDir);
}
});
it('can create Image entity with Value Objects', function () {
expect($this->testImage->filename)->toBe('test.jpg');
expect($this->testImage->originalFilename)->toBe('original-test.jpg');
expect($this->testImage->width)->toBe(100);
expect($this->testImage->height)->toBe(200);
expect($this->testImage->altText)->toBe('Test image');
});
it('can get full file path using FilePath join', function () {
$fullPath = $this->testImage->path->join($this->testImage->filename);
expect($fullPath->toString())->toBe($this->testDir . '/test.jpg');
});
it('can check if image file exists on filesystem', function () {
$fullPath = $this->testImage->path->join($this->testImage->filename);
expect(file_exists($fullPath->toString()))->toBeTrue();
});
it('returns correct MIME type', function () {
expect($this->testImage->mimeType->value)->toBe('image/jpeg');
expect($this->testImage->mimeType->isImage())->toBeTrue();
});
it('can verify hash', function () {
$testHash = Hash::fromString('2f36ee4cde5b43e02c118f4b21e5a4904d0c13597b5c2f1127097b808080622d');
expect($this->testImage->verifyHash($testHash))->toBeTrue();
$wrongHash = Hash::fromString('1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef');
expect($this->testImage->verifyHash($wrongHash))->toBeFalse();
});
it('can get human readable file size', function () {
$readableSize = $this->testImage->getHumanReadableFileSize();
expect($readableSize)->toBeString();
expect(strlen($readableSize))->toBeGreaterThan(0);
});
it('can get image dimensions and aspect ratio', function () {
$dimensions = $this->testImage->getDimensions();
expect($dimensions->width)->toBe(100);
expect($dimensions->height)->toBe(200);
$aspectRatio = $this->testImage->getAspectRatio();
expect($aspectRatio)->toBe(0.5); // 100/200
expect($this->testImage->isPortrait())->toBeTrue();
expect($this->testImage->isLandscape())->toBeFalse();
expect($this->testImage->isSquare())->toBeFalse();
});
it('can create immutable copy with updated filename', function () {
$newImage = $this->testImage->withFilename('new-name.jpg');
expect($newImage->filename)->toBe('new-name.jpg');
expect($this->testImage->filename)->toBe('test.jpg'); // Original unchanged
expect($newImage->ulid)->toEqual($this->testImage->ulid); // Other properties same
});
it('can create immutable copy with updated alt text', function () {
$newImage = $this->testImage->withAltText('Updated alt text');
expect($newImage->altText)->toBe('Updated alt text');
expect($this->testImage->altText)->toBe('Test image'); // Original unchanged
});
it('can create immutable copy with updated path', function () {
$newPath = FilePath::create('/new/path');
$newImage = $this->testImage->withPath($newPath);
expect($newImage->path->toString())->toBe('/new/path');
expect($this->testImage->path->toString())->toBe($this->testDir); // Original unchanged
});