docs: add README, boost skill, and documentation site
This commit is contained in:
1
docs/content/2.essentials/.navigation.yml
Normal file
1
docs/content/2.essentials/.navigation.yml
Normal file
@@ -0,0 +1 @@
|
||||
title: Essentials
|
||||
189
docs/content/2.essentials/1.configuration.md
Normal file
189
docs/content/2.essentials/1.configuration.md
Normal file
@@ -0,0 +1,189 @@
|
||||
---
|
||||
title: Configuration
|
||||
description: Configure threading, reactions, mentions, attachments, notifications, and more.
|
||||
navigation:
|
||||
icon: i-lucide-settings
|
||||
seo:
|
||||
description: Complete configuration reference for the Comments package.
|
||||
---
|
||||
|
||||
Publish the configuration file:
|
||||
|
||||
```bash
|
||||
php artisan vendor:publish --tag=comments-config
|
||||
```
|
||||
|
||||
This creates `config/comments.php` with all available options.
|
||||
|
||||
## Table Name
|
||||
|
||||
```php
|
||||
'tables' => [
|
||||
'comments' => 'comments',
|
||||
],
|
||||
```
|
||||
|
||||
Change the table name if it conflicts with your application.
|
||||
|
||||
## Models
|
||||
|
||||
```php
|
||||
'models' => [
|
||||
'comment' => \Relaticle\Comments\Comment::class,
|
||||
],
|
||||
|
||||
'commenter' => [
|
||||
'model' => \App\Models\User::class,
|
||||
],
|
||||
```
|
||||
|
||||
Override the Comment model to add custom behavior. The commenter model defines which class represents the user who comments.
|
||||
|
||||
## Policy
|
||||
|
||||
```php
|
||||
'policy' => \Relaticle\Comments\Policies\CommentPolicy::class,
|
||||
```
|
||||
|
||||
See the [Authorization](/essentials/authorization) page for customization details.
|
||||
|
||||
## Threading
|
||||
|
||||
```php
|
||||
'threading' => [
|
||||
'max_depth' => 2,
|
||||
],
|
||||
```
|
||||
|
||||
Controls how many levels of nested replies are allowed. A depth of `2` means top-level comments and one level of replies. Set to `1` to disable replies entirely.
|
||||
|
||||
## Pagination
|
||||
|
||||
```php
|
||||
'pagination' => [
|
||||
'per_page' => 10,
|
||||
],
|
||||
```
|
||||
|
||||
Number of comments loaded initially and per "Load More" click.
|
||||
|
||||
## Reactions
|
||||
|
||||
```php
|
||||
'reactions' => [
|
||||
'emoji_set' => [
|
||||
'thumbs_up' => "\u{1F44D}",
|
||||
'heart' => "\u{2764}\u{FE0F}",
|
||||
'celebrate' => "\u{1F389}",
|
||||
'laugh' => "\u{1F604}",
|
||||
'thinking' => "\u{1F914}",
|
||||
'sad' => "\u{1F622}",
|
||||
],
|
||||
],
|
||||
```
|
||||
|
||||
Customize the available emoji reactions. Keys are used as identifiers in the database, values are the displayed emoji characters.
|
||||
|
||||
## Mentions
|
||||
|
||||
```php
|
||||
'mentions' => [
|
||||
'resolver' => \Relaticle\Comments\Mentions\DefaultMentionResolver::class,
|
||||
'max_results' => 5,
|
||||
],
|
||||
```
|
||||
|
||||
The resolver handles searching for users during @mention autocomplete. See the [Mentions](/essentials/mentions) page for creating a custom resolver.
|
||||
|
||||
## Editor Toolbar
|
||||
|
||||
```php
|
||||
'editor' => [
|
||||
'toolbar' => [
|
||||
['bold', 'italic', 'strike', 'link'],
|
||||
['bulletList', 'orderedList'],
|
||||
['codeBlock'],
|
||||
],
|
||||
],
|
||||
```
|
||||
|
||||
Defines which formatting buttons appear in the comment editor. Groups create visual separators in the toolbar.
|
||||
|
||||
## Notifications
|
||||
|
||||
```php
|
||||
'notifications' => [
|
||||
'channels' => ['database'],
|
||||
'enabled' => true,
|
||||
],
|
||||
```
|
||||
|
||||
Add `'mail'` to the channels array to send email notifications. Set `enabled` to `false` to disable all notifications.
|
||||
|
||||
## Subscriptions
|
||||
|
||||
```php
|
||||
'subscriptions' => [
|
||||
'auto_subscribe' => true,
|
||||
],
|
||||
```
|
||||
|
||||
When enabled, users are automatically subscribed to a thread when they create a comment or are mentioned. They receive notifications for subsequent replies.
|
||||
|
||||
## Attachments
|
||||
|
||||
```php
|
||||
'attachments' => [
|
||||
'enabled' => true,
|
||||
'disk' => 'public',
|
||||
'max_size' => 10240, // KB
|
||||
'allowed_types' => [
|
||||
'image/jpeg',
|
||||
'image/png',
|
||||
'image/gif',
|
||||
'image/webp',
|
||||
'application/pdf',
|
||||
'text/plain',
|
||||
'application/msword',
|
||||
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
||||
],
|
||||
],
|
||||
```
|
||||
|
||||
Controls file upload behavior. Set `enabled` to `false` to remove the attachment UI entirely. The `max_size` is in kilobytes (default 10 MB).
|
||||
|
||||
## Broadcasting
|
||||
|
||||
```php
|
||||
'broadcasting' => [
|
||||
'enabled' => false,
|
||||
'channel_prefix' => 'comments',
|
||||
],
|
||||
```
|
||||
|
||||
When enabled, comment events are broadcast on private channels using the format `{prefix}.{commentable_type}.{commentable_id}`. Requires Laravel Echo and a broadcasting driver.
|
||||
|
||||
## Polling
|
||||
|
||||
```php
|
||||
'polling' => [
|
||||
'interval' => '10s',
|
||||
],
|
||||
```
|
||||
|
||||
When broadcasting is disabled, the Livewire component polls for new comments at this interval. Set to `null` to disable polling.
|
||||
|
||||
## Custom User Resolution
|
||||
|
||||
Override how the authenticated user is resolved:
|
||||
|
||||
```php
|
||||
use Relaticle\Comments\Config;
|
||||
|
||||
// In AppServiceProvider::boot()
|
||||
Config::resolveAuthenticatedUserUsing(function () {
|
||||
return auth()->user();
|
||||
});
|
||||
```
|
||||
|
||||
This is useful for multi-guard applications or custom authentication flows.
|
||||
74
docs/content/2.essentials/2.authorization.md
Normal file
74
docs/content/2.essentials/2.authorization.md
Normal file
@@ -0,0 +1,74 @@
|
||||
---
|
||||
title: Authorization
|
||||
description: Control who can create, edit, delete, and reply to comments.
|
||||
navigation:
|
||||
icon: i-lucide-shield
|
||||
seo:
|
||||
description: Configure comment authorization policies.
|
||||
---
|
||||
|
||||
## Default Policy
|
||||
|
||||
The built-in `CommentPolicy` provides sensible defaults:
|
||||
|
||||
| Method | Default | Description |
|
||||
|--------|---------|-------------|
|
||||
| `viewAny()` | `true` | Everyone can view comments |
|
||||
| `create()` | `true` | Everyone can create comments |
|
||||
| `update()` | Owner only | Only the comment author can edit |
|
||||
| `delete()` | Owner only | Only the comment author can delete |
|
||||
| `reply()` | Depth check | Can reply if `max_depth` not exceeded |
|
||||
|
||||
## Custom Policy
|
||||
|
||||
Create your own policy to customize authorization:
|
||||
|
||||
```php
|
||||
namespace App\Policies;
|
||||
|
||||
use Relaticle\Comments\Comment;
|
||||
use Relaticle\Comments\Contracts\Commenter;
|
||||
|
||||
class CustomCommentPolicy
|
||||
{
|
||||
public function viewAny(Commenter $user): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function create(Commenter $user): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function update(Commenter $user, Comment $comment): bool
|
||||
{
|
||||
return $comment->user_id === $user->getKey()
|
||||
&& $comment->user_type === $user->getMorphClass();
|
||||
}
|
||||
|
||||
public function delete(Commenter $user, Comment $comment): bool
|
||||
{
|
||||
return $comment->user_id === $user->getKey()
|
||||
|| $user->hasRole('admin');
|
||||
}
|
||||
|
||||
public function reply(Commenter $user, Comment $comment): bool
|
||||
{
|
||||
return $comment->canReply();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Register it in your config:
|
||||
|
||||
```php
|
||||
// config/comments.php
|
||||
'policy' => App\Policies\CustomCommentPolicy::class,
|
||||
```
|
||||
|
||||
## How Authorization Works
|
||||
|
||||
The Livewire components check the policy before rendering action buttons. Edit and delete buttons only appear for authorized users. Reply buttons are hidden when the thread has reached the configured `max_depth`.
|
||||
|
||||
The policy is registered automatically by the service provider using Laravel's Gate system.
|
||||
74
docs/content/2.essentials/3.mentions.md
Normal file
74
docs/content/2.essentials/3.mentions.md
Normal file
@@ -0,0 +1,74 @@
|
||||
---
|
||||
title: Mentions
|
||||
description: User @mentions with autocomplete and notification support.
|
||||
navigation:
|
||||
icon: i-lucide-at-sign
|
||||
seo:
|
||||
description: Configure @mention autocomplete and create custom mention resolvers.
|
||||
---
|
||||
|
||||
## How Mentions Work
|
||||
|
||||
Type `@` in the comment editor to trigger user autocomplete. Select a user to insert a mention. When the comment is saved, the `MentionParser` extracts mentions and:
|
||||
|
||||
1. Syncs mention records in the `comment_mentions` table
|
||||
2. Dispatches a `UserMentioned` event for each newly mentioned user
|
||||
3. The `SendUserMentionedNotification` listener sends notifications
|
||||
4. If auto-subscribe is enabled, mentioned users are subscribed to the thread
|
||||
|
||||
## Default Resolver
|
||||
|
||||
The `DefaultMentionResolver` searches the commenter model by name:
|
||||
|
||||
```php
|
||||
// Searches: User::where('name', 'like', "{$query}%")
|
||||
// Limited to: config('comments.mentions.max_results') results
|
||||
```
|
||||
|
||||
## Custom Mention Resolver
|
||||
|
||||
Implement the `MentionResolver` interface to customize user search behavior:
|
||||
|
||||
```php
|
||||
namespace App\Comments;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
use Relaticle\Comments\Contracts\MentionResolver;
|
||||
|
||||
class TeamMentionResolver implements MentionResolver
|
||||
{
|
||||
public function search(string $query): Collection
|
||||
{
|
||||
return User::query()
|
||||
->where('team_id', auth()->user()->team_id)
|
||||
->where('name', 'like', "{$query}%")
|
||||
->limit(config('comments.mentions.max_results'))
|
||||
->get();
|
||||
}
|
||||
|
||||
public function resolveByNames(array $names): Collection
|
||||
{
|
||||
return User::query()
|
||||
->where('team_id', auth()->user()->team_id)
|
||||
->whereIn('name', $names)
|
||||
->get();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Register it in your config:
|
||||
|
||||
```php
|
||||
// config/comments.php
|
||||
'mentions' => [
|
||||
'resolver' => App\Comments\TeamMentionResolver::class,
|
||||
'max_results' => 5,
|
||||
],
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
| Key | Default | Description |
|
||||
|-----|---------|-------------|
|
||||
| `mentions.resolver` | `DefaultMentionResolver::class` | User search implementation |
|
||||
| `mentions.max_results` | `5` | Maximum autocomplete results |
|
||||
51
docs/content/2.essentials/4.reactions.md
Normal file
51
docs/content/2.essentials/4.reactions.md
Normal file
@@ -0,0 +1,51 @@
|
||||
---
|
||||
title: Reactions
|
||||
description: Emoji reactions on comments.
|
||||
navigation:
|
||||
icon: i-lucide-smile
|
||||
seo:
|
||||
description: Configure emoji reactions for comments.
|
||||
---
|
||||
|
||||
## Default Reactions
|
||||
|
||||
Six emoji reactions are available out of the box:
|
||||
|
||||
| Key | Emoji | Label |
|
||||
|-----|-------|-------|
|
||||
| `thumbs_up` | :thumbsup: | Like |
|
||||
| `heart` | :heart: | Love |
|
||||
| `celebrate` | :tada: | Celebrate |
|
||||
| `laugh` | :smile: | Laugh |
|
||||
| `thinking` | :thinking: | Thinking |
|
||||
| `sad` | :cry: | Sad |
|
||||
|
||||
## How Reactions Work
|
||||
|
||||
- Each user can add one reaction of each type per comment
|
||||
- Clicking the same reaction again removes it (toggle behavior)
|
||||
- The reaction summary shows which users reacted with each emoji
|
||||
- A `CommentReacted` event is dispatched with `action: 'added'` or `'removed'`
|
||||
|
||||
## Customizing Reactions
|
||||
|
||||
Override the emoji set in your config:
|
||||
|
||||
```php
|
||||
// config/comments.php
|
||||
'reactions' => [
|
||||
'emoji_set' => [
|
||||
'thumbs_up' => "\u{1F44D}",
|
||||
'thumbs_down' => "\u{1F44E}",
|
||||
'heart' => "\u{2764}\u{FE0F}",
|
||||
'fire' => "\u{1F525}",
|
||||
'eyes' => "\u{1F440}",
|
||||
],
|
||||
],
|
||||
```
|
||||
|
||||
Keys are stored in the database. If you change a key, existing reactions with the old key will no longer display.
|
||||
|
||||
## Storage
|
||||
|
||||
Reactions are stored in the `comment_reactions` table with a unique constraint on `(comment_id, user_id, user_type, reaction)`, ensuring one reaction of each type per user per comment.
|
||||
72
docs/content/2.essentials/5.attachments.md
Normal file
72
docs/content/2.essentials/5.attachments.md
Normal file
@@ -0,0 +1,72 @@
|
||||
---
|
||||
title: Attachments
|
||||
description: File uploads for comments.
|
||||
navigation:
|
||||
icon: i-lucide-paperclip
|
||||
seo:
|
||||
description: Configure file attachments for comments.
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
Comments support file attachments for both images and documents. Images are displayed inline within the comment body, while documents appear as downloadable links.
|
||||
|
||||
## Configuration
|
||||
|
||||
```php
|
||||
// config/comments.php
|
||||
'attachments' => [
|
||||
'enabled' => true,
|
||||
'disk' => 'public',
|
||||
'max_size' => 10240, // KB (10 MB)
|
||||
'allowed_types' => [
|
||||
'image/jpeg',
|
||||
'image/png',
|
||||
'image/gif',
|
||||
'image/webp',
|
||||
'application/pdf',
|
||||
'text/plain',
|
||||
'application/msword',
|
||||
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
||||
],
|
||||
],
|
||||
```
|
||||
|
||||
| Key | Default | Description |
|
||||
|-----|---------|-------------|
|
||||
| `enabled` | `true` | Show/hide the attachment upload UI |
|
||||
| `disk` | `'public'` | Laravel filesystem disk for storage |
|
||||
| `max_size` | `10240` | Maximum file size in kilobytes |
|
||||
| `allowed_types` | images, pdf, text, word | Array of allowed MIME types |
|
||||
|
||||
## Disabling Attachments
|
||||
|
||||
```php
|
||||
'attachments' => [
|
||||
'enabled' => false,
|
||||
],
|
||||
```
|
||||
|
||||
This removes the file upload UI from the comment form entirely.
|
||||
|
||||
## Storage
|
||||
|
||||
Attachments are stored via Livewire's file upload mechanism. Each attachment record tracks:
|
||||
|
||||
- `file_path` -- Path on the configured disk
|
||||
- `original_name` -- Original filename for display
|
||||
- `mime_type` -- MIME type for rendering decisions
|
||||
- `size` -- File size in bytes
|
||||
- `disk` -- Storage disk name
|
||||
|
||||
When a comment is deleted, its attachments are cascade deleted from the database. The physical files are removed from the disk.
|
||||
|
||||
## Helper Methods
|
||||
|
||||
The `CommentAttachment` model provides:
|
||||
|
||||
```php
|
||||
$attachment->isImage(); // Check if attachment is an image
|
||||
$attachment->url(); // Get the storage URL
|
||||
$attachment->formattedSize(); // Human-readable size (e.g., "2.5 MB")
|
||||
```
|
||||
125
docs/content/2.essentials/6.notifications.md
Normal file
125
docs/content/2.essentials/6.notifications.md
Normal file
@@ -0,0 +1,125 @@
|
||||
---
|
||||
title: Notifications
|
||||
description: Comment notifications, subscriptions, and real-time updates.
|
||||
navigation:
|
||||
icon: i-lucide-bell
|
||||
seo:
|
||||
description: Configure comment notifications, subscriptions, broadcasting, and polling.
|
||||
---
|
||||
|
||||
## Notification Types
|
||||
|
||||
Two notification classes are included:
|
||||
|
||||
### CommentRepliedNotification
|
||||
|
||||
Sent to all thread subscribers when a new comment or reply is posted. The comment author is excluded from receiving their own notification.
|
||||
|
||||
### UserMentionedNotification
|
||||
|
||||
Sent to a user when they are @mentioned in a comment. Self-mentions are ignored.
|
||||
|
||||
## Channels
|
||||
|
||||
```php
|
||||
// config/comments.php
|
||||
'notifications' => [
|
||||
'channels' => ['database'],
|
||||
'enabled' => true,
|
||||
],
|
||||
```
|
||||
|
||||
Available channels: `'database'` and `'mail'`. Add both to send email notifications alongside database notifications:
|
||||
|
||||
```php
|
||||
'notifications' => [
|
||||
'channels' => ['database', 'mail'],
|
||||
'enabled' => true,
|
||||
],
|
||||
```
|
||||
|
||||
## Subscriptions
|
||||
|
||||
Users can subscribe to comment threads on any commentable model. Subscribers receive notifications when new comments are posted.
|
||||
|
||||
### Auto-Subscribe
|
||||
|
||||
```php
|
||||
'subscriptions' => [
|
||||
'auto_subscribe' => true,
|
||||
],
|
||||
```
|
||||
|
||||
When enabled:
|
||||
- Users are auto-subscribed when they post a comment
|
||||
- Users are auto-subscribed when they are @mentioned
|
||||
|
||||
### Manual Subscription
|
||||
|
||||
Users can toggle their subscription using the subscribe/unsubscribe button in the comments UI.
|
||||
|
||||
### Programmatic Access
|
||||
|
||||
```php
|
||||
use Relaticle\Comments\CommentSubscription;
|
||||
|
||||
// Check subscription status
|
||||
CommentSubscription::isSubscribed($commentable, $user);
|
||||
|
||||
// Subscribe/unsubscribe
|
||||
CommentSubscription::subscribe($commentable, $user);
|
||||
CommentSubscription::unsubscribe($commentable, $user);
|
||||
|
||||
// Get all subscribers for a commentable
|
||||
$subscribers = CommentSubscription::subscribersFor($commentable);
|
||||
```
|
||||
|
||||
## Events
|
||||
|
||||
| Event | Trigger | Broadcasts |
|
||||
|-------|---------|------------|
|
||||
| `CommentCreated` | New comment or reply | Yes |
|
||||
| `CommentUpdated` | Comment edited | Yes |
|
||||
| `CommentDeleted` | Comment soft-deleted | Yes |
|
||||
| `CommentReacted` | Reaction added/removed | Yes |
|
||||
| `UserMentioned` | User @mentioned | No |
|
||||
|
||||
## Real-time Updates
|
||||
|
||||
### Broadcasting
|
||||
|
||||
Enable broadcasting for instant updates across browser sessions:
|
||||
|
||||
```php
|
||||
// config/comments.php
|
||||
'broadcasting' => [
|
||||
'enabled' => true,
|
||||
'channel_prefix' => 'comments',
|
||||
],
|
||||
```
|
||||
|
||||
Events are broadcast on private channels: `{prefix}.{commentable_type}.{commentable_id}`
|
||||
|
||||
This requires Laravel Echo and a broadcasting driver (Pusher, Ably, etc.) configured in your application.
|
||||
|
||||
### Polling Fallback
|
||||
|
||||
When broadcasting is disabled, the Livewire component polls for updates:
|
||||
|
||||
```php
|
||||
'polling' => [
|
||||
'interval' => '10s',
|
||||
],
|
||||
```
|
||||
|
||||
Set to `null` to disable polling entirely.
|
||||
|
||||
## Disabling Notifications
|
||||
|
||||
```php
|
||||
'notifications' => [
|
||||
'enabled' => false,
|
||||
],
|
||||
```
|
||||
|
||||
This disables all notification dispatching. Subscriptions and events still work, but no notifications are sent.
|
||||
107
docs/content/2.essentials/7.database-schema.md
Normal file
107
docs/content/2.essentials/7.database-schema.md
Normal file
@@ -0,0 +1,107 @@
|
||||
---
|
||||
title: Database Schema
|
||||
description: Tables, relationships, and indexes used by the Comments package.
|
||||
navigation:
|
||||
icon: i-lucide-database
|
||||
seo:
|
||||
description: Database schema reference for the Comments package.
|
||||
---
|
||||
|
||||
## Tables
|
||||
|
||||
Five tables are created by the package migrations.
|
||||
|
||||
### comments
|
||||
|
||||
The main comments table with polymorphic relationships and threading support.
|
||||
|
||||
| Column | Type | Description |
|
||||
|--------|------|-------------|
|
||||
| `id` | bigint | Primary key |
|
||||
| `commentable_type` | string | Polymorphic model type |
|
||||
| `commentable_id` | bigint | Polymorphic model ID |
|
||||
| `user_type` | string | Commenter model type |
|
||||
| `user_id` | bigint | Commenter model ID |
|
||||
| `parent_id` | bigint (nullable) | Parent comment for replies |
|
||||
| `body` | text | HTML comment content |
|
||||
| `edited_at` | timestamp (nullable) | When the comment was last edited |
|
||||
| `deleted_at` | timestamp (nullable) | Soft delete timestamp |
|
||||
| `created_at` | timestamp | |
|
||||
| `updated_at` | timestamp | |
|
||||
|
||||
**Indexes:** `(commentable_type, commentable_id, parent_id)`
|
||||
|
||||
### comment_reactions
|
||||
|
||||
Tracks emoji reactions per user per comment.
|
||||
|
||||
| Column | Type | Description |
|
||||
|--------|------|-------------|
|
||||
| `id` | bigint | Primary key |
|
||||
| `comment_id` | bigint | Foreign key to comments |
|
||||
| `user_type` | string | Reactor model type |
|
||||
| `user_id` | bigint | Reactor model ID |
|
||||
| `reaction` | string | Reaction key (e.g., `thumbs_up`) |
|
||||
| `created_at` | timestamp | |
|
||||
|
||||
**Unique constraint:** `(comment_id, user_id, user_type, reaction)`
|
||||
|
||||
### comment_mentions
|
||||
|
||||
Tracks @mentioned users per comment.
|
||||
|
||||
| Column | Type | Description |
|
||||
|--------|------|-------------|
|
||||
| `id` | bigint | Primary key |
|
||||
| `comment_id` | bigint | Foreign key to comments |
|
||||
| `user_type` | string | Mentioned user model type |
|
||||
| `user_id` | bigint | Mentioned user model ID |
|
||||
| `created_at` | timestamp | |
|
||||
|
||||
**Unique constraint:** `(comment_id, user_id, user_type)`
|
||||
|
||||
### comment_subscriptions
|
||||
|
||||
Tracks which users are subscribed to comment threads on specific models.
|
||||
|
||||
| Column | Type | Description |
|
||||
|--------|------|-------------|
|
||||
| `id` | bigint | Primary key |
|
||||
| `commentable_type` | string | Subscribed model type |
|
||||
| `commentable_id` | bigint | Subscribed model ID |
|
||||
| `user_type` | string | Subscriber model type |
|
||||
| `user_id` | bigint | Subscriber model ID |
|
||||
| `created_at` | timestamp | |
|
||||
|
||||
**Unique constraint:** `(commentable_type, commentable_id, user_type, user_id)`
|
||||
|
||||
### comment_attachments
|
||||
|
||||
Stores file attachment metadata for comments.
|
||||
|
||||
| Column | Type | Description |
|
||||
|--------|------|-------------|
|
||||
| `id` | bigint | Primary key |
|
||||
| `comment_id` | bigint | Foreign key to comments |
|
||||
| `file_path` | string | Path on the storage disk |
|
||||
| `original_name` | string | Original uploaded filename |
|
||||
| `mime_type` | string | File MIME type |
|
||||
| `size` | bigint | File size in bytes |
|
||||
| `disk` | string | Laravel filesystem disk |
|
||||
| `created_at` | timestamp | |
|
||||
| `updated_at` | timestamp | |
|
||||
|
||||
## Relationships
|
||||
|
||||
```
|
||||
Commentable Model (e.g., Project)
|
||||
└── comments (morphMany)
|
||||
├── user (morphTo → User)
|
||||
├── parent (belongsTo → Comment)
|
||||
├── replies (hasMany → Comment)
|
||||
├── reactions (hasMany → CommentReaction)
|
||||
├── attachments (hasMany → CommentAttachment)
|
||||
└── mentions (morphToMany → User)
|
||||
```
|
||||
|
||||
All relationships are polymorphic, allowing the same comment system to work across any number of models in your application.
|
||||
Reference in New Issue
Block a user