Skip to content

Conversation

@gocanto
Copy link
Collaborator

@gocanto gocanto commented Nov 17, 2025

Summary by CodeRabbit

  • Bug Fixes

    • Improved database import robustness: better per-row handling of duplicate entries so repeated imports skip duplicates and continue.
  • Chores

    • Renamed build command labels for clarity.
    • Removed an unused dependency.
  • Refactor

    • Reorganized API routing and added internal request protections at the proxy level.
    • Moved CORS handling out of the application and into the reverse proxy.

@coderabbitai
Copy link

coderabbitai bot commented Nov 17, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Refactors the seeder to use per-row SAVEPOINTs for COPY inserts with centralized duplicate-skip logic; updates tests to expect per-row savepoints; restructures Caddy routing to a /api/* handler and moves CORS to Caddy; removes rs/cors from go.mod and Go-level CORS; adjusts docker-compose ports and renames Makefile Caddy commands.

Changes

Cohort / File(s) Summary
Makefile Caddy commands
Makefile
Renames help/command entries from caddy-gen-cert/caddy-del-cert to caddy-gen-certs/caddy-del-certs.
Database seeder (runtime)
database/seeder/importer/runner.go
Adds per-row SAVEPOINT/ROLLBACK TO/RELEASE around COPY inserts; introduces shouldSkipCopyInsertError and shouldSkipDuplicateSchemaMigrationInsert helpers; aligns INSERT and COPY duplicate-skip logic and updates error/rollback control flow.
Database seeder tests
database/seeder/importer/runner_sql_test.go, database/seeder/importer/runner_test.go
Adds and updates tests to expect per-row SAVEPOINT/RELEASE sequences for COPY; adds TestExecuteCopySkipsDuplicateCopyRows and TestSeedFromFileSkipsDuplicateSchemaMigrationsCopy to verify duplicate skipping/idempotence.
Infrastructure / Caddy
infra/caddy/Caddyfile.local
Introduces handle_path /api/* with prefix stripping, scoped protected-path matching (403), moves reverse_proxy into /api/* handler, adds internal Prometheus proxy and a catch-all 404.
Docker Compose
docker-compose.yml
Removes explicit 8443:443 host port mappings from Caddy services; adds comments around API port exposure and retains ${ENV_HTTP_PORT} exposure for the API.
Dependencies
go.mod
Removes github.com/rs/cors v1.11.1 from the require block.
Server CORS handling
pkg/endpoint/server.go
Removes development CORS wrapper and imports (strings, cors); updates comment to note CORS is handled by the reverse proxy; retains optional Sentry wrapping via cfg.Wrap.

Sequence Diagram(s)

sequenceDiagram
    participant Importer as COPY Importer
    participant DB as Database
    participant Checker as Duplicate Checker

    loop each COPY row
        Importer->>DB: CREATE SAVEPOINT importer_copy_row_X
        Importer->>DB: INSERT row
        alt insert succeeds
            Importer->>DB: RELEASE SAVEPOINT importer_copy_row_X
        else insert fails
            Importer->>Checker: shouldSkipCopyInsertError(table, err)
            alt should skip (duplicate)
                Importer->>DB: ROLLBACK TO SAVEPOINT importer_copy_row_X
                Importer->>DB: RELEASE SAVEPOINT importer_copy_row_X
                Checker->>Importer: log skip, continue
            else hard error
                Importer->>DB: ROLLBACK TO SAVEPOINT importer_copy_row_X
                Importer->>Importer: return error
            end
        end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Pay attention to SAVEPOINT creation/release ordering and error-handling branches in database/seeder/importer/runner.go.
  • Verify updated SQL expectations in runner_sql_test.go align with DB transaction behavior.
  • Confirm Caddyfile.local /api/* handler preserves previous protections and routing semantics.
  • Ensure removal of rs/cors and Go-level CORS does not leave unintended gaps.

Possibly related PRs

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 7.14% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The pull request title 'chore: Local environment + UX' is vague and overly broad, using non-descriptive terms that don't clearly convey what was changed. The changeset includes database importer improvements, docker-compose modifications, Caddy configuration updates, and dependency removal—none of which are meaningfully captured by the generic phrase 'Local environment + UX'. Consider a more specific title that highlights the primary change, such as 'chore: Add per-row savepoints to database importer and update local dev setup' or focus on the most significant functional change.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/db-importter

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c34a096 and 5473b46.

📒 Files selected for processing (1)
  • infra/caddy/Caddyfile.local (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-11-17T09:16:09.377Z
Learnt from: gocanto
Repo: oullin/api PR: 163
File: infra/caddy/Caddyfile.local:7-7
Timestamp: 2025-11-17T09:16:09.377Z
Learning: In Caddy v2, the `metrics` directive should be placed directly in the global options block (e.g., `{ metrics }`), not nested inside a `servers` block. The nested `servers { metrics }` syntax is deprecated.

Applied to files:

  • infra/caddy/Caddyfile.local
🔇 Additional comments (2)
infra/caddy/Caddyfile.local (2)

47-56: LGTM! API routing restructure properly implemented.

The handle_path /api/* correctly strips the /api prefix before forwarding, and the protected paths matcher appropriately blocks both /metrics and /generate-signature* with a 403 response. This aligns with the PR objective to restructure Caddy routing to a /api/* handler.


58-61: LGTM! Appropriate fallback behavior.

The catch-all handler correctly returns 404 for non-API routes, ensuring clean handling of any unmatched paths.


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

@gocanto gocanto changed the title db importer chore: Local environment Nov 17, 2025
@gocanto gocanto marked this pull request as ready for review November 17, 2025 08:50
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Copy link

@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: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e0a7b88 and fbd07f3.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (9)
  • Makefile (1 hunks)
  • database/seeder/importer/runner.go (3 hunks)
  • database/seeder/importer/runner_sql_test.go (4 hunks)
  • database/seeder/importer/runner_test.go (1 hunks)
  • docker-compose.yml (1 hunks)
  • go.mod (0 hunks)
  • infra/caddy/Caddyfile.local (2 hunks)
  • infra/caddy/Caddyfile.prod (1 hunks)
  • pkg/endpoint/server.go (1 hunks)
💤 Files with no reviewable changes (1)
  • go.mod
🧰 Additional context used
🧬 Code graph analysis (1)
database/seeder/importer/runner_test.go (1)
database/seeder/importer/runner.go (1)
  • SeedFromFile (22-60)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: test (1.25.3)
🔇 Additional comments (12)
database/seeder/importer/runner_test.go (1)

409-441: LGTM! Well-structured test for COPY duplicate handling.

The test properly validates idempotent behavior for COPY operations by:

  • Including duplicate rows (version 42) in the COPY data
  • Running the seed process twice to verify cross-execution idempotency
  • Asserting that only a single migration row persists

This mirrors the INSERT-based test effectively and ensures the per-row savepoint logic works correctly.

database/seeder/importer/runner_sql_test.go (2)

112-118: LGTM! Test expectations correctly reflect per-row savepoint handling.

The test now expects savepoint creation and release around each COPY row insert, which aligns with the implementation changes.


227-272: LGTM! Comprehensive test for duplicate handling in COPY operations.

The test validates the per-row savepoint rollback and skip logic:

  • First row inserts successfully with savepoint create/release
  • Second duplicate row triggers error, rollback to savepoint, and release
  • The COPY operation completes without error despite the duplicate

This correctly exercises the new error handling path in executeCopy.

database/seeder/importer/runner.go (3)

646-678: LGTM! Per-row savepoint handling is correctly implemented.

The implementation properly handles duplicate rows during COPY operations:

  • Creates a savepoint before each row insert
  • On error: checks if the error should be skipped, rolls back to the savepoint, releases it, and continues
  • On success: releases the savepoint

This ensures idempotent behavior for COPY operations, particularly for schema_migrations duplicates.


731-752: LGTM! Well-designed helper functions for duplicate detection.

The new helpers centralize duplicate-skip logic:

  • shouldSkipCopyInsertError handles COPY-specific error checking (23505 duplicate key)
  • shouldSkipDuplicateSchemaMigrationInsert is shared between COPY and INSERT paths
  • Proper identifier normalization ensures consistent behavior

This refactoring eliminates code duplication and improves maintainability.


714-716: LGTM! Good refactoring to eliminate code duplication.

The refactoring consolidates duplicate-migration skip logic into a shared helper, ensuring consistency between INSERT and COPY execution paths.

Makefile (1)

106-107: LGTM: Consistent naming with plural form.

The help text updates correctly reflect plural naming (certs instead of cert), improving consistency.

docker-compose.yml (1)

398-400: LGTM: Helpful documentation.

The added comments clearly explain the port exposure strategy for local versus production environments, improving configuration clarity.

infra/caddy/Caddyfile.local (2)

45-54: LGTM: API path handling properly structured.

The new handle_path /api/* block correctly:

  • Strips the /api prefix before forwarding to the backend
  • Blocks access to protected paths like /metrics
  • Proxies requests to the API service

This architecture aligns with the production configuration and provides consistent routing behavior across environments.


62-75: LGTM: Dedicated metrics endpoint for Prometheus.

The :9180 listener correctly exposes only the /metrics endpoint by proxying to the admin API (localhost:2019), with a fallback 404 for all other paths. This provides secure, isolated metrics scraping for Prometheus without exposing the full admin API.

pkg/endpoint/server.go (1)

84-98: LGTM: CORS properly delegated to Caddy and fully configured.

Verification confirms all required CORS scenarios are properly configured in both Caddy files:

  • Preflight handling: @preflight matchers and handlers present in both Caddyfile.local and Caddyfile.prod
  • Origin validation: Hardcoded per environment (localhost:5173 for local, oullin.io for prod) with dynamic fallback
  • Methods & headers: GET, POST, PUT, DELETE, OPTIONS allowed; all custom headers configured

The application-level delegation to Caddy is complete and appropriate.

infra/caddy/Caddyfile.prod (1)

4-4: Global metrics directive syntax is valid.

The global metrics directive is valid Caddy v2 syntax and can be enabled at the top-level in a global options block. The change moves metrics configuration to global scope, which is a documented and supported pattern in Caddy v2. No syntax issues identified.

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@gocanto gocanto changed the title chore: Local environment chore: Local environment + UX Nov 17, 2025
@gocanto gocanto merged commit a030bea into main Nov 18, 2025
5 checks passed
@gocanto gocanto deleted the fix/db-importter branch November 18, 2025 02:04
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