Skip to content

feat(backend): Clean Architecture, migrations, and label taxonomy#8

Merged
GRACENOBLE merged 6 commits into
mainfrom
backend-setup
Jun 14, 2026
Merged

feat(backend): Clean Architecture, migrations, and label taxonomy#8
GRACENOBLE merged 6 commits into
mainfrom
backend-setup

Conversation

@GRACENOBLE

@GRACENOBLE GRACENOBLE commented Jun 14, 2026

Copy link
Copy Markdown
Owner

Summary

  • Refactors backend from a flat database/server monolith to Clean Architecture: domainusecaserepository/postgres + handlerserver
  • Adds goose v3 schema migrations with a cmd/migrate entry point and full set of make migrate-* targets
  • Replaces GitHub default labels with a structured area/type/priority/needs taxonomy and updates the labeler to match
  • Updates CLAUDE.md and backend docs so agents follow the migration-first workflow for any feature that touches the DB

What changed

Architecture

  • internal/domain/HealthStats typed struct (was map[string]string)
  • internal/usecase/HealthReader interface + HealthUseCase with connection pool message thresholds
  • internal/repository/postgres/ — raw DB adapter; business logic moved to use case
  • internal/handler/Handler struct wired on use case interfaces; HealthHandler exported
  • internal/server/server.go — composition root only; NewServer() returns error
  • Deleted internal/database/ and internal/server/routes.go

Migrations

  • cmd/migrate/main.go — goose wrapper; create runs without DB, all other commands use postgres.NewPostgresDB
  • migrations/20260614201325_init.sql — starter users table migration
  • make migrate-create name=<slug> always produces .sql files; Go migrations intentionally unsupported via go run

CI / Labels

  • .github/labeler.yml — area labels renamed to area: backend, area: web, area: mobile, area: infra; dependency changes now auto-apply type: chore
  • 18 labels created in repo (area:, type:, priority:, needs:, meta)

Docs & agents

  • backend/docs/migrations.md — full goose workflow, format rules, Testcontainers isolation note, hard rules
  • backend/docs/_index.md — migrations added to topic index
  • CLAUDE.md — migration commands, cmd/migrate + migrations/ in layout, Migrations conventions section, migration step in feature workflow

Test plan

  • go vet ./... passes
  • make test passes (handler unit tests)
  • make itest passes against Testcontainers Postgres (requires Docker)
  • make migrate-status shows pending/applied state
  • make migrate-create name=test_table creates a .sql file without Docker running
  • make migrate-up applies the init migration; make migrate-down rolls it back
  • GET /{"message":"Hello World"} 200
  • GET /health → typed JSON stats 200 (503 when DB is down)

Summary by CodeRabbit

  • New Features

    • Added database migration infrastructure with Goose v3 support.
    • Introduced users table to the database schema.
  • Documentation

    • Added comprehensive migration workflow and conventions guide.
  • Chores

    • Updated dependencies including migration management tooling.
    • Enhanced GitHub automation configuration for improved label handling.

GRACENOBLE and others added 5 commits June 14, 2026 23:01
Replaces bare labels (backend, web, mobile, ci) and GitHub defaults
with the area/type/priority/needs taxonomy. Dependency file changes
now auto-apply type: chore instead of the removed dependencies label.
Adds github.com/pressly/goose/v3 and a cmd/migrate entry point that
reuses the existing postgres.NewPostgresDB connection and reads the
same BLUEPRINT_DB_* env vars as the server.

Makefile targets added:
  migrate-up         apply all pending migrations
  migrate-up-one     apply the next migration only
  migrate-down       roll back the last migration
  migrate-down-to    roll back to a specific version (version=N)
  migrate-reset      roll back all migrations to 0
  migrate-status     print applied/pending state
  migrate-version    print current schema version
  migrate-create     create a new SQL migration (name=<slug>)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- backend/docs/migrations.md — full goose workflow: make targets,
  SQL format rules, new-table checklist, Go migrations exclusion,
  Testcontainers/migration isolation explanation, hard rules
