diff --git a/src/main/java/com/example/solidconnection/chat/domain/ChatAttachment.java b/src/main/java/com/example/solidconnection/chat/domain/ChatAttachment.java new file mode 100644 index 000000000..5c0f5e651 --- /dev/null +++ b/src/main/java/com/example/solidconnection/chat/domain/ChatAttachment.java @@ -0,0 +1,35 @@ +package com.example.solidconnection.chat.domain; + +import com.example.solidconnection.common.BaseEntity; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.ManyToOne; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class ChatAttachment extends BaseEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(nullable = false) + private Boolean isImage; + + @Column(nullable = false, length = 500) + private String url; + + @Column(length = 500) + private String thumbnailUrl; + + @ManyToOne(fetch = FetchType.LAZY) + private ChatMessage chatMessage; +} diff --git a/src/main/java/com/example/solidconnection/chat/domain/ChatMessage.java b/src/main/java/com/example/solidconnection/chat/domain/ChatMessage.java new file mode 100644 index 000000000..8d513c5a7 --- /dev/null +++ b/src/main/java/com/example/solidconnection/chat/domain/ChatMessage.java @@ -0,0 +1,38 @@ +package com.example.solidconnection.chat.domain; + +import com.example.solidconnection.common.BaseEntity; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.OneToMany; +import java.util.ArrayList; +import java.util.List; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class ChatMessage extends BaseEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(nullable = false, length = 500) + private String content; + + private long senderId; + + @ManyToOne(fetch = FetchType.LAZY) + private ChatRoom chatRoom; + + @OneToMany(mappedBy = "chatMessage", cascade = CascadeType.ALL) + private List chatAttachments = new ArrayList<>(); +} diff --git a/src/main/java/com/example/solidconnection/chat/domain/ChatParticipant.java b/src/main/java/com/example/solidconnection/chat/domain/ChatParticipant.java new file mode 100644 index 000000000..169e1dd06 --- /dev/null +++ b/src/main/java/com/example/solidconnection/chat/domain/ChatParticipant.java @@ -0,0 +1,37 @@ +package com.example.solidconnection.chat.domain; + +import com.example.solidconnection.common.BaseEntity; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; +import jakarta.persistence.UniqueConstraint; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Table(uniqueConstraints = { + @UniqueConstraint( + name = "uk_chat_participant_chat_room_id_site_user_id", + columnNames = {"chat_room_id", "site_user_id"} + ) +}) +public class ChatParticipant extends BaseEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "site_user_id") + private long siteUserId; + + @ManyToOne(fetch = FetchType.LAZY) + private ChatRoom chatRoom; +} diff --git a/src/main/java/com/example/solidconnection/chat/domain/ChatReadStatus.java b/src/main/java/com/example/solidconnection/chat/domain/ChatReadStatus.java new file mode 100644 index 000000000..13d4ac646 --- /dev/null +++ b/src/main/java/com/example/solidconnection/chat/domain/ChatReadStatus.java @@ -0,0 +1,35 @@ +package com.example.solidconnection.chat.domain; + +import com.example.solidconnection.common.BaseEntity; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import jakarta.persistence.UniqueConstraint; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Table(uniqueConstraints = { + @UniqueConstraint( + name = "uk_chat_read_status_chat_room_id_chat_participant_id", + columnNames = {"chat_room_id", "chat_participant_id"} + ) +}) +public class ChatReadStatus extends BaseEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "chat_room_id") + private long chatRoomId; + + @Column(name = "chat_participant_id") + private long chatParticipantId; +} diff --git a/src/main/java/com/example/solidconnection/chat/domain/ChatRoom.java b/src/main/java/com/example/solidconnection/chat/domain/ChatRoom.java new file mode 100644 index 000000000..020befe5f --- /dev/null +++ b/src/main/java/com/example/solidconnection/chat/domain/ChatRoom.java @@ -0,0 +1,32 @@ +package com.example.solidconnection.chat.domain; + +import com.example.solidconnection.common.BaseEntity; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.OneToMany; +import java.util.ArrayList; +import java.util.List; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class ChatRoom extends BaseEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private boolean isGroup = false; + + @OneToMany(mappedBy = "chatRoom", cascade = CascadeType.ALL) + private List chatParticipants = new ArrayList<>(); + + @OneToMany(mappedBy = "chatRoom", cascade = CascadeType.ALL) + private List chatMessages = new ArrayList<>(); +} diff --git a/src/main/resources/db/migration/V24__add_chat_related_tables.sql b/src/main/resources/db/migration/V24__add_chat_related_tables.sql new file mode 100644 index 000000000..20898a147 --- /dev/null +++ b/src/main/resources/db/migration/V24__add_chat_related_tables.sql @@ -0,0 +1,55 @@ +CREATE TABLE chat_room +( + id BIGINT AUTO_INCREMENT PRIMARY KEY, + is_group BOOLEAN NOT NULL DEFAULT false, + created_at DATETIME(6) NOT NULL, + updated_at DATETIME(6) NOT NULL +); + +CREATE TABLE chat_participant +( + id BIGINT AUTO_INCREMENT PRIMARY KEY, + site_user_id BIGINT NOT NULL, + chat_room_id BIGINT NOT NULL, + created_at DATETIME(6) NOT NULL, + updated_at DATETIME(6) NOT NULL, + CONSTRAINT FK_CHAT_PARTICIPANT_CHAT_ROOM_ID FOREIGN KEY (chat_room_id) REFERENCES chat_room (id), + CONSTRAINT FK_CHAT_PARTICIPANT_SITE_USER_ID FOREIGN KEY (site_user_id) REFERENCES site_user (id), + CONSTRAINT UK_CHAT_PARTICIPANT_CHAT_ROOM_ID_SITE_USER_ID UNIQUE (chat_room_id, site_user_id) +); + +CREATE TABLE chat_message +( + id BIGINT AUTO_INCREMENT PRIMARY KEY, + content VARCHAR(500) NOT NULL, + sender_id BIGINT NOT NULL, + chat_room_id BIGINT NOT NULL, + created_at DATETIME(6) NOT NULL, + updated_at DATETIME(6) NOT NULL, + CONSTRAINT FK_CHAT_MESSAGE_CHAT_ROOM_ID FOREIGN KEY (chat_room_id) REFERENCES chat_room (id), + CONSTRAINT FK_CHAT_MESSAGE_SENDER_ID FOREIGN KEY (sender_id) REFERENCES chat_participant (id) +); + +CREATE TABLE chat_attachment +( + id BIGINT AUTO_INCREMENT PRIMARY KEY, + is_image BOOLEAN NOT NULL, + url VARCHAR(500) NOT NULL, + thumbnail_url VARCHAR(500), + chat_message_id BIGINT NOT NULL, + created_at DATETIME(6) NOT NULL, + updated_at DATETIME(6) NOT NULL, + CONSTRAINT FK_CHAT_ATTACHMENT_CHAT_MESSAGE_ID FOREIGN KEY (chat_message_id) REFERENCES chat_message (id) +); + +CREATE TABLE chat_read_status +( + id BIGINT AUTO_INCREMENT PRIMARY KEY, + chat_room_id BIGINT NOT NULL, + chat_participant_id BIGINT NOT NULL, + created_at DATETIME(6) NOT NULL, + updated_at DATETIME(6) NOT NULL, + CONSTRAINT FK_CHAT_READ_STATUS_CHAT_ROOM_ID FOREIGN KEY (chat_room_id) REFERENCES chat_room (id), + CONSTRAINT FK_CHAT_READ_STATUS_CHAT_PARTICIPANT_ID FOREIGN KEY (chat_participant_id) REFERENCES chat_participant (id), + CONSTRAINT UK_CHAT_READ_STATUS_CHAT_ROOM_ID_CHAT_PARTICIPANT_ID UNIQUE (chat_room_id, chat_participant_id) +);