Skip to content

Commit 0d10f91

Browse files
committed
Basic api implemented for current data model
1 parent e82e4d5 commit 0d10f91

File tree

9 files changed

+221
-41
lines changed

9 files changed

+221
-41
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package no.nav.klage.document.api
2+
3+
data class CommentInput(
4+
val text: String,
5+
val author: Author
6+
) {
7+
data class Author(
8+
val name: String,
9+
val ident: String
10+
)
11+
}

src/main/kotlin/no/nav/klage/document/api/CommentView.kt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@ import java.util.*
66
data class CommentView(
77
val id: UUID,
88
val text: String,
9+
val author: Author,
10+
val comments: List<CommentView> = emptyList(),
911
val created: LocalDateTime,
1012
val modified: LocalDateTime
11-
)
13+
) {
14+
data class Author(
15+
val name: String,
16+
val ident: String
17+
)
18+
}
Lines changed: 77 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
package no.nav.klage.document.api
22

3+
import no.nav.klage.document.domain.Comment
4+
import no.nav.klage.document.domain.Document
5+
import no.nav.klage.document.service.CommentService
6+
import no.nav.klage.document.service.DocumentService
37
import no.nav.klage.document.util.getLogger
4-
import org.springframework.web.bind.annotation.GetMapping
5-
import org.springframework.web.bind.annotation.PostMapping
6-
import org.springframework.web.bind.annotation.RequestBody
7-
import org.springframework.web.bind.annotation.RestController
8+
import org.springframework.web.bind.annotation.*
9+
import java.util.*
810

