Move Entity.Request to Routes

This commit is contained in:
2020-04-15 00:43:59 +02:00
parent 9e50e3af58
commit 7dc1772708
15 changed files with 239 additions and 216 deletions

View File

@@ -1,5 +1,5 @@
<component name="ProjectRunConfigurationManager"> <component name="ProjectRunConfigurationManager">
<configuration default="false" name="Build and start Docker" type="docker-deploy" factoryName="docker-compose.yml" server-name="Docker"> <configuration default="false" name="Build and start all Docker" type="docker-deploy" factoryName="docker-compose.yml" server-name="Docker">
<deployment type="docker-compose.yml"> <deployment type="docker-compose.yml">
<settings> <settings>
<option name="envVars"> <option name="envVars">

View File

@@ -0,0 +1,27 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Run dependencies" type="docker-deploy" factoryName="docker-compose.yml" server-name="Docker">
<deployment type="docker-compose.yml">
<settings>
<option name="envVars">
<list>
<DockerEnvVarImpl>
<option name="name" value="SEND_GRID_KEY" />
<option name="value" value="$SEND_GRID_KEY$" />
</DockerEnvVarImpl>
</list>
</option>
<option name="commandLineOptions" value="--build" />
<option name="services">
<list>
<option value="db" />
<option value="elasticsearch" />
<option value="rabbitmq" />
<option value="redis" />
</list>
</option>
<option name="sourceFilePath" value="docker-compose.yml" />
</settings>
</deployment>
<method v="2" />
</configuration>
</component>

View File

@@ -2,6 +2,14 @@
<configuration default="false" name="Start Db" type="docker-deploy" factoryName="docker-compose.yml" server-name="Docker"> <configuration default="false" name="Start Db" type="docker-deploy" factoryName="docker-compose.yml" server-name="Docker">
<deployment type="docker-compose.yml"> <deployment type="docker-compose.yml">
<settings> <settings>
<option name="envVars">
<list>
<DockerEnvVarImpl>
<option name="name" value="SEND_GRID_KEY" />
<option name="value" value="$SEND_GRID_KEY$" />
</DockerEnvVarImpl>
</list>
</option>
<option name="commandLineOptions" value="--build" /> <option name="commandLineOptions" value="--build" />
<option name="services"> <option name="services">
<list> <list>

View File

@@ -2,6 +2,14 @@
<configuration default="false" name="Start OpenAPI" type="docker-deploy" factoryName="docker-compose.yml" server-name="Docker"> <configuration default="false" name="Start OpenAPI" type="docker-deploy" factoryName="docker-compose.yml" server-name="Docker">
<deployment type="docker-compose.yml"> <deployment type="docker-compose.yml">
<settings> <settings>
<option name="envVars">
<list>
<DockerEnvVarImpl>
<option name="name" value="SEND_GRID_KEY" />
<option name="value" value="$SEND_GRID_KEY$" />
</DockerEnvVarImpl>
</list>
</option>
<option name="commandLineOptions" value="--build" /> <option name="commandLineOptions" value="--build" />
<option name="services"> <option name="services">
<list> <list>

View File

@@ -0,0 +1,24 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Start RabbitMQ" type="docker-deploy" factoryName="docker-compose.yml" server-name="Docker">
<deployment type="docker-compose.yml">
<settings>
<option name="envVars">
<list>
<DockerEnvVarImpl>
<option name="name" value="SEND_GRID_KEY" />
<option name="value" value="$SEND_GRID_KEY$" />
</DockerEnvVarImpl>
</list>
</option>
<option name="commandLineOptions" value="--build" />
<option name="services">
<list>
<option value="rabbitmq" />
</list>
</option>
<option name="sourceFilePath" value="docker-compose.yml" />
</settings>
</deployment>
<method v="2" />
</configuration>
</component>

View File

