Skip to content

Commit

Permalink
Merge pull request #2484 from objectcomputing/feature-2446/backend-fo…
Browse files Browse the repository at this point in the history
…r-certifications

Add API for managing certifications and earning them
  • Loading branch information
mkimberlin authored Jun 11, 2024
2 parents da6628a + c7cda48 commit f001bd0
Show file tree
Hide file tree
Showing 21 changed files with 1,487 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package com.objectcomputing.checkins.services.certification;

import io.micronaut.core.annotation.Introspected;
import io.micronaut.core.annotation.Nullable;
import io.micronaut.data.annotation.AutoPopulated;
import io.micronaut.data.annotation.TypeDef;
import io.micronaut.data.model.DataType;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import jakarta.validation.constraints.NotBlank;
import lombok.Getter;
import lombok.Setter;

import java.util.UUID;

@Setter
@Getter
@Entity
@Introspected
@Table(name = "certification")
public class Certification {

@Id
@Column(name = "certification_id")
@AutoPopulated
@TypeDef(type = DataType.STRING)
@Schema(description = "id of the certification")
private UUID id;

@Column(name = "name")
@NotBlank
@Schema(description = "name of the certification")
private String name;

@Nullable
@Column(name = "badge_url")
@Schema(description = "url of the badge")
private String badgeUrl;

@Column(name = "is_active")
@Schema(description = "whether the Certification is active")
private boolean active = true;

public Certification() {
}

Certification(UUID id, String name, @Nullable String badgeUrl, boolean active) {
this.id = id;
this.name = name;
this.badgeUrl = badgeUrl;
this.active = active;
}

public Certification(String name, @Nullable String badgeUrl) {
this(null, name, badgeUrl, true);
}

Certification(String name, String badgeUrl, boolean active) {
this(null, name, badgeUrl, active);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package com.objectcomputing.checkins.services.certification;

import com.objectcomputing.checkins.services.permissions.Permission;
import com.objectcomputing.checkins.services.permissions.RequiredPermission;
import io.micronaut.http.HttpStatus;
import io.micronaut.http.annotation.Body;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;
import io.micronaut.http.annotation.Post;
import io.micronaut.http.annotation.Put;
import io.micronaut.http.annotation.Status;
import io.micronaut.scheduling.TaskExecutors;
import io.micronaut.scheduling.annotation.ExecuteOn;
import io.micronaut.security.annotation.Secured;
import io.micronaut.security.rules.SecurityRule;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;

import java.util.List;
import java.util.UUID;

@ExecuteOn(TaskExecutors.BLOCKING)
@Secured(SecurityRule.IS_AUTHENTICATED)
@Controller("/services/certification")
@Tag(name = "certification")
class CertificationController {

private final CertificationService certificationService;

CertificationController(CertificationService certificationService) {
this.certificationService = certificationService;
}

/**
* List all certifications
*
* @return a List of {@link Certification}
*/
@Get
List<Certification> findAll() {
return certificationService.findAllCertifications();
}

/**
* Create a new certification
*
* @param certification the certification to create
* @return the created {@link Certification}
*/
@Post
@Status(HttpStatus.CREATED)
Certification create(@Body @Valid CertificationDTO certification) {
return certificationService.saveCertification(new Certification(
certification.getName(),
certification.getBadgeUrl(),
!Boolean.FALSE.equals(certification.getActive())
));
}

/**
* Update a certification
*
* @param id the id of the certification to update
* @param certification the updated certification details in the body
* @return the updated {@link Certification}
*/
@Put("/{id}")
@RequiredPermission(Permission.CAN_MANAGE_CERTIFICATIONS)
Certification update(@NotNull UUID id, @Body @Valid CertificationDTO certification) {
return certificationService.updateCertification(new Certification(
id,
certification.getName(),
certification.getBadgeUrl(),
!Boolean.FALSE.equals(certification.getActive())
));
}

/**
* Given a source and target certification, move all earned certifications from the source to the target and delete the source certification.
*
* @param certificationMergeDTO the source and target certifications to merge
* @return the merged {@link Certification}
*/
@Post("/merge")
@RequiredPermission(Permission.CAN_MANAGE_CERTIFICATIONS)
Certification mergeCertifications(@Valid @Body CertificationMergeDTO certificationMergeDTO) {
return certificationService.mergeCertifications(certificationMergeDTO.getSourceId(), certificationMergeDTO.getTargetId());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.objectcomputing.checkins.services.certification;

import io.micronaut.core.annotation.Introspected;
import io.micronaut.core.annotation.Nullable;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;

@Setter
@Getter
@AllArgsConstructor
@Introspected
class CertificationDTO {

@NotNull
@Schema(description = "name of the certification")
private String name;

@Nullable
@Schema(description = "badge url of the certification")
private String badgeUrl;

@Nullable
@Schema(description = "whether the Certification is active")
private Boolean active;

CertificationDTO(String name, String badgeUrl) {
this(name, badgeUrl, true);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.objectcomputing.checkins.services.certification;

import io.micronaut.core.annotation.Introspected;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;

import java.util.UUID;

@Setter
@Getter
@AllArgsConstructor
@Introspected
class CertificationMergeDTO {

@NotNull
@Schema(description = "the ID of the certification to remove")
private UUID sourceId;

@NotNull
@Schema(description = "the ID of the certification to move all the earned certificates to")
private UUID targetId;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.objectcomputing.checkins.services.certification;

import io.micronaut.data.jdbc.annotation.JdbcRepository;
import io.micronaut.data.model.query.builder.sql.Dialect;
import io.micronaut.data.repository.CrudRepository;

import java.util.List;
import java.util.Optional;
import java.util.UUID;

@JdbcRepository(dialect = Dialect.POSTGRES)
public interface CertificationRepository extends CrudRepository<Certification, UUID> {

Optional<Certification> getByName(String name);

List<Certification> findAllOrderByNameAsc();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.objectcomputing.checkins.services.certification;

import io.micronaut.core.annotation.Nullable;

import java.util.List;
import java.util.UUID;

interface CertificationService {

List<Certification> findAllCertifications();

Certification saveCertification(Certification certification);

Certification updateCertification(Certification certification);

List<EarnedCertification> findAllEarnedCertifications(@Nullable UUID memberId, @Nullable UUID certificationId, boolean includeInactive);

EarnedCertification saveEarnedCertification(EarnedCertification certification);

EarnedCertification updateEarnedCertification(EarnedCertification certification);

void deleteEarnedCertification(UUID id);

Certification mergeCertifications(UUID sourceId, UUID targetId);
}
Loading

0 comments on commit f001bd0

Please sign in to comment.