911
@RestController
10-
class DocumentController() {
12+
class DocumentController(
13+
private val documentService: DocumentService,
14+
private val commentService: CommentService
15+
) {
1116

1217
companion object {
1318
@Suppress("JAVA_CLASS_ON_COMPANION")
@@ -19,37 +24,85 @@ class DocumentController() {
1924
@RequestBody json: String
2025
): DocumentView {
2126
logger.debug("createDocument: received json: {}", json)
22-
TODO()
27+
return mapToDocumentView(documentService.createDocument(json))
2328
}
2429

2530
@GetMapping("/documents/{documentId}")
26-
fun getDocument(): DocumentView {
31+
fun getDocument(@PathVariable("documentId") documentId: UUID): DocumentView {
2732
logger.debug("getDocument")
28-
TODO()
33+
return mapToDocumentView(documentService.getDocument(documentId))
2934
}
3035

31-
@PostMapping("/documents/{documentId}/commentthreads")
32-
fun createCommentThread() {
33-
logger.debug("createCommentThread")
34-
TODO()
36+
@PostMapping("/documents/{documentId}/comments")
37+
fun createComment(
38+
@PathVariable("documentId") documentId: UUID,
39+
@RequestBody commentInput: CommentInput
40+
): CommentView {
41+
logger.debug("createComment")
42+
return mapCommentToView(
43+
commentService.createComment(
44+
documentId = documentId,
45+
text = commentInput.text,
46+
authorName = commentInput.author.name,
47+
authorIdent = commentInput.author.ident
48+
)
49+
)
3550
}
3651

37-
@GetMapping("/documents/{documentId}/commentthreads")
38-
fun getAllThreadsWithComments() {
39-
logger.debug("getAllThreadsWithComments")
40-
TODO()
52+
@GetMapping("/documents/{documentId}/comments")
53+
fun getAllCommentsWithPossibleThreads(
54+
@PathVariable("documentId") documentId: UUID
55+
): List<CommentView> {
56+
logger.debug("getAllCommentsWithPossibleThreads")
57+
return commentService.getComments(documentId).map { mapCommentToView(it) }
4158
}
4259

43-
@PostMapping("/documents/{documentId}/commentthreads/{threadId}")
44-
fun createCommentInThread() {
45-
logger.debug("createCommentInThread")
46-
TODO()
60+
@PostMapping("/documents/{documentId}/comments/{commentId}")
61+
fun replyToComment(
62+
@PathVariable("documentId") documentId: UUID,
63+
@PathVariable("commentId") commentId: UUID,
64+
@RequestBody commentInput: CommentInput,
65+
): CommentView {
66+
logger.debug("replyToComment")
67+
return mapCommentToView(
68+
commentService.replyToComment(
69+
documentId = documentId,
70+
parentCommentId = commentId,
71+
text = commentInput.text,
72+
authorName = commentInput.author.name,
73+
authorIdent = commentInput.author.ident
74+
)
75+
)
4776
}
4877

49-
@GetMapping("/documents/{documentId}/commentthreads/{threadId}")
50-
fun getCommentsInThread() {
51-
logger.debug("getCommentsInThread")
52-
TODO()
78+
@GetMapping("/documents/{documentId}/comments/{commentId}")
79+
fun getCommentWithPossibleThread(
80+
@PathVariable("documentId") documentId: UUID,
81+
@PathVariable("commentId") commentId: UUID
82+
): CommentView {
83+
logger.debug("getCommentWithPossibleThread")
84+
return mapCommentToView(commentService.getComment(commentId = commentId))
5385
}
5486

87+
private fun mapToDocumentView(document: Document): DocumentView =
88+
DocumentView(
89+
id = document.id,
90+
json = document.json,
91+
created = document.created,
92+
modified = document.modified
93+
)
94+
95+
private fun mapCommentToView(comment: Comment): CommentView =
96+
CommentView(
97+
id = comment.id,
98+
text = comment.text,
99+
author = CommentView.Author(
100+
name = comment.authorName,
101+
ident = comment.authorIdent
102+
),
103+
comments = comment.comments.map { mapCommentToView(it) },
104+
created = comment.created,
105+
modified = comment.modified
106+
)
107+
55108
}

src/main/kotlin/no/nav/klage/document/domain/Comment.kt

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,32 @@
11
package no.nav.klage.document.domain
22

3+
import org.hibernate.annotations.BatchSize
4+
import org.hibernate.annotations.Fetch
5+
import org.hibernate.annotations.FetchMode
36
import java.time.LocalDateTime
47
import java.util.*
5-
import javax.persistence.Column
6-
import javax.persistence.Entity
7-
import javax.persistence.Id
8-
import javax.persistence.Table
8+
import javax.persistence.*
99

1010
@Entity
11-
@Table(name = "document_comment", schema = "klage")
11+
@Table(name = "comment", schema = "klage")
1212
class Comment(
1313
@Id
1414
val id: UUID = UUID.randomUUID(),
15+
@Column(name = "parent_comment_id")
16+
var parentCommentId: UUID? = null,
1517
@Column(name = "document_id")
1618
var documentId: UUID,
1719
@Column(name = "text")
1820
var text: String,
21+
@Column(name = "author_name")
22+
var authorName: String,
23+
@Column(name = "author_ident")
24+
var authorIdent: String,
25+
@OneToMany(cascade = [CascadeType.ALL], orphanRemoval = true, fetch = FetchType.EAGER)
26+
@JoinColumn(name = "parent_comment_id", referencedColumnName = "id")
27+
@Fetch(FetchMode.SELECT)
28+
@BatchSize(size = 100)
29+
val comments: MutableSet<Comment> = mutableSetOf(),
1930
@Column(name = "created")
2031
val created: LocalDateTime,
2132
@Column(name = "modified")

src/main/kotlin/no/nav/klage/document/repositories/CommentRepository.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ import java.util.*
66

77
interface CommentRepository : JpaRepository<Comment, UUID> {
88

9-
fun findByDocumentId(documentId: UUID): List<Comment>
9+
/**
10+
* Only find parent comments
11+
*/
12+
fun findByDocumentIdAndParentCommentIdIsNull(documentId: UUID): List<Comment>
1013

1114
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package no.nav.klage.document.service
2+
3+
import no.nav.klage.document.domain.Comment
4+
import no.nav.klage.document.repositories.CommentRepository
5+
import org.springframework.stereotype.Service
6+
import org.springframework.transaction.annotation.Transactional
7+
import java.time.LocalDateTime
8+
import java.util.*
9+
10+
@Service
11+
@Transactional
12+
class CommentService(private val commentRepository: CommentRepository) {
13+
14+
fun createComment(documentId: UUID, text: String, authorName: String, authorIdent: String): Comment {
15+
val now = LocalDateTime.now()
16+
return commentRepository.save(
17+
Comment(
18+
documentId = documentId,
19+
text = text,
20+
authorName = authorName,
21+
authorIdent = authorIdent,
22+
created = now,
23+
modified = now
24+
)
25+
)
26+
}
27+
28+
fun replyToComment(
29+
documentId: UUID,
30+
parentCommentId: UUID,
31+
text: String,
32+
authorName: String,
33+
authorIdent: String
34+
): Comment {
35+
val now = LocalDateTime.now()
36+
return commentRepository.save(
37+
Comment(
38+
documentId = documentId,
39+
parentCommentId = parentCommentId,
40+
text = text,
41+
authorName = authorName,
42+
authorIdent = authorIdent,
43+
created = now,
44+
modified = now
45+
)
46+
)
47+
}
48+
49+
fun getComments(documentId: UUID): List<Comment> {
50+
return commentRepository.findByDocumentIdAndParentCommentIdIsNull(documentId)
51+
}
52+
53+
fun getComment(commentId: UUID): Comment {
54+
return commentRepository.getById(commentId)
55+
}
56+
57+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package no.nav.klage.document.service
2+
3+
import no.nav.klage.document.domain.Document
4+
import no.nav.klage.document.repositories.DocumentRepository
5+
import org.springframework.stereotype.Service
6+
import org.springframework.transaction.annotation.Transactional
7+
import java.time.LocalDateTime
8+
import java.util.*
9+
10+
@Service
11+
@Transactional
12+
class DocumentService(private val documentRepository: DocumentRepository) {
13+
14+
fun createDocument(json: String): Document {
15+
val now = LocalDateTime.now()
16+
return documentRepository.save(
17+
Document(
18+
json = json,
19+
created = now,
20+
modified = now
21+
)
22+
)
23+
}
24+
25+
fun getDocument(documentId: UUID): Document {
26+
return documentRepository.getById(documentId)
27+
}
28+
29+
}

src/main/resources/db/migration/V1__Create_baseline.sql

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,17 @@ CREATE TABLE klage.document
2222
modified TIMESTAMP NOT NULL
2323
);
2424

25-
CREATE TABLE klage.document_comment
25+
CREATE TABLE klage.comment
2626
(
27-
id UUID PRIMARY KEY,
28-
document_id UUID REFERENCES klage.document (id),
29-
text TEXT NOT NULL,
30-
created TIMESTAMP NOT NULL,
31-
modified TIMESTAMP NOT NULL
27+
id UUID PRIMARY KEY,
28+
parent_comment_id UUID REFERENCES klage.comment (id),
29+
document_id UUID REFERENCES klage.document (id),
30+
text TEXT NOT NULL,
31+
author_name TEXT NOT NULL,
32+
author_ident TEXT NOT NULL,
33+
created TIMESTAMP NOT NULL,
34+
modified TIMESTAMP NOT NULL
3235
);
3336

34-
CREATE INDEX document_comment_ix ON klage.document_comment (document_id);
37+
CREATE INDEX document_comment_ix ON klage.comment (document_id);
38+
CREATE INDEX comment_parent_comment_ix ON klage.comment (parent_comment_id);

src/test/kotlin/no/nav/klage/document/repositories/RepositoryTest.kt

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,18 @@ class RepositoryTest {
5656
val comment1 = Comment(
5757
documentId = document.id,
5858
text = "my comment 1",
59+
authorName = "Kalle Anka",
60+
authorIdent = "Z123456",
5961
created = now.plusDays(1),
6062
modified = now.plusDays(1)
6163
)
6264

6365
val comment2 = Comment(
6466
documentId = document.id,
65-
text = "my comment 2",
67+
parentCommentId = comment1.id,
68+
text = "my sub comment 2",
69+
authorName = "Kajsa Anka",
70+
authorIdent = "Z654321",
6671
created = now.plusDays(2),
6772
modified = now.plusDays(2)
6873
)
@@ -73,9 +78,9 @@ class RepositoryTest {
7378
testEntityManager.flush()
7479
testEntityManager.clear()
7580

76-
val comments = commentRepository.findByDocumentId(document.id)
81+
val comments = commentRepository.findByDocumentIdAndParentCommentIdIsNull(document.id)
7782

78-
assertThat(comments).hasSize(2)
83+
assertThat(comments.first().comments).hasSize(1)
7984
}
8085

8186
}

0 commit comments

Comments
 (0)