Skip to content

Refactor: extract service layers from API routes + consistent UI#12

Merged
msogin merged 22 commits into
mainfrom
refactor-api-layers
Mar 20, 2026
Merged

Refactor: extract service layers from API routes + consistent UI#12
msogin merged 22 commits into
mainfrom
refactor-api-layers

Conversation

@PavelLoparev

@PavelLoparev PavelLoparev commented Mar 20, 2026

Copy link
Copy Markdown
Contributor

The most important change

New app icon:

image

Just kidding. But it does look good.

Summary

  • Extract service layers from all API route handlers into src/lib/ modules — separates business logic from HTTP concerns
  • Add comprehensive unit tests for all extracted services (~1,700 lines of new test coverage)
  • Add shared timeline aggregation helper (src/lib/report/timeline.ts) to DRY up repeated date-bucketing logic
  • Consolidate schedule module — move schedule-manager.ts and schedule-validation.ts into src/lib/schedule/
  • Fix icon conflict — remove duplicate public/icon.svg that caused a Next.js 500 error, replace with hexagonal gem design

Modules extracted

Module Path
Teams src/lib/teams/
Developers src/lib/developers/
Orgs src/lib/orgs/
LLM Config src/lib/llm-config/
Report CRUD/lifecycle src/lib/report/service.ts
Report org/dev/summary/commits src/lib/report/*.ts
Report highlights src/lib/report-highlights/
Schedule src/lib/schedule/

Consistent delete entity confirmation UI (the same as on report delete dialog)

image image

Test plan

  • All existing tests pass
  • New unit tests added for every extracted service
  • Verify API routes return identical responses before/after
  • Smoke test dev server (npm run dev)

🤖 Generated with Claude Code

PavelLoparev and others added 21 commits March 20, 2026 21:04
…/schedule/

Move schedule-manager.ts and schedule-validation.ts into src/lib/schedule/,
extract business logic from API controllers into a new service.ts, and slim
controllers down to thin HTTP adapters (matching the chat/ folder pattern).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move business logic from teams API controllers into a new service module,
matching the schedule/ folder pattern. Adds 404 check for team updates
and typed errors (TeamNotFoundError, TeamDuplicateError).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Tests cover DB dedup (keeps first/latest row per login), case-insensitive
query filtering by login and github_name, limit truncation, and GitHub
source path (member mapping, query filtering, 20-result cap).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move DB query, dedup, filtering, and GitHub member lookup out of the API
controller into listDevelopers() and listDevelopersFromGitHub() service
functions. Controller is now a thin adapter. Barrel export via index.ts.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
18 tests covering listReports, createReport, getReport, deleteReport,
getReportProgress, stopReport, and resumeReport — including typed error
cases (ReportNotFoundError, ReportNotRunningError, ReportAlreadyCompletedError).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Creates src/lib/report/service.ts with typed errors (ReportNotFoundError,
ReportNotRunningError, ReportAlreadyCompletedError) and all business logic
extracted from 5 controller files. Controllers are now thin adapters that
parse params, call service functions, and map typed errors to HTTP status codes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Tests for dedupCommitsBySha and aggregateWeekly covering deduplication,
Monday-aligned weekly grouping, complexity averaging, AI percent
calculation, dev tracking, type grouping, and null date skipping.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Extracts dedupCommitsBySha and aggregateWeekly into src/lib/report/timeline.ts
to eliminate duplicated weekly bucketing logic across report controllers.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Tests for getReportCommits and getOrgReport covering happy paths,
ReportNotFoundError, JSON column parsing, trackDevs timeline, and SHA dedup.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Extract business logic from commits and org route controllers into
src/lib/report/commits.ts and src/lib/report/org.ts, using the shared
dedupCommitsBySha/aggregateWeekly helpers from timeline.ts. Controllers
become thin adapters.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add unit tests for getDevReport and getDevSummary covering happy paths,
error cases (ReportNotFoundError, DeveloperNotFoundError), JSON column
parsing, timeline shape (no activeDevs), dedup, caching, and LLM call.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Extract business logic from the 157-line dev controller into
src/lib/report/dev.ts (getDevReport, DeveloperNotFoundError) and from
the 192-line summary controller into src/lib/report/summary.ts
(getDevSummary). Slim both controllers down to error-dispatch wrappers.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace dog mascot icon with hexagonal crystal design. Remove duplicate
icon from public/ that caused a Next.js conflicting file error (500).
Drop redundant icons metadata from layout since Next.js auto-discovers
app/icon.svg.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@PavelLoparev PavelLoparev requested a review from msogin March 20, 2026 20:12
Use consistent red overlay confirmation UI for schedule and team
deletion, matching the existing report deletion pattern.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@PavelLoparev PavelLoparev changed the title Refactor: extract service layers from API routes Refactor: extract service layers from API routes + consistent UI Mar 20, 2026
@msogin msogin merged commit 9a985f1 into main Mar 20, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants