feat(backend,api): Add comment

This commit is contained in:
2025-05-04 10:35:29 +02:00
parent 324c534fdf
commit 6a751285dc
13 changed files with 184 additions and 11 deletions

View File

@@ -656,6 +656,8 @@ components:
$ref: "#/components/schemas/FormOptionDto"
type:
$ref: "#/components/schemas/FormElementType"
comments:
$ref: "#/components/schemas/PagedCommentDto"
CreateFormElementDto:
type: object
@@ -714,20 +716,27 @@ components:
required:
- id
- message
- formElementId
- createdAt
- modifiedAt
- createdBy
properties:
id:
type: string
format: uuid
message:
type: string
formElementId:
type: string
format: uuid
createdAt:
type: string
format: date-time
modifiedAt:
type: string
format: date-time
createdBy:
$ref: "#/components/schemas/UserDto"
CreateCommentDto:
type: object

View File

@@ -1,5 +1,6 @@
package com.betriebsratkanzlei.legalconsenthub.application_form
import com.betriebsratkanzlei.legalconsenthub.form_element.FormElementMapper
import com.betriebsratkanzlei.legalconsenthub.security.CustomJwtTokenPrincipal
import com.betriebsratkanzlei.legalconsenthub.user.User
import com.betriebsratkanzlei.legalconsenthub.user.UserMapper

View File

@@ -21,6 +21,4 @@ class PagedApplicationFormMapper(private val applicationFormMapper: ApplicationF
first = pagedApplicationForm.isFirst,
)
}
// fun toApplicationForm(applicationForm: ApplicationFormDto): ApplicationForm {}
// fun toApplicationForm(createApplicationFormDto: CreateApplicationFormDto): ApplicationForm
}

View File

@@ -0,0 +1,47 @@
package com.betriebsratkanzlei.legalconsenthub.comment;
import com.betriebsratkanzlei.legalconsenthub.form_element.FormElement
import com.betriebsratkanzlei.legalconsenthub.user.User
import jakarta.persistence.AttributeOverride
import jakarta.persistence.AttributeOverrides
import jakarta.persistence.Column
import jakarta.persistence.Embedded
import jakarta.persistence.Entity
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn
import jakarta.persistence.ManyToOne
import org.springframework.data.annotation.CreatedDate
import org.springframework.data.annotation.LastModifiedDate
import java.time.LocalDateTime
import java.util.UUID;
@Entity
class Comment(
@Id
@GeneratedValue
var id: UUID? = null,
@Column(nullable = false)
var message: String = "",
@Embedded
@AttributeOverrides(
AttributeOverride(name = "id", column = Column(name = "created_by_id", nullable = false)),
AttributeOverride(name = "name", column = Column(name = "created_by_name", nullable = false))
)
var createdBy: User,
@CreatedDate
@Column(nullable = false)
var createdAt: LocalDateTime? = null,
@LastModifiedDate
@Column(nullable = false)
var modifiedAt: LocalDateTime? = null,
@ManyToOne
@JoinColumn(name = "form_element_id", nullable = false)
var formElement: FormElement? = null,
)

View File

@@ -0,0 +1,35 @@
package com.betriebsratkanzlei.legalconsenthub.comment
import com.betriebsratkanzlei.legalconsenthub.error.FormElementNotFoundException
import com.betriebsratkanzlei.legalconsenthub.form_element.FormElementRepository
import com.betriebsratkanzlei.legalconsenthub.user.UserMapper
import com.betriebsratkanzlei.legalconsenthub_api.model.CommentDto
import org.springframework.stereotype.Component
import java.time.LocalDateTime
@Component
class CommentMapper(private val userMapper: UserMapper, private val formElementRepository: FormElementRepository) {
fun toCommentDto(comment: Comment): CommentDto {
return CommentDto(
id = comment.id ?: throw IllegalStateException("Comment ID must not be null!"),
message = comment.message,
createdAt = comment.createdAt ?: LocalDateTime.now(),
modifiedAt = comment.modifiedAt ?: LocalDateTime.now(),
createdBy = userMapper.toUserDto(comment.createdBy),
formElementId = comment.formElement?.id ?: throw IllegalStateException("FormElement ID must not be null!"),
)
}
fun toComment(commentDto: CommentDto): Comment {
val formElement = formElementRepository.findById(commentDto.formElementId).orElseThrow { FormElementNotFoundException(commentDto.formElementId) }
return Comment(
id = commentDto.id,
message = commentDto.message,
createdAt = commentDto.createdAt,
modifiedAt = commentDto.modifiedAt,
createdBy = userMapper.toUser(commentDto.createdBy),
formElement = formElement
)
}
}

View File

@@ -0,0 +1,8 @@
package com.betriebsratkanzlei.legalconsenthub.comment
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.stereotype.Repository
import java.util.UUID
@Repository
interface CommentRepository : JpaRepository<Comment, UUID>

View File

@@ -0,0 +1,22 @@
package com.betriebsratkanzlei.legalconsenthub.comment
import com.betriebsratkanzlei.legalconsenthub_api.model.PagedCommentDto
import org.springframework.data.domain.Page
import org.springframework.stereotype.Component
@Component
class PagedCommentMapper(private val commentMapper: CommentMapper) {
fun toPagedCommentDto(pagedComment: Page<Comment>): PagedCommentDto {
return PagedCommentDto(
content = pagedComment.content.map { commentMapper.toCommentDto(it) },
number = pagedComment.number,
propertySize = pagedComment.size,
numberOfElements = pagedComment.numberOfElements,
last = pagedComment.isLast,
totalPages = pagedComment.totalPages,
totalElements = pagedComment.totalElements,
empty = pagedComment.isEmpty,
first = pagedComment.isFirst,
)
}
}

