autocomit
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
package com.ldpv2.controller;
|
||||
|
||||
import com.ldpv2.dto.request.RecordDeploymentRequest;
|
||||
import com.ldpv2.dto.response.CurrentDeploymentStateResponse;
|
||||
import com.ldpv2.dto.response.DeploymentResponse;
|
||||
import com.ldpv2.service.DeploymentService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/deployments")
|
||||
@Tag(name = "Deployments", description = "Deployment tracking endpoints")
|
||||
@SecurityRequirement(name = "bearerAuth")
|
||||
public class DeploymentController {
|
||||
|
||||
@Autowired
|
||||
private DeploymentService deploymentService;
|
||||
|
||||
@PostMapping
|
||||
@Operation(summary = "Record deployment", description = "Record a new deployment")
|
||||
public ResponseEntity<DeploymentResponse> recordDeployment(
|
||||
@Valid @RequestBody RecordDeploymentRequest request) {
|
||||
DeploymentResponse response = deploymentService.recordDeployment(request);
|
||||
return new ResponseEntity<>(response, HttpStatus.CREATED);
|
||||
}
|
||||
|
||||
@GetMapping("/{id}")
|
||||
@Operation(summary = "Get deployment", description = "Get deployment by ID")
|
||||
public ResponseEntity<DeploymentResponse> getById(@PathVariable UUID id) {
|
||||
DeploymentResponse response = deploymentService.findById(id);
|
||||
return ResponseEntity.ok(response);
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
@Operation(summary = "List deployments", description = "Get paginated list of deployments with optional filters")
|
||||
public ResponseEntity<Page<DeploymentResponse>> getAll(
|
||||
@RequestParam(required = false) UUID applicationId,
|
||||
@RequestParam(required = false) UUID environmentId,
|
||||
@RequestParam(required = false) UUID versionId,
|
||||
@RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime dateFrom,
|
||||
@RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime dateTo,
|
||||
@RequestParam(defaultValue = "0") int page,
|
||||
@RequestParam(defaultValue = "20") int size,
|
||||
@RequestParam(defaultValue = "deploymentDate") String sortBy,
|
||||
@RequestParam(defaultValue = "desc") String sortDirection) {
|
||||
|
||||
Sort sort = sortDirection.equalsIgnoreCase("desc")
|
||||
? Sort.by(sortBy).descending()
|
||||
: Sort.by(sortBy).ascending();
|
||||
|
||||
Pageable pageable = PageRequest.of(page, size, sort);
|
||||
|
||||
Page<DeploymentResponse> response;
|
||||
if (applicationId != null || environmentId != null || versionId != null || dateFrom != null || dateTo != null) {
|
||||
response = deploymentService.search(applicationId, environmentId, versionId, dateFrom, dateTo, pageable);
|
||||
} else {
|
||||
response = deploymentService.findAll(pageable);
|
||||
}
|
||||
|
||||
return ResponseEntity.ok(response);
|
||||
}
|
||||
|
||||
@GetMapping("/current")
|
||||
@Operation(summary = "Get current state", description = "Get current deployment state across environments")
|
||||
public ResponseEntity<List<CurrentDeploymentStateResponse>> getCurrentState(
|
||||
@RequestParam(required = false) UUID applicationId,
|
||||
@RequestParam(required = false) UUID environmentId) {
|
||||
List<CurrentDeploymentStateResponse> response = deploymentService.getCurrentState(applicationId, environmentId);
|
||||
return ResponseEntity.ok(response);
|
||||
}
|
||||
|
||||
@GetMapping("/by-application/{applicationId}")
|
||||
@Operation(summary = "Get deployments by application", description = "Get deployment history for an application")
|
||||
public ResponseEntity<Page<DeploymentResponse>> getByApplication(
|
||||
@PathVariable UUID applicationId,
|
||||
@RequestParam(defaultValue = "0") int page,
|
||||
@RequestParam(defaultValue = "20") int size) {
|
||||
|
||||
Pageable pageable = PageRequest.of(page, size, Sort.by("deploymentDate").descending());
|
||||
Page<DeploymentResponse> response = deploymentService.findByApplication(applicationId, pageable);
|
||||
return ResponseEntity.ok(response);
|
||||
}
|
||||
|
||||
@GetMapping("/by-environment/{environmentId}")
|
||||
@Operation(summary = "Get deployments by environment", description = "Get all deployments to an environment")
|
||||
public ResponseEntity<Page<DeploymentResponse>> getByEnvironment(
|
||||
@PathVariable UUID environmentId,
|
||||
@RequestParam(defaultValue = "0") int page,
|
||||
@RequestParam(defaultValue = "20") int size) {
|
||||
|
||||
Pageable pageable = PageRequest.of(page, size, Sort.by("deploymentDate").descending());
|
||||
Page<DeploymentResponse> response = deploymentService.findByEnvironment(environmentId, pageable);
|
||||
return ResponseEntity.ok(response);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package com.ldpv2.controller;
|
||||
|
||||
import com.ldpv2.dto.request.CreateVersionRequest;
|
||||
import com.ldpv2.dto.request.UpdateVersionRequest;
|
||||
import com.ldpv2.dto.response.VersionResponse;
|
||||
import com.ldpv2.service.VersionService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/applications/{applicationId}/versions")
|
||||
@Tag(name = "Versions", description = "Version management endpoints")
|
||||
@SecurityRequirement(name = "bearerAuth")
|
||||
public class VersionController {
|
||||
|
||||
@Autowired
|
||||
private VersionService versionService;
|
||||
|
||||
@PostMapping
|
||||
@Operation(summary = "Create version", description = "Create a new version for an application")
|
||||
public ResponseEntity<VersionResponse> create(
|
||||
@PathVariable UUID applicationId,
|
||||
@Valid @RequestBody CreateVersionRequest request) {
|
||||
VersionResponse response = versionService.create(applicationId, request);
|
||||
return new ResponseEntity<>(response, HttpStatus.CREATED);
|
||||
}
|
||||
|
||||
@PutMapping("/{id}")
|
||||
@Operation(summary = "Update version", description = "Update an existing version")
|
||||
public ResponseEntity<VersionResponse> update(
|
||||
@PathVariable UUID applicationId,
|
||||
@PathVariable UUID id,
|
||||
@Valid @RequestBody UpdateVersionRequest request) {
|
||||
VersionResponse response = versionService.update(id, request);
|
||||
return ResponseEntity.ok(response);
|
||||
}
|
||||
|
||||
@GetMapping("/{id}")
|
||||
@Operation(summary = "Get version", description = "Get version by ID")
|
||||
public ResponseEntity<VersionResponse> getById(
|
||||
@PathVariable UUID applicationId,
|
||||
@PathVariable UUID id) {
|
||||
VersionResponse response = versionService.findById(id);
|
||||
return ResponseEntity.ok(response);
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
@Operation(summary = "List versions", description = "Get all versions for an application")
|
||||
public ResponseEntity<Page<VersionResponse>> getAll(
|
||||
@PathVariable UUID applicationId,
|
||||
@RequestParam(defaultValue = "0") int page,
|
||||
@RequestParam(defaultValue = "20") int size,
|
||||
@RequestParam(defaultValue = "releaseDate") String sortBy,
|
||||
@RequestParam(defaultValue = "desc") String sortDirection) {
|
||||
|
||||
Sort sort = sortDirection.equalsIgnoreCase("desc")
|
||||
? Sort.by(sortBy).descending()
|
||||
: Sort.by(sortBy).ascending();
|
||||
|
||||
Pageable pageable = PageRequest.of(page, size, sort);
|
||||
Page<VersionResponse> response = versionService.findByApplication(applicationId, pageable);
|
||||
return ResponseEntity.ok(response);
|
||||
}
|
||||
|
||||
@GetMapping("/latest")
|
||||
@Operation(summary = "Get latest version", description = "Get the most recent version for an application")
|
||||
public ResponseEntity<VersionResponse> getLatest(@PathVariable UUID applicationId) {
|
||||
Optional<VersionResponse> response = versionService.findLatestByApplication(applicationId);
|
||||
return response.map(ResponseEntity::ok)
|
||||
.orElse(ResponseEntity.notFound().build());
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
@Operation(summary = "Delete version", description = "Delete a version")
|
||||
public ResponseEntity<Void> delete(
|
||||
@PathVariable UUID applicationId,
|
||||
@PathVariable UUID id) {
|
||||
versionService.delete(id);
|
||||
return ResponseEntity.noContent().build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.ldpv2.domain.entity;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* Deployment entity - immutable record of deployments
|
||||
* Tracks which version of which application is deployed to which environment
|
||||
*/
|
||||
@Data
|
||||
@Entity
|
||||
@Table(name = "deployment")
|
||||
@NoArgsConstructor @AllArgsConstructor
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class Deployment extends BaseEntity {
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "application_id", nullable = false)
|
||||
private Application application;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "version_id", nullable = false)
|
||||
private Version version;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "environment_id", nullable = false)
|
||||
private Environment environment;
|
||||
|
||||
@Column(name = "deployment_date", nullable = false)
|
||||
private LocalDateTime deploymentDate;
|
||||
|
||||
@Column(name = "deployed_by", length = 255)
|
||||
private String deployedBy;
|
||||
|
||||
@Column(columnDefinition = "TEXT")
|
||||
private String notes;
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.ldpv2.domain.entity;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
/**
|
||||
* Version entity representing application releases
|
||||
*/
|
||||
@Data
|
||||
@Entity
|
||||
@Table(name = "version", uniqueConstraints = {
|
||||
@UniqueConstraint(name = "uk_version_app_identifier",
|
||||
columnNames = {"application_id", "version_identifier"})
|
||||
})
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class Version extends BaseEntity {
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "application_id", nullable = false)
|
||||
private Application application;
|
||||
|
||||
@Column(name = "version_identifier", nullable = false, length = 100)
|
||||
private String versionIdentifier;
|
||||
|
||||
@Column(name = "external_reference", length = 500)
|
||||
private String externalReference;
|
||||
|
||||
@Column(name = "release_date", nullable = false)
|
||||
private LocalDate releaseDate;
|
||||
|
||||
@Column(name = "end_of_life_date")
|
||||
private LocalDate endOfLifeDate;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.ldpv2.dto.request;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class CreateVersionRequest {
|
||||
|
||||
@NotBlank(message = "Version identifier is required")
|
||||
@Size(max = 100, message = "Version identifier must not exceed 100 characters")
|
||||
private String versionIdentifier;
|
||||
|
||||
@Size(max = 500, message = "External reference must not exceed 500 characters")
|
||||
private String externalReference;
|
||||
|
||||
@NotNull(message = "Release date is required")
|
||||
private LocalDate releaseDate;
|
||||
|
||||
private LocalDate endOfLifeDate;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.ldpv2.dto.request;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.UUID;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class RecordDeploymentRequest {
|
||||
|
||||
@NotNull(message = "Application ID is required")
|
||||
private UUID applicationId;
|
||||
|
||||
@NotNull(message = "Version ID is required")
|
||||
private UUID versionId;
|
||||
|
||||
@NotNull(message = "Environment ID is required")
|
||||
private UUID environmentId;
|
||||
|
||||
@NotNull(message = "Deployment date is required")
|
||||
private LocalDateTime deploymentDate;
|
||||
|
||||
private String deployedBy;
|
||||
|
||||
private String notes;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.ldpv2.dto.request;
|
||||
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class UpdateVersionRequest {
|
||||
|
||||
@Size(max = 100, message = "Version identifier must not exceed 100 characters")
|
||||
private String versionIdentifier;
|
||||
|
||||
@Size(max = 500, message = "External reference must not exceed 500 characters")
|
||||
private String externalReference;
|
||||
|
||||
private LocalDate releaseDate;
|
||||
|
||||
private LocalDate endOfLifeDate;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.ldpv2.dto.response;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class CurrentDeploymentStateResponse {
|
||||
private ApplicationSummaryResponse application;
|
||||
private EnvironmentSummaryResponse environment;
|
||||
private VersionSummaryResponse version;
|
||||
private LocalDateTime deploymentDate;
|
||||
private String deployedBy;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.ldpv2.dto.response;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.UUID;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class DeploymentResponse {
|
||||
private UUID id;
|
||||
private ApplicationSummaryResponse application;
|
||||
private VersionSummaryResponse version;
|
||||
private EnvironmentSummaryResponse environment;
|
||||
private LocalDateTime deploymentDate;
|
||||
private String deployedBy;
|
||||
private String notes;
|
||||
private LocalDateTime createdAt;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.ldpv2.dto.response;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class EnvironmentSummaryResponse {
|
||||
private UUID id;
|
||||
private String name;
|
||||
private boolean isProduction;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.ldpv2.dto.response;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.UUID;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class VersionResponse {
|
||||
private UUID id;
|
||||
private UUID applicationId;
|
||||
private String applicationName;
|
||||
private String versionIdentifier;
|
||||
private String externalReference;
|
||||
private LocalDate releaseDate;
|
||||
private LocalDate endOfLifeDate;
|
||||
private LocalDateTime createdAt;
|
||||
private LocalDateTime updatedAt;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.ldpv2.dto.response;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.UUID;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class VersionSummaryResponse {
|
||||
private UUID id;
|
||||
private String versionIdentifier;
|
||||
private LocalDate releaseDate;
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package com.ldpv2.repository;
|
||||
|
||||
import com.ldpv2.domain.entity.Deployment;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
@Repository
|
||||
public interface DeploymentRepository extends JpaRepository<Deployment, UUID> {
|
||||
|
||||
Page<Deployment> findByApplicationId(UUID applicationId, Pageable pageable);
|
||||
|
||||
Page<Deployment> findByEnvironmentId(UUID environmentId, Pageable pageable);
|
||||
|
||||
Page<Deployment> findByApplicationIdAndEnvironmentId(UUID applicationId, UUID environmentId, Pageable pageable);
|
||||
|
||||
@Query("SELECT d FROM Deployment d WHERE " +
|
||||
"(:applicationId IS NULL OR d.application.id = :applicationId) AND " +
|
||||
"(:environmentId IS NULL OR d.environment.id = :environmentId) AND " +
|
||||
"(:versionId IS NULL OR d.version.id = :versionId) AND " +
|
||||
"(:dateFrom IS NULL OR d.deploymentDate >= :dateFrom) AND " +
|
||||
"(:dateTo IS NULL OR d.deploymentDate <= :dateTo)")
|
||||
Page<Deployment> search(
|
||||
@Param("applicationId") UUID applicationId,
|
||||
@Param("environmentId") UUID environmentId,
|
||||
@Param("versionId") UUID versionId,
|
||||
@Param("dateFrom") LocalDateTime dateFrom,
|
||||
@Param("dateTo") LocalDateTime dateTo,
|
||||
Pageable pageable
|
||||
);
|
||||
|
||||
/**
|
||||
* Get current deployment state - most recent deployment per application/environment
|
||||
*/
|
||||
@Query("SELECT d FROM Deployment d WHERE d.id IN (" +
|
||||
" SELECT MAX(d2.id) FROM Deployment d2 " +
|
||||
" WHERE (:applicationId IS NULL OR d2.application.id = :applicationId) AND " +
|
||||
" (:environmentId IS NULL OR d2.environment.id = :environmentId) " +
|
||||
" GROUP BY d2.application.id, d2.environment.id" +
|
||||
")")
|
||||
List<Deployment> findCurrentState(
|
||||
@Param("applicationId") UUID applicationId,
|
||||
@Param("environmentId") UUID environmentId
|
||||
);
|
||||
|
||||
/**
|
||||
* Get current deployment for specific application in specific environment
|
||||
*/
|
||||
@Query("SELECT d FROM Deployment d " +
|
||||
"WHERE d.application.id = :applicationId AND d.environment.id = :environmentId " +
|
||||
"ORDER BY d.deploymentDate DESC LIMIT 1")
|
||||
Optional<Deployment> findCurrentForApplicationInEnvironment(
|
||||
@Param("applicationId") UUID applicationId,
|
||||
@Param("environmentId") UUID environmentId
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.ldpv2.repository;
|
||||
|
||||
import com.ldpv2.domain.entity.Version;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
@Repository
|
||||
public interface VersionRepository extends JpaRepository<Version, UUID> {
|
||||
|
||||
Page<Version> findByApplicationId(UUID applicationId, Pageable pageable);
|
||||
|
||||
Optional<Version> findByApplicationIdAndVersionIdentifier(UUID applicationId, String versionIdentifier);
|
||||
|
||||
boolean existsByApplicationIdAndVersionIdentifier(UUID applicationId, String versionIdentifier);
|
||||
|
||||
@Query("SELECT v FROM Version v WHERE v.application.id = :applicationId ORDER BY v.releaseDate DESC LIMIT 1")
|
||||
Optional<Version> findLatestByApplicationId(@Param("applicationId") UUID applicationId);
|
||||
}
|
||||
@@ -0,0 +1,189 @@
|
||||
package com.ldpv2.service;
|
||||
|
||||
import com.ldpv2.domain.entity.Application;
|
||||
import com.ldpv2.domain.entity.Deployment;
|
||||
import com.ldpv2.domain.entity.Environment;
|
||||
import com.ldpv2.domain.entity.Version;
|
||||
import com.ldpv2.dto.request.RecordDeploymentRequest;
|
||||
import com.ldpv2.dto.response.*;
|
||||
import com.ldpv2.exception.BadRequestException;
|
||||
import com.ldpv2.exception.ResourceNotFoundException;
|
||||
import com.ldpv2.repository.ApplicationRepository;
|
||||
import com.ldpv2.repository.DeploymentRepository;
|
||||
import com.ldpv2.repository.EnvironmentRepository;
|
||||
import com.ldpv2.repository.VersionRepository;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
public class DeploymentService {
|
||||
|
||||
@Autowired
|
||||
private DeploymentRepository deploymentRepository;
|
||||
|
||||
@Autowired
|
||||
private ApplicationRepository applicationRepository;
|
||||
|
||||
@Autowired
|
||||
private VersionRepository versionRepository;
|
||||
|
||||
@Autowired
|
||||
private EnvironmentRepository environmentRepository;
|
||||
|
||||
@Transactional
|
||||
public DeploymentResponse recordDeployment(RecordDeploymentRequest request) {
|
||||
// Validate application exists
|
||||
Application application = applicationRepository.findById(request.getApplicationId())
|
||||
.orElseThrow(() -> new ResourceNotFoundException(
|
||||
"Application not found with id: " + request.getApplicationId()));
|
||||
|
||||
// Validate version exists
|
||||
Version version = versionRepository.findById(request.getVersionId())
|
||||
.orElseThrow(() -> new ResourceNotFoundException(
|
||||
"Version not found with id: " + request.getVersionId()));
|
||||
|
||||
// Validate environment exists
|
||||
Environment environment = environmentRepository.findById(request.getEnvironmentId())
|
||||
.orElseThrow(() -> new ResourceNotFoundException(
|
||||
"Environment not found with id: " + request.getEnvironmentId()));
|
||||
|
||||
// Validate that version belongs to the application
|
||||
if (!version.getApplication().getId().equals(request.getApplicationId())) {
|
||||
throw new BadRequestException(
|
||||
"Version does not belong to the specified application");
|
||||
}
|
||||
|
||||
// Validate deployment date is not in future
|
||||
if (request.getDeploymentDate().isAfter(LocalDateTime.now())) {
|
||||
throw new BadRequestException("Deployment date cannot be in the future");
|
||||
}
|
||||
|
||||
Deployment deployment = new Deployment();
|
||||
deployment.setApplication(application);
|
||||
deployment.setVersion(version);
|
||||
deployment.setEnvironment(environment);
|
||||
deployment.setDeploymentDate(request.getDeploymentDate());
|
||||
deployment.setDeployedBy(request.getDeployedBy());
|
||||
deployment.setNotes(request.getNotes());
|
||||
|
||||
deployment = deploymentRepository.save(deployment);
|
||||
return mapToResponse(deployment);
|
||||
}
|
||||
|
||||
public DeploymentResponse findById(UUID id) {
|
||||
Deployment deployment = deploymentRepository.findById(id)
|
||||
.orElseThrow(() -> new ResourceNotFoundException(
|
||||
"Deployment not found with id: " + id));
|
||||
return mapToResponse(deployment);
|
||||
}
|
||||
|
||||
public Page<DeploymentResponse> findAll(Pageable pageable) {
|
||||
return deploymentRepository.findAll(pageable).map(this::mapToResponse);
|
||||
}
|
||||
|
||||
public Page<DeploymentResponse> findByApplication(UUID applicationId, Pageable pageable) {
|
||||
if (!applicationRepository.existsById(applicationId)) {
|
||||
throw new ResourceNotFoundException(
|
||||
"Application not found with id: " + applicationId);
|
||||
}
|
||||
return deploymentRepository.findByApplicationId(applicationId, pageable)
|
||||
.map(this::mapToResponse);
|
||||
}
|
||||
|
||||
public Page<DeploymentResponse> findByEnvironment(UUID environmentId, Pageable pageable) {
|
||||
if (!environmentRepository.existsById(environmentId)) {
|
||||
throw new ResourceNotFoundException(
|
||||
"Environment not found with id: " + environmentId);
|
||||
}
|
||||
return deploymentRepository.findByEnvironmentId(environmentId, pageable)
|
||||
.map(this::mapToResponse);
|
||||
}
|
||||
|
||||
public Page<DeploymentResponse> search(
|
||||
UUID applicationId,
|
||||
UUID environmentId,
|
||||
UUID versionId,
|
||||
LocalDateTime dateFrom,
|
||||
LocalDateTime dateTo,
|
||||
Pageable pageable) {
|
||||
return deploymentRepository.search(
|
||||
applicationId, environmentId, versionId, dateFrom, dateTo, pageable)
|
||||
.map(this::mapToResponse);
|
||||
}
|
||||
|
||||
public List<CurrentDeploymentStateResponse> getCurrentState(UUID applicationId, UUID environmentId) {
|
||||
List<Deployment> deployments = deploymentRepository.findCurrentState(applicationId, environmentId);
|
||||
return deployments.stream()
|
||||
.map(this::mapToCurrentStateResponse)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private DeploymentResponse mapToResponse(Deployment deployment) {
|
||||
ApplicationSummaryResponse appSummary = new ApplicationSummaryResponse(
|
||||
deployment.getApplication().getId(),
|
||||
deployment.getApplication().getName(),
|
||||
deployment.getApplication().getStatus(),
|
||||
deployment.getApplication().getBusinessUnit().getName()
|
||||
);
|
||||
|
||||
VersionSummaryResponse versionSummary = new VersionSummaryResponse(
|
||||
deployment.getVersion().getId(),
|
||||
deployment.getVersion().getVersionIdentifier(),
|
||||
deployment.getVersion().getReleaseDate()
|
||||
);
|
||||
|
||||
EnvironmentSummaryResponse envSummary = new EnvironmentSummaryResponse(
|
||||
deployment.getEnvironment().getId(),
|
||||
deployment.getEnvironment().getName(),
|
||||
deployment.getEnvironment().getIsProduction()
|
||||
);
|
||||
|
||||
return new DeploymentResponse(
|
||||
deployment.getId(),
|
||||
appSummary,
|
||||
versionSummary,
|
||||
envSummary,
|
||||
deployment.getDeploymentDate(),
|
||||
deployment.getDeployedBy(),
|
||||
deployment.getNotes(),
|
||||
deployment.getCreatedAt()
|
||||
);
|
||||
}
|
||||
|
||||
private CurrentDeploymentStateResponse mapToCurrentStateResponse(Deployment deployment) {
|
||||
ApplicationSummaryResponse appSummary = new ApplicationSummaryResponse(
|
||||
deployment.getApplication().getId(),
|
||||
deployment.getApplication().getName(),
|
||||
deployment.getApplication().getStatus(),
|
||||
deployment.getApplication().getBusinessUnit().getName()
|
||||
);
|
||||
|
||||
VersionSummaryResponse versionSummary = new VersionSummaryResponse(
|
||||
deployment.getVersion().getId(),
|
||||
deployment.getVersion().getVersionIdentifier(),
|
||||
deployment.getVersion().getReleaseDate()
|
||||
);
|
||||
|
||||
EnvironmentSummaryResponse envSummary = new EnvironmentSummaryResponse(
|
||||
deployment.getEnvironment().getId(),
|
||||
deployment.getEnvironment().getName(),
|
||||
deployment.getEnvironment().getIsProduction()
|
||||
);
|
||||
|
||||
return new CurrentDeploymentStateResponse(
|
||||
appSummary,
|
||||
envSummary,
|
||||
versionSummary,
|
||||
deployment.getDeploymentDate(),
|
||||
deployment.getDeployedBy()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
package com.ldpv2.service;
|
||||
|
||||
import com.ldpv2.domain.entity.Application;
|
||||
import com.ldpv2.domain.entity.Version;
|
||||
import com.ldpv2.dto.request.CreateVersionRequest;
|
||||
import com.ldpv2.dto.request.UpdateVersionRequest;
|
||||
import com.ldpv2.dto.response.VersionResponse;
|
||||
import com.ldpv2.exception.BadRequestException;
|
||||
import com.ldpv2.exception.ResourceNotFoundException;
|
||||
import com.ldpv2.repository.ApplicationRepository;
|
||||
import com.ldpv2.repository.VersionRepository;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
@Service
|
||||
public class VersionService {
|
||||
|
||||
@Autowired
|
||||
private VersionRepository versionRepository;
|
||||
|
||||
@Autowired
|
||||
private ApplicationRepository applicationRepository;
|
||||
|
||||
@Transactional
|
||||
public VersionResponse create(UUID applicationId, CreateVersionRequest request) {
|
||||
Application application = applicationRepository.findById(applicationId)
|
||||
.orElseThrow(() -> new ResourceNotFoundException(
|
||||
"Application not found with id: " + applicationId));
|
||||
|
||||
// Check if version identifier already exists for this application
|
||||
if (versionRepository.existsByApplicationIdAndVersionIdentifier(
|
||||
applicationId, request.getVersionIdentifier())) {
|
||||
throw new BadRequestException(
|
||||
"Version '" + request.getVersionIdentifier() +
|
||||
"' already exists for this application");
|
||||
}
|
||||
|
||||
// Validate dates
|
||||
if (request.getEndOfLifeDate() != null &&
|
||||
request.getReleaseDate().isAfter(request.getEndOfLifeDate())) {
|
||||
throw new BadRequestException(
|
||||
"End of life date must be after release date");
|
||||
}
|
||||
|
||||
// Validate release date is not in future
|
||||
if (request.getReleaseDate().isAfter(LocalDate.now())) {
|
||||
throw new BadRequestException("Release date cannot be in the future");
|
||||
}
|
||||
|
||||
Version version = new Version();
|
||||
version.setApplication(application);
|
||||
version.setVersionIdentifier(request.getVersionIdentifier());
|
||||
version.setExternalReference(request.getExternalReference());
|
||||
version.setReleaseDate(request.getReleaseDate());
|
||||
version.setEndOfLifeDate(request.getEndOfLifeDate());
|
||||
|
||||
version = versionRepository.save(version);
|
||||
return mapToResponse(version);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public VersionResponse update(UUID id, UpdateVersionRequest request) {
|
||||
Version version = versionRepository.findById(id)
|
||||
.orElseThrow(() -> new ResourceNotFoundException(
|
||||
"Version not found with id: " + id));
|
||||
|
||||
if (request.getVersionIdentifier() != null) {
|
||||
// Check if new version identifier already exists for this application
|
||||
if (!request.getVersionIdentifier().equals(version.getVersionIdentifier()) &&
|
||||
versionRepository.existsByApplicationIdAndVersionIdentifier(
|
||||
version.getApplication().getId(), request.getVersionIdentifier())) {
|
||||
throw new BadRequestException(
|
||||
"Version '" + request.getVersionIdentifier() +
|
||||
"' already exists for this application");
|
||||
}
|
||||
version.setVersionIdentifier(request.getVersionIdentifier());
|
||||
}
|
||||
|
||||
if (request.getExternalReference() != null) {
|
||||
version.setExternalReference(request.getExternalReference());
|
||||
}
|
||||
|
||||
if (request.getReleaseDate() != null) {
|
||||
if (request.getReleaseDate().isAfter(LocalDate.now())) {
|
||||
throw new BadRequestException("Release date cannot be in the future");
|
||||
}
|
||||
version.setReleaseDate(request.getReleaseDate());
|
||||
}
|
||||
|
||||
if (request.getEndOfLifeDate() != null) {
|
||||
version.setEndOfLifeDate(request.getEndOfLifeDate());
|
||||
}
|
||||
|
||||
// Validate dates
|
||||
if (version.getEndOfLifeDate() != null &&
|
||||
version.getReleaseDate().isAfter(version.getEndOfLifeDate())) {
|
||||
throw new BadRequestException(
|
||||
"End of life date must be after release date");
|
||||
}
|
||||
|
||||
version = versionRepository.save(version);
|
||||
return mapToResponse(version);
|
||||
}
|
||||
|
||||
public VersionResponse findById(UUID id) {
|
||||
Version version = versionRepository.findById(id)
|
||||
.orElseThrow(() -> new ResourceNotFoundException(
|
||||
"Version not found with id: " + id));
|
||||
return mapToResponse(version);
|
||||
}
|
||||
|
||||
public Page<VersionResponse> findByApplication(UUID applicationId, Pageable pageable) {
|
||||
if (!applicationRepository.existsById(applicationId)) {
|
||||
throw new ResourceNotFoundException(
|
||||
"Application not found with id: " + applicationId);
|
||||
}
|
||||
return versionRepository.findByApplicationId(applicationId, pageable)
|
||||
.map(this::mapToResponse);
|
||||
}
|
||||
|
||||
public Optional<VersionResponse> findLatestByApplication(UUID applicationId) {
|
||||
if (!applicationRepository.existsById(applicationId)) {
|
||||
throw new ResourceNotFoundException(
|
||||
"Application not found with id: " + applicationId);
|
||||
}
|
||||
return versionRepository.findLatestByApplicationId(applicationId)
|
||||
.map(this::mapToResponse);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void delete(UUID id) {
|
||||
Version version = versionRepository.findById(id)
|
||||
.orElseThrow(() -> new ResourceNotFoundException(
|
||||
"Version not found with id: " + id));
|
||||
|
||||
// Note: In production, check if version is deployed anywhere before deletion
|
||||
versionRepository.delete(version);
|
||||
}
|
||||
|
||||
private VersionResponse mapToResponse(Version version) {
|
||||
return new VersionResponse(
|
||||
version.getId(),
|
||||
version.getApplication().getId(),
|
||||
version.getApplication().getName(),
|
||||
version.getVersionIdentifier(),
|
||||
version.getExternalReference(),
|
||||
version.getReleaseDate(),
|
||||
version.getEndOfLifeDate(),
|
||||
version.getCreatedAt(),
|
||||
version.getUpdatedAt()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -5,18 +5,13 @@
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
|
||||
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
|
||||
|
||||
<!-- Story 0: Foundation -->
|
||||
<include file="db/changelog/v1.0/001-create-user-table.xml"/>
|
||||
<include file="db/changelog/v1.0/002-create-environment-table.xml"/>
|
||||
<include file="db/changelog/data/initial-data.xml"/>
|
||||
|
||||
<!-- Story 1: Business Units -->
|
||||
<include file="db/changelog/v1.0/003-create-business-unit-table.xml"/>
|
||||
|
||||
<!-- Story 2: Applications -->
|
||||
<include file="db/changelog/v1.0/004-create-application-table.xml"/>
|
||||
|
||||
<!-- Story 3: Contacts -->
|
||||
<include file="db/changelog/v1.0/005-create-contact-tables.xml"/>
|
||||
<include file="db/changelog/v1.0/006-create-version-table.xml"/>
|
||||
<include file="db/changelog/v1.0/007-create-deployment-table.xml"/>
|
||||
|
||||
</databaseChangeLog>
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<databaseChangeLog
|
||||
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
|
||||
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
|
||||
|
||||
<changeSet id="006-create-version-table" author="ldpv2-team">
|
||||
|
||||
<createTable tableName="version">
|
||||
<column name="id" type="UUID" defaultValueComputed="uuid_generate_v4()">
|
||||
<constraints primaryKey="true" nullable="false"/>
|
||||
</column>
|
||||
<column name="application_id" type="UUID">
|
||||
<constraints nullable="false"
|
||||
foreignKeyName="fk_version_application"
|
||||
references="application(id)"
|
||||
deleteCascade="true"/>
|
||||
</column>
|
||||
<column name="version_identifier" type="VARCHAR(100)">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="external_reference" type="VARCHAR(500)"/>
|
||||
<column name="release_date" type="DATE">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="end_of_life_date" type="DATE"/>
|
||||
<column name="created_at" type="TIMESTAMP" defaultValueComputed="CURRENT_TIMESTAMP">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="updated_at" type="TIMESTAMP" defaultValueComputed="CURRENT_TIMESTAMP">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</createTable>
|
||||
|
||||
<addUniqueConstraint
|
||||
tableName="version"
|
||||
columnNames="application_id, version_identifier"
|
||||
constraintName="uk_version_app_identifier"/>
|
||||
|
||||
<createIndex tableName="version" indexName="idx_version_application">
|
||||
<column name="application_id"/>
|
||||
</createIndex>
|
||||
|
||||
<createIndex tableName="version" indexName="idx_version_release_date">
|
||||
<column name="release_date"/>
|
||||
</createIndex>
|
||||
|
||||
<!-- Sample data -->
|
||||
<insert tableName="version">
|
||||
<column name="application_id" valueComputed="(SELECT id FROM application WHERE name = 'Customer Portal' LIMIT 1)"/>
|
||||
<column name="version_identifier" value="1.0.0"/>
|
||||
<column name="external_reference" value="https://github.com/org/customer-portal/releases/tag/v1.0.0"/>
|
||||
<column name="release_date" value="2024-01-15"/>
|
||||
</insert>
|
||||
|
||||
<insert tableName="version">
|
||||
<column name="application_id" valueComputed="(SELECT id FROM application WHERE name = 'Customer Portal' LIMIT 1)"/>
|
||||
<column name="version_identifier" value="1.1.0"/>
|
||||
<column name="release_date" value="2024-06-20"/>
|
||||
</insert>
|
||||
|
||||
<insert tableName="version">
|
||||
<column name="application_id" valueComputed="(SELECT id FROM application WHERE name = 'Customer Portal' LIMIT 1)"/>
|
||||
<column name="version_identifier" value="1.2.0"/>
|
||||
<column name="release_date" value="2025-01-10"/>
|
||||
</insert>
|
||||
|
||||
<insert tableName="version">
|
||||
<column name="application_id" valueComputed="(SELECT id FROM application WHERE name = 'Internal CRM' LIMIT 1)"/>
|
||||
<column name="version_identifier" value="2.0.0"/>
|
||||
<column name="release_date" value="2024-03-01"/>
|
||||
</insert>
|
||||
|
||||
<insert tableName="version">
|
||||
<column name="application_id" valueComputed="(SELECT id FROM application WHERE name = 'Internal CRM' LIMIT 1)"/>
|
||||
<column name="version_identifier" value="2.1.0"/>
|
||||
<column name="release_date" value="2024-09-15"/>
|
||||
</insert>
|
||||
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,76 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<databaseChangeLog
|
||||
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
|
||||
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
|
||||
|
||||
<changeSet id="007-create-deployment-table" author="ldpv2-team">
|
||||
|
||||
<createTable tableName="deployment">
|
||||
<column name="id" type="UUID" defaultValueComputed="uuid_generate_v4()">
|
||||
<constraints primaryKey="true" nullable="false"/>
|
||||
</column>
|
||||
<column name="application_id" type="UUID">
|
||||
<constraints nullable="false"
|
||||
foreignKeyName="fk_deployment_application"
|
||||
references="application(id)"/>
|
||||
</column>
|
||||
<column name="version_id" type="UUID">
|
||||
<constraints nullable="false"
|
||||
foreignKeyName="fk_deployment_version"
|
||||
references="version(id)"/>
|
||||
</column>
|
||||
<column name="environment_id" type="UUID">
|
||||
<constraints nullable="false"
|
||||
foreignKeyName="fk_deployment_environment"
|
||||
references="environment(id)"/>
|
||||
</column>
|
||||
<column name="deployment_date" type="TIMESTAMP">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="deployed_by" type="VARCHAR(255)"/>
|
||||
<column name="notes" type="TEXT"/>
|
||||
<column name="created_at" type="TIMESTAMP" defaultValueComputed="CURRENT_TIMESTAMP">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</createTable>
|
||||
|
||||
<createIndex tableName="deployment" indexName="idx_deployment_application">
|
||||
<column name="application_id"/>
|
||||
</createIndex>
|
||||
|
||||
<createIndex tableName="deployment" indexName="idx_deployment_environment">
|
||||
<column name="environment_id"/>
|
||||
</createIndex>
|
||||
|
||||
<createIndex tableName="deployment" indexName="idx_deployment_date">
|
||||
<column name="deployment_date" descending="true"/>
|
||||
</createIndex>
|
||||
|
||||
<createIndex tableName="deployment" indexName="idx_deployment_app_env">
|
||||
<column name="application_id"/>
|
||||
<column name="environment_id"/>
|
||||
</createIndex>
|
||||
|
||||
<!-- Sample deployments -->
|
||||
<insert tableName="deployment">
|
||||
<column name="application_id" valueComputed="(SELECT id FROM application WHERE name = 'Customer Portal' LIMIT 1)"/>
|
||||
<column name="version_id" valueComputed="(SELECT id FROM version WHERE version_identifier = '1.2.0' LIMIT 1)"/>
|
||||
<column name="environment_id" valueComputed="(SELECT id FROM environment WHERE name = 'PROD-EU' LIMIT 1)"/>
|
||||
<column name="deployment_date" value="2025-01-15T10:30:00"/>
|
||||
<column name="deployed_by" value="admin"/>
|
||||
<column name="notes" value="Production deployment"/>
|
||||
</insert>
|
||||
|
||||
<insert tableName="deployment">
|
||||
<column name="application_id" valueComputed="(SELECT id FROM application WHERE name = 'Internal CRM' LIMIT 1)"/>
|
||||
<column name="version_id" valueComputed="(SELECT id FROM version WHERE version_identifier = '2.1.0' LIMIT 1)"/>
|
||||
<column name="environment_id" valueComputed="(SELECT id FROM environment WHERE name = 'PROD-EU' LIMIT 1)"/>
|
||||
<column name="deployment_date" value="2024-10-01T11:00:00"/>
|
||||
<column name="deployed_by" value="admin"/>
|
||||
<column name="notes" value="Major update"/>
|
||||
</insert>
|
||||
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
Reference in New Issue
Block a user