- backend/docs/_index.md — add migrations.md to the topic index
- CLAUDE.md — migration commands block, cmd/migrate + migrations/
  in project layout, Migrations section in Go conventions,
  migration step added to the feature development workflow,
  docs list updated to include migrations topic

Agents reading CLAUDE.md will now know to create a migration
whenever a feature introduces new tables.
- migrate-create no longer passes 'sql' as a CLI arg; type is hardcoded
  in Go so the Makefile stays clean and the arg can't be misinterpreted
- create command runs before DB connection (filesystem-only op), so
  make migrate-create works without Docker running
- Removed bash-specific 'test' guard; Go logs a clear fatal when name
  is absent, which works on all platforms
- Adds 20260614201325_init.sql (users table) as the starter migration,
  validated end-to-end with migrate-up / migrate-down
@coderabbitai

coderabbitai Bot commented Jun 14, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@GRACENOBLE, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 50 minutes and 19 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more credits in the billing tab to continue.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c92cfcda-32d1-4008-9983-0cd917039281

📥 Commits

Reviewing files that changed from the base of the PR and between 518270e and 65679e9.

📒 Files selected for processing (1)
  • backend/migrations/20260614201325_init.sql
📝 Walkthrough

Walkthrough

Introduces a goose v3-based database migration system for the backend: a new cmd/migrate/main.go CLI reads Postgres credentials from environment variables and dispatches goose commands; eight migrate-* Makefile targets wrap the CLI; an initial SQL migration creates the users table; and CLAUDE.md plus backend/docs/migrations.md document the conventions. Separately, .github/labeler.yml is restructured with area:-prefixed label keys and explicit dependency file globs.

Changes

Backend goose migration system

Layer / File(s) Summary
goose dependency and migration CLI
backend/go.mod, backend/cmd/migrate/main.go
Adds github.com/pressly/goose/v3 v3.27.1 to go.mod (plus indirect dep bumps) and implements the main.go CLI that sets the Postgres dialect, special-cases create to skip DB connection, otherwise opens a DB from BLUEPRINT_DB_* env vars and runs goose.RunContext.
Makefile targets and initial SQL migration
backend/Makefile, backend/migrations/20260614201325_init.sql
Adds eight migrate-* Makefile targets invoking go run ./cmd/migrate, and introduces the first migration that creates a users table (BIGSERIAL PK, TIMESTAMPTZ timestamps) with a rollback DROP TABLE.
Migration docs and CLAUDE.md conventions
CLAUDE.md, backend/docs/migrations.md, backend/docs/_index.md
Creates backend/docs/migrations.md covering tool, file naming, Makefile targets, SQL structure, hard rules, and test behavior; registers it in the docs index; updates CLAUDE.md with the migration step and goose conventions.

CI Labeler Update

Layer / File(s) Summary
Labeler rule restructure
.github/labeler.yml
Renames label keys to area: prefixes, replaces ci with area: infra for .github/**, adds type: chore, removes documentation, and populates dependencies with globs for Go, npm/pnpm, and Gradle files.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~15 minutes

Poem

🐇 Hop, hop — the database waits!
With goose in tow I'll open the gates,
migrate-up and the users arrive,
BIGSERIAL IDs help tables survive.
No DDL in Go — that's the rule!
A tidy migration is every rabbit's tool. 🗃️

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the main change: introducing Clean Architecture, database migrations, and label taxonomy updates to the backend.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch backend-setup

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.github/labeler.yml (1)

28-30: ⚠️ Potential issue | 🟡 Minor

Add missing mobile/settings.gradle.kts to the labeler patterns.

The current patterns miss mobile/settings.gradle.kts, which defines the module structure and can contain dependency-related configuration changes. Additionally, consider using glob patterns like mobile/**/*.gradle.kts to simplify maintenance and prepare for potential multi-module expansion.