@@ -1,5 +1,5 @@
<component name="ProjectRunConfigurationManager"> <component name="ProjectRunConfigurationManager">
<configuration default="false" name="Docker" type="docker-deploy" factoryName="docker-compose.yml" server-name="Docker"> <configuration default="false" name="Start Redis" type="docker-deploy" factoryName="docker-compose.yml" server-name="Docker">
<deployment type="docker-compose.yml"> <deployment type="docker-compose.yml">
<settings> <settings>
<option name="envVars"> <option name="envVars">
@@ -11,6 +11,11 @@
</list> </list>
</option> </option>
<option name="commandLineOptions" value="--build" /> <option name="commandLineOptions" value="--build" />
<option name="services">
<list>
<option value="redis" />
</list>
</option>
<option name="sourceFilePath" value="docker-compose.yml" /> <option name="sourceFilePath" value="docker-compose.yml" />
</settings> </settings>
</deployment> </deployment>

View File

@@ -1,42 +0,0 @@
package fr.dcproject.entity.request
import fr.dcproject.entity.ArticleFull
import fr.dcproject.entity.Citizen
import java.util.*
import fr.dcproject.entity.Article as ArticleEntity
class Article(
val id: UUID?,
val title: String,
val anonymous: Boolean = true,
val content: String,
val description: String,
val tags: List<String> = emptyList(),
val draft: Boolean = false,
val versionId: UUID?
) :
Request {
fun merge(article: ArticleFull) {
article.title = this.title
article.content = this.content
article.description = this.description
article.tags = this.tags.distinct()
article.anonymous = this.anonymous
article.draft = this.draft
article.versionId = this.versionId ?: UUID.randomUUID()
}
fun create(createdBy: Citizen): ArticleEntity {
return ArticleEntity(
id ?: UUID.randomUUID(),
title,
anonymous,
content,
description,
tags,
draft,
createdBy = createdBy
).apply { this.versionId = this@Article.versionId ?: UUID.randomUUID() }
}
}

View File

@@ -1,5 +0,0 @@
package fr.dcproject.entity.request
class Comment(
val content: String
) : Request

View File

@@ -1,48 +0,0 @@
package fr.dcproject.entity.request
import fr.dcproject.entity.ArticleRef
import fr.dcproject.entity.Citizen
import fr.dcproject.entity.CitizenSimple
import fr.dcproject.entity.ConstitutionSimple
import fr.postgresjson.entity.immutable.UuidEntity
import java.util.*
class Constitution(
var title: String,
var anonymous: Boolean = true,
var titles: MutableList<Title> = mutableListOf(),
var draft: Boolean = false,
var lastVersion: Boolean = false,
var versionId: UUID = UUID.randomUUID()
) {
init {
titles.forEachIndexed { index, title ->
title.rank = index
}
}
class Title(
id: UUID = UUID.randomUUID(),
var name: String,
var rank: Int? = null,
var articles: MutableList<ArticleRef> = mutableListOf()
) : UuidEntity(id) {
fun create(): ConstitutionSimple.TitleSimple<ArticleRef> {
return ConstitutionSimple.TitleSimple(
id, name, rank, articles
)
}
}
fun create(createdBy: Citizen): ConstitutionSimple<CitizenSimple, ConstitutionSimple.TitleSimple<ArticleRef>> {
return ConstitutionSimple(
title = title,
titles = titles.create(),
createdBy = createdBy,
versionId = versionId
)
}
}
fun List<Constitution.Title>.create(): MutableList<ConstitutionSimple.TitleSimple<ArticleRef>> =
map { it.create() }.toMutableList()

View File

@@ -1,11 +0,0 @@
package fr.dcproject.entity.request
import io.ktor.application.ApplicationCall
interface Request
interface RequestBuilder<E> {
suspend fun getContent(call: ApplicationCall): E
}
suspend fun <E> ApplicationCall.getContent(builder: RequestBuilder<E>) = builder.getContent(this)

View File

