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
Expand Up @@ -17,7 +17,7 @@
requires jakarta.persistence;
requires kotlin.stdlib;

exports org.rostilos.codecrow.analysisengine.client;
exports org.rostilos.codecrow.analysisengine.aiclient;
exports org.rostilos.codecrow.analysisengine.config;
exports org.rostilos.codecrow.analysisengine.dto.request.ai;
exports org.rostilos.codecrow.analysisengine.dto.request.processor;
Expand All @@ -30,7 +30,7 @@
exports org.rostilos.codecrow.analysisengine.service.vcs;
exports org.rostilos.codecrow.analysisengine.util;

opens org.rostilos.codecrow.analysisengine.client to spring.core, spring.beans, spring.context;
opens org.rostilos.codecrow.analysisengine.aiclient to spring.core, spring.beans, spring.context;
opens org.rostilos.codecrow.analysisengine.config to spring.core, spring.beans, spring.context;
opens org.rostilos.codecrow.analysisengine.processor to spring.core, spring.beans, spring.context;
opens org.rostilos.codecrow.analysisengine.processor.analysis to spring.core, spring.beans, spring.context;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.rostilos.codecrow.analysisengine.client;
package org.rostilos.codecrow.analysisengine.aiclient;

import org.rostilos.codecrow.analysisengine.dto.request.ai.AiAnalysisRequest;
import org.slf4j.Logger;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.rostilos.codecrow.analysisengine.client;
package org.rostilos.codecrow.analysisengine.aiclient;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import org.rostilos.codecrow.core.model.branch.BranchIssue;
import org.rostilos.codecrow.core.model.project.Project;
import org.rostilos.codecrow.core.model.vcs.VcsConnection;
import org.rostilos.codecrow.core.model.vcs.VcsRepoBinding;
import org.rostilos.codecrow.core.persistence.repository.branch.BranchIssueRepository;
import org.rostilos.codecrow.core.persistence.repository.codeanalysis.CodeAnalysisIssueRepository;
import org.rostilos.codecrow.core.persistence.repository.branch.BranchRepository;
Expand All @@ -24,7 +23,7 @@
import org.rostilos.codecrow.analysisengine.service.vcs.VcsAiClientService;
import org.rostilos.codecrow.analysisengine.service.vcs.VcsOperationsService;
import org.rostilos.codecrow.analysisengine.service.vcs.VcsServiceFactory;
import org.rostilos.codecrow.analysisengine.client.AiAnalysisClient;
import org.rostilos.codecrow.analysisengine.aiclient.AiAnalysisClient;
import org.rostilos.codecrow.vcsclient.VcsClientProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -87,28 +86,21 @@ public BranchAnalysisProcessor(
}

/**
* Helper record to hold VCS info from either ProjectVcsConnectionBinding or VcsRepoBinding.
* Helper record to hold VCS info.
*/
public record VcsInfo(VcsConnection vcsConnection, String workspace, String repoSlug) {}


