Big refactoring #77
@@ -16,8 +16,8 @@ class VoteForView<T : TargetI>(
|
|||||||
id: UUID = UUID.randomUUID(),
|
id: UUID = UUID.randomUUID(),
|
||||||
override val createdBy: CitizenCreator,
|
override val createdBy: CitizenCreator,
|
||||||
override val target: T,
|
override val target: T,
|
||||||
var note: Int,
|
val note: Int,
|
||||||
var anonymous: Boolean = true
|
val anonymous: Boolean = true
|
||||||
) : ExtraI<T, CitizenCreatorI>,
|
) : ExtraI<T, CitizenCreatorI>,
|
||||||
VoteRef(id),
|
VoteRef(id),
|
||||||
CreatedAt by CreatedAt.Imp(),
|
CreatedAt by CreatedAt.Imp(),
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package fr.dcproject.component.vote.routes
|
package fr.dcproject.component.vote.routes
|
||||||
|
|
||||||
|
import fr.dcproject.common.response.toOutput
|
||||||
import fr.dcproject.common.security.assert
|
import fr.dcproject.common.security.assert
|
||||||
import fr.dcproject.common.utils.toUUID
|
import fr.dcproject.common.utils.toUUID
|
||||||
import fr.dcproject.component.auth.citizenOrNull
|
import fr.dcproject.component.auth.citizenOrNull
|
||||||
@@ -7,6 +8,7 @@ import fr.dcproject.component.citizen.database.CitizenRef
|
|||||||
import fr.dcproject.component.vote.VoteAccessControl
|
import fr.dcproject.component.vote.VoteAccessControl
|
||||||
import fr.dcproject.component.vote.database.VoteRepository
|
import fr.dcproject.component.vote.database.VoteRepository
|
||||||
import io.ktor.application.call
|
import io.ktor.application.call
|
||||||
|
import io.ktor.http.HttpStatusCode
|
||||||
import io.ktor.locations.KtorExperimentalLocationsAPI
|
import io.ktor.locations.KtorExperimentalLocationsAPI
|
||||||
import io.ktor.locations.Location
|
import io.ktor.locations.Location
|
||||||
import io.ktor.locations.get
|
import io.ktor.locations.get
|
||||||
@@ -28,7 +30,10 @@ object GetCitizenVotes {
|
|||||||
if (votes.isNotEmpty()) {
|
if (votes.isNotEmpty()) {
|
||||||
ac.assert { canView(votes, citizenOrNull) }
|
ac.assert { canView(votes, citizenOrNull) }
|
||||||
}
|
}
|
||||||
call.respond(votes)
|
call.respond(
|
||||||
|
HttpStatusCode.OK,
|
||||||
|
votes.map { it.toOutput() }
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package fr.dcproject.component.vote.routes
|
package fr.dcproject.component.vote.routes
|
||||||
|
|
||||||
|
import fr.dcproject.common.response.toOutput
|
||||||
import fr.dcproject.common.security.assert
|
import fr.dcproject.common.security.assert
|
||||||
import fr.dcproject.component.auth.citizenOrNull
|
import fr.dcproject.component.auth.citizenOrNull
|
||||||
import fr.dcproject.component.citizen.database.CitizenRef
|
import fr.dcproject.component.citizen.database.CitizenRef
|
||||||
@@ -8,6 +9,7 @@ import fr.dcproject.component.vote.database.VoteArticleRepository
|
|||||||
import fr.dcproject.routes.PaginatedRequest
|
import fr.dcproject.routes.PaginatedRequest
|
||||||
import fr.dcproject.routes.PaginatedRequestI
|
import fr.dcproject.routes.PaginatedRequestI
|
||||||
import io.ktor.application.call
|
import io.ktor.application.call
|
||||||
|
import io.ktor.http.HttpStatusCode
|
||||||
import io.ktor.locations.KtorExperimentalLocationsAPI
|
import io.ktor.locations.KtorExperimentalLocationsAPI
|
||||||
import io.ktor.locations.Location
|
import io.ktor.locations.Location
|
||||||
import io.ktor.locations.get
|
import io.ktor.locations.get
|
||||||
@@ -32,7 +34,10 @@ object GetCitizenVotesOnArticle {
|
|||||||
val votes = repo.findByCitizen(it.citizen, it.page, it.limit)
|
val votes = repo.findByCitizen(it.citizen, it.page, it.limit)
|
||||||
ac.assert { canView(votes.result, citizenOrNull) }
|
ac.assert { canView(votes.result, citizenOrNull) }
|
||||||
|
|
||||||
call.respond(votes)
|
call.respond(
|
||||||
|
HttpStatusCode.OK,
|
||||||
|
votes.toOutput { it.toOutput() }
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,10 @@ object PutVoteOnArticle {
|
|||||||
)
|
)
|
||||||
ac.assert { canCreate(vote, citizenOrNull) }
|
ac.assert { canCreate(vote, citizenOrNull) }
|
||||||
val votes = repo.vote(vote)
|
val votes = repo.vote(vote)
|
||||||
call.respond(HttpStatusCode.Created, votes)
|
call.respond(
|
||||||
|
HttpStatusCode.Created,
|
||||||
|
votes.toOutput()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,10 @@ object PutVoteOnComment {
|
|||||||
)
|
)
|
||||||
ac.assert { canCreate(vote, citizenOrNull) }
|
ac.assert { canCreate(vote, citizenOrNull) }
|
||||||
val votes = voteCommentRepo.vote(vote)
|
val votes = voteCommentRepo.vote(vote)
|
||||||
call.respond(HttpStatusCode.Created, votes)
|
call.respond(
|
||||||
|
HttpStatusCode.Created,
|
||||||
|
votes.toOutput()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import fr.dcproject.component.constitution.database.ConstitutionRepository
|
|||||||
import fr.dcproject.component.vote.VoteAccessControl
|
import fr.dcproject.component.vote.VoteAccessControl
|
||||||
import fr.dcproject.component.vote.database.VoteConstitutionRepository
|
import fr.dcproject.component.vote.database.VoteConstitutionRepository
|
||||||
import fr.dcproject.component.vote.database.VoteForUpdate
|
import fr.dcproject.component.vote.database.VoteForUpdate
|
||||||
import fr.dcproject.component.vote.routes.VoteConstitution.ConstitutionVoteRequest.Input
|
import fr.dcproject.component.vote.routes.PutVoteOnConstitution.ConstitutionVoteRequest.Input
|
||||||
import io.ktor.application.call
|
import io.ktor.application.call
|
||||||
import io.ktor.features.NotFoundException
|
import io.ktor.features.NotFoundException
|
||||||
import io.ktor.http.HttpStatusCode
|
import io.ktor.http.HttpStatusCode
|
||||||
@@ -21,7 +21,7 @@ import io.ktor.routing.Route
|
|||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
|
||||||
@KtorExperimentalLocationsAPI
|
@KtorExperimentalLocationsAPI
|
||||||
object VoteConstitution {
|
object PutVoteOnConstitution {
|
||||||
@Location("/constitutions/{constitution}/vote")
|
@Location("/constitutions/{constitution}/vote")
|
||||||
class ConstitutionVoteRequest(constitution: UUID) {
|
class ConstitutionVoteRequest(constitution: UUID) {
|
||||||
val constitution = ConstitutionRef(constitution)
|
val constitution = ConstitutionRef(constitution)
|
||||||
@@ -4,7 +4,7 @@ import fr.dcproject.component.vote.routes.GetCitizenVotes.getCitizenVote
|
|||||||
import fr.dcproject.component.vote.routes.GetCitizenVotesOnArticle.getCitizenVotesOnArticle
|
import fr.dcproject.component.vote.routes.GetCitizenVotesOnArticle.getCitizenVotesOnArticle
|
||||||
import fr.dcproject.component.vote.routes.PutVoteOnArticle.putVoteOnArticle
|
import fr.dcproject.component.vote.routes.PutVoteOnArticle.putVoteOnArticle
|
||||||
import fr.dcproject.component.vote.routes.PutVoteOnComment.putVoteOnComment
|
import fr.dcproject.component.vote.routes.PutVoteOnComment.putVoteOnComment
|
||||||
import fr.dcproject.component.vote.routes.VoteConstitution.voteConstitution
|
import fr.dcproject.component.vote.routes.PutVoteOnConstitution.voteConstitution
|
||||||
import io.ktor.auth.authenticate
|
import io.ktor.auth.authenticate
|
||||||
import io.ktor.locations.KtorExperimentalLocationsAPI
|
import io.ktor.locations.KtorExperimentalLocationsAPI
|
||||||
import io.ktor.routing.Routing
|
import io.ktor.routing.Routing
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package fr.dcproject.component.vote.routes
|
||||||
|
|
||||||
|
import fr.dcproject.common.response.toOutput
|
||||||
|
import fr.dcproject.component.vote.database.VoteForView
|
||||||
|
import fr.dcproject.component.vote.entity.VoteAggregation
|
||||||
|
import org.joda.time.DateTime
|
||||||
|
import java.util.UUID
|
||||||
|
|
||||||
|
fun VoteForView<*>.toOutput(): Any = this.let { v ->
|
||||||
|
object {
|
||||||
|
val id: UUID = v.id
|
||||||
|
val note: Int = v.note
|
||||||
|
val createdAt: DateTime = v.createdAt
|
||||||
|
val createdBy: Any = v.createdBy.toOutput()
|
||||||
|
val target: Any = object {
|
||||||
|
val id: UUID = v.target.id
|
||||||
|
val reference: String = v.target.reference
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun VoteAggregation.toOutput(): Any = this.let { v ->
|
||||||
|
object {
|
||||||
|
val up: Int = v.up
|
||||||
|
val neutral: Int = v.neutral
|
||||||
|
val down: Int = v.down
|
||||||
|
val total: Int = v.total
|
||||||
|
val score: Int = v.score
|
||||||
|
val updatedAt: DateTime = v.updatedAt
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -795,7 +795,6 @@ paths:
|
|||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
$ref: '#/components/schemas/FollowResponse'
|
$ref: '#/components/schemas/FollowResponse'
|
||||||
|
|
||||||
/constitutions/{constitution}/follows:
|
/constitutions/{constitution}/follows:
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: '#/components/parameters/constitution'
|
- $ref: '#/components/parameters/constitution'
|
||||||
@@ -905,7 +904,6 @@ paths:
|
|||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/components/schemas/OpinionChoice'
|
$ref: '#/components/schemas/OpinionChoice'
|
||||||
|
|
||||||
/citizens/{citizen}/opinions:
|
/citizens/{citizen}/opinions:
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: '#/components/parameters/citizen'
|
- $ref: '#/components/parameters/citizen'
|
||||||
@@ -961,7 +959,6 @@ paths:
|
|||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
$ref: '#/components/schemas/Opinion'
|
$ref: '#/components/schemas/Opinion'
|
||||||
|
|
||||||
/articles/{article}/opinions:
|
/articles/{article}/opinions:
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: '#/components/parameters/article'
|
- $ref: '#/components/parameters/article'
|
||||||
@@ -996,6 +993,136 @@ paths:
|
|||||||
401:
|
401:
|
||||||
$ref: '#/components/responses/401'
|
$ref: '#/components/responses/401'
|
||||||
|
|
||||||
|
/constitutions/{constitution}/vote:
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/components/parameters/constitution'
|
||||||
|
put:
|
||||||
|
security:
|
||||||
|
- JWTAuth: [ ]
|
||||||
|
summary: Vote for one constitution
|
||||||
|
tags:
|
||||||
|
- vote
|
||||||
|
- constitution
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/VoteRequest'
|
||||||
|
responses:
|
||||||
|
201:
|
||||||
|
description: Return only http status 201 on success
|
||||||
|
/citizens/{citizen}/votes:
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/components/parameters/citizen'
|
||||||
|
get:
|
||||||
|
security:
|
||||||
|
- JWTAuth: [ ]
|
||||||
|
summary: Get Citizen
|
||||||
|
tags:
|
||||||
|
- vote
|
||||||
|
- citizen
|
||||||
|
operationId: getCitizenVotes
|
||||||
|
parameters:
|
||||||
|
- name: id
|
||||||
|
in: query
|
||||||
|
required: true
|
||||||
|
example:
|
||||||
|
- 1329ab90-edae-cfed-f863-c8cb069fa327
|
||||||
|
- cab54e50-ce85-bba0-da23-fc9f75feeaf5
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
format: uuid
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: The Votes objects
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/VoteResponse'
|
||||||
|
404:
|
||||||
|
description: Citizen not found
|
||||||
|
401:
|
||||||
|
$ref: '#/components/responses/401'
|
||||||
|
/comments/{comment}/vote:
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/components/parameters/comment'
|
||||||
|
put:
|
||||||
|
security:
|
||||||
|
- JWTAuth: []
|
||||||
|
summary: Vote for a comment
|
||||||
|
tags:
|
||||||
|
- vote
|
||||||
|
- comment
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/VoteRequest'
|
||||||
|
responses:
|
||||||
|
201:
|
||||||
|
description: Return votes aggregation
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/VoteAggregation'
|
||||||
|
401:
|
||||||
|
$ref: '#/components/responses/401'
|
||||||
|
/citizens/{citizen}/votes/articles:
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/components/parameters/citizen'
|
||||||
|
get:
|
||||||
|
security:
|
||||||
|
- JWTAuth: [ ]
|
||||||
|
summary: all article vote for one citizen
|
||||||
|
tags:
|
||||||
|
- vote
|
||||||
|
- article
|
||||||
|
- citizen
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: Votes
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/components/schemas/Paginated'
|
||||||
|
- type: object
|
||||||
|
properties:
|
||||||
|
result:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/VoteResponse'
|
||||||
|
401:
|
||||||
|
$ref: '#/components/responses/401'
|
||||||
|
/articles/{article}/vote:
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/components/parameters/article'
|
||||||
|
put:
|
||||||
|
security:
|
||||||
|
- JWTAuth: [ ]
|
||||||
|
summary: Vote for one article
|
||||||
|
tags:
|
||||||
|
- vote
|
||||||
|
- article
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/VoteRequest'
|
||||||
|
responses:
|
||||||
|
201:
|
||||||
|
description: Return only http status 201 on success
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/VoteAggregation'
|
||||||
|
401:
|
||||||
|
$ref: '#/components/responses/401'
|
||||||
|
|
||||||
components:
|
components:
|
||||||
parameters:
|
parameters:
|
||||||
page:
|
page:
|
||||||
@@ -1696,6 +1823,74 @@ components:
|
|||||||
type: string
|
type: string
|
||||||
format: 'date-time'
|
format: 'date-time'
|
||||||
|
|
||||||
|
VoteRequest:
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required:
|
||||||
|
- note
|
||||||
|
properties:
|
||||||
|
note:
|
||||||
|
type: integer
|
||||||
|
minimum: -1
|
||||||
|
maximum: 1
|
||||||
|
VoteResponse:
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
required:
|
||||||
|
- id
|
||||||
|
- note
|
||||||
|
- createdAt
|
||||||
|
- createdBy
|
||||||
|
- target
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
$ref: '#/components/schemas/UUID'
|
||||||
|
note:
|
||||||
|
type: integer
|
||||||
|
minimum: -1
|
||||||
|
maximum: 1
|
||||||
|
createdAt:
|
||||||
|
type: string
|
||||||
|
format: 'date-time'
|
||||||
|
createdBy:
|
||||||
|
$ref: '#/components/schemas/CitizenCreator'
|
||||||
|
target:
|
||||||
|
required:
|
||||||
|
- id
|
||||||
|
- reference
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
$ref: '#/components/schemas/UUID'
|
||||||
|
reference:
|
||||||
|
type: string
|
||||||
|
VoteAggregation:
|
||||||
|
additionalProperties: false
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- up
|
||||||
|
- neutral
|
||||||
|
- down
|
||||||
|
- total
|
||||||
|
- score
|
||||||
|
- updatedAt
|
||||||
|
properties:
|
||||||
|
up:
|
||||||
|
type: number
|
||||||
|
minimum: 0
|
||||||
|
neutral:
|
||||||
|
type: number
|
||||||
|
minimum: 0
|
||||||
|
down:
|
||||||
|
type: number
|
||||||
|
minimum: 0
|
||||||
|
total:
|
||||||
|
type: number
|
||||||
|
minimum: 0
|
||||||
|
score:
|
||||||
|
type: number
|
||||||
|
updatedAt:
|
||||||
|
type: string
|
||||||
|
format: 'date-time'
|
||||||
|
|
||||||
securitySchemes:
|
securitySchemes:
|
||||||
JWTAuth:
|
JWTAuth:
|
||||||
|
|||||||
Reference in New Issue
Block a user