feat(#28): Initialize backend with application form template

This commit is contained in:
2025-12-23 19:19:06 +01:00
parent c64ed6a749
commit 46d6431747
5 changed files with 82 additions and 3 deletions

View File

@@ -770,5 +770,5 @@ act -n
- CI/CD Pipeline: `.github/workflows/pipeline.yaml`
- Act Configuration: `.actrc` and `.secrets.example`
- Database Management Script: `manage-db.sh`
- Test Data: `testdata.json`
- Initial Application Form Template: `initial_application_form_template.json`
- IT System Config: `it-system.json`

View File

@@ -1,6 +1,7 @@
package com.betriebsratkanzlei.legalconsenthub.application_form
import com.betriebsratkanzlei.legalconsenthub.form_element.FormElementSectionMapper
import com.betriebsratkanzlei.legalconsenthub.user.User
import com.betriebsratkanzlei.legalconsenthub.user.UserMapper
import com.betriebsratkanzlei.legalconsenthub.user.UserService
import com.betriebsratkanzlei.legalconsenthub_api.model.ApplicationFormDto
@@ -37,6 +38,13 @@ class ApplicationFormMapper(
fun toNewApplicationForm(applicationFormDto: ApplicationFormDto): ApplicationForm {
val currentUser = userService.getCurrentUser()
return toNewApplicationForm(applicationFormDto, currentUser)
}
fun toNewApplicationForm(
applicationFormDto: ApplicationFormDto,
user: User,
): ApplicationForm {
val applicationForm =
ApplicationForm(
id = null,
@@ -46,8 +54,8 @@ class ApplicationFormMapper(
status =
applicationFormDto.status
?: com.betriebsratkanzlei.legalconsenthub_api.model.ApplicationFormStatus.DRAFT,
createdBy = currentUser,
lastModifiedBy = currentUser,
createdBy = user,
lastModifiedBy = user,
)
applicationForm.formElementSections =
applicationFormDto.formElementSections

View File

@@ -11,6 +11,8 @@ import java.util.UUID
interface ApplicationFormRepository : JpaRepository<ApplicationForm, UUID> {
fun findAllByIsTemplateTrue(page: Pageable): Page<ApplicationForm>
fun existsByIsTemplateTrue(): Boolean
@Query(
"SELECT c FROM ApplicationForm c WHERE (c.isTemplate IS false) AND (:organizationId is null or c.organizationId = :organizationId)",
)

View File

@@ -0,0 +1,69 @@
package com.betriebsratkanzlei.legalconsenthub.seed
import com.betriebsratkanzlei.legalconsenthub.application_form.ApplicationFormMapper
import com.betriebsratkanzlei.legalconsenthub.application_form.ApplicationFormRepository
import com.betriebsratkanzlei.legalconsenthub.user.User
import com.betriebsratkanzlei.legalconsenthub.user.UserRepository
import com.betriebsratkanzlei.legalconsenthub_api.model.ApplicationFormDto
import com.fasterxml.jackson.databind.ObjectMapper
import org.slf4j.LoggerFactory
import org.springframework.boot.ApplicationArguments
import org.springframework.boot.ApplicationRunner
import org.springframework.core.io.ClassPathResource
import org.springframework.stereotype.Component
import org.springframework.transaction.annotation.Transactional
@Component
class InitialApplicationFormTemplateSeeder(
private val applicationFormRepository: ApplicationFormRepository,
private val applicationFormMapper: ApplicationFormMapper,
private val userRepository: UserRepository,
private val objectMapper: ObjectMapper,
) : ApplicationRunner {
override fun run(args: ApplicationArguments) {
seedInitialTemplateIfMissing()
}
@Transactional
fun seedInitialTemplateIfMissing() {
if (applicationFormRepository.existsByIsTemplateTrue()) {
log.info(
"At least one application form template already present, skipping initial template seed",
)
return
}
val seedingUser = getOrCreateSeedingUser()
val dto = loadInitialTemplateDto()
val applicationForm = applicationFormMapper.toNewApplicationForm(dto.copy(isTemplate = true), seedingUser)
applicationFormRepository.save(applicationForm)
log.info("Seeded initial application form template (name={})", applicationForm.name)
}
private fun loadInitialTemplateDto(): ApplicationFormDto =
ClassPathResource(INITIAL_TEMPLATE_RESOURCE_PATH).inputStream.use { inputStream ->
objectMapper.readValue(inputStream, ApplicationFormDto::class.java)
}
private fun getOrCreateSeedingUser(): User {
val existing = userRepository.findById(SEEDING_USER_ID)
if (existing.isPresent) return existing.get()
val user =
User(
keycloakId = SEEDING_USER_ID,
name = "System Seeder",
organizationId = null,
email = null,
)
return userRepository.save(user)
}
companion object {
private val log = LoggerFactory.getLogger(InitialApplicationFormTemplateSeeder::class.java)
private const val INITIAL_TEMPLATE_RESOURCE_PATH = "seed/initial_application_form_template.json"
private const val SEEDING_USER_ID = "system-seeder"
}
}