@@ -6,9 +6,10 @@ import fr.dcproject.event.ArticleUpdate
import fr.dcproject.repository.Article.Filter import fr.dcproject.repository.Article.Filter
import fr.dcproject.security.voter.ArticleVoter.Action.CREATE import fr.dcproject.security.voter.ArticleVoter.Action.CREATE
import fr.dcproject.security.voter.ArticleVoter.Action.VIEW import fr.dcproject.security.voter.ArticleVoter.Action.VIEW
import fr.ktorVoter.assertCan
import fr.dcproject.views.ArticleViewManager import fr.dcproject.views.ArticleViewManager
import fr.ktorVoter.assertCan
import fr.postgresjson.repository.RepositoryI import fr.postgresjson.repository.RepositoryI
import io.ktor.application.ApplicationCall
import io.ktor.application.application import io.ktor.application.application
import io.ktor.application.call import io.ktor.application.call
import io.ktor.locations.KtorExperimentalLocationsAPI import io.ktor.locations.KtorExperimentalLocationsAPI
@@ -19,8 +20,8 @@ import io.ktor.request.receive
import io.ktor.response.respond import io.ktor.response.respond
import io.ktor.routing.Route import io.ktor.routing.Route
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import java.util.*
import fr.dcproject.entity.Article as ArticleEntity import fr.dcproject.entity.Article as ArticleEntity
import fr.dcproject.entity.request.Article as ArticleEntityRequest
import fr.dcproject.repository.Article as ArticleRepository import fr.dcproject.repository.Article as ArticleRepository
@KtorExperimentalLocationsAPI @KtorExperimentalLocationsAPI
@@ -55,7 +56,33 @@ object ArticlesPaths {
} }
@Location("/articles") @Location("/articles")
class PostArticleRequest class PostArticleRequest {
class Article(
val id: UUID?,
val title: String,
val anonymous: Boolean = true,
val content: String,
val description: String,
val tags: List<String> = emptyList(),
val draft: Boolean = false,
val versionId: UUID?
)
suspend fun getNewArticle(call: ApplicationCall): ArticleEntity = call.receive<Article>().run {
ArticleEntity(
id ?: UUID.randomUUID(),
title,
anonymous,
content,
description,
tags,
draft,
createdBy = call.citizen
).also {
it.versionId = versionId ?: UUID.randomUUID()
}
}
}
} }
@KtorExperimentalLocationsAPI @KtorExperimentalLocationsAPI
@@ -82,20 +109,17 @@ fun Route.article(repo: ArticleRepository, viewManager: ArticleViewManager) {
get<ArticlesPaths.ArticleVersionsRequest> { get<ArticlesPaths.ArticleVersionsRequest> {
assertCan(VIEW, it.article) assertCan(VIEW, it.article)
val versions = repo.findVerionsByVersionsId(it.page, it.limit, it.article.versionId) repo.findVerionsByVersionsId(it.page, it.limit, it.article.versionId).let {
call.respond(it)
call.respond(versions) }
} }
post<ArticlesPaths.PostArticleRequest> { post<ArticlesPaths.PostArticleRequest> {
val request = call.receive<ArticleEntityRequest>() it.getNewArticle(call).also { article ->
val article = request.create(citizen) assertCan(CREATE, article)
repo.upsert(article)
assertCan(CREATE, article) call.respond(article)
application.environment.monitor.raise(ArticleUpdate.event, ArticleUpdate(article))
repo.upsert(article) }
application.environment.monitor.raise(ArticleUpdate.event, ArticleUpdate(article))
call.respond(article)
} }
} }

View File

