fix: address PR review thread issues

Agent-Logs-Url: https://github.com/devitq/movienight-backend/sessions/d4d6ebbb-2508-484e-accf-c891be54750f

Co-authored-by: devitq <118541411+devitq@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-05-20 18:33:34 +00:00
committed by GitHub
co-authored by devitq
parent 1f22be3401
commit 50923e2e5a
9 changed files with 106 additions and 103 deletions
@@ -100,7 +100,7 @@ class JellyfinApiClient(
throw IllegalStateException("Failed to call Jellyfin at $uri", exception)
}
check(response.statusCode() !in 200..299) {
check(response.statusCode() in 200..299) {
"Jellyfin request failed with status ${response.statusCode()} for $uri"
}
@@ -8,12 +8,6 @@ import org.springframework.stereotype.Repository
class JellyfinEventRepository(
private val jdbc: NamedParameterJdbcTemplate,
) {
fun exists(eventId: String): Boolean {
val sql = "SELECT 1 FROM jellyfin_events WHERE event_id = :eventId"
val params = MapSqlParameterSource().addValue("eventId", eventId)
return jdbc.query(sql, params) { rs, _ -> rs.getInt(1) }.any()
}
fun save(
eventId: String,
serverId: String?,
@@ -22,7 +16,7 @@ class JellyfinEventRepository(
jellyfinUserId: String?,
jellyfinItemId: String?,
payload: String?,
) {
): Int {
val sql =
"""
INSERT INTO jellyfin_events(event_id, server_id, event_type, occurred_at, jellyfin_user_id, jellyfin_item_id, payload)
@@ -40,6 +34,12 @@ class JellyfinEventRepository(
.addValue("jellyfinItemId", jellyfinItemId)
.addValue("payload", payload)
return jdbc.update(sql, params)
}
fun delete(eventId: String) {
val sql = "DELETE FROM jellyfin_events WHERE event_id = :eventId"
val params = MapSqlParameterSource().addValue("eventId", eventId)
jdbc.update(sql, params)
}
}
@@ -27,6 +27,10 @@ class JellyfinEventsController(
@RequestHeader(value = "X-MovieNight-Plugin-Token", required = false) token: String?,
@RequestBody request: JellyfinEventRequest,
) {
if (!properties.enabled) {
throw ResponseStatusException(HttpStatus.SERVICE_UNAVAILABLE, "Jellyfin integration is disabled")
}
if (properties.pluginToken.isNotBlank()) {
if (token == null || token != properties.pluginToken) {
throw ResponseStatusException(HttpStatus.UNAUTHORIZED, "Invalid plugin token")
@@ -33,21 +33,7 @@ class FilmLibraryService(
ListFilmLibraryEntriesUseCase {
override fun create(command: CreateFilmLibraryCommand): FilmLibrary {
findByUserId(command.userId)?.let { return it }
val libraryId = idGenerator.generateId()
val saved =
filmLibraryRepository.save(
FilmLibrary(
id = libraryId,
userId = command.userId,
filmId = libraryId,
comment = command.name,
isViewed = false,
watchedAt = null,
),
)
businessMetricsService.recordLibraryEvent()
return saved
throw EntityNotFoundException(entity = "Film library", id = command.userId.toString())
}
override fun addFilm(command: AddFilmToLibraryCommand): FilmLibrary {
@@ -40,7 +40,7 @@ class FilmService(
try {
log.debug(
"Create film request received: title='{}', descriptionLength={}'",
"Create film request received: title='{}', descriptionLength={}",
command.title,
command.description.length,
)
@@ -30,23 +30,33 @@ class JellyfinEventService(
itemId: String,
payload: Map<String, Any>?,
) {
if (jellyfinEventRepository.exists(eventId = eventId)) {
val payloadJson = payload?.let { objectMapper.writeValueAsString(it) }
val inserted =
jellyfinEventRepository.save(
eventId = eventId,
serverId = serverId,
eventType = eventType,
occurredAt = occurredAt,
jellyfinUserId = jellyfinUserId,
jellyfinItemId = itemId,
payload = payloadJson,
)
if (inserted != 1) {
return
}
val payloadJson = payload?.let { objectMapper.writeValueAsString(it) }
jellyfinEventRepository.save(eventId, serverId, eventType, occurredAt, jellyfinUserId, itemId, payloadJson)
try {
if (playbackEventTypes.contains(eventType)) {
val localUser = userRepository.findAll().firstOrNull { it.jellyfinUserId == jellyfinUserId }
if (localUser == null) {
jellyfinEventRepository.delete(eventId)
businessMetricsService.recordJellyfinUnmappedUser()
return
}
val film = filmRepository.findByJellyfinItemId(itemId)
if (film == null) {
jellyfinEventRepository.delete(eventId)
businessMetricsService.recordBackendWriteFailure()
return
}
@@ -63,6 +73,7 @@ class JellyfinEventService(
} catch (
@Suppress("TooGenericExceptionCaught") ex: RuntimeException,
) {
jellyfinEventRepository.delete(eventId)
businessMetricsService.recordBackendWriteFailure()
throw ex
}