Refactor: split content order API; near-default detekt thresholds

This commit is contained in:
2026-09-27 22:38:48 +03:00
parent 1b3eeb2f40
commit af480a87f9
3 changed files with 94 additions and 86 deletions

View File

@@ -9,31 +9,35 @@ config:
warningsAsErrors: false
complexity:
# Пороги выставлены под реальный масштаб классов проекта. Дробление крупных
# агрегатов (web ApiClient, AdminController, ContentService) — отдельная задача;
# когда оно будет выполнено, пороги можно вернуть к значениям по умолчанию.
# Крупные агрегаты уже раздроблены (web ApiClient — по доменам, AdminController —
# на AdminSupport + 5 контроллеров, импорт материалов — в ContentImporter).
# Оставшиеся послабления точечные и перечислены ниже; после дробления ContentService
# и выноса хелперов из методов groupDetail/labDetail/editLab их можно снять.
LongMethod:
# groupDetail (82), labDetail (73), editLab (86) в админ-контроллерах.
threshold: 90
LongParameterList:
# MVC-обработчики форм принимают набор @RequestParam — для них это нормально.
functionThreshold: 8
constructorThreshold: 8
ignoreDefaultParameters: true
# MVC-обработчики форм принимают набор @RequestParam — для них параметров «много» нормально.
ignoreAnnotated:
- 'PostMapping'
- 'GetMapping'
TooManyFunctions:
thresholdInFiles: 80
thresholdInClasses: 80
thresholdInInterfaces: 40
thresholdInObjects: 40
thresholdInEnums: 40
# ContentService (26) — следующий кандидат на разделение.
thresholdInFiles: 27
thresholdInClasses: 27
thresholdInInterfaces: 20
thresholdInObjects: 20
thresholdInEnums: 20
LargeClass:
threshold: 1400
threshold: 600
ComplexCondition:
threshold: 4
CyclomaticComplexMethod:
threshold: 20
# editLab (16) в AdminLabController.
threshold: 17
style:
MagicNumber:

View File

@@ -33,31 +33,6 @@ fun ApiClient.contentArticle(
.body(ContentArticleDto::class.java)
}
fun ApiClient.setContentPublished(
token: String,
kind: String,
id: String,
published: Boolean,
) {
val path =
when (kind) {
"chapters" -> "/api/v1/content/chapters/{id}/published"
"sections" -> "/api/v1/content/sections/{id}/published"
"articles" -> "/api/v1/content/articles/{id}/published"
else -> throw IllegalArgumentException("Неизвестный тип материала: $kind")
}
call {
client
.put()
.uri(path, id)
.header(HttpHeaders.AUTHORIZATION, bearer(token))
.contentType(MediaType.APPLICATION_JSON)
.body(mapOf("published" to published))
.retrieve()
.toBodilessEntity()
}
}
fun ApiClient.contentTreeList(token: String?): List<ContentArticleDto> {
val type = object : ParameterizedTypeReference<List<ContentArticleDto>>() {}
return call {
@@ -68,56 +43,6 @@ fun ApiClient.contentTreeList(token: String?): List<ContentArticleDto> {
}
}
fun ApiClient.reorderContent(
token: String,
tree: ContentReorderDto,
) {
call {
client
.post()
.uri("/api/v1/content/reorder")
.header(HttpHeaders.AUTHORIZATION, bearer(token))
.contentType(MediaType.APPLICATION_JSON)
.body(tree)
.retrieve()
.toBodilessEntity()
}
}
fun ApiClient.reorderSections(
token: String,
chapterId: String,
body: SectionsReorderDto,
) {
call {
client
.post()
.uri("/api/v1/content/chapters/{id}/sections/reorder", chapterId)
.header(HttpHeaders.AUTHORIZATION, bearer(token))
.contentType(MediaType.APPLICATION_JSON)
.body(body)
.retrieve()
.toBodilessEntity()
}
}
fun ApiClient.reorderArticles(
token: String,
sectionId: String,
body: ArticlesReorderDto,
) {
call {
client
.post()
.uri("/api/v1/content/sections/{id}/articles/reorder", sectionId)
.header(HttpHeaders.AUTHORIZATION, bearer(token))
.contentType(MediaType.APPLICATION_JSON)
.body(body)
.retrieve()
.toBodilessEntity()
}
}
fun ApiClient.importContent(
token: String,
filename: String,

View File

@@ -0,0 +1,79 @@
package ru.ysu.lms.web.api
import org.springframework.http.HttpHeaders
import org.springframework.http.MediaType
fun ApiClient.setContentPublished(
token: String,
kind: String,
id: String,
published: Boolean,
) {
val path =
when (kind) {
"chapters" -> "/api/v1/content/chapters/{id}/published"
"sections" -> "/api/v1/content/sections/{id}/published"
"articles" -> "/api/v1/content/articles/{id}/published"
else -> throw IllegalArgumentException("Неизвестный тип материала: $kind")
}
call {
client
.put()
.uri(path, id)
.header(HttpHeaders.AUTHORIZATION, bearer(token))
.contentType(MediaType.APPLICATION_JSON)
.body(mapOf("published" to published))
.retrieve()
.toBodilessEntity()
}
}
fun ApiClient.reorderContent(
token: String,
tree: ContentReorderDto,
) {
call {
client
.post()
.uri("/api/v1/content/reorder")
.header(HttpHeaders.AUTHORIZATION, bearer(token))
.contentType(MediaType.APPLICATION_JSON)
.body(tree)
.retrieve()
.toBodilessEntity()
}
}
fun ApiClient.reorderSections(
token: String,
chapterId: String,
body: SectionsReorderDto,
) {
call {
client
.post()
.uri("/api/v1/content/chapters/{id}/sections/reorder", chapterId)
.header(HttpHeaders.AUTHORIZATION, bearer(token))
.contentType(MediaType.APPLICATION_JSON)
.body(body)
.retrieve()
.toBodilessEntity()
}
}
fun ApiClient.reorderArticles(
token: String,
sectionId: String,
body: ArticlesReorderDto,
) {
call {
client
.post()
.uri("/api/v1/content/sections/{id}/articles/reorder", sectionId)
.header(HttpHeaders.AUTHORIZATION, bearer(token))
.contentType(MediaType.APPLICATION_JSON)
.body(body)
.retrieve()
.toBodilessEntity()
}
}