Skip to content

Commit

Permalink
feat: skillLab admin api
Browse files Browse the repository at this point in the history
  • Loading branch information
tomwwinter committed Dec 3, 2024
1 parent 0c9d4fc commit 924f57c
Show file tree
Hide file tree
Showing 4 changed files with 168 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package com.aamdigital.aambackendservice.skill.controller

import com.aamdigital.aambackendservice.error.HttpErrorDto
import com.aamdigital.aambackendservice.skill.core.FetchUserProfileUpdatesRequest
import com.aamdigital.aambackendservice.skill.core.FetchUserProfileUpdatesUseCase
import com.aamdigital.aambackendservice.skill.repository.SkillLabUserProfileSyncRepository
import org.slf4j.LoggerFactory
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
import java.time.Instant
import java.time.ZoneOffset
import kotlin.jvm.optionals.getOrElse

data class SkillDto(
val projectId: String,
val latestSync: String,
)

enum class SyncModeDto {
DELTA,
FULL,
}

@RestController
@RequestMapping("/v1/skill")
class SkillAdminController(
private val skillLabFetchUserProfileUpdatesUseCase: FetchUserProfileUpdatesUseCase,
private val skillLabUserProfileSyncRepository: SkillLabUserProfileSyncRepository,
) {

private val logger = LoggerFactory.getLogger(javaClass)


@GetMapping("/sync")
fun fetchSyncStatus(): ResponseEntity<List<SkillDto>> {
val result = skillLabUserProfileSyncRepository.findAll().mapNotNull {
SkillDto(
projectId = it.projectId,
latestSync = it.latestSync.toString()
)
}

return ResponseEntity.ok().body(result)
}

@PostMapping("/sync/{projectId}")
fun triggerSync(
@PathVariable projectId: String,
syncMode: SyncModeDto = SyncModeDto.DELTA,
updatedFrom: String? = null,
): ResponseEntity<Any> {

val result = skillLabUserProfileSyncRepository.findByProjectId(projectId).getOrElse {
return ResponseEntity.notFound().build()
}

when (syncMode) {
SyncModeDto.DELTA -> if (!updatedFrom.isNullOrBlank()) {
result.latestSync = Instant.parse(updatedFrom).atOffset(ZoneOffset.UTC)
skillLabUserProfileSyncRepository.save(result)
}

SyncModeDto.FULL -> skillLabUserProfileSyncRepository.delete(result)
}

try {
skillLabFetchUserProfileUpdatesUseCase.run(
request = FetchUserProfileUpdatesRequest(
projectId = projectId
)
)
} catch (ex: Exception) {
logger.error(
"[${this.javaClass.name}] An error occurred: {}",
ex.localizedMessage,
ex
)
return ResponseEntity.internalServerError().body(
HttpErrorDto(
errorCode = "INTERNAL_SERVER_ERROR",
errorMessage = ex.localizedMessage,
)
)
}


return ResponseEntity.noContent().build()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,17 @@ class SkillLabSyncUserProfileUseCase(
val allSkillsEntities = getSkillEntities(userProfile.profile)
val userProfileEntity = fetchUserProfileEntity(userProfile.profile, allSkillsEntities)

if (!userProfileEntity.mobileNumber.isNullOrBlank()) {
userProfileEntity.mobileNumber = userProfileEntity.mobileNumber
?.replace(" ", "")
?.replace("-", "")
?.trim()
}

try {
skillLabUserProfileRepository.save(userProfileEntity)
skillLabUserProfileRepository.save(
userProfileEntity
)
} catch (ex: Exception) {
return UseCaseOutcome.Failure(
errorCode = SkillLabSyncUserProfileErrorCode.IO_ERROR,
Expand All @@ -44,10 +53,7 @@ class SkillLabSyncUserProfileUseCase(
result = UserProfile(
id = userProfileEntity.externalIdentifier,
fullName = userProfileEntity.fullName,
phone = userProfileEntity.mobileNumber
?.replace(" ", "")
?.replace("-", "")
?.trim(),
phone = userProfileEntity.mobileNumber,
email = userProfileEntity.email,
skills = allSkillsEntities.map { skill ->
EscoSkill(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ logging:
logback:
rollingpolicy:
max-file-size: 100MB

---

spring:
Expand Down
63 changes: 63 additions & 0 deletions docs/api-specs/skill-api-v1.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ paths:
get:
summary: Return all UserProfile
description: todo
tags:
- skills
parameters:
- name: fullName
in: query
Expand Down Expand Up @@ -44,6 +46,8 @@ paths:
get:
summary: Return all UserProfile
description: todo
tags:
- skills
parameters:
- name: userProfileId
in: path
Expand All @@ -59,6 +63,53 @@ paths:
schema:
$ref: '#/components/schemas/UserProfile'

/sync:
get:
summary: Return sync status for projects
description: Returns a list of all configured projects and the latest sync attempt
tags:
- admin
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/Sync'

/sync/{projectId}:
post:
summary: Trigger project sync
description: Import all changes for this project from SkillProvider
tags:
- admin
parameters:
- name: syncMode
in: query
required: false
schema:
type: string
default: DELTA
enum:
- DELTA
- FULL
- name: updatedFrom
description: Define the start date for the Delta load. Just used in syncMode DELTA, uses latest sync date if not defined manually.
in: query
required: false
schema:
type: string
default: "2024-12-03T11:50:00.231Z"
format: date-time
- name: projectId
in: path
required: true
schema:
type: string
responses:
'204':
description: Sync process started, can take some minutes until all changes are imported.

components:
schemas:
UserProfile:
Expand All @@ -79,10 +130,22 @@ components:
$ref: '#/components/schemas/Skill'
updatedAtExternalSystem:
type: string
format: date-time
importedAt:
type: string
format: date-time
latestSyncAt:
type: string
format: date-time

Sync:
type: object
properties:
project:
type: string
latestSync:
type: string
format: date-time

Skill:
type: object
Expand Down

0 comments on commit 924f57c

Please sign in to comment.