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,194 @@
<?php
use App\Domain\Common\ValueObject\Email;
use App\Framework\Notification\Channels\DatabaseChannel;
use App\Framework\Notification\Channels\EmailChannel;
use App\Framework\Notification\Channels\UserEmailResolver;
use App\Framework\Notification\Notification;
use App\Framework\Notification\NotificationDispatcher;
use App\Framework\Notification\Storage\DatabaseNotificationRepository;
use App\Framework\Notification\ValueObjects\NotificationChannel;
use App\Framework\Notification\ValueObjects\NotificationPriority;
use App\Framework\Notification\ValueObjects\NotificationType;
use App\Framework\EventBus\EventBus;
use App\Framework\Queue\InMemoryQueue;
// Mock EventBus for testing
class MockEventBus implements EventBus
{
public array $dispatchedEvents = [];
public function dispatch(object $event): void
{
$this->dispatchedEvents[] = $event;
}
}
describe('Notification System', function () {
beforeEach(function () {
// Setup test dependencies
$this->queue = new InMemoryQueue();
$this->eventBus = new MockEventBus();
});
it('can create a notification with required fields', function () {
$notification = Notification::create(
'user-123',
NotificationType::system(),
'System Update',
'Your system has been updated',
NotificationChannel::DATABASE,
NotificationChannel::EMAIL
);
expect($notification->recipientId)->toBe('user-123');
expect($notification->title)->toBe('System Update');
expect($notification->body)->toBe('Your system has been updated');
expect($notification->channels)->toHaveCount(2);
expect($notification->priority)->toBe(NotificationPriority::NORMAL);
});
it('can add action to notification', function () {
$notification = Notification::create(
'user-123',
NotificationType::system(),
'Action Required',
'Please review your settings',
NotificationChannel::DATABASE
)->withAction('/settings', 'Review Settings');
expect($notification->hasAction())->toBeTrue();
expect($notification->actionUrl)->toBe('/settings');
expect($notification->actionLabel)->toBe('Review Settings');
});
it('can set priority on notification', function () {
$notification = Notification::create(
'user-123',
NotificationType::security(),
'Security Alert',
'Unusual login detected',
NotificationChannel::DATABASE,
NotificationChannel::EMAIL
)->withPriority(NotificationPriority::URGENT);
expect($notification->priority)->toBe(NotificationPriority::URGENT);
expect($notification->priority->shouldInterruptUser())->toBeTrue();
});
it('can add custom data to notification', function () {
$notification = Notification::create(
'user-123',
NotificationType::social(),
'New Follower',
'John Doe started following you',
NotificationChannel::DATABASE
)->withData([
'follower_id' => 'user-456',
'follower_name' => 'John Doe',
'follower_avatar' => '/avatars/456.jpg',
]);
expect($notification->data)->toHaveKey('follower_id');
expect($notification->data['follower_name'])->toBe('John Doe');
});
it('validates required fields', function () {
try {
Notification::create(
'',
NotificationType::system(),
'Test',
'Test body',
NotificationChannel::DATABASE
);
expect(true)->toBeFalse('Should have thrown exception');
} catch (\InvalidArgumentException $e) {
expect($e->getMessage())->toContain('Recipient ID');
}
});
it('requires at least one channel', function () {
try {
new Notification(
id: \App\Framework\Notification\ValueObjects\NotificationId::generate(),
recipientId: 'user-123',
type: NotificationType::system(),
title: 'Test',
body: 'Test body',
data: [],
channels: [], // Empty channels
priority: NotificationPriority::NORMAL,
status: \App\Framework\Notification\ValueObjects\NotificationStatus::PENDING,
createdAt: \App\Framework\Core\ValueObjects\Timestamp::now()
);
expect(true)->toBeFalse('Should have thrown exception');
} catch (\InvalidArgumentException $e) {
expect($e->getMessage())->toContain('channel');
}
});
it('can mark notification as read', function () {
$notification = Notification::create(
'user-123',
NotificationType::system(),
'Test',
'Test body',
NotificationChannel::DATABASE
);
expect($notification->isRead())->toBeFalse();
$readNotification = $notification->markAsRead();
expect($readNotification->isRead())->toBeTrue();
expect($readNotification->readAt)->toBeInstanceOf(\App\Framework\Core\ValueObjects\Timestamp::class);
});
it('can convert notification to array', function () {
$notification = Notification::create(
'user-123',
NotificationType::transactional(),
'Payment Received',
'Your payment of $50 was processed',
NotificationChannel::DATABASE,
NotificationChannel::EMAIL
)->withData(['amount' => 50, 'currency' => 'USD']);
$array = $notification->toArray();
expect($array)->toHaveKey('id');
expect($array)->toHaveKey('recipient_id');
expect($array['title'])->toBe('Payment Received');
expect($array['data']['amount'])->toBe(50);
expect($array['channels'])->toContain('database');
expect($array['channels'])->toContain('email');
});
});
describe('Notification Dispatcher', function () {
it('can queue notification for async delivery', function () {
$queue = new InMemoryQueue();
$eventBus = new MockEventBus();
$dispatcher = new NotificationDispatcher(
channels: [],
queue: $queue,
eventBus: $eventBus
);
$notification = Notification::create(
'user-123',
NotificationType::system(),
'Test',
'Test body',
NotificationChannel::DATABASE
);
expect($queue->size())->toBe(0);
$dispatcher->sendLater($notification);
expect($queue->size())->toBe(1);
});
});