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,440 @@
# Notification System
Multi-channel notification system with support for email, database, push, SMS, and webhooks.
## Features
- **Multi-Channel Delivery**: Email, Database (in-app), Push, SMS, Webhook
- **Queue Integration**: Async delivery via framework Queue system
- **Event System**: NotificationSent and NotificationFailed events
- **Priority Levels**: LOW, NORMAL, HIGH, URGENT
- **Read Tracking**: Mark notifications as read, count unread
- **Action Buttons**: Optional action URL and label
- **Type Safety**: Fully typed with Value Objects and Enums
- **Framework Integration**: Uses existing Mail, Queue, EventBus, Database modules
## Basic Usage
### Creating and Sending a Notification
```php
use App\Framework\Notification\Notification;
use App\Framework\Notification\NotificationDispatcher;
use App\Framework\Notification\ValueObjects\NotificationChannel;
use App\Framework\Notification\ValueObjects\NotificationPriority;
use App\Framework\Notification\ValueObjects\NotificationType;
// Create notification
$notification = Notification::create(
recipientId: 'user-123',
type: NotificationType::system(),
title: 'System Update',
body: 'Your system has been updated to version 2.0',
NotificationChannel::DATABASE,
NotificationChannel::EMAIL
);
// Add optional features
$notification = $notification
->withPriority(NotificationPriority::HIGH)
->withAction('/changelog', 'View Changelog')
->withData([
'version' => '2.0.0',
'features' => ['performance', 'security']
]);
// Send asynchronously (via Queue)
$dispatcher->sendLater($notification);
// Or send immediately
$result = $dispatcher->sendNow($notification);
```
### Common Notification Types
```php
// System notifications
NotificationType::system()
// Security alerts
NotificationType::security()
// Marketing messages
NotificationType::marketing()
// Social interactions
NotificationType::social()
// Transactional emails
NotificationType::transactional()
// Custom types
NotificationType::fromString('order-status')
```
### Retrieving Notifications
```php
use App\Framework\Notification\Storage\NotificationRepository;
// Get user's notifications
$notifications = $repository->findByUser('user-123', limit: 20);
// Get unread notifications
$unread = $repository->findUnreadByUser('user-123');
// Count unread
$count = $repository->countUnreadByUser('user-123');
// Mark as read
$repository->markAsRead($notificationId);
// Mark all as read
$repository->markAllAsReadForUser('user-123');
```
## Channels
### Database Channel (In-App Notifications)
Stores notifications in database for user inbox/notification center.
```php
NotificationChannel::DATABASE
```
**Features**:
- Persistent storage
- Read/unread tracking
- Pagination support
- Automatic cleanup of old notifications
### Email Channel
Sends notifications via email using framework's Mail module.
```php
NotificationChannel::EMAIL
```
**Features**:
- HTML and plain text emails
- Priority mapping
- Action buttons in email
- Automatic HTML formatting
**Requirements**:
- UserEmailResolver implementation to map user IDs to email addresses
```php
class DatabaseUserEmailResolver implements UserEmailResolver
{
public function resolveEmail(string $userId): ?Email
{
// Lookup user email from database
return $this->userRepository->findEmailById($userId);
}
}
```
### Push Channel (Placeholder)
For web push and mobile push notifications.
```php
NotificationChannel::PUSH
```
**Status**: Interface defined, implementation needed.
### SMS Channel (Placeholder)
For SMS notifications via external provider.
```php
NotificationChannel::SMS
```
**Status**: Interface defined, implementation needed.
### Webhook Channel (Placeholder)
For sending notifications to external systems via HTTP webhooks.
```php
NotificationChannel::WEBHOOK
```
**Status**: Interface defined, implementation needed.
## Queue Integration
The notification system integrates seamlessly with the framework's Queue system for asynchronous delivery.
### Async Delivery
```php
// Queue for background processing
$dispatcher->sendLater($notification);
// Priority is mapped from notification priority:
// URGENT → HIGH
// HIGH → MEDIUM
// NORMAL → LOW
// LOW → LOW
```
### Immediate Delivery
```php
// Send immediately (blocks until complete)
$result = $dispatcher->sendNow($notification);
if ($result->isSuccess()) {
echo "Sent via: " . count($result->getSuccessful()) . " channels\n";
} else {
echo "Errors: " . implode(', ', $result->getErrors()) . "\n";
}
```
## Event System
The notification system dispatches events via the framework's EventBus.
### NotificationSent Event
Dispatched when a notification is successfully sent via at least one channel.
```php
use App\Framework\Notification\Events\NotificationSent;
use App\Framework\EventBus\Attributes\EventHandler;
#[EventHandler]
final class NotificationLogger
{
public function handleNotificationSent(NotificationSent $event): void
{
$this->logger->info('Notification sent', [
'notification_id' => $event->notification->id->toString(),
'recipient' => $event->notification->recipientId,
'channels' => count($event->result->getSuccessful())
]);
}
}
```
### NotificationFailed Event
Dispatched when a notification fails on all channels.
```php
use App\Framework\Notification\Events\NotificationFailed;
use App\Framework\EventBus\Attributes\EventHandler;
#[EventHandler]
final class NotificationFailureHandler
{
public function handleNotificationFailure(NotificationFailed $event): void
{
$this->alerting->sendAlert(
'Notification delivery failed',
$event->result->getErrors()
);
}
}
```
## Database Schema
The notifications table is created via migration:
```php
src/Framework/Notification/Migrations/CreateNotificationsTable.php
```
**Table Structure**:
- `id` (ULID) - Primary key
- `recipient_id` - User/entity receiving notification
- `type` - Notification category
- `title` - Notification title
- `body` - Notification message
- `data` - JSON structured data
- `channels` - JSON array of delivery channels
- `priority` - Delivery priority
- `status` - Current status (pending, sent, delivered, failed, read, archived)
- `created_at` - Creation timestamp
- `sent_at` - Delivery timestamp
- `read_at` - Read timestamp
- `action_url` - Optional action URL
- `action_label` - Optional action button label
**Indexes**:
- `recipient_id` + `status` + `created_at` (composite)
- `recipient_id` + `type` (composite)
- `read_at` (for unread queries)
## Configuration
### Setting Up Channels
```php
// In your Initializer
use App\Framework\Notification\Channels\DatabaseChannel;
use App\Framework\Notification\Channels\EmailChannel;
use App\Framework\Notification\NotificationDispatcher;
$container->singleton(NotificationDispatcher::class, function($c) {
return new NotificationDispatcher(
channels: [
$c->get(DatabaseChannel::class),
$c->get(EmailChannel::class),
// Add more channels as needed
],
queue: $c->get(Queue::class),
eventBus: $c->get(EventBus::class)
);
});
```
### Email Channel Setup
```php
$container->singleton(EmailChannel::class, function($c) {
return new EmailChannel(
mailer: $c->get(MailerInterface::class),
fromAddress: new Email('notifications@example.com'),
userEmailResolver: $c->get(UserEmailResolver::class)
);
});
```
## Best Practices
1. **Use Async Delivery**: Always prefer `sendLater()` for better performance
2. **Set Appropriate Priority**: Reserve URGENT for critical notifications
3. **Include Actions**: Add action URLs when user interaction is expected
4. **Structured Data**: Use `withData()` for additional context
5. **Type Classification**: Use proper NotificationType for filtering
6. **Cleanup Old Notifications**: Periodically delete old read/archived notifications
## Examples
### Welcome Notification
```php
$notification = Notification::create(
recipientId: $user->id,
type: NotificationType::system(),
title: 'Welcome to Our Platform!',
body: 'Thank you for signing up. Get started by completing your profile.',
NotificationChannel::DATABASE,
NotificationChannel::EMAIL
)->withAction('/profile/complete', 'Complete Profile');
$dispatcher->sendLater($notification);
```
### Security Alert
```php
$notification = Notification::create(
recipientId: $user->id,
type: NotificationType::security(),
title: 'New Login Detected',
body: "We detected a login from {$location} at {$time}",
NotificationChannel::DATABASE,
NotificationChannel::EMAIL
)
->withPriority(NotificationPriority::HIGH)
->withData([
'ip_address' => $ipAddress,
'location' => $location,
'device' => $device
]);
$dispatcher->sendNow($notification); // Immediate for security
```
### Order Confirmation
```php
$notification = Notification::create(
recipientId: $order->userId,
type: NotificationType::transactional(),
title: 'Order Confirmed',
body: "Your order #{$order->number} has been confirmed",
NotificationChannel::EMAIL
)
->withData([
'order_id' => $order->id,
'total' => $order->total->toDecimal(),
'items' => count($order->items)
])
->withAction("/orders/{$order->id}", 'View Order');
$dispatcher->sendLater($notification);
```
## Testing
Run tests with:
```bash
./vendor/bin/pest tests/Feature/NotificationSystemTest.php
```
## Extending the System
### Adding a New Channel
1. Implement `NotificationChannelInterface`
2. Add channel to `NotificationChannel` enum
3. Register channel in dispatcher initialization
4. Implement `send()` method with delivery logic
```php
final readonly class SmsChannel implements NotificationChannelInterface
{
public function __construct(
private SmsProvider $provider
) {}
public function send(Notification $notification): ChannelResult
{
// Implementation
}
public function supports(Notification $notification): bool
{
return $notification->supportsChannel(NotificationChannel::SMS);
}
public function getChannel(): NotificationChannel
{
return NotificationChannel::SMS;
}
}
```
## Architecture
The notification system follows framework principles:
-**Readonly Value Objects**: Notification, NotificationId, etc.
-**Final Classes**: All implementation classes are final
-**Composition over Inheritance**: Channel interface composition
-**Event-Driven**: Integration with EventBus
-**Queue Integration**: Async delivery via Queue system
-**Module Reuse**: Leverages Mail, Queue, EventBus, Database modules
## Future Enhancements
- [ ] User preference management for notification types
- [ ] Notification templates with variables
- [ ] Push notification implementation (Web Push API)
- [ ] SMS channel implementation
- [ ] Webhook channel implementation
- [ ] Notification batching/digest mode
- [ ] Quiet hours / Do Not Disturb
- [ ] A/B testing for notification content
- [ ] Analytics tracking