Skip to content

Commit

Permalink
#58 Added grades table api method
Browse files Browse the repository at this point in the history
  • Loading branch information
vityaman committed Apr 13, 2024
1 parent 25a8926 commit 7a7b3f2
Show file tree
Hide file tree
Showing 12 changed files with 289 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package ru.vityaman.lms.botalka.api.http.endpoint

import org.springframework.beans.factory.annotation.Autowired
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.RestController
import ru.vityaman.lms.botalka.api.http.server.GetRatingGrades200ResponseMessage
import ru.vityaman.lms.botalka.api.http.server.HomeworkGradeMessage
import ru.vityaman.lms.botalka.api.http.server.StudentGradesMessage
import ru.vityaman.lms.botalka.api.http.server.apis.RatingApi
import ru.vityaman.lms.botalka.logic.RatingService

typealias RatingGrades = GetRatingGrades200ResponseMessage

@RestController
class RatingHttpApi(
@Autowired private val service: RatingService,
) : RatingApi {
override suspend fun getRatingGrades(): ResponseEntity<RatingGrades> =
ResponseEntity.ok(
RatingGrades(
grades = service.grades().map { (student, grades) ->
println("$student $grades")
StudentGradesMessage(
studentId = student.id.number,
grades = grades.entries
.map { (homework, grade) ->
HomeworkGradeMessage(
homeworkId = homework.number,
score = grade.value.toInt(),
)
},
)
},
),
)
}
18 changes: 12 additions & 6 deletions botalka/src/main/kotlin/ru/vityaman/lms/botalka/commons/Merge.kt
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
package ru.vityaman.lms.botalka.commons

import kotlinx.coroutines.channels.ReceiveChannel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.channelFlow
import kotlinx.coroutines.flow.produceIn

private suspend fun <T> ReceiveChannel<T>.receiveIfNotEmpty(): T? =
this.receiveCatching().also {
it.exceptionOrNull()?.let { throw it }
}.getOrNull()