/**
* Get VCS info from project, preferring ProjectVcsConnectionBinding but falling back to VcsRepoBinding.
* Get VCS info from project using the unified accessor.
*/
public VcsInfo getVcsInfo(Project project) {
if (project.getVcsBinding() != null) {
var vcsInfo = project.getEffectiveVcsRepoInfo();
if (vcsInfo != null && vcsInfo.getVcsConnection() != null) {
return new VcsInfo(
project.getVcsBinding().getVcsConnection(),
project.getVcsBinding().getWorkspace(),
project.getVcsBinding().getRepoSlug()
);
}
VcsRepoBinding repoBinding = project.getVcsRepoBinding();
if (repoBinding != null && repoBinding.getVcsConnection() != null) {
return new VcsInfo(
repoBinding.getVcsConnection(),
repoBinding.getExternalNamespace(),
repoBinding.getExternalRepoSlug()
vcsInfo.getVcsConnection(),
vcsInfo.getRepoWorkspace(),
vcsInfo.getRepoSlug()
);
}
throw new IllegalStateException("No VCS connection configured for project: " + project.getId());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import org.rostilos.codecrow.analysisengine.service.vcs.VcsAiClientService;
import org.rostilos.codecrow.analysisengine.service.vcs.VcsReportingService;
import org.rostilos.codecrow.analysisengine.service.vcs.VcsServiceFactory;
import org.rostilos.codecrow.analysisengine.client.AiAnalysisClient;
import org.rostilos.codecrow.analysisengine.aiclient.AiAnalysisClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
Expand Down Expand Up @@ -57,11 +57,10 @@ public interface EventConsumer {
}

private EVcsProvider getVcsProvider(Project project) {
if (project.getVcsBinding() != null && project.getVcsBinding().getVcsConnection() != null) {
return project.getVcsBinding().getVcsConnection().getProviderType();
}
if (project.getVcsRepoBinding() != null && project.getVcsRepoBinding().getVcsConnection() != null) {
return project.getVcsRepoBinding().getVcsConnection().getProviderType();
// Use unified method to get effective VCS connection
var vcsConnection = project.getEffectiveVcsConnection();
if (vcsConnection != null) {
return vcsConnection.getProviderType();
}
throw new IllegalStateException("No VCS connection configured for project: " + project.getId());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,8 @@ public Project getProjectWithConnections(Long projectId) throws IOException {
}

private void validateProjectConnections(Project project) throws IOException {
// Check for VCS connection: either legacy ProjectVcsConnectionBinding or new VcsRepoBinding
boolean hasVcsConnection = project.getVcsBinding() != null ||
(project.getVcsRepoBinding() != null && project.getVcsRepoBinding().getVcsConnection() != null);

if (!hasVcsConnection) {
// Use unified hasVcsBinding() method that checks both bindings
if (!project.hasVcsBinding()) {
throw new IOException("VCS connection is not configured for project: " + project.getId());
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.rostilos.codecrow.pipelineagent.generic.service;
package org.rostilos.codecrow.analysisengine.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import org.rostilos.codecrow.core.model.branch.Branch;
import org.rostilos.codecrow.core.model.project.Project;
import org.rostilos.codecrow.core.model.project.config.ProjectConfig;
import org.rostilos.codecrow.core.model.vcs.VcsConnection;
import org.rostilos.codecrow.core.model.vcs.VcsRepoInfo;

import java.util.List;

Expand Down Expand Up @@ -35,31 +37,21 @@ public static ProjectDTO fromProject(Project project) {
String vcsWorkspace = null;
String repoSlug = null;

// Check vcsBinding first (manual OAuth connection)
if (project.getVcsBinding() != null && project.getVcsBinding().getVcsConnection() != null) {
vcsConnectionId = project.getVcsBinding().getVcsConnection().getId();
vcsWorkspace = project.getVcsBinding().getWorkspace();
repoSlug = project.getVcsBinding().getRepoSlug();
if (project.getVcsBinding().getVcsConnection().getConnectionType() != null) {
vcsConnectionType = project.getVcsBinding().getVcsConnection().getConnectionType().name();
}
if (project.getVcsBinding().getVcsConnection().getProviderType() != null) {
vcsProvider = project.getVcsBinding().getVcsConnection().getProviderType().name();
}
}
// Fallback to vcsRepoBinding (App-based connection)
else if (project.getVcsRepoBinding() != null) {
if (project.getVcsRepoBinding().getVcsConnection() != null) {
vcsConnectionId = project.getVcsRepoBinding().getVcsConnection().getId();
if (project.getVcsRepoBinding().getVcsConnection().getConnectionType() != null) {
vcsConnectionType = project.getVcsRepoBinding().getVcsConnection().getConnectionType().name();
// Use unified method to get VCS info (prefers VcsRepoBinding over legacy vcsBinding)
VcsRepoInfo vcsInfo = project.getEffectiveVcsRepoInfo();
if (vcsInfo != null) {
VcsConnection conn = vcsInfo.getVcsConnection();
if (conn != null) {
vcsConnectionId = conn.getId();
if (conn.getConnectionType() != null) {
vcsConnectionType = conn.getConnectionType().name();
}
if (project.getVcsRepoBinding().getVcsConnection().getProviderType() != null) {
vcsProvider = project.getVcsRepoBinding().getVcsConnection().getProviderType().name();
if (conn.getProviderType() != null) {
vcsProvider = conn.getProviderType().name();
}
}
vcsWorkspace = project.getVcsRepoBinding().getExternalNamespace();
repoSlug = project.getVcsRepoBinding().getExternalRepoSlug();
vcsWorkspace = vcsInfo.getRepoWorkspace();
repoSlug = vcsInfo.getRepoSlug();
}

Long aiConnectionId = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
import org.hibernate.annotations.JdbcTypeCode;
import org.hibernate.type.SqlTypes;
import org.rostilos.codecrow.core.model.project.config.ProjectConfig;
import org.rostilos.codecrow.core.model.vcs.VcsConnection;
import org.rostilos.codecrow.core.model.vcs.VcsRepoBinding;
import org.rostilos.codecrow.core.model.vcs.VcsRepoInfo;
import org.rostilos.codecrow.core.model.workspace.Workspace;

@Entity
Expand Down Expand Up @@ -154,10 +156,52 @@ public void setVcsBinding(ProjectVcsConnectionBinding projectVcsConnectionBindin
this.vcsBinding = projectVcsConnectionBinding;
}

/**
* @deprecated Use {@link #getEffectiveVcsRepoInfo()} or {@link #getVcsRepoBinding()} instead.
* This method returns the legacy Bitbucket-specific binding.
*/
@Deprecated(since = "2.0", forRemoval = true)
public ProjectVcsConnectionBinding getVcsBinding() {
return this.vcsBinding;
}

/**
* Returns the effective VCS repository information for this project.
* <p>
* This method provides a unified way to access VCS repository info regardless
* of whether the project uses the legacy {@link ProjectVcsConnectionBinding}
* or the new provider-agnostic {@link VcsRepoBinding}.
* <p>
* Priority: VcsRepoBinding (new) > ProjectVcsConnectionBinding (legacy)
*
* @return VcsRepoInfo if any binding exists, null otherwise
*/
public VcsRepoInfo getEffectiveVcsRepoInfo() {
if (vcsRepoBinding != null) {
return vcsRepoBinding;
}
return vcsBinding;
}

/**
* Returns the VCS connection for this project, checking both new and legacy bindings.
*
* @return VcsConnection if any binding exists, null otherwise
*/
public VcsConnection getEffectiveVcsConnection() {
VcsRepoInfo info = getEffectiveVcsRepoInfo();
return info != null ? info.getVcsConnection() : null;
}

/**
* Checks if this project has any VCS binding configured.
*
* @return true if either vcsRepoBinding or vcsBinding is present
*/
public boolean hasVcsBinding() {
return vcsRepoBinding != null || vcsBinding != null;
}

public void setAiConnectionBinding(ProjectAiConnectionBinding projectAiConnectionBinding) {
this.aiBinding = projectAiConnectionBinding;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,19 @@
import jakarta.persistence.*;
import org.rostilos.codecrow.core.model.vcs.EVcsProvider;
import org.rostilos.codecrow.core.model.vcs.VcsConnection;
import org.rostilos.codecrow.core.model.vcs.VcsRepoBinding;
import org.rostilos.codecrow.core.model.vcs.VcsRepoInfo;

import java.util.UUID;

/**
* @deprecated Use {@link VcsRepoBinding} instead. This class is Bitbucket-specific and lacks
* webhook tracking, timestamps, and provider-agnostic repository ID support.
* <p>
* Migration: Use {@link Project#getEffectiveVcsRepoInfo()} which returns {@link VcsRepoInfo}
* and handles both legacy and new bindings transparently.
*/
@Deprecated(since = "2.0", forRemoval = true)
@Entity
@Table(name = "project_vcs_connection", uniqueConstraints = {
@UniqueConstraint(name = "uq_repo_unique", columnNames = {"repository_id"})
Expand Down
Loading