Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b1a8985b29 | ||
|
|
9073c52b5c | ||
|
|
6981734bda | ||
|
|
5f4f417edc |
+52
-55
@@ -1,83 +1,80 @@
|
|||||||
val wiremockVersion = "3.12.0"
|
val wiremockVersion = "3.12.0"
|
||||||
val postgresqlVersion = "42.7.11"
|
val postgresqlVersion = "42.7.11"
|
||||||
|
val springAiVersion by extra("2.0.0")
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
java
|
java
|
||||||
jacoco
|
jacoco
|
||||||
id("org.springframework.boot") version "4.1.0"
|
id("org.springframework.boot") version "4.1.0"
|
||||||
id("io.spring.dependency-management") version "1.1.7"
|
id("io.spring.dependency-management") version "1.1.7"
|
||||||
id("org.sonarqube") version "7.3.0.8198"
|
id("org.sonarqube") version "7.3.0.8198"
|
||||||
}
|
}
|
||||||
|
|
||||||
group = "com.vaessl"
|
group = "com.vaessl"
|
||||||
version = "0.0.1-SNAPSHOT"
|
version = "0.0.1-SNAPSHOT"
|
||||||
|
|
||||||
java {
|
java {
|
||||||
toolchain {
|
toolchain {
|
||||||
languageVersion = JavaLanguageVersion.of(25)
|
languageVersion = JavaLanguageVersion.of(25)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sonar {
|
sonar {
|
||||||
properties {
|
properties {
|
||||||
property("sonar.projectKey", "Vaessl")
|
property("sonar.projectKey", "Vaessl")
|
||||||
property("sonar.projectName", "Vaessl")
|
property("sonar.projectName", "Vaessl")
|
||||||
property("sonar.coverage.jacoco.xmlReportPaths",
|
property("sonar.coverage.jacoco.xmlReportPaths",
|
||||||
"${layout.buildDirectory.get()}/reports/jacoco/test/jacocoTestReport.xml")
|
"${layout.buildDirectory.get()}/reports/jacoco/test/jacocoTestReport.xml")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
configurations {
|
configurations {
|
||||||
compileOnly {
|
compileOnly {
|
||||||
extendsFrom(configurations.annotationProcessor.get())
|
extendsFrom(configurations.annotationProcessor.get())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
|
||||||
|
|
||||||
extra["springAiVersion"] = "2.0.0"
|
|
||||||
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
|
|
||||||
implementation("org.springframework.boot:spring-boot-starter-session-jdbc")
|
|
||||||
// implementation("org.springframework.boot:spring-boot-starter-security")
|
|
||||||
implementation("org.springframework.boot:spring-boot-starter-validation")
|
|
||||||
implementation("org.springframework.boot:spring-boot-starter-webmvc")
|
|
||||||
implementation("org.springframework.ai:spring-ai-starter-model-openai")
|
|
||||||
implementation("org.postgresql:postgresql:$postgresqlVersion")
|
|
||||||
implementation("org.springframework.ai:spring-ai-starter-vector-store-pgvector")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
compileOnly("org.projectlombok:lombok")
|
|
||||||
|
|
||||||
developmentOnly("org.springframework.boot:spring-boot-devtools")
|
|
||||||
|
|
||||||
runtimeOnly("org.postgresql:postgresql")
|
|
||||||
|
|
||||||
annotationProcessor("org.projectlombok:lombok")
|
|
||||||
|
|
||||||
testImplementation("org.springframework.boot:spring-boot-starter-data-jpa-test")
|
|
||||||
// testImplementation("org.springframework.boot:spring-boot-starter-security-test")
|
|
||||||
testImplementation("org.springframework.boot:spring-boot-starter-validation-test")
|
|
||||||
testImplementation("org.springframework.boot:spring-boot-starter-webmvc-test")
|
|
||||||
testImplementation("org.wiremock:wiremock-standalone:$wiremockVersion")
|
|
||||||
testImplementation("org.springframework.boot:spring-boot-starter-session-jdbc-test")
|
|
||||||
|
|
||||||
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencyManagement {
|
dependencyManagement {
|
||||||
imports {
|
imports {
|
||||||
mavenBom("org.springframework.ai:spring-ai-bom:${property("springAiVersion")}")
|
mavenBom("org.springframework.ai:spring-ai-bom:$springAiVersion")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
// Spring Boot Starters
|
||||||
|
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
|
||||||
|
implementation("org.springframework.boot:spring-boot-starter-session-jdbc")
|
||||||
|
implementation("org.springframework.boot:spring-boot-starter-validation")
|
||||||
|
implementation("org.springframework.boot:spring-boot-starter-webmvc")
|
||||||
|
|
||||||
|
// Spring AI Starters (versions managed by spring-ai-bom)
|
||||||
|
implementation("org.springframework.ai:spring-ai-starter-model-openai")
|
||||||
|
implementation("org.springframework.ai:spring-ai-starter-vector-store-pgvector")
|
||||||
|
|
||||||
|
// Database
|
||||||
|
implementation("org.postgresql:postgresql:$postgresqlVersion")
|
||||||
|
|
||||||
|
// Tooling & Code Generation
|
||||||
|
compileOnly("org.projectlombok:lombok")
|
||||||
|
annotationProcessor("org.projectlombok:lombok")
|
||||||
|
developmentOnly("org.springframework.boot:spring-boot-devtools")
|
||||||
|
|
||||||
|
// Testing
|
||||||
|
testImplementation("org.springframework.boot:spring-boot-starter-data-jpa-test")
|
||||||
|
testImplementation("org.springframework.boot:spring-boot-starter-validation-test")
|
||||||
|
testImplementation("org.springframework.boot:spring-boot-starter-webmvc-test")
|
||||||
|
testImplementation("org.springframework.boot:spring-boot-starter-session-jdbc-test")
|
||||||
|
testImplementation("org.wiremock:wiremock-standalone:$wiremockVersion")
|
||||||
|
|
||||||
|
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.withType<JavaCompile> {
|
tasks.withType<JavaCompile> {
|
||||||
options.compilerArgs.add("-parameters")
|
options.compilerArgs.add("-parameters")
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.withType<Test> {
|
tasks.withType<Test> {
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import org.springframework.ai.vectorstore.filter.FilterExpressionBuilder;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import com.vaessl.app.shared.ServiceItem;
|
import com.vaessl.app.shared.ServiceItem;
|
||||||
import com.vaessl.app.shared.ServiceType;
|
import com.vaessl.app.shared.ServiceType;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Embeds {@link ServiceItem}s into the shared vector store and prunes entries that no longer exist
|
* Embeds {@link ServiceItem}s into the shared vector store and prunes entries that no longer exist
|
||||||
@@ -18,14 +19,11 @@ import com.vaessl.app.shared.ServiceType;
|
|||||||
* singleton bean shared across concurrent sync runs; callers own the per-sync ID accumulator.
|
* singleton bean shared across concurrent sync runs; callers own the per-sync ID accumulator.
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
public class EmbeddingService {
|
public class EmbeddingService {
|
||||||
|
|
||||||
private final VectorStore vectorStore;
|
private final VectorStore vectorStore;
|
||||||
|
|
||||||
public EmbeddingService(VectorStore vectorStore) {
|
|
||||||
this.vectorStore = vectorStore;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Embeds and upserts {@code items} into the vector store, appending each item's ID to
|
* Embeds and upserts {@code items} into the vector store, appending each item's ID to
|
||||||
* {@code currentItemIds} so the caller can later prune stale entries via
|
* {@code currentItemIds} so the caller can later prune stale entries via
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
# Git Conventions
|
||||||
|
|
||||||
|
## Branch Naming
|
||||||
|
|
||||||
|
```
|
||||||
|
<type>/<short-kebab-case-description>
|
||||||
|
```
|
||||||
|
|
||||||
|
- All lowercase, hyphens only — no camelCase or Title-Case
|
||||||
|
- Keep the description short (3–5 words); the branch name is not the place for detail
|
||||||
|
- If using a ticket tracker, include the ID: `feature/VAE-123-ai-search`
|
||||||
|
|
||||||
|
| Type | Use for |
|
||||||
|
|---|---|
|
||||||
|
| `feature/` | New functionality |
|
||||||
|
| `fix/` | Bug fixes |
|
||||||
|
| `refactor/` | Code changes with no behavior change |
|
||||||
|
| `chore/` | Tooling, deps, config, cleanup |
|
||||||
|
| `docs/` | Documentation only |
|
||||||
|
|
||||||
|
**Example:** `feature/ai-search`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Commit Messages
|
||||||
|
|
||||||
|
Follow [Conventional Commits](https://www.conventionalcommits.org/):
|
||||||
|
|
||||||
|
```
|
||||||
|
<type>(<scope>): <imperative, present-tense summary>
|
||||||
|
|
||||||
|
<optional body — explain WHY, not WHAT>
|
||||||
|
```
|
||||||
|
|
||||||
|
- **Type** — same list as branch types above, plus `test`, `style`
|
||||||
|
- **Scope** — the module/package touched (e.g. `search`, `sync`, `connection`, `vector`, `frontend`)
|
||||||
|
- **Summary** — imperative mood ("add", not "added" or "adds"); no period at the end
|
||||||
|
- **Body** — only when the reasoning isn't obvious from the diff (a constraint, a bug workaround, a decision). Skip it for simple/self-explanatory changes.
|
||||||
|
|
||||||
|
**Examples:**
|
||||||
|
```
|
||||||
|
feat(search): route SearchRequest.aiSearch to AI provider map
|
||||||
|
fix(sync): prune stale vectors only after full page loop completes
|
||||||
|
style: reformat
|
||||||
|
refactor(vector): nest extraData by section for clearer embedding
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Ticket Titles
|
||||||
|
|
||||||
|
Frame as the outcome, not a task log:
|
||||||
|
|
||||||
|
```
|
||||||
|
<Type>: <what changes for the user/system>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Examples:**
|
||||||
|
- `Feature: Add AI-powered search to Homebox connector`
|
||||||
|
- `Bug: /api/sync not triggered on login`
|
||||||
|
- `Chore: Consolidate SearchService provider maps`
|
||||||
Reference in New Issue
Block a user