fun <T, U : Comparable<U>> mergeOrdered(
lhs: Flow<T>,
rhs: Flow<T>,
Expand All @@ -12,26 +18,26 @@ fun <T, U : Comparable<U>> mergeOrdered(
val lhsChan = lhs.produceIn(this)
val rhsChan = rhs.produceIn(this)

var left = lhsChan.receiveCatching().getOrNull()
var right = rhsChan.receiveCatching().getOrNull()
var left = lhsChan.receiveIfNotEmpty()
var right = rhsChan.receiveIfNotEmpty()

while (left != null && right != null) {
if (key(left) < key(right)) {
send(left)
left = lhsChan.receiveCatching().getOrNull()
left = lhsChan.receiveIfNotEmpty()
} else {
send(right)
right = rhsChan.receiveCatching().getOrNull()
right = rhsChan.receiveIfNotEmpty()
}
}

while (left != null) {
send(left)
left = lhsChan.receiveCatching().getOrNull()
left = lhsChan.receiveIfNotEmpty()
}

while (right != null) {
send(right)
right = rhsChan.receiveCatching().getOrNull()
right = rhsChan.receiveIfNotEmpty()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package ru.vityaman.lms.botalka.logic

import ru.vityaman.lms.botalka.domain.model.Homework
import ru.vityaman.lms.botalka.domain.model.Student

typealias Grades = Map<Student, Map<Homework.Id, Homework.Score>>

interface RatingService {
suspend fun grades(): Grades
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
package ru.vityaman.lms.botalka.logic

import kotlinx.coroutines.flow.Flow
import ru.vityaman.lms.botalka.domain.model.Homework
import ru.vityaman.lms.botalka.domain.model.Workspace

interface WorkspaceService {
fun events(id: Workspace.Id): Flow<Workspace.Event>

suspend fun produce(
id: Workspace.Id,
event: Workspace.Event.Draft,
): Workspace.Event

suspend fun grade(id: Workspace.Id): Homework.Score?

fun all(): Flow<Workspace.Id>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package ru.vityaman.lms.botalka.logic.basic

import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.flow.toList
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
import ru.vityaman.lms.botalka.domain.model.Homework
import ru.vityaman.lms.botalka.domain.model.Student
import ru.vityaman.lms.botalka.logic.Grades
import ru.vityaman.lms.botalka.logic.RatingService
import ru.vityaman.lms.botalka.logic.WorkspaceService

@Service
class BasicRatingService(
@Autowired private val workspaces: WorkspaceService,
) : RatingService {
override suspend fun grades(): Grades {
val byStuds = mutableMapOf<
Student,
MutableMap<Homework.Id, Homework.Score>,
>()

coroutineScope {
for (id in workspaces.all().toList()) {
workspaces.grade(id)?.let { grade ->
val byHws = byStuds.getOrPut(id.student) { mutableMapOf() }
byHws[id.homework] = grade
}
}
}

return byStuds
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package ru.vityaman.lms.botalka.logic.basic

import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.lastOrNull
import kotlinx.coroutines.flow.map
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
import ru.vityaman.lms.botalka.domain.model.Homework
import ru.vityaman.lms.botalka.domain.model.Workspace
import ru.vityaman.lms.botalka.logic.WorkspaceService
import ru.vityaman.lms.botalka.storage.WorkspaceStorage
Expand All @@ -23,4 +27,15 @@ class BasicWorkspaceService(
is Workspace.Submission.Draft -> storage.save(id, event)
is Workspace.Feedback.Draft -> storage.save(id, event)
}

override suspend fun grade(id: Workspace.Id): Homework.Score? =
events(id)
.map { it as? Workspace.Feedback }
.filterNotNull()
.map { it.score }
.filterNotNull()
.lastOrNull()

override fun all(): Flow<Workspace.Id> =
storage.all()
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,6 @@ interface WorkspaceStorage {
id: Workspace.Id,
event: Workspace.Feedback.Draft,
): Workspace.Feedback

fun all(): Flow<Workspace.Id>
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Repository
import reactor.kotlin.core.publisher.toMono
import ru.vityaman.lms.botalka.commons.mergeOrdered
import ru.vityaman.lms.botalka.domain.model.Homework
import ru.vityaman.lms.botalka.domain.model.Student
import ru.vityaman.lms.botalka.domain.model.User
import ru.vityaman.lms.botalka.domain.model.Workspace
import ru.vityaman.lms.botalka.storage.WorkspaceStorage
import ru.vityaman.lms.botalka.storage.jooq.entity.toModel
Expand Down Expand Up @@ -83,16 +86,31 @@ class JooqWorkspaceStorage(
HOMEWORK_FEEDBACK.STUDENT_ID,
HOMEWORK_FEEDBACK.TEACHER_ID,
HOMEWORK_FEEDBACK.COMMENT,
HOMEWORK_FEEDBACK.SCORE,
)
.values(
id.homework.number,
id.student.id.number,
event.teacher.id.number,
event.comment,
event.score?.value,
)
.returning()
.coerce(HOMEWORK_FEEDBACK)
.toMono()
.map { it.toModel() }
.awaitSingle()

override fun all(): Flow<Workspace.Id> =
database.execute
.selectFrom(HOMEWORK_SUBMISSION)
.where(HOMEWORK_SUBMISSION.ID.eq(HOMEWORK_SUBMISSION.ID))
.toFlux()
.map {
Workspace.Id(
Homework.Id(it.homeworkId),
Student(User.Id(it.studentId)),
)
}
.asFlow()
}
11 changes: 8 additions & 3 deletions botalka/src/main/resources/static/openapi/api.yml
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,14 @@ paths:
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/StudentGrades'
type: object
properties:
grades:
type: array
items:
$ref: '#/components/schemas/StudentGrades'
required:
- grades
/user/{id}:
get:
tags: [ User ]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import org.springframework.context.annotation.Bean
import org.springframework.stereotype.Component
import ru.vityaman.lms.botalka.api.http.client.apis.HomeworkApi
import ru.vityaman.lms.botalka.api.http.client.apis.MonitoringApi
import ru.vityaman.lms.botalka.api.http.client.apis.RatingApi
import ru.vityaman.lms.botalka.api.http.client.apis.UserApi

@Component
Expand All @@ -18,4 +19,7 @@ class ApiClientSet {

@Bean
fun userApi() = UserApi(url)

@Bean
fun ratingApi() = RatingApi(url)
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class HomeworkApiClient(
WorkspaceFeedbackDraftMessage(
kind = WorkspaceEventKindMessage.feedback,
comment = draft.comment,
score = draft.score?.value?.toInt(),
),
).awaitSingle()
}
Expand Down
Loading

0 comments on commit 7a7b3f2

Please sign in to comment.