diff --git a/PROJECT_DESCRIPTION.md b/PROJECT_DESCRIPTION.md
index 1ad9163..417f802 100644
--- a/PROJECT_DESCRIPTION.md
+++ b/PROJECT_DESCRIPTION.md
@@ -78,10 +78,11 @@ Strict **Controller → Service → Repository** layering. No controller accesse
│ AsyncDataSourceCollectService · SyncJobTracker │
│ GitLocalCollector · RepoService · GitRepositoryService │
│ GitHubClientFactory · GitHubRepositoryService │
-│ GitHubCollector · GitHubCommitIngestService │
+│ GitHubCommitCollector · GitHubCommitIngestService │
│ GitHubCommitStatsEnrichmentService │
-│ GitHubPrCollector · GitHubPullRequestCollector │
-│ GitHubPrStatsEnrichmentService · GitHubIssuesCollector │
+│ GitHubPullRequestCollector · GitHubPullRequestIngestService │
+│ GitHubPullRequestStatsEnrichmentService │
+│ GitHubPullRequestQueryService · GitHubIssuesCollector │
│ JiraCollector · IssueService │
│ MetricsService · MetricSnapshotService · MetricsScheduler │
│ MetricBackfillService · MetricBackfillScheduler │
@@ -121,6 +122,22 @@ Strict **Controller → Service → Repository** layering. No controller accesse
| `messaging/` | 1:1 direct message service and controller, conversation/inbox API |
| `invite/` | Token-based team invitation issuance and redemption |
+`github/` runs two collection pipelines, so it is split further. `controller/`, `model/` and
+`repository/` sit beside these.
+
+| Subpackage | Classes |
+|---|---|
+| `github/client/` | `GitHubClientFactory` |
+| `github/repo/` | `GitHubRepositoryService` |
+| `github/identity/` | `GitHubAccountLookup`, `GitHubAccountLookupImpl`, `GitHubIdentityBackfill`, `GitHubIdentityBackfillService` |
+| `github/commit/` | `GitHubCommitCollector`, `GitHubCommitIngestService`, `GitHubCommitStatsEnrichmentService` |
+| `github/pullrequest/` | `GitHubPullRequestCollector`, `GitHubPullRequestIngestService`, `GitHubPullRequestStatsEnrichmentService`, `GitHubPullRequestQueryService` |
+| `github/issue/` | `GitHubIssuesCollector`, `AsyncIssuesCollector` |
+| `github/scheduler/` | `StatsEnrichmentScheduler` |
+
+`commit/` and `pullrequest/` hold the same three roles — collector, ingest service, stats
+enrichment service — so the two-phase pattern is legible from the tree.
+
---
## 3. Backend — Domain Packages
@@ -430,7 +447,7 @@ CHECK constraints (added V35):
**`DataSourceCollectService`** — Dispatches to collectors based on `DataSourceType`. For GITHUB type it also conditionally collects issues per repo when `repo.isCollectIssues()` is true:
- `GIT_LOCAL` → `GitLocalCollector.collectForRepository()`
-- `GITHUB` → Phase 1: `GitHubCollector.collectForRepository()` (commits), Phase 2: `GitHubPrCollector.collectForRepository()` (PRs), Phase 3 (conditional): `GitHubIssuesCollector.collectIssuesForRepo()` if `repo.collectIssues`
+- `GITHUB` → Phase 1: `GitHubCommitCollector.collectForRepository()` (commits), Phase 2: `GitHubPullRequestCollector.collectForRepository()` (PRs), Phase 3 (conditional): `GitHubIssuesCollector.collectIssuesForRepo()` if `repo.collectIssues`
- `GITHUB_ISSUES` → `GitHubIssuesCollector.collectIssuesForRepo(cfg, repoFullName)` per repo
- `JIRA` → iterates `JiraProjectService.listTrackedProjects(cfg)`; calls `JiraCollector.collectIssues(project)` per project. Logs a warning if no tracked projects exist.
- Updates `lastSuccessSync` on success.
@@ -834,21 +851,23 @@ The datasource a subscription belongs to is derived via `repo_id → git_reposit
- `enrichSingle(entity, ...)` — `GET /repos/{owner}/{repo}/commits/{sha}`. On 200: applies `additions`/`deletions`/`filesChanged`, sets `COMPLETE`. On 403 diff-too-large: sets `SKIPPED`. On 404/422: sets `FAILED`. On 5xx: increments attempts, backs off.
- Rate limiting: synchronized token bucket on `MIN_INTERVAL_NS`; 100–300 ms jitter; proactive throttle when `X-RateLimit-Remaining < 100`; exponential backoff on error.
-**`GitHubCollector`** — Orchestrates commit collection:
+**`GitHubCommitCollector`** — Orchestrates commit collection:
1. `GitHubCommitIngestService.ingestForRepository()` (Phase A).
2. Sort saved by `authorDate` desc.
3. `GitHubCommitStatsEnrichmentService.enrichImmediate()` (Phase B — top 150).
4. Log remaining PENDING count (Phase C handled by scheduler).
-**`GitHubPrCollector`** — Orchestrates PR collection:
-1. `GitHubPullRequestCollector` (ingest): pages all PRs, upserts by `(repoId, number)`, saves with `statsStatus=PENDING`.
+**`GitHubPullRequestCollector`** — Orchestrates PR collection:
+1. `GitHubPullRequestIngestService` (ingest): pages all PRs, upserts by `(repoId, number)`, saves with `statsStatus=PENDING`.
2. Sort saved by `createdAt` desc.
-3. `GitHubPrStatsEnrichmentService.enrichImmediate()` (Phase B — top 150): fetches reviews (delete+save in `github_pr_reviews`) and detail stats per PR.
+3. `GitHubPullRequestStatsEnrichmentService.enrichImmediate()` (Phase B — top 150): fetches reviews (delete+save in `github_pr_reviews`) and detail stats per PR.
4. Phase C handled by scheduler.
-**`GitHubPullRequestCollector`** — Ingest-only service. Pages PRs from GitHub API, upserts into `github_pull_requests`. Also used by `GitHubPullRequestController` for paginated listing. Returns `IngestResult(savedEntities, apiBase, token)`.
+**`GitHubPullRequestIngestService`** — Ingest-only service. Pages PRs from GitHub API, upserts into `github_pull_requests`. Returns `IngestResult(savedEntities, apiBase, token)`.
+
+**`GitHubPullRequestQueryService`** — Read side for stored PRs. `listPullRequests(repoId, pageable)` — the paginated listing `GitHubPullRequestController` serves.
-**`GitHubPrStatsEnrichmentService`** — Enriches PR stats. Same rate-limit pattern as commit enrichment. `enrichSingle(pr, ...)` — `GET /repos/{owner}/{repo}/pulls/{number}` for additions/deletions/changedFiles/commitsCount; `GET .../reviews` for review list (delete+save all reviews then mark PR `COMPLETE`).
+**`GitHubPullRequestStatsEnrichmentService`** — Enriches PR stats. Same rate-limit pattern as commit enrichment. `enrichSingle(pr, ...)` — `GET /repos/{owner}/{repo}/pulls/{number}` for additions/deletions/changedFiles/commitsCount; `GET .../reviews` for review list (delete+save all reviews then mark PR `COMPLETE`).
**`GitHubIssuesCollector`** — Fetches all issues (open + closed) via Kohsuke API, maps to `IssueEntity` with `externalId = owner/repo#{number}`. Upserts by `(dataSourceId, externalId)`. Accepts either a `GitRepositoryEntity` or a bare `repoFullName` string.
@@ -1618,8 +1637,8 @@ POST /datasources/{id}/collect
│ └─▶ reads lastSuccessSync [before collection stamps it → "first run?"]
│ └─▶ DataSourceCollectService.collectForDataSource()
│ ├─ GIT_LOCAL → GitLocalCollector.collectForRepository()
- │ ├─ GITHUB → GitHubCollector.collectForRepository() [commits]
- │ │ GitHubPrCollector.collectForRepository() [PRs]
+ │ ├─ GITHUB → GitHubCommitCollector.collectForRepository() [commits]
+ │ │ GitHubPullRequestCollector.collectForRepository() [PRs]
│ │ GitHubIssuesCollector (if repo.collectIssues) [issues]
│ ├─ GITHUB_ISSUES → GitHubIssuesCollector.collectIssuesForRepo()
│ └─ JIRA → JiraCollector.collectIssues()
@@ -1633,14 +1652,14 @@ Client polls `GET /datasources/{id}/collect/status` every 3 seconds. `SyncJobTra
```
Phase A — Fast ingest (seconds)
- GitHubCommitIngestService / GitHubPullRequestCollector
+ GitHubCommitIngestService / GitHubPullRequestIngestService
→ pages all items from GitHub list endpoint (100/page)
→ saves with statsStatus=PENDING
→ returns List sorted newest-first
Phase B — Immediate enrich top 150 (seconds to minutes)
GitHubCommitStatsEnrichmentService.enrichImmediate() ← 2 worker threads
- GitHubPrStatsEnrichmentService.enrichImmediate()
+ GitHubPullRequestStatsEnrichmentService.enrichImmediate()
→ fetches detail/reviews per item, sets statsStatus=COMPLETE
→ rate-limited: ~1.4 req/s, proactive throttle on X-RateLimit-Remaining < 100
diff --git a/dev-analytics/src/main/java/com/juliashtal/devanalytics/attribution/AttributionMigrationJob.java b/dev-analytics/src/main/java/com/juliashtal/devanalytics/attribution/AttributionMigrationJob.java
index e28eaab..4951171 100644
--- a/dev-analytics/src/main/java/com/juliashtal/devanalytics/attribution/AttributionMigrationJob.java
+++ b/dev-analytics/src/main/java/com/juliashtal/devanalytics/attribution/AttributionMigrationJob.java
@@ -2,7 +2,7 @@
import com.juliashtal.devanalytics.git.model.GitRepositoryEntity;
import com.juliashtal.devanalytics.git.repository.GitRepositoryEntityRepository;
-import com.juliashtal.devanalytics.github.service.GitHubIdentityBackfill;
+import com.juliashtal.devanalytics.github.identity.GitHubIdentityBackfill;
import com.juliashtal.devanalytics.jira.service.JiraIdentityBackfill;
import com.juliashtal.devanalytics.metrics.service.MetricBackfillTrigger;
import com.juliashtal.devanalytics.user.model.User;
diff --git a/dev-analytics/src/main/java/com/juliashtal/devanalytics/datasource/collect/GitHubSourceCollector.java b/dev-analytics/src/main/java/com/juliashtal/devanalytics/datasource/collect/GitHubSourceCollector.java
index 3ffff21..6e67c9d 100644
--- a/dev-analytics/src/main/java/com/juliashtal/devanalytics/datasource/collect/GitHubSourceCollector.java
+++ b/dev-analytics/src/main/java/com/juliashtal/devanalytics/datasource/collect/GitHubSourceCollector.java
@@ -5,10 +5,10 @@
import com.juliashtal.devanalytics.datasource.service.SyncJobTracker;
import com.juliashtal.devanalytics.git.model.GitRepositoryEntity;
import com.juliashtal.devanalytics.git.repository.GitRepositoryEntityRepository;
-import com.juliashtal.devanalytics.github.service.GitHubAccountLookup;
-import com.juliashtal.devanalytics.github.service.GitHubCollector;
-import com.juliashtal.devanalytics.github.service.GitHubIssuesCollector;
-import com.juliashtal.devanalytics.github.service.GitHubPrCollector;
+import com.juliashtal.devanalytics.github.identity.GitHubAccountLookup;
+import com.juliashtal.devanalytics.github.commit.GitHubCommitCollector;
+import com.juliashtal.devanalytics.github.issue.GitHubIssuesCollector;
+import com.juliashtal.devanalytics.github.pullrequest.GitHubPullRequestCollector;
import com.juliashtal.devanalytics.user.service.AuthorIdentityService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -24,8 +24,8 @@
public class GitHubSourceCollector implements SourceCollector {
private final GitRepositoryEntityRepository gitRepoRepository;
- private final GitHubCollector gitHubCollector;
- private final GitHubPrCollector prCollector;
+ private final GitHubCommitCollector commitCollector;
+ private final GitHubPullRequestCollector prCollector;
private final GitHubIssuesCollector issuesCollector;
private final GitHubAccountLookup accountLookup;
private final AuthorIdentityService authorIdentityService;
@@ -51,7 +51,7 @@ public int collect(DataSourceConfig cfg, SyncJobTracker.JobState jobState) {
for (var repo : gitRepoRepository.findAllByDataSourceConfig(cfg)) {
try {
if (jobState != null) tracker.setPhase(jobState, "commits", -1);
- int commits = gitHubCollector.collectForRepository(repo.getId(), jobState);
+ int commits = commitCollector.collectForRepository(repo.getId(), jobState);
if (jobState != null) tracker.setPhase(jobState, "pull requests", -1);
int prs = prCollector.collectForRepository(repo.getId(), jobState);
diff --git a/dev-analytics/src/main/java/com/juliashtal/devanalytics/datasource/controller/DataSourceRepoController.java b/dev-analytics/src/main/java/com/juliashtal/devanalytics/datasource/controller/DataSourceRepoController.java
index 42c4758..1083254 100644
--- a/dev-analytics/src/main/java/com/juliashtal/devanalytics/datasource/controller/DataSourceRepoController.java
+++ b/dev-analytics/src/main/java/com/juliashtal/devanalytics/datasource/controller/DataSourceRepoController.java
@@ -5,7 +5,7 @@
import com.juliashtal.devanalytics.git.model.dto.RepoDto;
import com.juliashtal.devanalytics.github.model.dto.DiscoveredRepoDto;
import com.juliashtal.devanalytics.github.model.dto.DiscoveryResult;
-import com.juliashtal.devanalytics.github.service.GitHubRepositoryService;
+import com.juliashtal.devanalytics.github.repo.GitHubRepositoryService;
import com.juliashtal.devanalytics.security.SecurityUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
diff --git a/dev-analytics/src/main/java/com/juliashtal/devanalytics/datasource/service/DataSourceService.java b/dev-analytics/src/main/java/com/juliashtal/devanalytics/datasource/service/DataSourceService.java
index 415dce4..dba22ad 100644
--- a/dev-analytics/src/main/java/com/juliashtal/devanalytics/datasource/service/DataSourceService.java
+++ b/dev-analytics/src/main/java/com/juliashtal/devanalytics/datasource/service/DataSourceService.java
@@ -16,7 +16,7 @@
import com.juliashtal.devanalytics.git.repository.GitRepositoryEntityRepository;
import com.juliashtal.devanalytics.git.repository.UserRepoRegistrationRepository;
import com.juliashtal.devanalytics.git.service.GitRepositoryService;
-import com.juliashtal.devanalytics.github.service.GitHubRepositoryService;
+import com.juliashtal.devanalytics.github.repo.GitHubRepositoryService;
import com.juliashtal.devanalytics.jira.service.JiraProjectService;
import com.juliashtal.devanalytics.user.model.Role;
import com.juliashtal.devanalytics.user.model.Team;
diff --git a/dev-analytics/src/main/java/com/juliashtal/devanalytics/git/controller/RepoController.java b/dev-analytics/src/main/java/com/juliashtal/devanalytics/git/controller/RepoController.java
index f8beb72..730d48f 100644
--- a/dev-analytics/src/main/java/com/juliashtal/devanalytics/git/controller/RepoController.java
+++ b/dev-analytics/src/main/java/com/juliashtal/devanalytics/git/controller/RepoController.java
@@ -2,7 +2,7 @@
import com.juliashtal.devanalytics.git.model.dto.RepoDto;
import com.juliashtal.devanalytics.git.service.RepoService;
-import com.juliashtal.devanalytics.github.service.AsyncIssuesCollectService;
+import com.juliashtal.devanalytics.github.issue.AsyncIssuesCollector;
import io.swagger.v3.oas.annotations.Operation;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
@@ -26,7 +26,7 @@
public class RepoController {
private final RepoService repoService;
- private final AsyncIssuesCollectService asyncIssuesCollectService;
+ private final AsyncIssuesCollector asyncIssuesCollector;
@Operation(summary = "List repos visible to the current user (own + team), with subscribed flag")
@GetMapping
@@ -58,6 +58,6 @@ public RepoDto setCollectIssues(
) {
boolean enabled = Boolean.TRUE.equals(body.get("enabled"));
return repoService.setCollectIssues(repoId, enabled,
- asyncIssuesCollectService::collectIssuesForRepo);
+ asyncIssuesCollector::collectIssuesForRepo);
}
}
diff --git a/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/service/GitHubClientFactory.java b/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/client/GitHubClientFactory.java
similarity index 96%
rename from dev-analytics/src/main/java/com/juliashtal/devanalytics/github/service/GitHubClientFactory.java
rename to dev-analytics/src/main/java/com/juliashtal/devanalytics/github/client/GitHubClientFactory.java
index 981516d..b06ff4a 100644
--- a/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/service/GitHubClientFactory.java
+++ b/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/client/GitHubClientFactory.java
@@ -1,4 +1,4 @@
-package com.juliashtal.devanalytics.github.service;
+package com.juliashtal.devanalytics.github.client;
import com.juliashtal.devanalytics.datasource.model.DataSourceConfig;
import com.juliashtal.devanalytics.exception.GitHubException;
diff --git a/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/service/GitHubCollector.java b/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/commit/GitHubCommitCollector.java
similarity index 97%
rename from dev-analytics/src/main/java/com/juliashtal/devanalytics/github/service/GitHubCollector.java
rename to dev-analytics/src/main/java/com/juliashtal/devanalytics/github/commit/GitHubCommitCollector.java
index 76bcc33..0c28195 100644
--- a/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/service/GitHubCollector.java
+++ b/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/commit/GitHubCommitCollector.java
@@ -1,4 +1,4 @@
-package com.juliashtal.devanalytics.github.service;
+package com.juliashtal.devanalytics.github.commit;
import com.juliashtal.devanalytics.datasource.service.SyncJobTracker;
import com.juliashtal.devanalytics.git.model.GitCommitEntity;
@@ -35,7 +35,7 @@
@Service
@RequiredArgsConstructor
@Slf4j
-public class GitHubCollector {
+public class GitHubCommitCollector {
private final GitHubCommitIngestService ingestService;
private final GitHubCommitStatsEnrichmentService enrichmentService;
diff --git a/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/service/GitHubCommitIngestService.java b/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/commit/GitHubCommitIngestService.java
similarity index 99%
rename from dev-analytics/src/main/java/com/juliashtal/devanalytics/github/service/GitHubCommitIngestService.java
rename to dev-analytics/src/main/java/com/juliashtal/devanalytics/github/commit/GitHubCommitIngestService.java
index c124260..9e22eb5 100644
--- a/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/service/GitHubCommitIngestService.java
+++ b/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/commit/GitHubCommitIngestService.java
@@ -1,4 +1,4 @@
-package com.juliashtal.devanalytics.github.service;
+package com.juliashtal.devanalytics.github.commit;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -10,6 +10,7 @@
import com.juliashtal.devanalytics.git.model.StatsStatus;
import com.juliashtal.devanalytics.git.repository.GitCommitEntityRepository;
import com.juliashtal.devanalytics.git.repository.GitRepositoryEntityRepository;
+import com.juliashtal.devanalytics.github.client.GitHubClientFactory;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
diff --git a/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/service/GitHubCommitStatsEnrichmentService.java b/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/commit/GitHubCommitStatsEnrichmentService.java
similarity index 99%
rename from dev-analytics/src/main/java/com/juliashtal/devanalytics/github/service/GitHubCommitStatsEnrichmentService.java
rename to dev-analytics/src/main/java/com/juliashtal/devanalytics/github/commit/GitHubCommitStatsEnrichmentService.java
index 48c8f0e..50de1ff 100644
--- a/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/service/GitHubCommitStatsEnrichmentService.java
+++ b/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/commit/GitHubCommitStatsEnrichmentService.java
@@ -1,4 +1,4 @@
-package com.juliashtal.devanalytics.github.service;
+package com.juliashtal.devanalytics.github.commit;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
diff --git a/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/controller/GitHubController.java b/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/controller/GitHubController.java
index 81e3889..08d1778 100644
--- a/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/controller/GitHubController.java
+++ b/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/controller/GitHubController.java
@@ -3,8 +3,8 @@
import com.juliashtal.devanalytics.git.model.dto.GitRepositoryDto;
import com.juliashtal.devanalytics.git.model.GitRepositoryEntity;
import com.juliashtal.devanalytics.github.model.dto.RegisterGitHubRepoRequest;
-import com.juliashtal.devanalytics.github.service.GitHubCollector;
-import com.juliashtal.devanalytics.github.service.GitHubRepositoryService;
+import com.juliashtal.devanalytics.github.commit.GitHubCommitCollector;
+import com.juliashtal.devanalytics.github.repo.GitHubRepositoryService;
import com.juliashtal.devanalytics.security.SecurityUtils;
import io.swagger.v3.oas.annotations.Operation;
import lombok.RequiredArgsConstructor;
@@ -23,7 +23,7 @@
public class GitHubController {
private final GitHubRepositoryService gitHubRepositoryService;
- private final GitHubCollector gitHubCollector;
+ private final GitHubCommitCollector commitCollector;
@Operation(summary = "Register a GitHub repository under a data source, reusing an existing entity if already registered")
@PostMapping("/repos")
@@ -40,7 +40,7 @@ public ResponseEntity registerRepo(@RequestBody RegisterGitHub
@Operation(summary = "Synchronously collect new commits for a GitHub repository")
@PostMapping("/repos/{repoId}/collect")
public ResponseEntity collect(@PathVariable Long repoId) {
- int saved = gitHubCollector.collectForRepository(repoId, null);
+ int saved = commitCollector.collectForRepository(repoId, null);
return ResponseEntity.ok("Collected " + saved + " commits from GitHub");
}
}
diff --git a/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/controller/GitHubPullRequestController.java b/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/controller/GitHubPullRequestController.java
index b0bd8b2..ef6b64d 100644
--- a/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/controller/GitHubPullRequestController.java
+++ b/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/controller/GitHubPullRequestController.java
@@ -2,8 +2,8 @@
import com.juliashtal.devanalytics.github.model.dto.GitHubPullRequestDto;
-import com.juliashtal.devanalytics.github.service.GitHubPrCollector;
-import com.juliashtal.devanalytics.github.service.GitHubPullRequestCollector;
+import com.juliashtal.devanalytics.github.pullrequest.GitHubPullRequestCollector;
+import com.juliashtal.devanalytics.github.pullrequest.GitHubPullRequestQueryService;
import io.swagger.v3.oas.annotations.Operation;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
@@ -22,8 +22,8 @@
@RequiredArgsConstructor
public class GitHubPullRequestController {
- private final GitHubPrCollector prCollector;
- private final GitHubPullRequestCollector prQueryService;
+ private final GitHubPullRequestCollector prCollector;
+ private final GitHubPullRequestQueryService prQueryService;
@Operation(summary = "Synchronously collect new and updated pull requests for a GitHub repository")
@PostMapping("/repos/{repoId}/pull-requests/collect")
diff --git a/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/service/GitHubAccountLookup.java b/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/identity/GitHubAccountLookup.java
similarity index 96%
rename from dev-analytics/src/main/java/com/juliashtal/devanalytics/github/service/GitHubAccountLookup.java
rename to dev-analytics/src/main/java/com/juliashtal/devanalytics/github/identity/GitHubAccountLookup.java
index 7540bd5..181636b 100644
--- a/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/service/GitHubAccountLookup.java
+++ b/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/identity/GitHubAccountLookup.java
@@ -1,4 +1,4 @@
-package com.juliashtal.devanalytics.github.service;
+package com.juliashtal.devanalytics.github.identity;
import com.juliashtal.devanalytics.datasource.model.DataSourceConfig;
diff --git a/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/service/GitHubAccountLookupImpl.java b/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/identity/GitHubAccountLookupImpl.java
similarity index 97%
rename from dev-analytics/src/main/java/com/juliashtal/devanalytics/github/service/GitHubAccountLookupImpl.java
rename to dev-analytics/src/main/java/com/juliashtal/devanalytics/github/identity/GitHubAccountLookupImpl.java
index bb619d6..0051d52 100644
--- a/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/service/GitHubAccountLookupImpl.java
+++ b/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/identity/GitHubAccountLookupImpl.java
@@ -1,4 +1,4 @@
-package com.juliashtal.devanalytics.github.service;
+package com.juliashtal.devanalytics.github.identity;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -6,6 +6,7 @@
import com.juliashtal.devanalytics.datasource.model.DataSourceType;
import com.juliashtal.devanalytics.datasource.repository.DataSourceConfigRepository;
import com.juliashtal.devanalytics.exception.GitHubException;
+import com.juliashtal.devanalytics.github.client.GitHubClientFactory;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
diff --git a/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/service/GitHubIdentityBackfill.java b/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/identity/GitHubIdentityBackfill.java
similarity index 95%
rename from dev-analytics/src/main/java/com/juliashtal/devanalytics/github/service/GitHubIdentityBackfill.java
rename to dev-analytics/src/main/java/com/juliashtal/devanalytics/github/identity/GitHubIdentityBackfill.java
index 7e9d6fb..bb6b240 100644
--- a/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/service/GitHubIdentityBackfill.java
+++ b/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/identity/GitHubIdentityBackfill.java
@@ -1,4 +1,4 @@
-package com.juliashtal.devanalytics.github.service;
+package com.juliashtal.devanalytics.github.identity;
import com.juliashtal.devanalytics.git.model.GitRepositoryEntity;
diff --git a/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/service/GitHubIdentityBackfillService.java b/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/identity/GitHubIdentityBackfillService.java
similarity index 96%
rename from dev-analytics/src/main/java/com/juliashtal/devanalytics/github/service/GitHubIdentityBackfillService.java
rename to dev-analytics/src/main/java/com/juliashtal/devanalytics/github/identity/GitHubIdentityBackfillService.java
index c0ecd74..5fe3ed5 100644
--- a/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/service/GitHubIdentityBackfillService.java
+++ b/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/identity/GitHubIdentityBackfillService.java
@@ -1,4 +1,4 @@
-package com.juliashtal.devanalytics.github.service;
+package com.juliashtal.devanalytics.github.identity;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -7,7 +7,10 @@
import com.juliashtal.devanalytics.git.model.GitCommitEntity;
import com.juliashtal.devanalytics.git.model.GitRepositoryEntity;
import com.juliashtal.devanalytics.git.repository.GitCommitEntityRepository;
+import com.juliashtal.devanalytics.github.client.GitHubClientFactory;
+import com.juliashtal.devanalytics.github.issue.GitHubIssuesCollector;
import com.juliashtal.devanalytics.github.model.GitHubPullRequestEntity;
+import com.juliashtal.devanalytics.github.pullrequest.GitHubPullRequestStatsEnrichmentService;
import com.juliashtal.devanalytics.github.repository.GitHubPullRequestRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -45,7 +48,7 @@ public class GitHubIdentityBackfillService implements GitHubIdentityBackfill {
private final GitCommitEntityRepository commitRepository;
private final GitHubPullRequestRepository prRepository;
- private final GitHubPrStatsEnrichmentService prEnrichmentService;
+ private final GitHubPullRequestStatsEnrichmentService prEnrichmentService;
private final GitHubIssuesCollector issuesCollector;
private final GitHubClientFactory clientFactory;
private final ObjectMapper objectMapper;
diff --git a/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/service/AsyncIssuesCollectService.java b/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/issue/AsyncIssuesCollector.java
similarity index 94%
rename from dev-analytics/src/main/java/com/juliashtal/devanalytics/github/service/AsyncIssuesCollectService.java
rename to dev-analytics/src/main/java/com/juliashtal/devanalytics/github/issue/AsyncIssuesCollector.java
index 6700f98..095c1c8 100644
--- a/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/service/AsyncIssuesCollectService.java
+++ b/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/issue/AsyncIssuesCollector.java
@@ -1,4 +1,4 @@
-package com.juliashtal.devanalytics.github.service;
+package com.juliashtal.devanalytics.github.issue;
import com.juliashtal.devanalytics.git.model.GitRepositoryEntity;
import com.juliashtal.devanalytics.git.repository.GitRepositoryEntityRepository;
@@ -16,7 +16,7 @@
@Service
@RequiredArgsConstructor
@Slf4j
-public class AsyncIssuesCollectService {
+public class AsyncIssuesCollector {
private final GitHubIssuesCollector issuesCollector;
private final GitRepositoryEntityRepository gitRepoRepository;
diff --git a/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/service/GitHubIssuesCollector.java b/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/issue/GitHubIssuesCollector.java
similarity index 97%
rename from dev-analytics/src/main/java/com/juliashtal/devanalytics/github/service/GitHubIssuesCollector.java
rename to dev-analytics/src/main/java/com/juliashtal/devanalytics/github/issue/GitHubIssuesCollector.java
index e0cf064..39c06f8 100644
--- a/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/service/GitHubIssuesCollector.java
+++ b/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/issue/GitHubIssuesCollector.java
@@ -1,9 +1,10 @@
-package com.juliashtal.devanalytics.github.service;
+package com.juliashtal.devanalytics.github.issue;
import com.juliashtal.devanalytics.datasource.model.DataSourceConfig;
import com.juliashtal.devanalytics.exception.GitHubException;
import com.juliashtal.devanalytics.git.model.GitRepositoryEntity;
import com.juliashtal.devanalytics.git.repository.GitRepositoryEntityRepository;
+import com.juliashtal.devanalytics.github.client.GitHubClientFactory;
import com.juliashtal.devanalytics.issue.IssueRepository;
import com.juliashtal.devanalytics.issue.model.IssueEntity;
import com.juliashtal.devanalytics.issue.model.IssueSource;
diff --git a/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/service/GitHubPrCollector.java b/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/pullrequest/GitHubPullRequestCollector.java
similarity index 82%
rename from dev-analytics/src/main/java/com/juliashtal/devanalytics/github/service/GitHubPrCollector.java
rename to dev-analytics/src/main/java/com/juliashtal/devanalytics/github/pullrequest/GitHubPullRequestCollector.java
index 17c2204..86cd0dd 100644
--- a/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/service/GitHubPrCollector.java
+++ b/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/pullrequest/GitHubPullRequestCollector.java
@@ -1,4 +1,4 @@
-package com.juliashtal.devanalytics.github.service;
+package com.juliashtal.devanalytics.github.pullrequest;
import com.juliashtal.devanalytics.datasource.service.SyncJobTracker;
import com.juliashtal.devanalytics.git.model.StatsStatus;
@@ -12,16 +12,16 @@
/**
* Orchestrates two-phase GitHub PR collection for a single repository,
- * mirroring the commit collection design in {@link GitHubCollector}.
+ * mirroring the commit collection design in {@link GitHubCommitCollector}.
*
* Pipeline
*
- * - Phase A — ingest: {@link GitHubPullRequestCollector} pages through the
+ *
- Phase A — ingest: {@link GitHubPullRequestIngestService} pages through the
* GitHub PR list endpoint and saves new or changed PRs with
* {@code statsStatus=PENDING}. No review fetches or per-PR detail calls are made.
* Returns immediately after all pages are saved.
* - Phase B — immediate enrichment: the newest
- * {@value GitHubPrStatsEnrichmentService#IMMEDIATE_ENRICH_LIMIT} PENDING PRs are
+ * {@value GitHubPullRequestStatsEnrichmentService#IMMEDIATE_ENRICH_LIMIT} PENDING PRs are
* enriched synchronously (reviews + size stats) so dashboards reflect fresh data
* right away.
* - Phase C — background backfill: remaining PENDING PRs are handled by
@@ -34,10 +34,10 @@
@Service
@RequiredArgsConstructor
@Slf4j
-public class GitHubPrCollector {
+public class GitHubPullRequestCollector {
- private final GitHubPullRequestCollector ingestService;
- private final GitHubPrStatsEnrichmentService enrichmentService;
+ private final GitHubPullRequestIngestService ingestService;
+ private final GitHubPullRequestStatsEnrichmentService enrichmentService;
/**
* Runs the full two-phase collection for one repository.
@@ -46,7 +46,7 @@ public class GitHubPrCollector {
*/
public int collectForRepository(Long gitRepoId, SyncJobTracker.JobState jobState) {
// Phase A: fast ingest — saves all new/changed PRs as PENDING.
- GitHubPullRequestCollector.IngestResult ingest =
+ GitHubPullRequestIngestService.IngestResult ingest =
ingestService.collectPullRequests(gitRepoId, jobState);
List saved = ingest.savedEntities();
@@ -56,7 +56,7 @@ public int collectForRepository(Long gitRepoId, SyncJobTracker.JobState jobState
}
log.info("Ingested {} new/updated PRs for repo id={}, starting immediate enrichment of top {}",
- saved.size(), gitRepoId, GitHubPrStatsEnrichmentService.IMMEDIATE_ENRICH_LIMIT);
+ saved.size(), gitRepoId, GitHubPullRequestStatsEnrichmentService.IMMEDIATE_ENRICH_LIMIT);
// Phase B: immediate enrichment of the priority window — newest PRs first.
// Sort explicitly so the limit always picks the most recently created ones
diff --git a/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/service/GitHubPullRequestCollector.java b/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/pullrequest/GitHubPullRequestIngestService.java
similarity index 94%
rename from dev-analytics/src/main/java/com/juliashtal/devanalytics/github/service/GitHubPullRequestCollector.java
rename to dev-analytics/src/main/java/com/juliashtal/devanalytics/github/pullrequest/GitHubPullRequestIngestService.java
index 729c98f..a858215 100644
--- a/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/service/GitHubPullRequestCollector.java
+++ b/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/pullrequest/GitHubPullRequestIngestService.java
@@ -1,4 +1,4 @@
-package com.juliashtal.devanalytics.github.service;
+package com.juliashtal.devanalytics.github.pullrequest;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -8,12 +8,11 @@
import com.juliashtal.devanalytics.git.model.GitRepositoryEntity;
import com.juliashtal.devanalytics.git.model.StatsStatus;
import com.juliashtal.devanalytics.git.repository.GitRepositoryEntityRepository;
+import com.juliashtal.devanalytics.github.client.GitHubClientFactory;
import com.juliashtal.devanalytics.github.repository.GitHubPullRequestRepository;
import com.juliashtal.devanalytics.github.model.GitHubPullRequestEntity;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -34,12 +33,12 @@
import static com.juliashtal.devanalytics.helper.ParsingHelper.resolveApiBase;
/**
- * Queries stored pull requests and paginates the GitHub PR API.
+ * Paginates the GitHub PR API and stores the entries it returns.
*/
@Service
@RequiredArgsConstructor
@Slf4j
-public class GitHubPullRequestCollector {
+public class GitHubPullRequestIngestService {
private static final int BATCH_SIZE = 100;
private static final HttpClient HTTP_CLIENT = HttpClient.newHttpClient();
@@ -56,7 +55,7 @@ public class GitHubPullRequestCollector {
*
*
Pages through all PRs and saves new or changed ones with
* {@code statsStatus=PENDING}. No review fetches and no per-PR detail calls are
- * made here — that is the responsibility of {@link GitHubPrStatsEnrichmentService}.
+ * made here — that is the responsibility of {@link GitHubPullRequestStatsEnrichmentService}.
*
* Unchanged PRs (same {@code updated_at}) are skipped entirely, so incremental
* runs only write the rows that actually changed.
@@ -278,11 +277,4 @@ private int fetchTotalPrCount(String apiBase, String token, String repoFullName)
}
return -1;
}
-
- @Transactional(readOnly = true)
- public Page listPullRequests(Long repoId, Pageable pageable) {
- GitRepositoryEntity repo = repoRepository.findById(repoId)
- .orElseThrow(() -> new NoSuchElementException("Git repo not found: " + repoId));
- return prRepository.findByRepositoryOrderByCreatedAtDesc(repo, pageable);
- }
}
diff --git a/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/pullrequest/GitHubPullRequestQueryService.java b/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/pullrequest/GitHubPullRequestQueryService.java
new file mode 100644
index 0000000..4c40b12
--- /dev/null
+++ b/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/pullrequest/GitHubPullRequestQueryService.java
@@ -0,0 +1,32 @@
+package com.juliashtal.devanalytics.github.pullrequest;
+
+import com.juliashtal.devanalytics.git.model.GitRepositoryEntity;
+import com.juliashtal.devanalytics.git.repository.GitRepositoryEntityRepository;
+import com.juliashtal.devanalytics.github.model.GitHubPullRequestEntity;
+import com.juliashtal.devanalytics.github.repository.GitHubPullRequestRepository;
+import lombok.RequiredArgsConstructor;
+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.util.NoSuchElementException;
+
+/**
+ * Read side for stored pull requests.
+ * Separate from ingestion so neither half carries the other's dependencies.
+ */
+@Service
+@RequiredArgsConstructor
+public class GitHubPullRequestQueryService {
+
+ private final GitRepositoryEntityRepository repoRepository;
+ private final GitHubPullRequestRepository prRepository;
+
+ @Transactional(readOnly = true)
+ public Page listPullRequests(Long repoId, Pageable pageable) {
+ GitRepositoryEntity repo = repoRepository.findById(repoId)
+ .orElseThrow(() -> new NoSuchElementException("Git repo not found: " + repoId));
+ return prRepository.findByRepositoryOrderByCreatedAtDesc(repo, pageable);
+ }
+}
diff --git a/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/service/GitHubPrStatsEnrichmentService.java b/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/pullrequest/GitHubPullRequestStatsEnrichmentService.java
similarity index 98%
rename from dev-analytics/src/main/java/com/juliashtal/devanalytics/github/service/GitHubPrStatsEnrichmentService.java
rename to dev-analytics/src/main/java/com/juliashtal/devanalytics/github/pullrequest/GitHubPullRequestStatsEnrichmentService.java
index 9713647..06af0f3 100644
--- a/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/service/GitHubPrStatsEnrichmentService.java
+++ b/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/pullrequest/GitHubPullRequestStatsEnrichmentService.java
@@ -1,4 +1,4 @@
-package com.juliashtal.devanalytics.github.service;
+package com.juliashtal.devanalytics.github.pullrequest;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -59,7 +59,7 @@
@Service
@RequiredArgsConstructor
@Slf4j
-public class GitHubPrStatsEnrichmentService {
+public class GitHubPullRequestStatsEnrichmentService {
/** PRs enriched immediately after ingest (priority window — matches commit enricher). */
static final int IMMEDIATE_ENRICH_LIMIT = 150;
@@ -199,7 +199,7 @@ void enrichSingle(GitHubPullRequestEntity pr, String apiBase, String token, Stri
* Shared with {@link #enrichSingle}. Exposed so the attribution backfill can refresh
* reviews for a PR already {@code COMPLETE}, which enrichment never revisits.
*/
- void refreshReviews(GitHubPullRequestEntity pr, String apiBase, String token, String repoFullName)
+ public void refreshReviews(GitHubPullRequestEntity pr, String apiBase, String token, String repoFullName)
throws IOException, InterruptedException {
List reviews = fetchReviews(pr, apiBase, token, repoFullName);
reviewRepository.deleteAllByPullRequest(pr);
diff --git a/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/service/GitHubRepositoryService.java b/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/repo/GitHubRepositoryService.java
similarity index 98%
rename from dev-analytics/src/main/java/com/juliashtal/devanalytics/github/service/GitHubRepositoryService.java
rename to dev-analytics/src/main/java/com/juliashtal/devanalytics/github/repo/GitHubRepositoryService.java
index 3aa0bc2..e7f0fad 100644
--- a/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/service/GitHubRepositoryService.java
+++ b/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/repo/GitHubRepositoryService.java
@@ -1,4 +1,4 @@
-package com.juliashtal.devanalytics.github.service;
+package com.juliashtal.devanalytics.github.repo;
import com.juliashtal.devanalytics.datasource.model.DataSourceConfig;
import com.juliashtal.devanalytics.datasource.model.DataSourceType;
@@ -12,6 +12,7 @@
import com.juliashtal.devanalytics.git.repository.GitRepositoryEntityRepository;
import com.juliashtal.devanalytics.git.repository.UserRepoRegistrationRepository;
import com.juliashtal.devanalytics.datasource.repository.DataSourceConfigRepository;
+import com.juliashtal.devanalytics.github.client.GitHubClientFactory;
import com.juliashtal.devanalytics.github.model.dto.DiscoveredRepoDto;
import com.juliashtal.devanalytics.github.model.dto.DiscoveryResult;
import com.juliashtal.devanalytics.user.repository.UserRepository;
diff --git a/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/service/StatsEnrichmentScheduler.java b/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/scheduler/StatsEnrichmentScheduler.java
similarity index 90%
rename from dev-analytics/src/main/java/com/juliashtal/devanalytics/github/service/StatsEnrichmentScheduler.java
rename to dev-analytics/src/main/java/com/juliashtal/devanalytics/github/scheduler/StatsEnrichmentScheduler.java
index f9eb17e..6719579 100644
--- a/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/service/StatsEnrichmentScheduler.java
+++ b/dev-analytics/src/main/java/com/juliashtal/devanalytics/github/scheduler/StatsEnrichmentScheduler.java
@@ -1,10 +1,13 @@
-package com.juliashtal.devanalytics.github.service;
+package com.juliashtal.devanalytics.github.scheduler;
import com.juliashtal.devanalytics.git.model.GitRepositoryEntity;
import com.juliashtal.devanalytics.git.model.RepoType;
import com.juliashtal.devanalytics.git.model.StatsStatus;
import com.juliashtal.devanalytics.git.repository.GitCommitEntityRepository;
import com.juliashtal.devanalytics.git.repository.GitRepositoryEntityRepository;
+import com.juliashtal.devanalytics.github.client.GitHubClientFactory;
+import com.juliashtal.devanalytics.github.commit.GitHubCommitStatsEnrichmentService;
+import com.juliashtal.devanalytics.github.pullrequest.GitHubPullRequestStatsEnrichmentService;
import com.juliashtal.devanalytics.github.repository.GitHubPullRequestRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -40,7 +43,7 @@ public class StatsEnrichmentScheduler {
private final GitHubPullRequestRepository prRepository;
private final GitRepositoryEntityRepository repoRepository;
private final GitHubCommitStatsEnrichmentService commitEnrichmentService;
- private final GitHubPrStatsEnrichmentService prEnrichmentService;
+ private final GitHubPullRequestStatsEnrichmentService prEnrichmentService;
private final GitHubClientFactory clientFactory;
@Scheduled(fixedDelay = 120_000, initialDelay = 60_000)
diff --git a/dev-analytics/src/main/java/com/juliashtal/devanalytics/issue/controller/IssuesController.java b/dev-analytics/src/main/java/com/juliashtal/devanalytics/issue/controller/IssuesController.java
index eee8749..026baaf 100644
--- a/dev-analytics/src/main/java/com/juliashtal/devanalytics/issue/controller/IssuesController.java
+++ b/dev-analytics/src/main/java/com/juliashtal/devanalytics/issue/controller/IssuesController.java
@@ -5,7 +5,7 @@
import com.juliashtal.devanalytics.datasource.service.DataSourceService;
import com.juliashtal.devanalytics.git.model.GitRepositoryEntity;
import com.juliashtal.devanalytics.git.service.RepoService;
-import com.juliashtal.devanalytics.github.service.GitHubIssuesCollector;
+import com.juliashtal.devanalytics.github.issue.GitHubIssuesCollector;
import com.juliashtal.devanalytics.issue.model.IssueDto;
import com.juliashtal.devanalytics.issue.service.IssueService;
import com.juliashtal.devanalytics.jira.service.JiraCollector;
diff --git a/dev-analytics/src/main/java/com/juliashtal/devanalytics/user/service/AuthorIdentityService.java b/dev-analytics/src/main/java/com/juliashtal/devanalytics/user/service/AuthorIdentityService.java
index 8691818..818cb01 100644
--- a/dev-analytics/src/main/java/com/juliashtal/devanalytics/user/service/AuthorIdentityService.java
+++ b/dev-analytics/src/main/java/com/juliashtal/devanalytics/user/service/AuthorIdentityService.java
@@ -4,7 +4,7 @@
import com.juliashtal.devanalytics.exception.ConflictException;
import com.juliashtal.devanalytics.exception.NotFoundException;
import com.juliashtal.devanalytics.exception.UnprocessableEntityException;
-import com.juliashtal.devanalytics.github.service.GitHubAccountLookup;
+import com.juliashtal.devanalytics.github.identity.GitHubAccountLookup;
import com.juliashtal.devanalytics.user.model.AuthorIdentityChangedEvent;
import com.juliashtal.devanalytics.user.model.CommitEmailDto;
import com.juliashtal.devanalytics.user.model.User;
diff --git a/dev-analytics/src/test/java/com/juliashtal/devanalytics/attribution/AttributionMigrationTest.java b/dev-analytics/src/test/java/com/juliashtal/devanalytics/attribution/AttributionMigrationTest.java
index 06d627b..1da29eb 100644
--- a/dev-analytics/src/test/java/com/juliashtal/devanalytics/attribution/AttributionMigrationTest.java
+++ b/dev-analytics/src/test/java/com/juliashtal/devanalytics/attribution/AttributionMigrationTest.java
@@ -3,7 +3,7 @@
import com.juliashtal.devanalytics.exception.ConflictException;
import com.juliashtal.devanalytics.git.model.GitRepositoryEntity;
import com.juliashtal.devanalytics.git.repository.GitRepositoryEntityRepository;
-import com.juliashtal.devanalytics.github.service.GitHubIdentityBackfill;
+import com.juliashtal.devanalytics.github.identity.GitHubIdentityBackfill;
import com.juliashtal.devanalytics.jira.service.JiraIdentityBackfill;
import com.juliashtal.devanalytics.metrics.service.MetricBackfillTrigger;
import com.juliashtal.devanalytics.user.model.User;
diff --git a/dev-analytics/src/test/java/com/juliashtal/devanalytics/datasource/DataSourceServiceAttachDetachTest.java b/dev-analytics/src/test/java/com/juliashtal/devanalytics/datasource/DataSourceServiceAttachDetachTest.java
index fa3d985..faac459 100644
--- a/dev-analytics/src/test/java/com/juliashtal/devanalytics/datasource/DataSourceServiceAttachDetachTest.java
+++ b/dev-analytics/src/test/java/com/juliashtal/devanalytics/datasource/DataSourceServiceAttachDetachTest.java
@@ -15,7 +15,7 @@
import com.juliashtal.devanalytics.git.repository.GitRepositoryEntityRepository;
import com.juliashtal.devanalytics.git.repository.UserRepoRegistrationRepository;
import com.juliashtal.devanalytics.git.service.GitRepositoryService;
-import com.juliashtal.devanalytics.github.service.GitHubRepositoryService;
+import com.juliashtal.devanalytics.github.repo.GitHubRepositoryService;
import com.juliashtal.devanalytics.jira.service.JiraProjectService;
import com.juliashtal.devanalytics.security.TokenEncryptor;
import com.juliashtal.devanalytics.user.model.User;
diff --git a/dev-analytics/src/test/java/com/juliashtal/devanalytics/datasource/DataSourceServiceCoverageTest.java b/dev-analytics/src/test/java/com/juliashtal/devanalytics/datasource/DataSourceServiceCoverageTest.java
index bdd1acd..547d81c 100644
--- a/dev-analytics/src/test/java/com/juliashtal/devanalytics/datasource/DataSourceServiceCoverageTest.java
+++ b/dev-analytics/src/test/java/com/juliashtal/devanalytics/datasource/DataSourceServiceCoverageTest.java
@@ -15,7 +15,7 @@
import com.juliashtal.devanalytics.git.repository.GitRepositoryEntityRepository;
import com.juliashtal.devanalytics.git.repository.UserRepoRegistrationRepository;
import com.juliashtal.devanalytics.git.service.GitRepositoryService;
-import com.juliashtal.devanalytics.github.service.GitHubRepositoryService;
+import com.juliashtal.devanalytics.github.repo.GitHubRepositoryService;
import com.juliashtal.devanalytics.jira.model.JiraProjectEntity;
import com.juliashtal.devanalytics.jira.service.JiraProjectService;
import com.juliashtal.devanalytics.security.SecurityUtils;
diff --git a/dev-analytics/src/test/java/com/juliashtal/devanalytics/datasource/DataSourceServiceTest.java b/dev-analytics/src/test/java/com/juliashtal/devanalytics/datasource/DataSourceServiceTest.java
index e85da24..a8e25d0 100644
--- a/dev-analytics/src/test/java/com/juliashtal/devanalytics/datasource/DataSourceServiceTest.java
+++ b/dev-analytics/src/test/java/com/juliashtal/devanalytics/datasource/DataSourceServiceTest.java
@@ -10,7 +10,7 @@
import com.juliashtal.devanalytics.git.repository.GitRepositoryEntityRepository;
import com.juliashtal.devanalytics.git.repository.UserRepoRegistrationRepository;
import com.juliashtal.devanalytics.git.service.GitRepositoryService;
-import com.juliashtal.devanalytics.github.service.GitHubRepositoryService;
+import com.juliashtal.devanalytics.github.repo.GitHubRepositoryService;
import com.juliashtal.devanalytics.jira.service.JiraProjectService;
import com.juliashtal.devanalytics.jira.model.JiraProjectEntity;
import com.juliashtal.devanalytics.security.TokenEncryptor;
diff --git a/dev-analytics/src/test/java/com/juliashtal/devanalytics/datasource/collect/GitHubSourceCollectorTest.java b/dev-analytics/src/test/java/com/juliashtal/devanalytics/datasource/collect/GitHubSourceCollectorTest.java
index 2612e1f..3ba337f 100644
--- a/dev-analytics/src/test/java/com/juliashtal/devanalytics/datasource/collect/GitHubSourceCollectorTest.java
+++ b/dev-analytics/src/test/java/com/juliashtal/devanalytics/datasource/collect/GitHubSourceCollectorTest.java
@@ -5,9 +5,9 @@
import com.juliashtal.devanalytics.datasource.service.SyncJobTracker;
import com.juliashtal.devanalytics.git.model.GitRepositoryEntity;
import com.juliashtal.devanalytics.git.repository.GitRepositoryEntityRepository;
-import com.juliashtal.devanalytics.github.service.GitHubCollector;
-import com.juliashtal.devanalytics.github.service.GitHubIssuesCollector;
-import com.juliashtal.devanalytics.github.service.GitHubPrCollector;
+import com.juliashtal.devanalytics.github.commit.GitHubCommitCollector;
+import com.juliashtal.devanalytics.github.issue.GitHubIssuesCollector;
+import com.juliashtal.devanalytics.github.pullrequest.GitHubPullRequestCollector;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
@@ -27,8 +27,8 @@
class GitHubSourceCollectorTest {
@Mock GitRepositoryEntityRepository gitRepoRepository;
- @Mock GitHubCollector gitHubCollector;
- @Mock GitHubPrCollector prCollector;
+ @Mock GitHubCommitCollector commitCollector;
+ @Mock GitHubPullRequestCollector prCollector;
@Mock GitHubIssuesCollector issuesCollector;
@Mock SyncJobTracker tracker;
@@ -69,7 +69,7 @@ void collect_noIssues_collectsCommitsAndPrsOnly() {
DataSourceConfig cfg = new DataSourceConfig();
GitRepositoryEntity r = repo(10L, "owner/repo", false);
when(gitRepoRepository.findAllByDataSourceConfig(cfg)).thenReturn(List.of(r));
- when(gitHubCollector.collectForRepository(eq(10L), any())).thenReturn(3);
+ when(commitCollector.collectForRepository(eq(10L), any())).thenReturn(3);
when(prCollector.collectForRepository(eq(10L), any())).thenReturn(2);
SyncJobTracker.JobState js = new SyncJobTracker.JobState();
@@ -85,7 +85,7 @@ void collect_withIssues_collectsAllThree() {
DataSourceConfig cfg = new DataSourceConfig();
GitRepositoryEntity r = repo(11L, "owner/repo-issues", true);
when(gitRepoRepository.findAllByDataSourceConfig(cfg)).thenReturn(List.of(r));
- when(gitHubCollector.collectForRepository(eq(11L), any())).thenReturn(2);
+ when(commitCollector.collectForRepository(eq(11L), any())).thenReturn(2);
when(prCollector.collectForRepository(eq(11L), any())).thenReturn(1);
when(issuesCollector.collectIssuesForRepo(
any(DataSourceConfig.class), any(GitRepositoryEntity.class))).thenReturn(4);
diff --git a/dev-analytics/src/test/java/com/juliashtal/devanalytics/git/RepoTypeDiscriminatorTest.java b/dev-analytics/src/test/java/com/juliashtal/devanalytics/git/RepoTypeDiscriminatorTest.java
index d68d412..eda4900 100644
--- a/dev-analytics/src/test/java/com/juliashtal/devanalytics/git/RepoTypeDiscriminatorTest.java
+++ b/dev-analytics/src/test/java/com/juliashtal/devanalytics/git/RepoTypeDiscriminatorTest.java
@@ -10,7 +10,7 @@
import com.juliashtal.devanalytics.git.repository.UserRepoRegistrationRepository;
import com.juliashtal.devanalytics.git.service.GitRepositoryService;
import com.juliashtal.devanalytics.git.model.dto.RegisterLocalRepoRequest;
-import com.juliashtal.devanalytics.github.service.GitHubRepositoryService;
+import com.juliashtal.devanalytics.github.repo.GitHubRepositoryService;
import com.juliashtal.devanalytics.user.model.User;
import com.juliashtal.devanalytics.user.repository.UserRepository;
import org.junit.jupiter.api.BeforeEach;
diff --git a/dev-analytics/src/test/java/com/juliashtal/devanalytics/git/UserRepoRegistrationTest.java b/dev-analytics/src/test/java/com/juliashtal/devanalytics/git/UserRepoRegistrationTest.java
index eac17ad..b7a3d18 100644
--- a/dev-analytics/src/test/java/com/juliashtal/devanalytics/git/UserRepoRegistrationTest.java
+++ b/dev-analytics/src/test/java/com/juliashtal/devanalytics/git/UserRepoRegistrationTest.java
@@ -33,7 +33,7 @@ class UserRepoRegistrationTest {
JiraProjectService jiraProjectService;
@Mock com.juliashtal.devanalytics.datasource.service.DataSourceValidator validator;
@Mock com.juliashtal.devanalytics.git.service.GitRepositoryService gitRepositoryService;
- @Mock com.juliashtal.devanalytics.github.service.GitHubRepositoryService gitHubRepositoryService;
+ @Mock com.juliashtal.devanalytics.github.repo.GitHubRepositoryService gitHubRepositoryService;
@Mock com.juliashtal.devanalytics.security.TokenEncryptor tokenEncryptor;
@InjectMocks DataSourceService dataSourceService;
diff --git a/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/service/GitHubClientFactoryTest.java b/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/client/GitHubClientFactoryTest.java
similarity index 98%
rename from dev-analytics/src/test/java/com/juliashtal/devanalytics/github/service/GitHubClientFactoryTest.java
rename to dev-analytics/src/test/java/com/juliashtal/devanalytics/github/client/GitHubClientFactoryTest.java
index 7506ee7..917e5da 100644
--- a/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/service/GitHubClientFactoryTest.java
+++ b/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/client/GitHubClientFactoryTest.java
@@ -1,4 +1,4 @@
-package com.juliashtal.devanalytics.github.service;
+package com.juliashtal.devanalytics.github.client;
import com.juliashtal.devanalytics.datasource.model.DataSourceConfig;
import com.juliashtal.devanalytics.exception.GitHubException;
diff --git a/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/service/GitHubCollectorTest.java b/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/commit/GitHubCommitCollectorTest.java
similarity index 97%
rename from dev-analytics/src/test/java/com/juliashtal/devanalytics/github/service/GitHubCollectorTest.java
rename to dev-analytics/src/test/java/com/juliashtal/devanalytics/github/commit/GitHubCommitCollectorTest.java
index 11aecd1..e33e082 100644
--- a/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/service/GitHubCollectorTest.java
+++ b/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/commit/GitHubCommitCollectorTest.java
@@ -1,4 +1,4 @@
-package com.juliashtal.devanalytics.github.service;
+package com.juliashtal.devanalytics.github.commit;
import com.juliashtal.devanalytics.git.model.GitCommitEntity;
import com.juliashtal.devanalytics.git.model.GitRepositoryEntity;
@@ -19,13 +19,13 @@
import static org.mockito.Mockito.*;
@ExtendWith(MockitoExtension.class)
-class GitHubCollectorTest {
+class GitHubCommitCollectorTest {
@Mock GitHubCommitIngestService ingestService;
@Mock GitHubCommitStatsEnrichmentService enrichmentService;
@InjectMocks
- GitHubCollector collector;
+ GitHubCommitCollector collector;
private GitCommitEntity commit(Instant date, StatsStatus status, String repoFullName) {
GitRepositoryEntity repo = new GitRepositoryEntity();
diff --git a/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/service/GitHubCommitIngestServiceTest.java b/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/commit/GitHubCommitIngestServiceTest.java
similarity index 99%
rename from dev-analytics/src/test/java/com/juliashtal/devanalytics/github/service/GitHubCommitIngestServiceTest.java
rename to dev-analytics/src/test/java/com/juliashtal/devanalytics/github/commit/GitHubCommitIngestServiceTest.java
index 647d887..48db015 100644
--- a/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/service/GitHubCommitIngestServiceTest.java
+++ b/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/commit/GitHubCommitIngestServiceTest.java
@@ -1,4 +1,4 @@
-package com.juliashtal.devanalytics.github.service;
+package com.juliashtal.devanalytics.github.commit;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo;
@@ -11,6 +11,7 @@
import com.juliashtal.devanalytics.git.model.StatsStatus;
import com.juliashtal.devanalytics.git.repository.GitCommitEntityRepository;
import com.juliashtal.devanalytics.git.repository.GitRepositoryEntityRepository;
+import com.juliashtal.devanalytics.github.client.GitHubClientFactory;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
diff --git a/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/service/GitHubCommitStatsEnrichmentServiceTest.java b/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/commit/GitHubCommitStatsEnrichmentServiceTest.java
similarity index 99%
rename from dev-analytics/src/test/java/com/juliashtal/devanalytics/github/service/GitHubCommitStatsEnrichmentServiceTest.java
rename to dev-analytics/src/test/java/com/juliashtal/devanalytics/github/commit/GitHubCommitStatsEnrichmentServiceTest.java
index 5d03cf7..d1fe6ac 100644
--- a/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/service/GitHubCommitStatsEnrichmentServiceTest.java
+++ b/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/commit/GitHubCommitStatsEnrichmentServiceTest.java
@@ -1,4 +1,4 @@
-package com.juliashtal.devanalytics.github.service;
+package com.juliashtal.devanalytics.github.commit;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo;
diff --git a/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/service/GitHubAccountLookupImplTest.java b/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/identity/GitHubAccountLookupImplTest.java
similarity index 98%
rename from dev-analytics/src/test/java/com/juliashtal/devanalytics/github/service/GitHubAccountLookupImplTest.java
rename to dev-analytics/src/test/java/com/juliashtal/devanalytics/github/identity/GitHubAccountLookupImplTest.java
index 6a81844..6f378ad 100644
--- a/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/service/GitHubAccountLookupImplTest.java
+++ b/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/identity/GitHubAccountLookupImplTest.java
@@ -1,4 +1,4 @@
-package com.juliashtal.devanalytics.github.service;
+package com.juliashtal.devanalytics.github.identity;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo;
@@ -7,6 +7,7 @@
import com.juliashtal.devanalytics.datasource.model.DataSourceType;
import com.juliashtal.devanalytics.datasource.repository.DataSourceConfigRepository;
import com.juliashtal.devanalytics.exception.GitHubException;
+import com.juliashtal.devanalytics.github.client.GitHubClientFactory;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
diff --git a/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/service/GitHubIdentityBackfillServiceTest.java b/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/identity/GitHubIdentityBackfillServiceTest.java
similarity index 96%
rename from dev-analytics/src/test/java/com/juliashtal/devanalytics/github/service/GitHubIdentityBackfillServiceTest.java
rename to dev-analytics/src/test/java/com/juliashtal/devanalytics/github/identity/GitHubIdentityBackfillServiceTest.java
index b4c4663..7cb546c 100644
--- a/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/service/GitHubIdentityBackfillServiceTest.java
+++ b/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/identity/GitHubIdentityBackfillServiceTest.java
@@ -1,4 +1,4 @@
-package com.juliashtal.devanalytics.github.service;
+package com.juliashtal.devanalytics.github.identity;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo;
@@ -8,7 +8,10 @@
import com.juliashtal.devanalytics.git.model.GitCommitEntity;
import com.juliashtal.devanalytics.git.model.GitRepositoryEntity;
import com.juliashtal.devanalytics.git.repository.GitCommitEntityRepository;
+import com.juliashtal.devanalytics.github.client.GitHubClientFactory;
+import com.juliashtal.devanalytics.github.issue.GitHubIssuesCollector;
import com.juliashtal.devanalytics.github.model.GitHubPullRequestEntity;
+import com.juliashtal.devanalytics.github.pullrequest.GitHubPullRequestStatsEnrichmentService;
import com.juliashtal.devanalytics.github.repository.GitHubPullRequestRepository;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -43,7 +46,7 @@ class GitHubIdentityBackfillServiceTest {
@Mock GitCommitEntityRepository commitRepository;
@Mock GitHubPullRequestRepository prRepository;
- @Mock GitHubPrStatsEnrichmentService prEnrichmentService;
+ @Mock GitHubPullRequestStatsEnrichmentService prEnrichmentService;
@Mock GitHubIssuesCollector issuesCollector;
@Mock GitHubClientFactory clientFactory;
diff --git a/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/service/IdentityIngestMappingTest.java b/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/identity/IdentityIngestMappingTest.java
similarity index 95%
rename from dev-analytics/src/test/java/com/juliashtal/devanalytics/github/service/IdentityIngestMappingTest.java
rename to dev-analytics/src/test/java/com/juliashtal/devanalytics/github/identity/IdentityIngestMappingTest.java
index 5b846db..57ede6d 100644
--- a/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/service/IdentityIngestMappingTest.java
+++ b/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/identity/IdentityIngestMappingTest.java
@@ -1,4 +1,4 @@
-package com.juliashtal.devanalytics.github.service;
+package com.juliashtal.devanalytics.github.identity;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo;
@@ -8,7 +8,10 @@
import com.juliashtal.devanalytics.git.model.GitRepositoryEntity;
import com.juliashtal.devanalytics.git.repository.GitCommitEntityRepository;
import com.juliashtal.devanalytics.git.repository.GitRepositoryEntityRepository;
+import com.juliashtal.devanalytics.github.client.GitHubClientFactory;
+import com.juliashtal.devanalytics.github.commit.GitHubCommitIngestService;
import com.juliashtal.devanalytics.github.model.GitHubPullRequestEntity;
+import com.juliashtal.devanalytics.github.pullrequest.GitHubPullRequestIngestService;
import com.juliashtal.devanalytics.github.repository.GitHubPullRequestRepository;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -43,14 +46,14 @@ class IdentityIngestMappingTest {
@Mock GitHubClientFactory clientFactory;
GitHubCommitIngestService commitIngest;
- GitHubPullRequestCollector prCollector;
+ GitHubPullRequestIngestService prCollector;
String wmBaseUrl;
@BeforeEach
void setUp(WireMockRuntimeInfo wm) {
wmBaseUrl = wm.getHttpBaseUrl();
commitIngest = new GitHubCommitIngestService(repoRepository, commitRepository, clientFactory, new ObjectMapper());
- prCollector = new GitHubPullRequestCollector(repoRepository, prRepository, clientFactory, new ObjectMapper());
+ prCollector = new GitHubPullRequestIngestService(repoRepository, prRepository, clientFactory, new ObjectMapper());
}
private GitRepositoryEntity repo() {
diff --git a/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/service/AsyncIssuesCollectServiceTest.java b/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/issue/AsyncIssuesCollectorTest.java
similarity index 95%
rename from dev-analytics/src/test/java/com/juliashtal/devanalytics/github/service/AsyncIssuesCollectServiceTest.java
rename to dev-analytics/src/test/java/com/juliashtal/devanalytics/github/issue/AsyncIssuesCollectorTest.java
index 169534a..d190c25 100644
--- a/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/service/AsyncIssuesCollectServiceTest.java
+++ b/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/issue/AsyncIssuesCollectorTest.java
@@ -1,4 +1,4 @@
-package com.juliashtal.devanalytics.github.service;
+package com.juliashtal.devanalytics.github.issue;
import com.juliashtal.devanalytics.datasource.model.DataSourceConfig;
import com.juliashtal.devanalytics.git.model.GitRepositoryEntity;
@@ -14,13 +14,13 @@
import static org.mockito.Mockito.*;
@ExtendWith(MockitoExtension.class)
-class AsyncIssuesCollectServiceTest {
+class AsyncIssuesCollectorTest {
@Mock GitHubIssuesCollector issuesCollector;
@Mock GitRepositoryEntityRepository gitRepoRepository;
@InjectMocks
- AsyncIssuesCollectService service;
+ AsyncIssuesCollector service;
// ── repo not found → warns and returns without calling collector ─────────
diff --git a/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/service/GitHubIssuesCollectorTest.java b/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/issue/GitHubIssuesCollectorTest.java
similarity index 99%
rename from dev-analytics/src/test/java/com/juliashtal/devanalytics/github/service/GitHubIssuesCollectorTest.java
rename to dev-analytics/src/test/java/com/juliashtal/devanalytics/github/issue/GitHubIssuesCollectorTest.java
index da3560a..999a1a6 100644
--- a/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/service/GitHubIssuesCollectorTest.java
+++ b/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/issue/GitHubIssuesCollectorTest.java
@@ -1,9 +1,10 @@
-package com.juliashtal.devanalytics.github.service;
+package com.juliashtal.devanalytics.github.issue;
import com.juliashtal.devanalytics.datasource.model.DataSourceConfig;
import com.juliashtal.devanalytics.exception.GitHubException;
import com.juliashtal.devanalytics.git.model.GitRepositoryEntity;
import com.juliashtal.devanalytics.git.repository.GitRepositoryEntityRepository;
+import com.juliashtal.devanalytics.github.client.GitHubClientFactory;
import com.juliashtal.devanalytics.issue.IssueRepository;
import com.juliashtal.devanalytics.issue.model.IssueEntity;
import com.juliashtal.devanalytics.issue.model.IssueSource;
diff --git a/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/service/ReviewAndIssueIdentityMappingTest.java b/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/issue/ReviewAndIssueIdentityMappingTest.java
similarity index 95%
rename from dev-analytics/src/test/java/com/juliashtal/devanalytics/github/service/ReviewAndIssueIdentityMappingTest.java
rename to dev-analytics/src/test/java/com/juliashtal/devanalytics/github/issue/ReviewAndIssueIdentityMappingTest.java
index 457a985..9c6e4d7 100644
--- a/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/service/ReviewAndIssueIdentityMappingTest.java
+++ b/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/issue/ReviewAndIssueIdentityMappingTest.java
@@ -1,4 +1,4 @@
-package com.juliashtal.devanalytics.github.service;
+package com.juliashtal.devanalytics.github.issue;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo;
@@ -6,8 +6,10 @@
import com.juliashtal.devanalytics.datasource.model.DataSourceConfig;
import com.juliashtal.devanalytics.git.model.GitRepositoryEntity;
import com.juliashtal.devanalytics.git.repository.GitRepositoryEntityRepository;
+import com.juliashtal.devanalytics.github.client.GitHubClientFactory;
import com.juliashtal.devanalytics.github.model.GitHubPrReviewEntity;
import com.juliashtal.devanalytics.github.model.GitHubPullRequestEntity;
+import com.juliashtal.devanalytics.github.pullrequest.GitHubPullRequestStatsEnrichmentService;
import com.juliashtal.devanalytics.github.repository.GitHubPrReviewRepository;
import com.juliashtal.devanalytics.github.repository.GitHubPullRequestRepository;
import com.juliashtal.devanalytics.issue.IssueRepository;
@@ -51,14 +53,14 @@ class ReviewAndIssueIdentityMappingTest {
@Mock IssueRepository issueRepository;
@Mock GitRepositoryEntityRepository gitRepositoryEntityRepository;
- GitHubPrStatsEnrichmentService enrichment;
+ GitHubPullRequestStatsEnrichmentService enrichment;
GitHubIssuesCollector issuesCollector;
String wmBaseUrl;
@BeforeEach
void setUp(WireMockRuntimeInfo wm) {
wmBaseUrl = wm.getHttpBaseUrl();
- enrichment = new GitHubPrStatsEnrichmentService(prRepository, reviewRepository, new ObjectMapper());
+ enrichment = new GitHubPullRequestStatsEnrichmentService(prRepository, reviewRepository, new ObjectMapper());
issuesCollector = new GitHubIssuesCollector(clientFactory, issueRepository, gitRepositoryEntityRepository);
}
diff --git a/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/service/GitHubPrCollectorTest.java b/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/pullrequest/GitHubPullRequestCollectorTest.java
similarity index 87%
rename from dev-analytics/src/test/java/com/juliashtal/devanalytics/github/service/GitHubPrCollectorTest.java
rename to dev-analytics/src/test/java/com/juliashtal/devanalytics/github/pullrequest/GitHubPullRequestCollectorTest.java
index a02f63b..99e1ab1 100644
--- a/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/service/GitHubPrCollectorTest.java
+++ b/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/pullrequest/GitHubPullRequestCollectorTest.java
@@ -1,4 +1,4 @@
-package com.juliashtal.devanalytics.github.service;
+package com.juliashtal.devanalytics.github.pullrequest;
import com.juliashtal.devanalytics.git.model.GitRepositoryEntity;
import com.juliashtal.devanalytics.git.model.StatsStatus;
@@ -19,13 +19,13 @@
import static org.mockito.Mockito.*;
@ExtendWith(MockitoExtension.class)
-class GitHubPrCollectorTest {
+class GitHubPullRequestCollectorTest {
- @Mock GitHubPullRequestCollector ingestService;
- @Mock GitHubPrStatsEnrichmentService enrichmentService;
+ @Mock GitHubPullRequestIngestService ingestService;
+ @Mock GitHubPullRequestStatsEnrichmentService enrichmentService;
@InjectMocks
- GitHubPrCollector collector;
+ GitHubPullRequestCollector collector;
private GitHubPullRequestEntity pr(Instant createdAt, StatsStatus status, String repoFullName) {
GitRepositoryEntity repo = new GitRepositoryEntity();
@@ -44,7 +44,7 @@ private GitHubPullRequestEntity pr(Instant createdAt, StatsStatus status, String
@Test
void collectForRepository_emptyIngestResult_returnsZero() {
when(ingestService.collectPullRequests(eq(1L), any()))
- .thenReturn(new GitHubPullRequestCollector.IngestResult(
+ .thenReturn(new GitHubPullRequestIngestService.IngestResult(
new ArrayList<>(), "https://api.github.com", "token"));
int result = collector.collectForRepository(1L, null);
@@ -63,7 +63,7 @@ void collectForRepository_withNewPrs_enrichesAndReturnsCount() {
StatsStatus.PENDING, "owner/repo");
when(ingestService.collectPullRequests(eq(1L), any()))
- .thenReturn(new GitHubPullRequestCollector.IngestResult(
+ .thenReturn(new GitHubPullRequestIngestService.IngestResult(
new ArrayList<>(List.of(p1, p2)), "https://api.github.com", "token"));
int result = collector.collectForRepository(1L, null);
@@ -84,7 +84,7 @@ void collectForRepository_pendingRemainsAfterEnrichment_returnsTotalCount() {
StatsStatus.PENDING, "owner/repo");
when(ingestService.collectPullRequests(eq(2L), any()))
- .thenReturn(new GitHubPullRequestCollector.IngestResult(
+ .thenReturn(new GitHubPullRequestIngestService.IngestResult(
new ArrayList<>(List.of(p)), "https://api.github.com", "token"));
int result = collector.collectForRepository(2L, null);
@@ -106,7 +106,7 @@ void collectForRepository_noRepoFullName_usesNameForEnrichment() {
p.setRepository(repo);
when(ingestService.collectPullRequests(eq(3L), any()))
- .thenReturn(new GitHubPullRequestCollector.IngestResult(
+ .thenReturn(new GitHubPullRequestIngestService.IngestResult(
new ArrayList<>(List.of(p)), "https://api.github.com", "token"));
collector.collectForRepository(3L, null);
diff --git a/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/service/GitHubPullRequestCollectorTest.java b/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/pullrequest/GitHubPullRequestIngestServiceTest.java
similarity index 86%
rename from dev-analytics/src/test/java/com/juliashtal/devanalytics/github/service/GitHubPullRequestCollectorTest.java
rename to dev-analytics/src/test/java/com/juliashtal/devanalytics/github/pullrequest/GitHubPullRequestIngestServiceTest.java
index f9ca512..a400d82 100644
--- a/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/service/GitHubPullRequestCollectorTest.java
+++ b/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/pullrequest/GitHubPullRequestIngestServiceTest.java
@@ -1,4 +1,4 @@
-package com.juliashtal.devanalytics.github.service;
+package com.juliashtal.devanalytics.github.pullrequest;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo;
@@ -9,6 +9,7 @@
import com.juliashtal.devanalytics.git.model.GitRepositoryEntity;
import com.juliashtal.devanalytics.git.model.StatsStatus;
import com.juliashtal.devanalytics.git.repository.GitRepositoryEntityRepository;
+import com.juliashtal.devanalytics.github.client.GitHubClientFactory;
import com.juliashtal.devanalytics.github.model.GitHubPullRequestEntity;
import com.juliashtal.devanalytics.github.repository.GitHubPullRequestRepository;
import org.junit.jupiter.api.BeforeEach;
@@ -16,9 +17,6 @@
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.PageImpl;
-import org.springframework.data.domain.PageRequest;
import java.time.Instant;
import java.util.List;
@@ -33,19 +31,19 @@
@ExtendWith(MockitoExtension.class)
@WireMockTest
-class GitHubPullRequestCollectorTest {
+class GitHubPullRequestIngestServiceTest {
@Mock GitRepositoryEntityRepository repoRepository;
@Mock GitHubPullRequestRepository prRepository;
@Mock GitHubClientFactory clientFactory;
- GitHubPullRequestCollector service;
+ GitHubPullRequestIngestService service;
String wmBaseUrl;
DataSourceConfig cfg;
@BeforeEach
void setUp(WireMockRuntimeInfo wm) {
- service = new GitHubPullRequestCollector(repoRepository, prRepository, clientFactory, new ObjectMapper());
+ service = new GitHubPullRequestIngestService(repoRepository, prRepository, clientFactory, new ObjectMapper());
wmBaseUrl = wm.getHttpBaseUrl();
cfg = new DataSourceConfig();
cfg.setId(1L);
@@ -85,7 +83,7 @@ void collectPullRequests_emptyList_returnsEmptyResult() {
.willReturn(aResponse().withStatus(200).withBody("[]")
.withHeader("Content-Type", "application/json")));
- GitHubPullRequestCollector.IngestResult result = service.collectPullRequests(10L, null);
+ GitHubPullRequestIngestService.IngestResult result = service.collectPullRequests(10L, null);
assertThat(result.savedEntities()).isEmpty();
verify(repoRepository).save(repo);
@@ -112,7 +110,7 @@ void collectPullRequests_newPr_savedAsPendingWithFields() {
.willReturn(aResponse().withStatus(200).withBody(body)
.withHeader("Content-Type", "application/json")));
- GitHubPullRequestCollector.IngestResult result = service.collectPullRequests(10L, null);
+ GitHubPullRequestIngestService.IngestResult result = service.collectPullRequests(10L, null);
assertThat(result.savedEntities()).hasSize(1);
GitHubPullRequestEntity pr = result.savedEntities().get(0);
@@ -146,7 +144,7 @@ void collectPullRequests_mergedPr_calculatesLeadTimeHours() {
.willReturn(aResponse().withStatus(200).withBody(body)
.withHeader("Content-Type", "application/json")));
- GitHubPullRequestCollector.IngestResult result = service.collectPullRequests(10L, null);
+ GitHubPullRequestIngestService.IngestResult result = service.collectPullRequests(10L, null);
GitHubPullRequestEntity pr = result.savedEntities().get(0);
assertThat(pr.getLeadTimeHours()).isEqualTo(48L);
@@ -178,7 +176,7 @@ void collectPullRequests_unchangedPr_skipsAndDoesNotSave() {
.willReturn(aResponse().withStatus(200).withBody(body)
.withHeader("Content-Type", "application/json")));
- GitHubPullRequestCollector.IngestResult result = service.collectPullRequests(10L, null);
+ GitHubPullRequestIngestService.IngestResult result = service.collectPullRequests(10L, null);
assertThat(result.savedEntities()).isEmpty();
verify(prRepository, never()).saveAll(any());
@@ -213,7 +211,7 @@ void collectPullRequests_updatedOpenPr_resetsStatsToPending() {
.willReturn(aResponse().withStatus(200).withBody(body)
.withHeader("Content-Type", "application/json")));
- GitHubPullRequestCollector.IngestResult result = service.collectPullRequests(10L, null);
+ GitHubPullRequestIngestService.IngestResult result = service.collectPullRequests(10L, null);
assertThat(result.savedEntities()).hasSize(1);
GitHubPullRequestEntity pr = result.savedEntities().get(0);
@@ -250,7 +248,7 @@ void collectPullRequests_updatedMergedCompletePr_preservesStats() {
.willReturn(aResponse().withStatus(200).withBody(body)
.withHeader("Content-Type", "application/json")));
- GitHubPullRequestCollector.IngestResult result = service.collectPullRequests(10L, null);
+ GitHubPullRequestIngestService.IngestResult result = service.collectPullRequests(10L, null);
assertThat(result.savedEntities()).hasSize(1);
GitHubPullRequestEntity pr = result.savedEntities().get(0);
@@ -332,39 +330,8 @@ void collectPullRequests_multiplePages_collectsAllPrs() {
.willReturn(aResponse().withStatus(200).withBody(page2)
.withHeader("Content-Type", "application/json")));
- GitHubPullRequestCollector.IngestResult result = service.collectPullRequests(10L, null);
+ GitHubPullRequestIngestService.IngestResult result = service.collectPullRequests(10L, null);
assertThat(result.savedEntities()).hasSize(2);
}
-
- // ── listPullRequests: delegates to repository ───────────────────────────
-
- @Test
- void listPullRequests_repoFound_returnsPage() {
- GitRepositoryEntity repo = repo();
- when(repoRepository.findById(10L)).thenReturn(Optional.of(repo));
-
- GitHubPullRequestEntity pr = new GitHubPullRequestEntity();
- pr.setNumber(1);
- Page page =
- new PageImpl<>(List.of(pr), PageRequest.of(0, 20), 1);
- when(prRepository.findByRepositoryOrderByCreatedAtDesc(repo, PageRequest.of(0, 20)))
- .thenReturn(page);
-
- Page result =
- service.listPullRequests(10L, PageRequest.of(0, 20));
-
- assertThat(result.getContent()).hasSize(1);
- assertThat(result.getContent().get(0).getNumber()).isEqualTo(1);
- }
-
- // ── listPullRequests: repo not found ────────────────────────────────────
-
- @Test
- void listPullRequests_repoNotFound_throwsNoSuchElement() {
- when(repoRepository.findById(99L)).thenReturn(Optional.empty());
-
- assertThatThrownBy(() -> service.listPullRequests(99L, PageRequest.of(0, 20)))
- .isInstanceOf(NoSuchElementException.class);
- }
}
diff --git a/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/pullrequest/GitHubPullRequestQueryServiceTest.java b/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/pullrequest/GitHubPullRequestQueryServiceTest.java
new file mode 100644
index 0000000..211a241
--- /dev/null
+++ b/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/pullrequest/GitHubPullRequestQueryServiceTest.java
@@ -0,0 +1,74 @@
+package com.juliashtal.devanalytics.github.pullrequest;
+
+import com.juliashtal.devanalytics.git.model.GitRepositoryEntity;
+import com.juliashtal.devanalytics.git.repository.GitRepositoryEntityRepository;
+import com.juliashtal.devanalytics.github.model.GitHubPullRequestEntity;
+import com.juliashtal.devanalytics.github.repository.GitHubPullRequestRepository;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageImpl;
+import org.springframework.data.domain.PageRequest;
+
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.Optional;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.mockito.Mockito.when;
+
+/**
+ * Pins the read side: a known repository returns its stored pull requests newest-first,
+ * and an unknown one is rejected rather than returning an empty page.
+ */
+@ExtendWith(MockitoExtension.class)
+class GitHubPullRequestQueryServiceTest {
+
+ @Mock GitRepositoryEntityRepository repoRepository;
+ @Mock GitHubPullRequestRepository prRepository;
+
+ GitHubPullRequestQueryService service;
+
+ @BeforeEach
+ void setUp() {
+ service = new GitHubPullRequestQueryService(repoRepository, prRepository);
+ }
+
+ /** Only identity matters here — the query path reads no other field. */
+ private GitRepositoryEntity repo() {
+ GitRepositoryEntity r = new GitRepositoryEntity();
+ r.setId(10L);
+ return r;
+ }
+
+ @Test
+ void listPullRequests_repoFound_returnsPage() {
+ GitRepositoryEntity repo = repo();
+ when(repoRepository.findById(10L)).thenReturn(Optional.of(repo));
+
+ GitHubPullRequestEntity pr = new GitHubPullRequestEntity();
+ pr.setNumber(1);
+ Page page =
+ new PageImpl<>(List.of(pr), PageRequest.of(0, 20), 1);
+ when(prRepository.findByRepositoryOrderByCreatedAtDesc(repo, PageRequest.of(0, 20)))
+ .thenReturn(page);
+
+ Page result =
+ service.listPullRequests(10L, PageRequest.of(0, 20));
+
+ assertThat(result.getContent()).hasSize(1);
+ assertThat(result.getContent().get(0).getNumber()).isEqualTo(1);
+ }
+
+ @Test
+ void listPullRequests_repoNotFound_throwsNoSuchElement() {
+ when(repoRepository.findById(99L)).thenReturn(Optional.empty());
+
+ assertThatThrownBy(() -> service.listPullRequests(99L, PageRequest.of(0, 20)))
+ .isInstanceOf(NoSuchElementException.class);
+ }
+}
diff --git a/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/service/GitHubPrStatsEnrichmentServiceTest.java b/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/pullrequest/GitHubPullRequestStatsEnrichmentServiceTest.java
similarity index 98%
rename from dev-analytics/src/test/java/com/juliashtal/devanalytics/github/service/GitHubPrStatsEnrichmentServiceTest.java
rename to dev-analytics/src/test/java/com/juliashtal/devanalytics/github/pullrequest/GitHubPullRequestStatsEnrichmentServiceTest.java
index 45089ba..e26f2d9 100644
--- a/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/service/GitHubPrStatsEnrichmentServiceTest.java
+++ b/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/pullrequest/GitHubPullRequestStatsEnrichmentServiceTest.java
@@ -1,4 +1,4 @@
-package com.juliashtal.devanalytics.github.service;
+package com.juliashtal.devanalytics.github.pullrequest;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo;
@@ -27,19 +27,19 @@
@ExtendWith(MockitoExtension.class)
@WireMockTest
-class GitHubPrStatsEnrichmentServiceTest {
+class GitHubPullRequestStatsEnrichmentServiceTest {
@Mock GitHubPullRequestRepository prRepository;
@Mock GitHubPrReviewRepository reviewRepository;
- GitHubPrStatsEnrichmentService service;
+ GitHubPullRequestStatsEnrichmentService service;
String wmBaseUrl;
private static final String REPO_NAME = "owner/test-repo";
@BeforeEach
void setUp(WireMockRuntimeInfo wm) {
- service = new GitHubPrStatsEnrichmentService(prRepository, reviewRepository, new ObjectMapper());
+ service = new GitHubPullRequestStatsEnrichmentService(prRepository, reviewRepository, new ObjectMapper());
wmBaseUrl = wm.getHttpBaseUrl();
}
diff --git a/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/GitHubRepoDiscoveryTest.java b/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/repo/GitHubRepoDiscoveryTest.java
similarity index 97%
rename from dev-analytics/src/test/java/com/juliashtal/devanalytics/github/GitHubRepoDiscoveryTest.java
rename to dev-analytics/src/test/java/com/juliashtal/devanalytics/github/repo/GitHubRepoDiscoveryTest.java
index 3ae0853..c9c8910 100644
--- a/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/GitHubRepoDiscoveryTest.java
+++ b/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/repo/GitHubRepoDiscoveryTest.java
@@ -1,4 +1,4 @@
-package com.juliashtal.devanalytics.github;
+package com.juliashtal.devanalytics.github.repo;
import com.juliashtal.devanalytics.datasource.model.DataSourceConfig;
import com.juliashtal.devanalytics.datasource.model.DataSourceType;
@@ -11,8 +11,8 @@
import com.juliashtal.devanalytics.git.repository.UserRepoRegistrationRepository;
import com.juliashtal.devanalytics.github.model.dto.DiscoveredRepoDto;
import com.juliashtal.devanalytics.github.model.dto.DiscoveryResult;
-import com.juliashtal.devanalytics.github.service.GitHubClientFactory;
-import com.juliashtal.devanalytics.github.service.GitHubRepositoryService;
+import com.juliashtal.devanalytics.github.client.GitHubClientFactory;
+import com.juliashtal.devanalytics.github.repo.GitHubRepositoryService;
import com.juliashtal.devanalytics.user.model.User;
import com.juliashtal.devanalytics.user.repository.UserRepository;
import org.junit.jupiter.api.BeforeEach;
diff --git a/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/GitHubRepositoryServiceRegisterTest.java b/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/repo/GitHubRepositoryServiceRegisterTest.java
similarity index 97%
rename from dev-analytics/src/test/java/com/juliashtal/devanalytics/github/GitHubRepositoryServiceRegisterTest.java
rename to dev-analytics/src/test/java/com/juliashtal/devanalytics/github/repo/GitHubRepositoryServiceRegisterTest.java
index 4fd43e1..62b9dd4 100644
--- a/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/GitHubRepositoryServiceRegisterTest.java
+++ b/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/repo/GitHubRepositoryServiceRegisterTest.java
@@ -1,4 +1,4 @@
-package com.juliashtal.devanalytics.github;
+package com.juliashtal.devanalytics.github.repo;
import com.juliashtal.devanalytics.datasource.model.DataSourceConfig;
import com.juliashtal.devanalytics.datasource.model.DataSourceType;
@@ -8,8 +8,8 @@
import com.juliashtal.devanalytics.git.model.UserRepoRegistration;
import com.juliashtal.devanalytics.git.repository.GitRepositoryEntityRepository;
import com.juliashtal.devanalytics.git.repository.UserRepoRegistrationRepository;
-import com.juliashtal.devanalytics.github.service.GitHubClientFactory;
-import com.juliashtal.devanalytics.github.service.GitHubRepositoryService;
+import com.juliashtal.devanalytics.github.client.GitHubClientFactory;
+import com.juliashtal.devanalytics.github.repo.GitHubRepositoryService;
import com.juliashtal.devanalytics.user.model.User;
import com.juliashtal.devanalytics.user.repository.UserRepository;
import org.junit.jupiter.api.BeforeEach;
diff --git a/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/service/StatsEnrichmentSchedulerTest.java b/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/scheduler/StatsEnrichmentSchedulerTest.java
similarity index 95%
rename from dev-analytics/src/test/java/com/juliashtal/devanalytics/github/service/StatsEnrichmentSchedulerTest.java
rename to dev-analytics/src/test/java/com/juliashtal/devanalytics/github/scheduler/StatsEnrichmentSchedulerTest.java
index ad40897..9db4698 100644
--- a/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/service/StatsEnrichmentSchedulerTest.java
+++ b/dev-analytics/src/test/java/com/juliashtal/devanalytics/github/scheduler/StatsEnrichmentSchedulerTest.java
@@ -1,4 +1,4 @@
-package com.juliashtal.devanalytics.github.service;
+package com.juliashtal.devanalytics.github.scheduler;
import com.juliashtal.devanalytics.datasource.model.DataSourceConfig;
import com.juliashtal.devanalytics.git.model.GitRepositoryEntity;
@@ -6,6 +6,9 @@
import com.juliashtal.devanalytics.git.model.StatsStatus;
import com.juliashtal.devanalytics.git.repository.GitCommitEntityRepository;
import com.juliashtal.devanalytics.git.repository.GitRepositoryEntityRepository;
+import com.juliashtal.devanalytics.github.client.GitHubClientFactory;
+import com.juliashtal.devanalytics.github.commit.GitHubCommitStatsEnrichmentService;
+import com.juliashtal.devanalytics.github.pullrequest.GitHubPullRequestStatsEnrichmentService;
import com.juliashtal.devanalytics.github.repository.GitHubPullRequestRepository;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@@ -27,7 +30,7 @@ class StatsEnrichmentSchedulerTest {
@Mock GitHubPullRequestRepository prRepository;
@Mock GitRepositoryEntityRepository repoRepository;
@Mock GitHubCommitStatsEnrichmentService commitEnrichmentService;
- @Mock GitHubPrStatsEnrichmentService prEnrichmentService;
+ @Mock GitHubPullRequestStatsEnrichmentService prEnrichmentService;
@Mock GitHubClientFactory clientFactory;
@InjectMocks
diff --git a/dev-analytics/src/test/java/com/juliashtal/devanalytics/user/AuthorIdentityServiceTest.java b/dev-analytics/src/test/java/com/juliashtal/devanalytics/user/AuthorIdentityServiceTest.java
index 79a0afc..a617381 100644
--- a/dev-analytics/src/test/java/com/juliashtal/devanalytics/user/AuthorIdentityServiceTest.java
+++ b/dev-analytics/src/test/java/com/juliashtal/devanalytics/user/AuthorIdentityServiceTest.java
@@ -3,7 +3,7 @@
import com.juliashtal.devanalytics.exception.BadRequestException;
import com.juliashtal.devanalytics.exception.ConflictException;
import com.juliashtal.devanalytics.exception.UnprocessableEntityException;
-import com.juliashtal.devanalytics.github.service.GitHubAccountLookup;
+import com.juliashtal.devanalytics.github.identity.GitHubAccountLookup;
import com.juliashtal.devanalytics.user.model.AuthorIdentityChangedEvent;
import com.juliashtal.devanalytics.user.model.User;
import com.juliashtal.devanalytics.user.model.UserCommitEmail;