diff --git a/.github/workflows/flow_backend_build_push.yml b/.github/workflows/flow_backend_build_push.yml new file mode 100644 index 0000000..c527c78 --- /dev/null +++ b/.github/workflows/flow_backend_build_push.yml @@ -0,0 +1,63 @@ +name: Build & push backend container image + +on: + workflow_call: + inputs: + service-build-context-path: + description: The path to the context to use when building the container image + default: ./backend + required: false + type: string + service-name: + description: The name of the service to build + required: true + type: string + push-image: + description: Whether to push the container image to the registry + default: false + required: false + type: boolean + image-tags: + description: The tags to pass to the "docker/metadata-action" action + required: true + type: string + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +jobs: + build: + runs-on: ubuntu-latest + permissions: + packages: write + contents: read + steps: + - name: Setup Docker buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to the Container registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - uses: docker/metadata-action@v5 + name: Extract metadata (tags, labels) for Docker + id: meta + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/${{ inputs.service-name }} + tags: ${{ inputs.image-tags }} + flavor: latest=false + + - name: Build and push Docker image + uses: docker/build-push-action@v5 + with: + push: ${{ inputs.push-image }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max + context: "{{ defaultContext }}:${{ inputs.service-build-context-path }}" + build-args: SERVICE_NAME=${{ inputs.service-name }} diff --git a/.github/workflows/flow_backend_lint.yml b/.github/workflows/flow_backend_lint.yml new file mode 100644 index 0000000..6d729e8 --- /dev/null +++ b/.github/workflows/flow_backend_lint.yml @@ -0,0 +1,34 @@ +name: Lint backend + +on: + workflow_call: + inputs: + gradle-root-project-path: + description: The path to the Gradle root project + default: ./backend + required: false + type: string + +jobs: + lint: + runs-on: ubuntu-latest + defaults: + run: + working-directory: ${{ inputs.gradle-root-project-path }} + steps: + - uses: actions/checkout@v4 + + - name: Use Java + uses: actions/setup-java@v3 + with: + java-version: 17 + distribution: corretto + + - name: Setup Gradle + uses: gradle/gradle-build-action@v2 + + - name: Lint Kotlin + run: ./gradlew ktlintCheck + + - name: Execute Gradle build + run: ./gradlew build -x test diff --git a/.github/workflows/flow_front_lint.yml b/.github/workflows/flow_front_lint.yml new file mode 100644 index 0000000..b1d8948 --- /dev/null +++ b/.github/workflows/flow_front_lint.yml @@ -0,0 +1,38 @@ +name: Lint frontend + +on: + workflow_call: + inputs: + app-dir-path: + description: The directory where the frontend application is stored + default: ./front + required: false + type: string + +jobs: + lint: + runs-on: ubuntu-latest + defaults: + run: + working-directory: ${{ inputs.app-dir-path }} + steps: + - uses: actions/checkout@v4 + + - name: Use Node.js 18 + uses: actions/setup-node@v4 + with: + node-version: 18 + cache: 'npm' + cache-dependency-path: ${{ inputs.app-dir-path }} + + - name: Install dependencies + run: npm ci + + - name: Run Prettier + run: npm run prettier:check + + - name: Run ESLint + run: npm run eslint:check + + - name: Run TypeScript + run: npm run typescript:check diff --git a/.github/workflows/on_push_pr_main.yml b/.github/workflows/on_push_pr_main.yml new file mode 100644 index 0000000..dfda62d --- /dev/null +++ b/.github/workflows/on_push_pr_main.yml @@ -0,0 +1,43 @@ +name: Push & PR to the main branch + +on: + push: + branches: + - main + pull_request: + branches: + - main + workflow_dispatch: + +jobs: + lint_frontend: + name: Lint frontend + uses: ./.github/workflows/flow_front_lint.yml + + lint_backend: + name: Lint backend + uses: ./.github/workflows/flow_backend_lint.yml + + build_api_gateway: + name: Build & push Docker image of the API gateway + needs: lint_backend + uses: ./.github/workflows/flow_backend_build_push.yml + with: + service-name: api_gateway + push-image: ${{ github.event_name != 'pull_request' }} + image-tags: | + type=sha + type=ref,event=branch + type=edge,branch=main + + build_jobs_service: + name: Build & push Docker image of the Jobs service + needs: lint_backend + uses: ./.github/workflows/flow_backend_build_push.yml + with: + service-name: jobs + push-image: ${{ github.event_name != 'pull_request' }} + image-tags: | + type=sha + type=ref,event=branch + type=edge diff --git a/.github/workflows/on_semver_tag.yml b/.github/workflows/on_semver_tag.yml new file mode 100644 index 0000000..3ef0ead --- /dev/null +++ b/.github/workflows/on_semver_tag.yml @@ -0,0 +1,29 @@ +name: Push a semver tag + +on: + push: + tags: + - v*.*.* + +jobs: + build_api_gateway: + name: Build & push Docker image of the API gateway + uses: ./.github/workflows/flow_backend_build_push.yml + with: + service-name: api_gateway + push-image: ${{ github.event_name != 'pull_request' }} + image-tags: | + type=sha + type=semver,pattern={{version}} + type=raw,value=latest + + build_jobs_service: + name: Build & push Docker image of the Jobs service + uses: ./.github/workflows/flow_backend_build_push.yml + with: + service-name: jobs + push-image: ${{ github.event_name != 'pull_request' }} + image-tags: | + type=sha + type=semver,pattern={{version}} + type=raw,value=latest diff --git a/backend/Dockerfile b/backend/Dockerfile new file mode 100644 index 0000000..36eff07 --- /dev/null +++ b/backend/Dockerfile @@ -0,0 +1,21 @@ +# Build stage +FROM amazoncorretto:17-alpine AS build +ARG SERVICE_NAME +WORKDIR /app + +COPY ./$SERVICE_NAME ./$SERVICE_NAME +COPY ./gradle ./gradle +COPY ./gradle.properties . +COPY ./gradlew . +COPY ./settings.gradle.kts . + +RUN --mount=type=cache,target=/root/.gradle ./gradlew clean build -x test + +# Run stage +FROM amazoncorretto:17-alpine AS run +ARG SERVICE_NAME +WORKDIR /app + +COPY --from=build /app/$SERVICE_NAME/build/libs/*-SNAPSHOT.jar ./app.jar + +ENTRYPOINT ["java", "-jar", "./app.jar"] diff --git a/backend/api_gateway/build.gradle.kts b/backend/api_gateway/build.gradle.kts index 0282f98..5e2dd7e 100644 --- a/backend/api_gateway/build.gradle.kts +++ b/backend/api_gateway/build.gradle.kts @@ -1,41 +1,45 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { - id("org.springframework.boot") - id("io.spring.dependency-management") - kotlin("jvm") - kotlin("plugin.spring") - kotlin("plugin.jpa") + id("org.springframework.boot") + id("io.spring.dependency-management") + id("org.jlleitschuh.gradle.ktlint") + kotlin("jvm") + kotlin("plugin.spring") + kotlin("plugin.jpa") } group = "com.linkedout" version = "1.0.0-SNAPSHOT" java { - sourceCompatibility = JavaVersion.VERSION_17 + sourceCompatibility = JavaVersion.VERSION_17 } repositories { - mavenCentral() + mavenCentral() } dependencies { - implementation("org.springframework.boot:spring-boot-starter-actuator:3.1.5") - implementation("org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.1.5") - implementation("org.springframework.boot:spring-boot-starter-security:3.1.5") - implementation("org.springframework.boot:spring-boot-starter-validation:3.1.5") - implementation("org.springframework.boot:spring-boot-starter-web:3.1.5") - developmentOnly("org.springframework.boot:spring-boot-devtools") - testImplementation("org.springframework.boot:spring-boot-starter-test") + implementation("org.springframework.boot:spring-boot-starter-actuator:3.1.5") + implementation("org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.1.5") + implementation("org.springframework.boot:spring-boot-starter-security:3.1.5") + implementation("org.springframework.boot:spring-boot-starter-validation:3.1.5") + implementation("org.springframework.boot:spring-boot-starter-web:3.1.5") + developmentOnly("org.springframework.boot:spring-boot-devtools") + testImplementation("org.springframework.boot:spring-boot-starter-test") + testImplementation("org.springframework.boot:spring-boot-testcontainers") + testImplementation("org.testcontainers:junit-jupiter") + testImplementation("org.testcontainers:postgresql") } tasks.withType { - kotlinOptions { - freeCompilerArgs += "-Xjsr305=strict" - jvmTarget = "17" - } + kotlinOptions { + freeCompilerArgs += "-Xjsr305=strict" + jvmTarget = "17" + } } tasks.withType { - useJUnitPlatform() + useJUnitPlatform() } diff --git a/backend/api_gateway/src/main/kotlin/com/linkedout/backend/config/SecurityConfig.kt b/backend/api_gateway/src/main/kotlin/com/linkedout/backend/config/SecurityConfig.kt index 8d03a1b..c47ac6b 100644 --- a/backend/api_gateway/src/main/kotlin/com/linkedout/backend/config/SecurityConfig.kt +++ b/backend/api_gateway/src/main/kotlin/com/linkedout/backend/config/SecurityConfig.kt @@ -10,7 +10,6 @@ import org.springframework.security.oauth2.server.resource.authentication.JwtAut import org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter import org.springframework.security.web.SecurityFilterChain - @Configuration @EnableWebSecurity @EnableMethodSecurity diff --git a/backend/api_gateway/src/test/java/com/linkedout/backend/ApiGatewayApplicationTests.java b/backend/api_gateway/src/test/java/com/linkedout/backend/ApiGatewayApplicationTests.java deleted file mode 100644 index 958c8de..0000000 --- a/backend/api_gateway/src/test/java/com/linkedout/backend/ApiGatewayApplicationTests.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.linkedout.backend; - -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.SpringBootTest; - -@SpringBootTest -class ApiGatewayApplicationTests { - - @Test - void contextLoads() { - } - -} diff --git a/backend/api_gateway/src/test/java/com/linkedout/backend/TestBackendApplication.java b/backend/api_gateway/src/test/java/com/linkedout/backend/TestBackendApplication.java deleted file mode 100644 index 8d4b041..0000000 --- a/backend/api_gateway/src/test/java/com/linkedout/backend/TestBackendApplication.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.linkedout.backend; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.test.context.TestConfiguration; -import org.springframework.boot.testcontainers.service.connection.ServiceConnection; -import org.springframework.context.annotation.Bean; -import org.testcontainers.containers.PostgreSQLContainer; -import org.testcontainers.utility.DockerImageName; - -@TestConfiguration(proxyBeanMethods = false) -public class TestBackendApplication { - - @Bean - @ServiceConnection - PostgreSQLContainer postgresContainer() { - return new PostgreSQLContainer<>(DockerImageName.parse("postgres:latest")); - } - - public static void main(String[] args) { - SpringApplication.from(ApiGatewayApplication::main).with(TestBackendApplication.class).run(args); - } - -} diff --git a/backend/api_gateway/src/test/kotlin/com/linkedout/backend/ApiGatewayApplicationTests.kt b/backend/api_gateway/src/test/kotlin/com/linkedout/backend/ApiGatewayApplicationTests.kt new file mode 100644 index 0000000..d0895c6 --- /dev/null +++ b/backend/api_gateway/src/test/kotlin/com/linkedout/backend/ApiGatewayApplicationTests.kt @@ -0,0 +1,32 @@ +package com.linkedout.backend + +import org.junit.jupiter.api.Test +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase +import org.springframework.boot.test.context.SpringBootTest +import org.springframework.test.context.DynamicPropertyRegistry +import org.springframework.test.context.DynamicPropertySource +import org.testcontainers.containers.PostgreSQLContainer +import org.testcontainers.junit.jupiter.Container +import org.testcontainers.junit.jupiter.Testcontainers + +@SpringBootTest +@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) +@Testcontainers +internal class ApiGatewayApplicationTests { + companion object { + @Container + private val postgreSQLContainer = PostgreSQLContainer("postgres:latest") + + @DynamicPropertySource + @JvmStatic + fun registerDynamicProperties(registry: DynamicPropertyRegistry) { + registry.add("spring.datasource.url", postgreSQLContainer::getJdbcUrl) + registry.add("spring.datasource.username", postgreSQLContainer::getUsername) + registry.add("spring.datasource.password", postgreSQLContainer::getPassword) + } + } + + @Test + fun contextLoads() { + } +} diff --git a/backend/jobs/build.gradle.kts b/backend/jobs/build.gradle.kts index 2d4862f..4952f14 100644 --- a/backend/jobs/build.gradle.kts +++ b/backend/jobs/build.gradle.kts @@ -1,47 +1,48 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { - id("org.springframework.boot") - id("io.spring.dependency-management") - kotlin("jvm") - kotlin("plugin.spring") - kotlin("plugin.jpa") + id("org.springframework.boot") + id("io.spring.dependency-management") + id("org.jlleitschuh.gradle.ktlint") + kotlin("jvm") + kotlin("plugin.spring") + kotlin("plugin.jpa") } group = "com.linkedout" version = "1.0.0-SNAPSHOT" java { - sourceCompatibility = JavaVersion.VERSION_17 + sourceCompatibility = JavaVersion.VERSION_17 } repositories { - mavenCentral() + mavenCentral() } dependencies { - implementation("org.springframework.boot:spring-boot-starter-actuator:3.1.5") - implementation("org.springframework.boot:spring-boot-starter-data-r2dbc:3.1.5") - implementation("org.springframework.boot:spring-boot-starter-validation:3.1.5") - implementation("org.springframework.boot:spring-boot-starter-webflux:3.1.5") - implementation("org.springframework.boot:spring-boot-starter-web:3.1.5") - implementation("org.springframework:spring-jdbc:6.0.13") - implementation("org.flywaydb:flyway-core:9.22.3") - implementation("org.postgresql:r2dbc-postgresql:1.0.2.RELEASE") - implementation("jakarta.validation:jakarta.validation-api:3.0.2") - implementation("org.jetbrains.kotlin:kotlin-reflect:1.9.20") - developmentOnly("org.springframework.boot:spring-boot-devtools") - runtimeOnly("org.postgresql:postgresql") - testImplementation("org.springframework.boot:spring-boot-starter-test") + implementation("org.springframework.boot:spring-boot-starter-actuator:3.1.5") + implementation("org.springframework.boot:spring-boot-starter-data-r2dbc:3.1.5") + implementation("org.springframework.boot:spring-boot-starter-validation:3.1.5") + implementation("org.springframework.boot:spring-boot-starter-webflux:3.1.5") + implementation("org.springframework.boot:spring-boot-starter-web:3.1.5") + implementation("org.springframework:spring-jdbc:6.0.13") + implementation("org.flywaydb:flyway-core:9.22.3") + implementation("org.postgresql:r2dbc-postgresql:1.0.2.RELEASE") + implementation("jakarta.validation:jakarta.validation-api:3.0.2") + implementation("org.jetbrains.kotlin:kotlin-reflect:1.9.20") + developmentOnly("org.springframework.boot:spring-boot-devtools") + runtimeOnly("org.postgresql:postgresql") + testImplementation("org.springframework.boot:spring-boot-starter-test") } tasks.withType { - kotlinOptions { - freeCompilerArgs += "-Xjsr305=strict" - jvmTarget = "17" - } + kotlinOptions { + freeCompilerArgs += "-Xjsr305=strict" + jvmTarget = "17" + } } tasks.withType { - useJUnitPlatform() + useJUnitPlatform() } diff --git a/backend/jobs/src/main/kotlin/com/linkedout/jobs/JobsApplication.kt b/backend/jobs/src/main/kotlin/com/linkedout/jobs/JobsApplication.kt index d19edac..cfda8e2 100644 --- a/backend/jobs/src/main/kotlin/com/linkedout/jobs/JobsApplication.kt +++ b/backend/jobs/src/main/kotlin/com/linkedout/jobs/JobsApplication.kt @@ -7,5 +7,5 @@ import org.springframework.boot.runApplication class JobsApplication fun main(args: Array) { - runApplication(*args) + runApplication(*args) } diff --git a/backend/jobs/src/main/kotlin/com/linkedout/jobs/controller/JobOffersController.kt b/backend/jobs/src/main/kotlin/com/linkedout/jobs/controller/JobOffersController.kt index 192fc20..94c94f6 100644 --- a/backend/jobs/src/main/kotlin/com/linkedout/jobs/controller/JobOffersController.kt +++ b/backend/jobs/src/main/kotlin/com/linkedout/jobs/controller/JobOffersController.kt @@ -4,10 +4,10 @@ import com.linkedout.jobs.model.JobOffer import com.linkedout.jobs.service.JobApplicationService import com.linkedout.jobs.service.JobOfferService import org.springframework.web.bind.annotation.GetMapping -import org.springframework.web.bind.annotation.RequestMapping -import org.springframework.web.bind.annotation.RestController 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 reactor.core.publisher.Flux import reactor.core.publisher.Mono import java.util.UUID @@ -16,16 +16,21 @@ import java.util.UUID @RequestMapping("/jobOffers") class JobOffersController(private val jobOfferService: JobOfferService, private val jobApplicationService: JobApplicationService) { @GetMapping - fun getJobs(): Flux{ + fun getJobs(): Flux { return jobOfferService.findAll() } + @GetMapping("/{id}") - fun getJob(@PathVariable id: UUID): Mono { + fun getJob( + @PathVariable id: UUID + ): Mono { return jobOfferService.findOne(id) } @PostMapping("/{id}/apply") - fun applyToJob(@PathVariable id: UUID): Mono{ + fun applyToJob( + @PathVariable id: UUID + ): Mono { return jobApplicationService.apply(id) } -} \ No newline at end of file +} diff --git a/backend/jobs/src/main/kotlin/com/linkedout/jobs/controller/JobsController.kt b/backend/jobs/src/main/kotlin/com/linkedout/jobs/controller/JobsController.kt index cfef2ae..50344c2 100644 --- a/backend/jobs/src/main/kotlin/com/linkedout/jobs/controller/JobsController.kt +++ b/backend/jobs/src/main/kotlin/com/linkedout/jobs/controller/JobsController.kt @@ -2,11 +2,11 @@ package com.linkedout.jobs.controller import com.linkedout.jobs.model.Job import com.linkedout.jobs.model.JobCategory import com.linkedout.jobs.service.JobCategoryService +import com.linkedout.jobs.service.JobService import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RestController -import com.linkedout.jobs.service.JobService -import org.springframework.web.bind.annotation.PathVariable import reactor.core.publisher.Flux import reactor.core.publisher.Mono import java.util.UUID @@ -15,11 +15,14 @@ import java.util.UUID @RequestMapping("/jobs") class JobsController(private val jobService: JobService, private val jobCategoryService: JobCategoryService) { @GetMapping - fun getJobs(): Flux{ + fun getJobs(): Flux { return jobService.findAll() } + @GetMapping("/{id}") - fun getJob(@PathVariable id: UUID): Mono { + fun getJob( + @PathVariable id: UUID + ): Mono { return jobService.findOne(id) } @@ -27,4 +30,4 @@ class JobsController(private val jobService: JobService, private val jobCategory fun getCategories(): Flux { return jobCategoryService.findAll() } -} \ No newline at end of file +} diff --git a/backend/jobs/src/main/kotlin/com/linkedout/jobs/model/Job.kt b/backend/jobs/src/main/kotlin/com/linkedout/jobs/model/Job.kt index 5206c3f..88ea356 100644 --- a/backend/jobs/src/main/kotlin/com/linkedout/jobs/model/Job.kt +++ b/backend/jobs/src/main/kotlin/com/linkedout/jobs/model/Job.kt @@ -1,14 +1,13 @@ package com.linkedout.jobs.model import org.springframework.data.annotation.Id -import org.springframework.data.relational.core.mapping.Column import org.springframework.data.relational.core.mapping.Table import java.util.UUID @Table(name = "job") data class Job( - @Id - val id: UUID, - val title: String, - val category: UUID + @Id + val id: UUID, + val title: String, + val category: UUID ) diff --git a/backend/jobs/src/main/kotlin/com/linkedout/jobs/model/JobApplication.kt b/backend/jobs/src/main/kotlin/com/linkedout/jobs/model/JobApplication.kt index 3d53745..8250413 100644 --- a/backend/jobs/src/main/kotlin/com/linkedout/jobs/model/JobApplication.kt +++ b/backend/jobs/src/main/kotlin/com/linkedout/jobs/model/JobApplication.kt @@ -13,5 +13,5 @@ data class JobApplication( val jobId: UUID, @Column("userid") val userId: UUID, - val status: Boolean, -) \ No newline at end of file + val status: Boolean +) diff --git a/backend/jobs/src/main/kotlin/com/linkedout/jobs/model/JobCategory.kt b/backend/jobs/src/main/kotlin/com/linkedout/jobs/model/JobCategory.kt index 66779b4..9960ff1 100644 --- a/backend/jobs/src/main/kotlin/com/linkedout/jobs/model/JobCategory.kt +++ b/backend/jobs/src/main/kotlin/com/linkedout/jobs/model/JobCategory.kt @@ -1,13 +1,12 @@ package com.linkedout.jobs.model import org.springframework.data.annotation.Id -import org.springframework.data.relational.core.mapping.Column import org.springframework.data.relational.core.mapping.Table import java.util.UUID @Table(name = "jobcategory") data class JobCategory( - @Id - val id: UUID, - val title: String, -) \ No newline at end of file + @Id + val id: UUID, + val title: String +) diff --git a/backend/jobs/src/main/kotlin/com/linkedout/jobs/model/JobOffer.kt b/backend/jobs/src/main/kotlin/com/linkedout/jobs/model/JobOffer.kt index 6b0509e..e1f20f6 100644 --- a/backend/jobs/src/main/kotlin/com/linkedout/jobs/model/JobOffer.kt +++ b/backend/jobs/src/main/kotlin/com/linkedout/jobs/model/JobOffer.kt @@ -8,15 +8,15 @@ import java.util.UUID @Table(name = "joboffer") data class JobOffer( - @Id - val id: UUID, - val job: UUID, - val title: String, - val description: String, - @Column("startdate") - val startDate: LocalDate, - @Column("enddate") - val endDate: LocalDate, - val company: UUID, - val salary: Int, + @Id + val id: UUID, + val job: UUID, + val title: String, + val description: String, + @Column("startdate") + val startDate: LocalDate, + @Column("enddate") + val endDate: LocalDate, + val company: UUID, + val salary: Int ) diff --git a/backend/jobs/src/main/kotlin/com/linkedout/jobs/repository/JobApplicationRepository.kt b/backend/jobs/src/main/kotlin/com/linkedout/jobs/repository/JobApplicationRepository.kt index 59c5ed0..29f72bb 100644 --- a/backend/jobs/src/main/kotlin/com/linkedout/jobs/repository/JobApplicationRepository.kt +++ b/backend/jobs/src/main/kotlin/com/linkedout/jobs/repository/JobApplicationRepository.kt @@ -1,6 +1,6 @@ package com.linkedout.jobs.repository import com.linkedout.jobs.model.JobApplication -import org.springframework.data.repository.reactive.ReactiveCrudRepository; +import org.springframework.data.repository.reactive.ReactiveCrudRepository import java.util.UUID -interface JobApplicationRepository : ReactiveCrudRepository \ No newline at end of file +interface JobApplicationRepository : ReactiveCrudRepository diff --git a/backend/jobs/src/main/kotlin/com/linkedout/jobs/repository/JobCategoryRepository.kt b/backend/jobs/src/main/kotlin/com/linkedout/jobs/repository/JobCategoryRepository.kt index fa8aeae..7024d20 100644 --- a/backend/jobs/src/main/kotlin/com/linkedout/jobs/repository/JobCategoryRepository.kt +++ b/backend/jobs/src/main/kotlin/com/linkedout/jobs/repository/JobCategoryRepository.kt @@ -1,6 +1,6 @@ package com.linkedout.jobs.repository import com.linkedout.jobs.model.JobCategory -import org.springframework.data.repository.reactive.ReactiveCrudRepository; +import org.springframework.data.repository.reactive.ReactiveCrudRepository import java.util.UUID -interface JobCategoryRepository : ReactiveCrudRepository \ No newline at end of file +interface JobCategoryRepository : ReactiveCrudRepository diff --git a/backend/jobs/src/main/kotlin/com/linkedout/jobs/repository/JobOfferRepository.kt b/backend/jobs/src/main/kotlin/com/linkedout/jobs/repository/JobOfferRepository.kt index 65fedae..731a034 100644 --- a/backend/jobs/src/main/kotlin/com/linkedout/jobs/repository/JobOfferRepository.kt +++ b/backend/jobs/src/main/kotlin/com/linkedout/jobs/repository/JobOfferRepository.kt @@ -1,6 +1,6 @@ package com.linkedout.jobs.repository import com.linkedout.jobs.model.JobOffer -import org.springframework.data.repository.reactive.ReactiveCrudRepository; +import org.springframework.data.repository.reactive.ReactiveCrudRepository import java.util.UUID -interface JobOfferRepository : ReactiveCrudRepository \ No newline at end of file +interface JobOfferRepository : ReactiveCrudRepository diff --git a/backend/jobs/src/main/kotlin/com/linkedout/jobs/repository/JobRepository.kt b/backend/jobs/src/main/kotlin/com/linkedout/jobs/repository/JobRepository.kt index 21c465d..c1508cb 100644 --- a/backend/jobs/src/main/kotlin/com/linkedout/jobs/repository/JobRepository.kt +++ b/backend/jobs/src/main/kotlin/com/linkedout/jobs/repository/JobRepository.kt @@ -1,6 +1,6 @@ package com.linkedout.jobs.repository import com.linkedout.jobs.model.Job -import org.springframework.data.repository.reactive.ReactiveCrudRepository; +import org.springframework.data.repository.reactive.ReactiveCrudRepository import java.util.UUID -interface JobRepository : ReactiveCrudRepository \ No newline at end of file +interface JobRepository : ReactiveCrudRepository diff --git a/backend/jobs/src/main/kotlin/com/linkedout/jobs/service/JobApplicationService.kt b/backend/jobs/src/main/kotlin/com/linkedout/jobs/service/JobApplicationService.kt index fd900c5..afb0748 100644 --- a/backend/jobs/src/main/kotlin/com/linkedout/jobs/service/JobApplicationService.kt +++ b/backend/jobs/src/main/kotlin/com/linkedout/jobs/service/JobApplicationService.kt @@ -11,19 +11,23 @@ import reactor.core.publisher.Mono import java.util.UUID @Service -class JobApplicationService(@Autowired private val jobApplicationRepository: JobApplicationRepository, @Autowired private val jobRepository: JobRepository ) { - fun apply(jobId: UUID): Mono{ +class JobApplicationService( + @Autowired private val jobApplicationRepository: JobApplicationRepository, + @Autowired private val jobRepository: JobRepository +) { + fun apply(jobId: UUID): Mono { val jobExistsMono: Mono = jobRepository.existsById(jobId) println(jobExistsMono) return jobExistsMono.flatMap { jobExists -> if (jobExists) { // TODO: retrieve userId val userId = "581104d5-3af7-4dc0-836b-30574d64a1e8" - val jobApplication = JobApplication( - jobId = jobId, - userId = UUID.fromString(userId), - status = false - ) + val jobApplication = + JobApplication( + jobId = jobId, + userId = UUID.fromString(userId), + status = false + ) // Save the job application jobApplicationRepository.save(jobApplication) } else { @@ -32,4 +36,4 @@ class JobApplicationService(@Autowired private val jobApplicationRepository: Job } } } -} \ No newline at end of file +} diff --git a/backend/jobs/src/main/kotlin/com/linkedout/jobs/service/JobCategoryService.kt b/backend/jobs/src/main/kotlin/com/linkedout/jobs/service/JobCategoryService.kt index 7b9181c..81ee25e 100644 --- a/backend/jobs/src/main/kotlin/com/linkedout/jobs/service/JobCategoryService.kt +++ b/backend/jobs/src/main/kotlin/com/linkedout/jobs/service/JobCategoryService.kt @@ -7,8 +7,10 @@ import org.springframework.stereotype.Service import reactor.core.publisher.Flux @Service -class JobCategoryService(@Autowired private val jobCategory: JobCategoryRepository) { - fun findAll(): Flux{ +class JobCategoryService( + @Autowired private val jobCategory: JobCategoryRepository +) { + fun findAll(): Flux { return jobCategory.findAll() } -} \ No newline at end of file +} diff --git a/backend/jobs/src/main/kotlin/com/linkedout/jobs/service/JobOfferService.kt b/backend/jobs/src/main/kotlin/com/linkedout/jobs/service/JobOfferService.kt index d0e6a53..ee0b858 100644 --- a/backend/jobs/src/main/kotlin/com/linkedout/jobs/service/JobOfferService.kt +++ b/backend/jobs/src/main/kotlin/com/linkedout/jobs/service/JobOfferService.kt @@ -9,11 +9,14 @@ import reactor.core.publisher.Mono import java.util.UUID @Service -class JobOfferService(@Autowired private val jobOffer: JobOfferRepository) { - fun findAll(): Flux{ +class JobOfferService( + @Autowired private val jobOffer: JobOfferRepository +) { + fun findAll(): Flux { return jobOffer.findAll() } + fun findOne(id: UUID): Mono { return jobOffer.findById(id) } -} \ No newline at end of file +} diff --git a/backend/jobs/src/main/kotlin/com/linkedout/jobs/service/JobService.kt b/backend/jobs/src/main/kotlin/com/linkedout/jobs/service/JobService.kt index 7f19bd8..10494d1 100644 --- a/backend/jobs/src/main/kotlin/com/linkedout/jobs/service/JobService.kt +++ b/backend/jobs/src/main/kotlin/com/linkedout/jobs/service/JobService.kt @@ -1,8 +1,6 @@ package com.linkedout.jobs.service import com.linkedout.jobs.model.Job -import com.linkedout.jobs.model.JobCategory -import com.linkedout.jobs.repository.JobCategoryRepository import com.linkedout.jobs.repository.JobRepository import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Service @@ -11,11 +9,14 @@ import reactor.core.publisher.Mono import java.util.UUID @Service -class JobService(@Autowired private val jobRepository: JobRepository) { - fun findAll(): Flux{ +class JobService( + @Autowired private val jobRepository: JobRepository +) { + fun findAll(): Flux { return jobRepository.findAll() } + fun findOne(id: UUID): Mono { return jobRepository.findById(id) } -} \ No newline at end of file +} diff --git a/backend/jobs/src/test/kotlin/com/linkedout/jobs/JobsApplicationTests.kt b/backend/jobs/src/test/kotlin/com/linkedout/jobs/JobsApplicationTests.kt index 26c2b19..eea0ed0 100644 --- a/backend/jobs/src/test/kotlin/com/linkedout/jobs/JobsApplicationTests.kt +++ b/backend/jobs/src/test/kotlin/com/linkedout/jobs/JobsApplicationTests.kt @@ -5,9 +5,7 @@ import org.springframework.boot.test.context.SpringBootTest @SpringBootTest class JobsApplicationTests { - - @Test - fun contextLoads() { - } - + @Test + fun contextLoads() { + } } diff --git a/backend/settings.gradle.kts b/backend/settings.gradle.kts index 853dbbd..c84d0f3 100644 --- a/backend/settings.gradle.kts +++ b/backend/settings.gradle.kts @@ -9,6 +9,7 @@ plugins { id("org.gradle.toolchains.foojay-resolver-convention") version "0.7.0" id("org.springframework.boot") version "3.1.5" apply false id("io.spring.dependency-management") version "1.1.3" apply false + id("org.jlleitschuh.gradle.ktlint") version "11.6.1" apply false kotlin("jvm") version "1.9.20" apply false kotlin("plugin.spring") version "1.9.20" apply false kotlin("plugin.jpa") version "1.9.20" apply false