Skip to content

Reorganize code into packages#50

Merged
jlpdeveloper merged 14 commits into
mainfrom
refactor-organization
May 7, 2026
Merged

Reorganize code into packages#50
jlpdeveloper merged 14 commits into
mainfrom
refactor-organization

Conversation

@jlpdeveloper
Copy link
Copy Markdown
Contributor

@jlpdeveloper jlpdeveloper commented May 7, 2026

Description

  • moved alot of code around

Code Rabbit Summary

Summary by CodeRabbit

  • Refactor
    • Restructured internal handler architecture for platforms and products to improve code organization and maintainability.

Note: This release contains internal infrastructure improvements with no changes to user-facing functionality or API behavior.

Fixes

Closes #49

Post Deployment Tasks?

- Consolidate and migrate API handlers for `platform` and `product` into their respective internal packages for improved modularity.
- Replace `db` references with query-specific instances and interfaces.
- Update imports, tests, and routes to reflect refactored handler structure.
- Regenerate SQLC files and adjust configurations for modular placement.
…ndlers to use interfaces, and update SQLC configuration for interface output.
… file for improved modularity in `product` package.
…st structs into dedicated files, implement `ToParams` methods, and add unit tests to improve modularity and test coverage.
… file for improved modularity in `platform` package.
@jlpdeveloper jlpdeveloper added this to the Phase 2: API Endpoints milestone May 7, 2026
@jlpdeveloper jlpdeveloper self-assigned this May 7, 2026
@jlpdeveloper jlpdeveloper added the chore refactor, maintenance, etc. label May 7, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 7, 2026

Warning

Rate limit exceeded

@jlpdeveloper has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 33 minutes and 8 seconds before requesting another review.

To continue reviewing without waiting, purchase usage credits in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, 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 have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: d21ae81c-5a9f-4ef3-9f19-1307b54bd78a

📥 Commits

Reviewing files that changed from the base of the PR and between 8e137f4 and 5214876.

📒 Files selected for processing (5)
  • internal/platform/handler.go
  • internal/platform/handler_test.go
  • internal/platform/request_test.go
  • internal/product/handler.go
  • internal/product/handler_test.go
📝 Walkthrough

Walkthrough

This PR restructures the project from a horizontal layer-separated architecture (with HTTP handlers in api/<domain> and database code in internal/db/<domain>) to a vertical domain-package architecture. HTTP handlers, request DTOs, and interfaces are now colocated within internal/<domain> packages. Handlers directly instantiate sqlc-generated Queries from DBTX, and the central Store abstraction is removed.

Changes

Vertical Domain Package Reorganization