@@ -7,6 +7,7 @@ import fr.dcproject.repository.CommentArticle.Sort
import fr.dcproject.security.voter.CommentVoter.Action.CREATE import fr.dcproject.security.voter.CommentVoter.Action.CREATE
import fr.dcproject.security.voter.CommentVoter.Action.VIEW import fr.dcproject.security.voter.CommentVoter.Action.VIEW
import fr.ktorVoter.assertCan import fr.ktorVoter.assertCan
import io.ktor.application.ApplicationCall
import io.ktor.application.call import io.ktor.application.call
import io.ktor.http.HttpStatusCode import io.ktor.http.HttpStatusCode
import io.ktor.locations.KtorExperimentalLocationsAPI import io.ktor.locations.KtorExperimentalLocationsAPI
@@ -17,7 +18,6 @@ import io.ktor.request.receive
import io.ktor.response.respond import io.ktor.response.respond
import io.ktor.routing.Route import io.ktor.routing.Route
import fr.dcproject.entity.Comment as CommentEntity import fr.dcproject.entity.Comment as CommentEntity
import fr.dcproject.entity.request.Comment as CommentEntityRequest
import fr.dcproject.repository.CommentArticle as CommentArticleRepository import fr.dcproject.repository.CommentArticle as CommentArticleRepository
@KtorExperimentalLocationsAPI @KtorExperimentalLocationsAPI
@@ -35,6 +35,23 @@ object CommentArticlePaths {
val sort: Sort = Sort.fromString(sort) ?: Sort.CREATED_AT val sort: Sort = Sort.fromString(sort) ?: Sort.CREATED_AT
} }
@Location("/articles/{article}/comments")
class PostArticleCommentRequest(
val article: Article
) {
class Comment(
val content: String
)
suspend fun getComment(call: ApplicationCall) = call.receive<Comment>().run {
CommentEntity(
target = article,
createdBy = call.citizen,
content = content
)
}
}
@Location("/citizens/{citizen}/comments/articles") @Location("/citizens/{citizen}/comments/articles")
class CitizenCommentArticleRequest(val citizen: Citizen) class CitizenCommentArticleRequest(val citizen: Citizen)
} }
@@ -49,23 +66,18 @@ fun Route.commentArticle(repo: CommentArticleRepository) {
call.respond(HttpStatusCode.OK, comment) call.respond(HttpStatusCode.OK, comment)
} }
post<CommentArticlePaths.ArticleCommentRequest> { post<CommentArticlePaths.PostArticleCommentRequest> {
val content = call.receive<CommentEntityRequest>().content it.getComment(call).let { comment ->
val comment = CommentEntity( assertCan(CREATE, comment)
target = it.article, repo.comment(comment)
createdBy = citizen, call.respond(HttpStatusCode.Created, comment)
content = content }
)
assertCan(CREATE, comment)
repo.comment(comment)
call.respond(HttpStatusCode.Created, comment)
} }
get<CommentArticlePaths.CitizenCommentArticleRequest> { get<CommentArticlePaths.CitizenCommentArticleRequest> {
val comments = repo.findByCitizen(it.citizen) repo.findByCitizen(it.citizen).let { comments ->
assertCan(VIEW, comments.result) assertCan(VIEW, comments.result)
call.respond(comments) call.respond(comments)
}
} }
} }

View File

@@ -1,11 +1,15 @@
package fr.dcproject.routes package fr.dcproject.routes
import fr.dcproject.citizen import fr.dcproject.citizen
import fr.dcproject.entity.request.Constitution import fr.dcproject.entity.ArticleRef
import fr.dcproject.entity.CitizenSimple
import fr.dcproject.entity.ConstitutionSimple
import fr.dcproject.security.voter.ConstitutionVoter.Action.CREATE import fr.dcproject.security.voter.ConstitutionVoter.Action.CREATE
import fr.dcproject.security.voter.ConstitutionVoter.Action.VIEW import fr.dcproject.security.voter.ConstitutionVoter.Action.VIEW
import fr.ktorVoter.assertCan import fr.ktorVoter.assertCan
import fr.postgresjson.entity.immutable.UuidEntity
import fr.postgresjson.repository.RepositoryI import fr.postgresjson.repository.RepositoryI
import io.ktor.application.ApplicationCall
import io.ktor.application.call import io.ktor.application.call
import io.ktor.locations.KtorExperimentalLocationsAPI import io.ktor.locations.KtorExperimentalLocationsAPI
import io.ktor.locations.Location import io.ktor.locations.Location
@@ -14,6 +18,7 @@ import io.ktor.locations.post
import io.ktor.request.receive import io.ktor.request.receive
import io.ktor.response.respond import io.ktor.response.respond
import io.ktor.routing.Route import io.ktor.routing.Route
import java.util.*
import fr.dcproject.entity.Constitution as ConstitutionEntity import fr.dcproject.entity.Constitution as ConstitutionEntity
import fr.dcproject.repository.Constitution as ConstitutionRepository import fr.dcproject.repository.Constitution as ConstitutionRepository
@@ -35,7 +40,46 @@ object ConstitutionPaths {
class ConstitutionRequest(val constitution: ConstitutionEntity) class ConstitutionRequest(val constitution: ConstitutionEntity)
@Location("/constitutions") @Location("/constitutions")
class PostConstitutionRequest class PostConstitutionRequest {
class Constitution(
var title: String,
var anonymous: Boolean = true,
var titles: MutableList<Title> = mutableListOf(),
var draft: Boolean = false,
var lastVersion: Boolean = false,
var versionId: UUID = UUID.randomUUID()
) {
init {
titles.forEachIndexed { index, title ->
title.rank = index
}
}
class Title(
id: UUID = UUID.randomUUID(),
var name: String,
var rank: Int? = null,
var articles: MutableList<ArticleRef> = mutableListOf()
) : UuidEntity(id) {
fun create(): ConstitutionSimple.TitleSimple<ArticleRef> =
ConstitutionSimple.TitleSimple(
id, name, rank, articles
)
}
fun List<Title>.create(): MutableList<ConstitutionSimple.TitleSimple<ArticleRef>> =
map { it.create() }.toMutableList()
}
suspend fun getNewConstitution(call: ApplicationCall): ConstitutionSimple<CitizenSimple, ConstitutionSimple.TitleSimple<ArticleRef>> = call.receive<Constitution>().run {
ConstitutionSimple(
title = title,
titles = titles.create(),
createdBy = call.citizen,
versionId = versionId
)
}
}
} }
@KtorExperimentalLocationsAPI @KtorExperimentalLocationsAPI
@@ -52,11 +96,10 @@ fun Route.constitution(repo: ConstitutionRepository) {
} }
post<ConstitutionPaths.PostConstitutionRequest> { post<ConstitutionPaths.PostConstitutionRequest> {
val constitution = call.receive<Constitution>().create(citizen) it.getNewConstitution(call).let { constitution ->
assertCan(CREATE, constitution) assertCan(CREATE, constitution)
repo.upsert(constitution)
repo.upsert(constitution) call.respond(constitution)
}
call.respond(constitution)
} }
} }