View File

@@ -0,0 +1,5 @@
package com.betriebsratkanzlei.legalconsenthub.error
import java.util.UUID
class FormElementNotFoundException(id: UUID): RuntimeException("Couldn't find form element with ID: $id")

View File

@@ -1,7 +1,9 @@
package com.betriebsratkanzlei.legalconsenthub.form_element;
import com.betriebsratkanzlei.legalconsenthub.application_form.ApplicationForm
import com.betriebsratkanzlei.legalconsenthub.comment.Comment
import com.betriebsratkanzlei.legalconsenthub_api.model.FormElementType
import jakarta.persistence.CascadeType
import jakarta.persistence.CollectionTable
import jakarta.persistence.Column
import jakarta.persistence.ElementCollection
@@ -10,6 +12,7 @@ import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn
import jakarta.persistence.ManyToOne
import jakarta.persistence.OneToMany
import java.util.UUID;
@@ -28,5 +31,8 @@ class FormElement (
var options: MutableList<FormOption> = mutableListOf(),
@Column(nullable = false)
var type: FormElementType
var type: FormElementType,
@OneToMany(mappedBy = "formElement", cascade = [CascadeType.ALL], orphanRemoval = true)
var comments: MutableList<Comment> = mutableListOf(),
)

View File

@@ -1,14 +1,21 @@
package com.betriebsratkanzlei.legalconsenthub.application_form
package com.betriebsratkanzlei.legalconsenthub.form_element
import com.betriebsratkanzlei.legalconsenthub.application_form.ApplicationForm
import com.betriebsratkanzlei.legalconsenthub.application_form.ApplicationFormRepository
import com.betriebsratkanzlei.legalconsenthub.comment.CommentMapper
import com.betriebsratkanzlei.legalconsenthub.comment.PagedCommentMapper
import com.betriebsratkanzlei.legalconsenthub.error.ApplicationFormNotFoundException
import com.betriebsratkanzlei.legalconsenthub.form_element.FormElement
import com.betriebsratkanzlei.legalconsenthub_api.model.CreateFormElementDto
import com.betriebsratkanzlei.legalconsenthub_api.model.FormElementDto
import org.springframework.data.domain.PageImpl
import org.springframework.data.domain.PageRequest
import org.springframework.stereotype.Component
@Component
class FormElementMapper(
private val formOptionMapper: FormOptionMapper,
private val commentMapper: CommentMapper,
private val pagedCommentMapper: PagedCommentMapper,
private val applicationFormRepository: ApplicationFormRepository
) {
fun toFormElementDto(formElement: FormElement): FormElementDto {
@@ -17,19 +24,27 @@ class FormElementMapper(
options = formElement.options.map { formOptionMapper.toFormOptionDto(it) },
type = formElement.type,
applicationFormId = formElement.applicationForm?.id
?: throw IllegalStateException("ApplicationForm ID must not be null!")
?: throw IllegalStateException("ApplicationForm ID must not be null!"),
comments = if (formElement.comments.size > 0) pagedCommentMapper.toPagedCommentDto(
PageImpl(
formElement.comments.toList(),
PageRequest.of(0, formElement.comments.size),
formElement.comments.size.toLong()
)
) else null
)
}
fun toFormElement(formElement: FormElementDto): FormElement {
val applicationForm = applicationFormRepository.findById(formElement.applicationFormId)
.orElseThrow { ApplicationFormNotFoundException(formElement.applicationFormId) }
.orElseThrow { ApplicationFormNotFoundException(formElement.applicationFormId) }
return FormElement(
id = formElement.id,
options = formElement.options.map { formOptionMapper.toFormOption(it) }.toMutableList(),
type = formElement.type,
applicationForm = applicationForm
applicationForm = applicationForm,
comments = formElement.comments?.content?.map { commentMapper.toComment(it) }?.toMutableList() ?: mutableListOf()
)
}
@@ -38,7 +53,7 @@ class FormElementMapper(
id = null,
options = formElement.options.map { formOptionMapper.toFormOption(it) }.toMutableList(),
type = formElement.type,
applicationForm = applicationForm
applicationForm = applicationForm,
)
}
}

View File

@@ -0,0 +1,11 @@
package com.betriebsratkanzlei.legalconsenthub.form_element
import com.betriebsratkanzlei.legalconsenthub.comment.Comment
import org.springframework.data.domain.Page
import org.springframework.data.domain.Pageable
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.stereotype.Repository
import java.util.UUID
@Repository
interface FormElementRepository : JpaRepository<FormElement, UUID>

View File

@@ -1,6 +1,5 @@
package com.betriebsratkanzlei.legalconsenthub.application_form
package com.betriebsratkanzlei.legalconsenthub.form_element
import com.betriebsratkanzlei.legalconsenthub.form_element.FormOption
import com.betriebsratkanzlei.legalconsenthub_api.model.FormOptionDto
import org.springframework.stereotype.Component

View File

@@ -13,6 +13,18 @@ create table application_form
primary key (id)
);
create table comment
(
created_at timestamp(6) not null,
modified_at timestamp(6) not null,
form_element_id uuid not null,
id uuid not null,
created_by_id varchar(255) not null,
created_by_name varchar(255) not null,
message varchar(255) not null,
primary key (id)
);
create table form_element_options
(
employee_data_category tinyint not null check (employee_data_category between 0 and 3),
@@ -30,6 +42,11 @@ create table form_element
primary key (id)
);
alter table if exists comment
add constraint FKfg84w0i76tw9os13950272c6f
foreign key (form_element_id)
references form_element;
alter table if exists form_element_options
add constraint FKnq0lpby5nspv1xi27n9el6us6
foreign key (form_element_id)