Layer / File(s) Summary
Interface & Type Definitions
internal/platform/interface.go, internal/product/interface.go, internal/platform/request.go, internal/product/request.go
Handler interfaces defining CRUD method signatures for each domain, and request DTOs (createPlatformRequest, updatePlatformRequest, createProductRequest, updateProductRequest) with ToParams() methods that map JSON fields into sqlc parameter structs and normalize timestamps.
HTTP Handler Implementation
internal/platform/handler.go, internal/product/handler.go
Handlers now live inside domain packages; each constructor (NewPlatformHandler, NewProductHandler) accepts DBTX and internally instantiates sqlc Queries, then returns a handler implementing the domain's interface. Methods decode requests, validate fields, apply timeouts, call queries, and map errors to HTTP status codes.
Handler Construction & Router Wiring
router/router.go, main.go
Router registration functions now accept domain Handler interfaces instead of querier types, and are called with platform.NewPlatformHandler(dbConn) and product.NewProductHandler(dbConn) directly. getDbConn return type changed from abstract db.DBTX to concrete *pgxpool.Pool with deferred close.
Removed Abstractions
api/platform/*, api/product/*, internal/db/store.go
Entire api/<domain> layer deleted (create/delete/get/update handlers and handler constructors). Central Store struct and New constructor removed from internal/db/store.go; the file now contains only the DBTX interface.
Code Generation Configuration
sqlc.yml
Query and model output paths updated from internal/db/<domain>/ to internal/<domain>/, and generated file names switched to .gen.go suffix (models.gen.go, db.gen.go, querier.gen.go).
Tests & Validation
internal/platform/handler_test.go, internal/platform/request_test.go, internal/product/handler_test.go, internal/product/request_test.go
Handler tests updated to construct handlers via direct struct initialization (&platformHandler{queries: mDB}) instead of constructors, and to use handler-layer request/response types. Request DTO tests validate field mapping and timestamp generation.

Sequence Diagram(s)

No sequence diagrams generated. While this PR involves multiple components (router, handlers, database), the changes are primarily architectural reorganization and refactoring rather than functional flow modifications. The control flow for request handling remains unchanged; only the package structure and handler instantiation pattern have been altered.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • service-atlas/products#43: Modifies product create flow and adapts CreateProduct params, directly related to handler and request DTO changes in this PR.
  • service-atlas/products#42: Touches db/sqlc package splits, querier types, router wiring, and handler constructors including changes to internal/db/store.go and handler setup.
  • service-atlas/products#17: Modifies platform HTTP handler creation flow, DB querier interfaces, router wiring, and main DB connection setup.

Suggested labels

skip-changelog


🐰 Whiskers twitching with glee,
Domains now stand tall and free,
No more scattered by the layered sea,
Each package complete—structured vertically!

🚥 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 'Reorganize code into packages' directly reflects the main change: restructuring the project from layer-oriented to vertical domain packages under internal/.
Linked Issues check ✅ Passed The PR implements all key requirements from issue #49: vertical domain packages (internal/platform, internal/product), handler constructors with internal DBTX wiring (NewPlatformHandler, NewProductHandler), removal of Store struct, router composition using domain handlers, and param helper functions (ToParams methods in request.go files).
Out of Scope Changes check ✅ Passed All changes are directly aligned with issue #49 objectives: domain package restructuring, handler interfaces, request/response types, and sqlc configuration updates to support the new layout. No unrelated modifications detected.

✏️ 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 refactor-organization

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.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

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

⚠️ Outside diff range comments (2)
internal/platform/handler_test.go (1)

371-375: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

TestUpdatePlatform uses the wrong request body type for handler decoding.

UpdatePlatform decodes into updatePlatformRequest where Description is a string, but tests send Platform where Description is pgtype.Text. When pgtype.Text is JSON-marshaled, it becomes an object shape, causing the JSON decoder to fail. This prevents the success path from being properly tested.

Suggested fix
-			requestBody: Platform{
+			requestBody: updatePlatformRequest{
 				ID:          1,
 				Name:        "Updated Platform",
-				Description: pgtype.Text{String: "Updated Description", Valid: true},
+				Description: "Updated Description",
 			},

Also update the mock assertion:

-						expectedBody := tt.requestBody.(Platform)
+						expectedBody := tt.requestBody.(updatePlatformRequest)
 						if arg.ID != expectedBody.ID {
 							t.Errorf("expected ID %d, got %d", expectedBody.ID, arg.ID)
 						}
 						if arg.Name != expectedBody.Name {
 							t.Errorf("expected Name %s, got %s", expectedBody.Name, arg.Name)
 						}
-						if arg.Description.String != expectedBody.Description.String {
-							t.Errorf("expected Description %s, got %s", expectedBody.Description.String, arg.Description.String)
+						if arg.Description.String != expectedBody.Description {
+							t.Errorf("expected Description %s, got %s", expectedBody.Description, arg.Description.String)
 						}

Applies to lines: 371-375, 382-385, 392-395, 402-405, 412-415, 422-425, 432-435, 449-452, 459-462, 474-483

🤖 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 `@internal/platform/handler_test.go` around lines 371 - 375, TestUpdatePlatform
is sending a Platform value (with Description as pgtype.Text) but the handler
decodes into updatePlatformRequest where Description is a string, causing JSON
decoding failures; change the test requestBody to use updatePlatformRequest (or
a struct literal matching updatePlatformRequest) with Description as a plain
string ("Updated Description") and update all related test cases (the
requestBody entries at the referenced locations) so the mock
expectation/assertions match the string description type (adjust the mock call
args to expect the string description instead of pgtype.Text) to exercise the
success path correctly.
internal/product/handler_test.go (1)

89-105: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add a whitespace-only Name case for CreateProduct.

Current create tests don’t cover " " input, so the invalid-name path at Line 34 in handler logic is not protected by tests.

Suggested test case
@@
 		{
 			name: "Missing Name",
 			requestBody: createProductRequest{
 				PlatformID: 1,
 			},
 			mockSetup:      func(m *mockProductQuerier) {},
 			expectedStatus: http.StatusBadRequest,
 		},
+		{
+			name: "Whitespace Name",
+			requestBody: createProductRequest{
+				PlatformID: 1,
+				Name:       "   ",
+			},
+			mockSetup:      func(m *mockProductQuerier) {},
+			expectedStatus: http.StatusBadRequest,
+		},

As per coding guidelines, "Assess the unit test code assessing sufficient code coverage for the changes associated in the pull request".

🤖 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 `@internal/product/handler_test.go` around lines 89 - 105, Add a new
table-driven test case for CreateProduct that uses createProductRequest{Name: " 
", PlatformID: 1} (a whitespace-only Name) to exercise the invalid-name branch
in the CreateProduct handler; call the same mockSetup (no DB interactions) as
the other bad-request cases, expect http.StatusBadRequest, and ensure the test
sends this request through the same test harness used by the existing cases (the
test table and test runner around mockProductQuerier and the CreateProduct
handler).
🤖 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 `@internal/platform/handler.go`:
- Around line 93-99: The delete handler currently writes raw internal errors to
clients (the branch after errors.Is(err, pgx.ErrNoRows)), leaking DB details via
err.Error(); change that response to a generic error message (e.g., "Internal
server error") and an appropriate 500 status instead of returning err.Error();
keep the special-case NotFound branch (errors.Is(err, pgx.ErrNoRows)) as-is and
only replace the generic http.Error(w, err.Error(),
http.StatusInternalServerError) call in this handler to a non-revealing message.

In `@internal/platform/request_test.go`:
- Around line 50-62: Add a test that verifies updatePlatformRequest.ToParams
prefers the method argument ID over the struct field: create an
updatePlatformRequest with ID set to a different value than the int32 id passed
into ToParams, call req.ToParams(id), and assert params.ID equals the method arg
id (and optionally assert Name/Description are preserved). This targets
updatePlatformRequest and its ToParams method to ensure path ID precedence is
enforced.

In `@internal/product/handler.go`:
- Around line 34-36: The request name blank check currently only tests for empty
string so names like "   " pass; in the create handler (where req.Name and
req.PlatformID are validated) trim whitespace from req.Name (e.g.,
strings.TrimSpace(req.Name)) before performing the empty check and
required-field validation, mirroring the update-path behavior; ensure you update
the same validation block that returns http.StatusBadRequest on missing fields
so whitespace-only names are rejected.

---

Outside diff comments:
In `@internal/platform/handler_test.go`:
- Around line 371-375: TestUpdatePlatform is sending a Platform value (with
Description as pgtype.Text) but the handler decodes into updatePlatformRequest
where Description is a string, causing JSON decoding failures; change the test
requestBody to use updatePlatformRequest (or a struct literal matching
updatePlatformRequest) with Description as a plain string ("Updated
Description") and update all related test cases (the requestBody entries at the
referenced locations) so the mock expectation/assertions match the string
description type (adjust the mock call args to expect the string description
instead of pgtype.Text) to exercise the success path correctly.

In `@internal/product/handler_test.go`:
- Around line 89-105: Add a new table-driven test case for CreateProduct that
uses createProductRequest{Name: "   ", PlatformID: 1} (a whitespace-only Name)
to exercise the invalid-name branch in the CreateProduct handler; call the same
mockSetup (no DB interactions) as the other bad-request cases, expect
http.StatusBadRequest, and ensure the test sends this request through the same
test harness used by the existing cases (the test table and test runner around
mockProductQuerier and the CreateProduct handler).
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 80bd7e23-588e-4510-b494-537840070299

📥 Commits

Reviewing files that changed from the base of the PR and between 6dcffc8 and 8e137f4.

📒 Files selected for processing (34)
  • api/platform/create.go
  • api/platform/delete.go
  • api/platform/get.go
  • api/platform/platform.go
  • api/platform/update.go
  • api/product/create.go
  • api/product/delete.go
  • api/product/get.go
  • api/product/product.go
  • api/product/update.go
  • internal/db/store.go
  • internal/platform/db.gen.go
  • internal/platform/handler.go
  • internal/platform/handler_test.go
  • internal/platform/interface.go
  • internal/platform/models.gen.go
  • internal/platform/platforms.sql
  • internal/platform/platforms.sql.gen.go
  • internal/platform/querier.gen.go
  • internal/platform/request.go
  • internal/platform/request_test.go
  • internal/product/db.gen.go
  • internal/product/handler.go
  • internal/product/handler_test.go
  • internal/product/interface.go
  • internal/product/models.gen.go
  • internal/product/products.sql
  • internal/product/products.sql.gen.go
  • internal/product/querier.gen.go
  • internal/product/request.go
  • internal/product/request_test.go
  • main.go
  • router/router.go
  • sqlc.yml
💤 Files with no reviewable changes (11)
  • api/product/product.go
  • api/platform/delete.go
  • api/product/delete.go
  • api/platform/update.go
  • api/product/create.go
  • api/product/update.go
  • internal/db/store.go
  • api/product/get.go
  • api/platform/get.go
  • api/platform/create.go
  • api/platform/platform.go

Comment thread internal/platform/handler.go
Comment thread internal/platform/request_test.go
Comment thread internal/product/handler.go
@jlpdeveloper jlpdeveloper merged commit 8118e2c into main May 7, 2026
3 checks passed
@jlpdeveloper jlpdeveloper deleted the refactor-organization branch May 7, 2026 01:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

chore refactor, maintenance, etc.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Reorganize Project Structure Around Domain Packages

1 participant