package fr.dcproject.component.article.routes import fr.dcproject.common.dto.CreatedAt import fr.dcproject.common.dto.Versionable import fr.dcproject.common.security.assert import fr.dcproject.component.article.ArticleAccessControl import fr.dcproject.component.article.ArticleViewManager import fr.dcproject.component.article.database.ArticleForView import fr.dcproject.component.article.database.ArticleRef import fr.dcproject.component.article.database.ArticleRepository import fr.dcproject.component.auth.citizenOrNull import fr.dcproject.component.opinion.dto.Opinionable import fr.dcproject.component.views.dto.Viewable import fr.dcproject.component.views.entity.ViewAggregation import fr.dcproject.component.vote.dto.Votable import io.ktor.application.call import io.ktor.features.NotFoundException import io.ktor.locations.KtorExperimentalLocationsAPI import io.ktor.locations.Location import io.ktor.locations.get import io.ktor.response.respond import io.ktor.routing.Route import kotlinx.coroutines.launch import java.util.UUID @KtorExperimentalLocationsAPI object GetOneArticle { @Location("/articles/{article}") class ArticleRequest(article: UUID) { val article = ArticleRef(article) } class Output( article: ArticleForView, views: ViewAggregation = ViewAggregation() ) : CreatedAt by CreatedAt.Imp(article), Opinionable by Opinionable.Imp(article), Votable by Votable.Imp(article), Versionable by Versionable.Imp(article), Viewable by Viewable.Imp(views) { val id = article.id val title = article.title val anonymous = article.anonymous val content = article.content val description = article.description val tags = article.tags val draft = article.draft val lastVersion = article.lastVersion val createdBy = article.createdBy val workgroup = article.workgroup?.let { Workgroup(article.workgroup.id, article.workgroup.name) } class Workgroup(val id: UUID, val name: String) } fun Route.getOneArticle(viewManager: ArticleViewManager, ac: ArticleAccessControl, repo: ArticleRepository) { get { val article: ArticleForView = repo.findById(it.article.id) ?: throw NotFoundException("Article ${it.article.id} not found") ac.assert { canView(article, citizenOrNull) } Output( article, viewManager.getViewsCount(article) ).also { out -> call.respond(out) } launch { viewManager.addView(call.request.local.remoteHost, article, citizenOrNull) } } } }