Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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