View File

@@ -3,13 +3,10 @@ package fr.dcproject.routes
import fr.dcproject.citizen import fr.dcproject.citizen
import fr.dcproject.entity.CitizenRef import fr.dcproject.entity.CitizenRef
import fr.dcproject.entity.OpinionChoiceRef import fr.dcproject.entity.OpinionChoiceRef
import fr.dcproject.entity.request.RequestBuilder
import fr.dcproject.entity.request.getContent
import fr.dcproject.security.voter.OpinionVoter.Action.CREATE import fr.dcproject.security.voter.OpinionVoter.Action.CREATE
import fr.dcproject.security.voter.OpinionVoter.Action.VIEW import fr.dcproject.security.voter.OpinionVoter.Action.VIEW
import fr.ktorVoter.assertCan import fr.ktorVoter.assertCan
import fr.dcproject.utils.toUUID import fr.dcproject.utils.toUUID
import io.ktor.application.ApplicationCall
import io.ktor.application.call import io.ktor.application.call
import io.ktor.http.HttpStatusCode import io.ktor.http.HttpStatusCode
import io.ktor.locations.KtorExperimentalLocationsAPI import io.ktor.locations.KtorExperimentalLocationsAPI
@@ -44,14 +41,10 @@ object OpinionArticlePaths {
*/ */
@Location("/articles/{article}/opinions") @Location("/articles/{article}/opinions")
@KtorExperimentalAPI @KtorExperimentalAPI
class ArticleOpinion(val article: ArticleEntity) : RequestBuilder<List<OpinionChoiceRef>> { class ArticleOpinion(val article: ArticleEntity) {
class Body(ids: List<String>) {
private class Content(ids: List<String>) : KoinComponent { val ids = ids.map { OpinionChoiceRef(it.toUUID()) }
val ids = ids.map { it.toUUID() }
} }
override suspend fun getContent(call: ApplicationCall): List<OpinionChoiceRef> =
call.receive<Content>().ids.map { OpinionChoiceRef(it) }
} }
/** /**
@@ -80,12 +73,11 @@ fun Route.opinionArticle(repo: OpinionArticleRepository) {
} }
put<OpinionArticlePaths.ArticleOpinion> { put<OpinionArticlePaths.ArticleOpinion> {
call.getContent(it) call.receive<OpinionArticlePaths.ArticleOpinion.Body>().ids.let { choices ->
.let { choices -> assertCan(CREATE, it.article)
assertCan(CREATE, it.article) repo.updateOpinions(choices, citizen, it.article)
repo.updateOpinions(choices, citizen, it.article) }.let {
}.let { call.respond(HttpStatusCode.Created, it)
call.respond(HttpStatusCode.Created, it) }
}
} }
} }

View File

@@ -3,8 +3,6 @@ package fr.dcproject.routes
import fr.dcproject.citizen import fr.dcproject.citizen
import fr.dcproject.entity.CitizenRef import fr.dcproject.entity.CitizenRef
import fr.dcproject.entity.WorkgroupSimple import fr.dcproject.entity.WorkgroupSimple
import fr.dcproject.entity.request.RequestBuilder
import fr.dcproject.entity.request.getContent
import fr.dcproject.repository.Workgroup.Filter import fr.dcproject.repository.Workgroup.Filter
import fr.dcproject.security.voter.WorkgroupVoter.Action.VIEW import fr.dcproject.security.voter.WorkgroupVoter.Action.VIEW
import fr.dcproject.security.voter.WorkgroupVoter.Action.CREATE import fr.dcproject.security.voter.WorkgroupVoter.Action.CREATE
@@ -27,7 +25,6 @@ import io.ktor.locations.delete
import io.ktor.request.receive import io.ktor.request.receive
import io.ktor.response.respond import io.ktor.response.respond
import io.ktor.routing.Route import io.ktor.routing.Route
import org.koin.core.KoinComponent
import java.util.* import java.util.*
import fr.dcproject.entity.Workgroup as WorkgroupEntity import fr.dcproject.entity.Workgroup as WorkgroupEntity
import fr.dcproject.repository.Workgroup as WorkgroupRepository import fr.dcproject.repository.Workgroup as WorkgroupRepository
@@ -51,54 +48,44 @@ object WorkgroupsPaths {
class WorkgroupRequest(val workgroup: WorkgroupEntity) class WorkgroupRequest(val workgroup: WorkgroupEntity)
@Location("/workgroups") @Location("/workgroups")
open class PostWorkgroupRequest : RequestBuilder<WorkgroupSimple<CitizenRef>> { open class PostWorkgroupRequest {
class Content( class Body(
val id: UUID?, val id: UUID?,
val name: String, val name: String,
val description: String, val description: String,
val logo: String?, val logo: String?,
val anonymous: Boolean?, val anonymous: Boolean?,
val owner: UUID? val owner: UUID?
) : KoinComponent { )
fun create(creator: CitizenRef): WorkgroupSimple<CitizenRef> {
return WorkgroupSimple(
id ?: UUID.randomUUID(),
name,
description,
logo,
anonymous ?: true,
owner?.let { CitizenRef(it) } ?: creator,
creator
)
}
}
override suspend fun getContent(call: ApplicationCall): WorkgroupSimple<CitizenRef> { suspend fun getNewWorkgroup(call: ApplicationCall): WorkgroupSimple<CitizenRef> = call.receive<Body>().run {
return call.receive<Content>().create(call.citizen) WorkgroupSimple(
id ?: UUID.randomUUID(),
name,
description,
logo,
anonymous ?: true,
owner?.let { CitizenRef(it) } ?: call.citizen,
call.citizen
)
} }
} }
@Location("/workgroups/{workgroup}") @Location("/workgroups/{workgroup}")
class PutWorkgroupRequest(val workgroup: WorkgroupEntity) : RequestBuilder<WorkgroupEntity> { class PutWorkgroupRequest(val workgroup: WorkgroupEntity) {
class Content( class Body(
val name: String?, val name: String?,
val description: String?, val description: String?,
val logo: String?, val logo: String?,
val anonymous: Boolean?, val anonymous: Boolean?,
val owner: UUID? val owner: UUID?
) : KoinComponent { )
fun update(workgroup: WorkgroupEntity): WorkgroupEntity {
name?.let { workgroup.name = it }
description?.let { workgroup.description = it }
logo?.let { workgroup.logo = it }
anonymous?.let { workgroup.anonymous = it }
return workgroup suspend fun updateWorkgroup(call: ApplicationCall): Unit = call.receive<Body>().run {
} name?.let { workgroup.name = it }
} description?.let { workgroup.description = it }
logo?.let { workgroup.logo = it }
override suspend fun getContent(call: ApplicationCall): WorkgroupEntity { anonymous?.let { workgroup.anonymous = it }
return call.receive<Content>().update(workgroup)
} }
} }
@@ -109,15 +96,15 @@ object WorkgroupsPaths {
@KtorExperimentalLocationsAPI @KtorExperimentalLocationsAPI
object WorkgroupsMembersPaths { object WorkgroupsMembersPaths {
@Location("/workgroups/{workgroup}/members") @Location("/workgroups/{workgroup}/members")
class WorkgroupsMembersRequest(val workgroup: WorkgroupEntity) : RequestBuilder<List<CitizenRef>> { class WorkgroupsMembersRequest(val workgroup: WorkgroupEntity) {
class Content : MutableList<Content.Item> by mutableListOf() { class Body : MutableList<Body.Item> by mutableListOf() {
class Item(val id: String) class Item(id: String) {
val id = id.toUUID()
}
} }
override suspend fun getContent(call: ApplicationCall): List<CitizenRef> { suspend fun getMembers(call: ApplicationCall): List<CitizenRef> = call.receive<Body>().map {
return call.receive<Content>().map { CitizenRef(it.id)
CitizenRef(it.id.toUUID())
}
} }
} }
} }
@@ -138,7 +125,7 @@ fun Route.workgroup(repo: WorkgroupRepository) {
} }
post<WorkgroupsPaths.PostWorkgroupRequest> { post<WorkgroupsPaths.PostWorkgroupRequest> {
call.getContent(it) it.getNewWorkgroup(call)
.let { workgroup -> .let { workgroup ->
assertCan(CREATE, workgroup) assertCan(CREATE, workgroup)
repo.upsert(workgroup) repo.upsert(workgroup)
@@ -148,13 +135,12 @@ fun Route.workgroup(repo: WorkgroupRepository) {
} }
put<WorkgroupsPaths.PutWorkgroupRequest> { put<WorkgroupsPaths.PutWorkgroupRequest> {
call.getContent(it) it.updateWorkgroup(call).let { workgroup ->
.let { workgroup -> assertCan(UPDATE, workgroup)
assertCan(UPDATE, workgroup) repo.upsert(workgroup as WorkgroupSimple<CitizenRef>)
repo.upsert(workgroup as WorkgroupSimple<CitizenRef>) }.let {
}.let { call.respond(HttpStatusCode.OK, it)
call.respond(HttpStatusCode.OK, it) }
}
} }
delete<WorkgroupsPaths.DeleteWorkgroupRequest> { delete<WorkgroupsPaths.DeleteWorkgroupRequest> {
@@ -165,7 +151,7 @@ fun Route.workgroup(repo: WorkgroupRepository) {
/* Add members to workgroup */ /* Add members to workgroup */
post<WorkgroupsMembersPaths.WorkgroupsMembersRequest> { post<WorkgroupsMembersPaths.WorkgroupsMembersRequest> {
call.getContent(it) it.getMembers(call)
.let { members -> .let { members ->
assertCan(ADD_MEMBERS, it.workgroup) assertCan(ADD_MEMBERS, it.workgroup)
repo.addMembers(it.workgroup, members) repo.addMembers(it.workgroup, members)
@@ -176,7 +162,7 @@ fun Route.workgroup(repo: WorkgroupRepository) {
/* Delete members of workgroup */ /* Delete members of workgroup */
delete<WorkgroupsMembersPaths.WorkgroupsMembersRequest> { delete<WorkgroupsMembersPaths.WorkgroupsMembersRequest> {
call.getContent(it) it.getMembers(call)
.let { members -> .let { members ->
assertCan(REMOVE_MEMBERS, it.workgroup) assertCan(REMOVE_MEMBERS, it.workgroup)
repo.removeMembers(it.workgroup, members) repo.removeMembers(it.workgroup, members)
@@ -187,7 +173,7 @@ fun Route.workgroup(repo: WorkgroupRepository) {
/* Update members of workgroup */ /* Update members of workgroup */
put<WorkgroupsMembersPaths.WorkgroupsMembersRequest> { put<WorkgroupsMembersPaths.WorkgroupsMembersRequest> {
call.getContent(it) it.getMembers(call)
.let { members -> .let { members ->
assertCan(UPDATE_MEMBERS, it.workgroup) assertCan(UPDATE_MEMBERS, it.workgroup)
repo.updateMembers(it.workgroup, members) repo.updateMembers(it.workgroup, members)