diff --git a/app/Http/Controllers/ConversationController.php b/app/Http/Controllers/ConversationController.php new file mode 100644 index 0000000..fb46ec9 --- /dev/null +++ b/app/Http/Controllers/ConversationController.php @@ -0,0 +1,65 @@ + 'boolean', + ]; + } + + public function participants(): HasMany + { + return $this->hasMany(Participant::class); + } + + public function messages(): HasMany + { + return $this->hasMany(Message::class); + } + + public function users(): BelongsToMany + { + return $this->belongsToMany(User::class, 'participants') + ->withTimestamps() + ->using(Participant::class); // Optional, but links the pivot back to Participant model if needed. + } +} diff --git a/app/Models/Message.php b/app/Models/Message.php new file mode 100644 index 0000000..c7f4d2e --- /dev/null +++ b/app/Models/Message.php @@ -0,0 +1,40 @@ + 'datetime', + ]; + } + + public function conversation(): BelongsTo + { + return $this->belongsTo(Conversation::class); + } + + public function user(): BelongsTo + { + return $this->belongsTo(User::class); + } +} diff --git a/app/Models/Participant.php b/app/Models/Participant.php new file mode 100644 index 0000000..a267400 --- /dev/null +++ b/app/Models/Participant.php @@ -0,0 +1,32 @@ +belongsTo(Conversation::class); + } + + public function user(): BelongsTo + { + return $this->belongsTo(User::class); + } +} diff --git a/database/migrations/2026_04_10_101124_create_conversations_table.php b/database/migrations/2026_04_10_101124_create_conversations_table.php new file mode 100644 index 0000000..c5a9d15 --- /dev/null +++ b/database/migrations/2026_04_10_101124_create_conversations_table.php @@ -0,0 +1,30 @@ +ulid('id')->primary(); + $table->string('label')->nullable(); + $table->boolean('is_group')->default(false); + $table->softDeletesTz(); + $table->timestampsTz(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('conversations'); + } +}; diff --git a/database/migrations/2026_04_10_101315_create_messages_table.php b/database/migrations/2026_04_10_101315_create_messages_table.php new file mode 100644 index 0000000..ad3eb06 --- /dev/null +++ b/database/migrations/2026_04_10_101315_create_messages_table.php @@ -0,0 +1,35 @@ +ulid('id')->primary(); + $table->foreignUlid('user_id')->constrained('users')->nullOnDelete(); + $table->string('sender_name'); + $table->string('sender_avatar_url')->nullable(); + $table->foreignUlid('conversation_id')->constrained('conversations')->cascadeOnDelete(); + $table->text('body')->nullable(); + $table->timestampTz('read_at')->nullable(); + $table->softDeletesTz(); + $table->timestampsTz(); + + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('messages'); + } +}; diff --git a/database/migrations/2026_04_10_101621_create_participants_table.php b/database/migrations/2026_04_10_101621_create_participants_table.php new file mode 100644 index 0000000..bf06464 --- /dev/null +++ b/database/migrations/2026_04_10_101621_create_participants_table.php @@ -0,0 +1,31 @@ +ulid('id')->primary(); + $table->foreignUlid('conversation_id')->constrained('conversations')->cascadeOnDelete(); + $table->foreignUlid('user_id')->constrained('users')->cascadeOnDelete(); + $table->timestampsTz(); + + $table->unique(['conversation_id', 'user_id']); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('participants'); + } +};