Suggested fix
 "type: chore":
   - changed-files:
     - any-glob-to-any-file:
       - "backend/go.mod"
       - "backend/go.sum"
       - "web/package.json"
       - "web/pnpm-lock.yaml"
-      - "mobile/gradle/libs.versions.toml"
-      - "mobile/build.gradle.kts"
-      - "mobile/app/build.gradle.kts"
+      - "mobile/gradle/libs.versions.toml"
+      - "mobile/**/*.gradle.kts"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/labeler.yml around lines 28 - 30, The labeler.yml file is missing
the mobile/settings.gradle.kts pattern in the gradle-related file labels
section. Add "mobile/settings.gradle.kts" to the patterns list alongside the
existing entries (mobile/gradle/libs.versions.toml, mobile/build.gradle.kts, and
mobile/app/build.gradle.kts). To improve maintainability and prepare for
multi-module expansion, consider consolidating these individual patterns into a
single glob pattern mobile/**/*.gradle.kts that will automatically catch all
gradle files in the mobile directory and subdirectories.
🧹 Nitpick comments (1)
backend/docs/migrations.md (1)

19-29: 💤 Low value

Add blank line before table per Markdown formatting rules.

The table starting at line 20 should be surrounded by blank lines. Add a blank line between the heading and the table.

✏️ Proposed formatting fix
 ## Makefile targets
+
 | Target | What it does |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/docs/migrations.md` around lines 19 - 29, Add a blank line between
the heading "## Makefile targets" and the table that begins with "| Target |
What it does |". This follows standard Markdown formatting rules which require
blank lines to separate headings from content blocks like tables.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@backend/migrations/20260614201325_init.sql`:
- Around line 1-9: The CREATE TABLE IF NOT EXISTS users statement is missing a
name column that downstream code expects when executing queries like SELECT id,
name FROM users. Add a name column to the users table definition in the
migration, choosing an appropriate type such as VARCHAR or TEXT with a NOT NULL
constraint. Verify the column definition matches the expected schema used by
downstream queries in backend/docs/database.md and the repository layer.

---

Outside diff comments:
In @.github/labeler.yml:
- Around line 28-30: The labeler.yml file is missing the
mobile/settings.gradle.kts pattern in the gradle-related file labels section.
Add "mobile/settings.gradle.kts" to the patterns list alongside the existing
entries (mobile/gradle/libs.versions.toml, mobile/build.gradle.kts, and
mobile/app/build.gradle.kts). To improve maintainability and prepare for
multi-module expansion, consider consolidating these individual patterns into a
single glob pattern mobile/**/*.gradle.kts that will automatically catch all
gradle files in the mobile directory and subdirectories.

---

Nitpick comments:
In `@backend/docs/migrations.md`:
- Around line 19-29: Add a blank line between the heading "## Makefile targets"
and the table that begins with "| Target | What it does |". This follows
standard Markdown formatting rules which require blank lines to separate
headings from content blocks like tables.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ecbe142f-f060-4729-bd19-b9c7c4124190

📥 Commits

Reviewing files that changed from the base of the PR and between 381ef15 and 518270e.

⛔ Files ignored due to path filters (1)
  • backend/go.sum is excluded by !**/*.sum
📒 Files selected for processing (9)
  • .github/labeler.yml
  • CLAUDE.md
  • backend/Makefile
  • backend/cmd/migrate/main.go
  • backend/docs/_index.md
  • backend/docs/migrations.md
  • backend/go.mod
  • backend/migrations/.gitkeep
  • backend/migrations/20260614201325_init.sql

Comment thread backend/migrations/20260614201325_init.sql
Resolves schema mismatch flagged in PR review — database.md example
queries SELECT id, name FROM users but the table had no name column.
@GRACENOBLE GRACENOBLE merged commit 5a033f6 into main Jun 14, 2026
2 checks passed
@GRACENOBLE GRACENOBLE deleted the backend-setup branch June 14, 2026 20:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant