feat: add OpenAPI/swagger, Playwright E2E, sqlc, and CI tooling upgrades#6
Conversation
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the 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 configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (2)
📒 Files selected for processing (30)
📝 WalkthroughWalkthroughThis PR introduces comprehensive API documentation through Swagger/OpenAPI 2.0 specifications with godoc annotations across all handler methods, generates a type-safe database access layer via sqlc for core tables (blog posts, products, categories, users), establishes end-to-end testing infrastructure with Playwright, implements Git commit standards via hooks and linting, and configures automated CI/CD workflows for security scanning, E2E testing, and semantic release versioning. ChangesSwagger API Documentation
Type-Safe Database Layer
End-to-End Testing & CI/CD
Development Standards & Configuration
🎯 3 (Moderate) | ⏱️ ~25 minutes
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Pull request overview
This PR adds additional project tooling across the repo: dependency automation (Renovate), commit workflow enforcement (Husky + commitlint), backend code generation (sqlc + Swagger/OpenAPI), Playwright E2E tests, and CI pipeline upgrades to run these checks.
Changes:
- Add Renovate configuration plus semantic-release configuration and CI release job.
- Add Playwright E2E scaffolding (config + basic tests) and wire E2E into CI.
- Add sqlc configuration + generated DB access layer and add Swagger/OpenAPI generation + UI route; upgrade backend dependencies accordingly.
Reviewed changes
Copilot reviewed 41 out of 45 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| renovate.json | Configure Renovate dependency updates and automerge rules. |
| package.json | Add root-level tooling deps (husky/commitlint) and scripts. |
| package-lock.json | Lockfile for root Node tooling dependencies. |
| Makefile | Add targets for vulncheck/swagger/sqlc/e2e and include sqlc in check. |
| frontend/package.json | Add Playwright dependency and an e2e script. |
| frontend/bun.lock | Lockfile updates for Playwright installation via Bun. |
| e2e/playwright.config.ts | New Playwright config to run against Docker Compose environment. |
| e2e/basic.spec.ts | Basic E2E smoke tests (health + frontend load). |
| commitlint.config.js | Configure commitlint conventional commits rules. |
| backend/sqlc.yaml | Configure sqlc code generation for Postgres schema/queries. |
| backend/internal/infrastructure/sqlc/db.go | Generated sqlc DB wrapper and query struct. |
| backend/internal/infrastructure/sqlc/models.go | Generated sqlc models for DB tables. |
| backend/internal/infrastructure/sqlc/querier.go | Generated sqlc Querier interface. |
| backend/internal/infrastructure/sqlc/users.sql.go | Generated sqlc queries for users. |
| backend/internal/infrastructure/sqlc/products.sql.go | Generated sqlc queries for products. |
| backend/internal/infrastructure/sqlc/categories.sql.go | Generated sqlc queries for categories. |
| backend/internal/infrastructure/sqlc/blog_posts.sql.go | Generated sqlc queries for blog posts. |
| backend/internal/infrastructure/sqlc/queries/users.sql | Source SQL for user queries. |
| backend/internal/infrastructure/sqlc/queries/products.sql | Source SQL for product queries (with optional filters). |
| backend/internal/infrastructure/sqlc/queries/categories.sql | Source SQL for category queries. |
| backend/internal/infrastructure/sqlc/queries/blog_posts.sql | Source SQL for blog post queries (with status filter). |
| backend/internal/handlers/waitlist.go | Add Swagger annotations for waitlist routes. |
| backend/internal/handlers/user.go | Add Swagger annotations for user routes. |
| backend/internal/handlers/tools.go | Add Swagger annotations for admin tools route. |
| backend/internal/handlers/store.go | Add Swagger annotations for store and admin store routes. |
| backend/internal/handlers/security.go | Add Swagger annotations for security settings routes. |
| backend/internal/handlers/payment.go | Add Swagger annotations for payment routes. |
| backend/internal/handlers/legal.go | Replace inline comments with Swagger annotations for legal routes. |
| backend/internal/handlers/jobs.go | Add Swagger annotations for jobs admin routes. |
| backend/internal/handlers/handler.go | Add Swagger annotations for feature flag routes. |
| backend/internal/handlers/envconfig.go | Replace inline comments with Swagger annotations for env/config routes. |
| backend/internal/handlers/coupon.go | Add Swagger annotations for coupon routes. |
| backend/internal/handlers/blog.go | Add Swagger annotations for blog routes (public + admin). |
| backend/internal/handlers/auth.go | Add Swagger annotations for auth routes. |
| backend/internal/handlers/admin.go | Add Swagger annotations for admin routes (upload, users, banners, etc.). |
| backend/go.mod | Add Swagger/sqlc-related deps and bump Fiber patch version. |
| backend/go.sum | Dependency checksum updates for new/updated backend modules. |
| backend/docs/swagger/swagger.yaml | Generated Swagger spec output checked into repo. |
| backend/cmd/server/main.go | Add Swagger metadata annotations and mount Swagger UI route. |
| .releaserc | Add semantic-release configuration. |
| .husky/pre-commit | Add pre-commit hook. |
| .husky/commit-msg | Add commit-msg hook for commitlint. |
| .gitignore | Ignore root node_modules and Playwright output directories. |
| .github/workflows/ci.yml | Add security job, sqlc diff check, E2E job, and release job. |
Comments suppressed due to low confidence (1)
.github/workflows/ci.yml:145
- The
releasejob uses@semantic-release/githubwithGITHUB_TOKEN, but the workflow does not declare anypermissions. On newer GitHub defaults,GITHUB_TOKENis read-only and semantic-release will fail to create releases/tags withoutcontents: write(and oftenissues/pull-requests: write). Consider adding an explicitpermissions:block (workflow-wide or for thereleasejob).
release:
needs: [security, build, e2e]
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
- name: Install semantic-release
run: npm install -g semantic-release @semantic-release/commit-analyzer @semantic-release/release-notes-generator @semantic-release/github
- name: Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: semantic-release
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // Swagger UI | ||
| app.Get("/swagger/*", swagger.New(swagger.Config{ | ||
| BasePath: "/", | ||
| FilePath: "docs/swagger/swagger.json", | ||
| Path: "/swagger", | ||
| })) |
| cd backend && sqlc generate | ||
|
|
||
| e2e: | ||
| npx playwright test --config e2e/playwright.config.ts |
| -- name: ListBlogPosts :many | ||
| SELECT id, title, slug, content, excerpt, cover_image, status, author_id, created_at, published_at, metadata | ||
| FROM blog_posts | ||
| WHERE ($1 = '' OR status = $1) | ||
| ORDER BY created_at DESC LIMIT $2 OFFSET $3; | ||
|
|
||
| -- name: CountBlogPosts :one | ||
| SELECT COUNT(*) FROM blog_posts WHERE ($1 = '' OR status = $1); |
| SELECT id, name, description, price, stock, is_pre_sale, pre_sale_available_at, images, category_id, is_active, created_at, updated_at | ||
| FROM products | ||
| WHERE ($1::uuid IS NULL OR category_id = $1) | ||
| AND ($2 = false OR is_active = true) | ||
| ORDER BY created_at DESC LIMIT $3 OFFSET $4; | ||
|
|
||
| -- name: CountProducts :one | ||
| SELECT COUNT(*) FROM products | ||
| WHERE ($1::uuid IS NULL OR category_id = $1) | ||
| AND ($2 = false OR is_active = true); |
|
@copilot apply changes based on the comments in this thread |
Agent-Logs-Url: https://github.com/afa7789/blueprint/sessions/32ffd8d6-cc69-4684-b0ac-93b7680679fd Co-authored-by: afa7789 <26887703+afa7789@users.noreply.github.com>
Applied the requested review-thread changes in commit
Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
|
@copilot consegue arrumar os erros de CI/CD não, ia ser interessante: |
There was a problem hiding this comment.
Actionable comments posted: 7
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (4)
backend/internal/handlers/blog.go (1)
455-562:⚠️ Potential issue | 🟠 Major | 🏗️ Heavy liftOpenAI API endpoint and request structure do not match documented patterns.
The implementation uses
https://api.openai.com/v1/responses(line 512), which is not the standard Chat Completions endpoint (/v1/chat/completions). The request structure also deviates: it usesinputinstead ofmessages, and expectsoutput_textin the response instead ofchoices. The model name"gpt-5.4-mini"(line 455) does not match documented OpenAI model naming.While OpenAI's Responses API exists as a newer interface, the request format here (with
text.format.json_schema, role"developer", andinput_texttypes) does not align with standard patterns. The README explicitly marks AI content generation as an "OpenAI placeholder," indicating this implementation is incomplete.Clarify which OpenAI API version/endpoint this should use, or update the implementation to match the intended API spec. If this is intentionally experimental, add documentation explaining the deviation.
🤖 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/internal/handlers/blog.go` around lines 455 - 562, The handler uses a mismatched OpenAI contract: it posts to "https://api.openai.com/v1/responses" with a custom payload (model "gpt-5.4-mini", "input" array, and "text.format.json_schema") but then parses a Chat-style response ("output_text"/"output" instead of "choices"), causing incompatibility; decide whether to target the Responses API or Chat Completions API, then update the request and parsing accordingly — if you choose Chat Completions, replace the payload to use "messages" (roles + content), use a valid model name, POST to "/v1/chat/completions" and parse "choices[].message.content"; if you choose Responses, align the payload to Responses API docs (use "input" as string or appropriate array, correct "modalities"/"format" usage) and parse the official Responses fields (not "output_text"/"output"); also update the model string ("gpt-5.4-mini") to a documented model or document the experimental choice. Ensure consistency between the payload creation (the variable building the payload) and the response unmarshalling (the anonymous struct using OutputText/Output).backend/internal/handlers/coupon.go (2)
100-108:⚠️ Potential issue | 🟠 Major | ⚡ Quick winAvoid shipping a documented DELETE coupon endpoint that is hardcoded to fail.
This creates a guaranteed-failure API surface (
/admin/coupons/{id}) and misleading Swagger docs. Either implement deletion in the repository layer or remove the route/docs until it exists.🤖 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/internal/handlers/coupon.go` around lines 100 - 108, The AdminDeleteCoupon handler is exposing a documented DELETE endpoint but always returns MethodNotAllowed; either implement deletion in the repository or remove the route/docs—add a Delete(ctx, id) (or similar) method to CouponRepository and have CouponHandler.AdminDeleteCoupon parse the coupon id from fiber.Ctx and call that repository Delete, returning appropriate 200/204 or 404/500 responses, or if deletion is not supported remove the swagger comment block and the route registration so AdminDeleteCoupon is not advertised. Ensure you update references to CouponRepository and AdminDeleteCoupon accordingly.
31-58:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winReject negative
subtotalbefore validation/discount logic.A negative subtotal can produce invalid discount/final totals and should be treated as bad input.
Suggested guard
if err := c.BodyParser(&req); err != nil { return fiber.NewError(fiber.StatusBadRequest, "invalid body") } if req.Code == "" { return fiber.NewError(fiber.StatusBadRequest, "code required") } +if req.Subtotal < 0 { + return fiber.NewError(fiber.StatusBadRequest, "subtotal must be non-negative") +}🤖 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/internal/handlers/coupon.go` around lines 31 - 58, Before any coupon validation logic, add a guard to reject negative request subtotals: after parsing the body (the c.BodyParser(&req) block) validate req.Subtotal and return a fiber.BadRequest error if req.Subtotal is less than 0. Place this check before using req.Subtotal in downstream checks (e.g., the MinPurchase comparison) so functions/methods like h.coupons.FindByCode and the coupon.* validations never run with a negative subtotal; use the same error style (fiber.NewError with fiber.StatusBadRequest and an explanatory message).Makefile (1)
1-7:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winAdd
e2eto.PHONYto avoid target/file collisions.
e2e(Line 135) is invokable but not declared phony, so a same-named file can suppress execution.Suggested patch
.PHONY: up down logs backend frontend build deploy ngrok \ test test-backend test-frontend \ lint lint-backend lint-frontend \ fmt fmt-backend fmt-frontend \ typecheck tidy vet \ deadcode deadcode-backend deadcode-frontend \ - vulncheck swagger sqlc check ci clean help + vulncheck swagger sqlc e2e check ci clean helpAlso applies to: 135-136
🤖 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 `@Makefile` around lines 1 - 7, The Makefile's .PHONY list is missing the e2e target, so a file named "e2e" could block the target; update the .PHONY declaration to include "e2e" (add e2e to the existing .PHONY line that currently lists up down logs backend frontend ... help) so the e2e target (defined later) is always treated as phony and cannot be shadowed by a file.
🧹 Nitpick comments (6)
renovate.json (1)
10-13: ⚡ Quick winConsider restricting automerge for devDependencies to non-major updates.
The current configuration will automerge all devDependencies updates, including major version bumps. Major updates in dev tools (linters, test frameworks, build tools) can introduce breaking changes that require code modifications.
🔧 Suggested refinement
{ "matchDepTypes": ["devDependencies"], + "matchUpdateTypes": ["minor", "patch"], "automerge": true }🤖 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 `@renovate.json` around lines 10 - 13, The current rule enables "automerge": true for all "matchDepTypes": ["devDependencies"] including majors; change it to a packageRules entry that only automerges non-major updates by replacing the simple object with a "packageRules" array and an entry like { "matchDepTypes": ["devDependencies"], "matchUpdateTypes": ["minor","patch"], "automerge": true } so major updates remain manual; update the JSON to use "packageRules" and "matchUpdateTypes" alongside the existing keys ("matchDepTypes" and "automerge") to scope automerge to patch/minor only.backend/internal/handlers/user.go (1)
73-79: ⚡ Quick winConsider adding response schema documentation.
The
@Successannotation is missing response type documentation. Adding@Success 200 {object} profileResponsewould provide complete API documentation and improve the generated Swagger spec.📝 Suggested enhancement
// UpdateProfile godoc // `@Summary` Update user profile // `@Tags` User // `@Accept` json // `@Produce` json +// `@Success` 200 {object} profileResponse // `@Security` BearerAuth // `@Router` /user/profile [put]🤖 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/internal/handlers/user.go` around lines 73 - 79, The OpenAPI comment block for the UpdateProfile handler is missing a success response schema; update the handler comment (the block above UpdateProfile) to include a `@Success` line such as "@Success 200 {object} profileResponse" and ensure a corresponding profileResponse type (struct) exists and is documented so the Swagger generator can include the response schema for UpdateProfile.e2e/basic.spec.ts (1)
8-11: ⚡ Quick winStrengthen frontend smoke assertion beyond
<body>visibility.
bodybeing visible is too permissive and can pass on broken/error pages. At minimum, assert successful navigation response plus one app-specific UI marker.🤖 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 `@e2e/basic.spec.ts` around lines 8 - 11, The test "frontend loads" is too weak—replace the single body visibility check with two stronger assertions: capture the result of page.goto('/') (using the returned Response from page.goto) and assert the navigation succeeded (response exists and status < 400), and then assert an application-specific UI marker is present (use page.locator with a stable selector such as a data-test-id or a unique visible text, e.g., the app root or welcome heading) instead of just 'body'; update the test function test('frontend loads', async ({ page }) => { ... }) to perform both checks via page.goto and page.locator/expect.backend/internal/handlers/legal.go (1)
93-99: ⚡ Quick winDocument the
{id}path parameter and response types for admin update/delete routes.Both
/admin/legal/{id}endpoints are missing explicit documentation for the path parameter and response types, resulting in incomplete OpenAPI specs. Add@Param id path string true "Legal page ID"and@Successannotations to both theAdminUpdateandAdminDeletefunctions.Suggested annotation patch
// AdminUpdate godoc // `@Summary` Update a legal page (admin) // `@Tags` Admin // `@Accept` json // `@Produce` json // `@Security` BearerAuth +// `@Param` id path string true "Legal page ID" +// `@Success` 200 {object} domain.LegalPage // `@Router` /admin/legal/{id} [put] // AdminDelete godoc // `@Summary` Delete a legal page (admin) // `@Tags` Admin // `@Security` BearerAuth +// `@Param` id path string true "Legal page ID" +// `@Success` 200 {object} map[string]bool // `@Router` /admin/legal/{id} [delete]🤖 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/internal/handlers/legal.go` around lines 93 - 99, Add OpenAPI annotations to the admin update/delete handlers: in the godoc comment blocks for AdminUpdate and AdminDelete, add a path parameter annotation `@Param id path string true "Legal page ID"` and appropriate `@Success` annotations indicating the response type(s) (e.g., `@Success 200 {object} models.Legal` for a successful update and `@Success 204` or `@Success 200 {object} models.Message` for delete as appropriate). Place these annotations alongside the existing `@Summary`, `@Tags`, `@Accept`, `@Produce`, `@Security`, and `@Router` lines so the OpenAPI generator picks up the `{id}` param and response schemas.backend/internal/infrastructure/sqlc/products.sql.go (1)
20-23: ⚡ Quick winName query args in SQL to generate clearer params than
Column1/Column2Lines 20-23 and 115-120 expose ambiguous generated fields, which makes call sites error-prone. Define named args in
backend/internal/infrastructure/sqlc/queries/products.sql(e.g.,sqlc.arg(category_id),sqlc.arg(active_only)) and regenerate.Suggested source-query change (then re-run sqlc)
-WHERE ($1::uuid IS NULL OR category_id = $1) - AND ($2::boolean = false OR is_active = true) +WHERE (sqlc.arg(category_id)::uuid IS NULL OR category_id = sqlc.arg(category_id)) + AND (sqlc.arg(active_only)::boolean = false OR is_active = true) -ORDER BY created_at DESC LIMIT $3 OFFSET $4 +ORDER BY created_at DESC +LIMIT sqlc.arg(limit) OFFSET sqlc.arg(offset)Also applies to: 115-120
🤖 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/internal/infrastructure/sqlc/products.sql.go` around lines 20 - 23, The generated param struct CountProductsParams (fields Column1 and Column2) is ambiguous; update the SQL file backend/internal/infrastructure/sqlc/queries/products.sql to use explicit sqlc argument names (e.g., replace anonymous args with sqlc.arg(category_id) and sqlc.arg(active_only) or similarly descriptive names used in the query), then re-run sqlc to regenerate the Go types so the struct and any other occurrences (including the other instance around lines 115-120) become meaningful (e.g., CategoryID, ActiveOnly) and update call sites to use the new field names.backend/internal/infrastructure/sqlc/blog_posts.sql.go (1)
18-18: ⚡ Quick winUse named sqlc arguments to avoid placeholder param names in generated API
Line 18 (
dollar_1) and Lines 129-133 (Column1) make the generated methods harder to use safely. Prefer naming parameters inbackend/internal/infrastructure/sqlc/queries/blog_posts.sql(e.g.,sqlc.arg(status)), then regenerate to get semantic fields/method params.Suggested source-query change (then re-run sqlc)
-SELECT COUNT(*) FROM blog_posts WHERE ($1::text = '' OR status = $1::text) +SELECT COUNT(*) FROM blog_posts +WHERE (sqlc.arg(status)::text = '' OR status = sqlc.arg(status)::text) -WHERE ($1::text = '' OR status = $1::text) -ORDER BY created_at DESC LIMIT $2 OFFSET $3 +WHERE (sqlc.arg(status)::text = '' OR status = sqlc.arg(status)::text) +ORDER BY created_at DESC +LIMIT sqlc.arg(limit) OFFSET sqlc.arg(offset)Also applies to: 129-133
🤖 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/internal/infrastructure/sqlc/blog_posts.sql.go` at line 18, The generated methods use anonymous placeholders (dollar_1 in CountBlogPosts and Column1 fields) because the SQL query lacks named sqlc arguments; edit the source SQL in backend/internal/infrastructure/sqlc/queries/blog_posts.sql to use named arguments (e.g., sqlc.arg(status) or sqlc.arg(your_param_name) in the WHERE/VALUES), then re-run sqlc to regenerate the Go code so the generated method signatures and struct fields use semantic names instead of dollar_1/Column1 (target symbols: CountBlogPosts and any generated Column1 types).
🤖 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 @.github/workflows/ci.yml:
- Around line 97-103: The "Wait for health" step currently loops against
/healthz but can silently continue if the endpoint never becomes healthy; change
the step so the loop fails fast when retries are exhausted by returning a
non-zero exit code. Update the for-loop logic in the "Wait for health" step (the
block using for i in $(seq 1 30) and curl -s http://localhost/healthz) to detect
success and, if no successful probe occurred after all retries, print a clear
error (e.g. "health check failed: /healthz not ready") and exit 1 so the
workflow stops immediately on a persistent health failure.
- Around line 67-69: The CI installs sqlc using a floating tag ("sqlc@latest"),
which makes builds non-deterministic; update the workflow to pin sqlc to the
specific version that matches the checked-in generated code (replace the "go
install github.com/sqlc-dev/sqlc/cmd/sqlc@latest" step with a fixed version like
"sqlc@vX.Y.Z"), ensuring the sqlc diff check remains but uses the pinned release
so CI is deterministic; verify the chosen version is the one that generated the
committed code before committing.
In `@backend/cmd/server/main.go`:
- Around line 123-129: The swagger route is being registered unconditionally
(app.Get("/swagger/*", swagger.New(...))) which exposes API schema in prod; wrap
the registration in an environment check (e.g., if !isProd or config.Environment
!= "production") or register it behind an admin-auth middleware (e.g., use
existing requireAdmin or create an adminAuth middleware) so the swagger endpoint
is only available in non-production or to authenticated admins; update the code
that calls swagger.New and uses swaggerdocs.SwaggerInfo.ReadDoc() accordingly to
only run when the env check passes or when the route is protected.
In `@backend/docs/swagger/swagger.yaml`:
- Around line 17-20: OpenAPI schema wrongly documents byte/JSON fields (e.g.,
metadata, shipping_address, images, address) as array<integer>, breaking SDKs;
to fix, update the Go struct definitions to add swaggertype:"string" tags on the
[]byte fields (e.g., the fields named metadata, shipping_address, images,
address) so swaggo generates them as string in the swagger.yaml, or if you
cannot edit the structs, create a .swaggo overrides file containing a
replacement rule mapping []byte to string and pass that file to swaggo via
--overridesFile when regenerating the docs; regenerate the swagger.yaml after
applying one of these changes.
In `@backend/internal/handlers/waitlist.go`:
- Line 21: The Swagger `@Param` inline object syntax must be replaced with named
request structs: create a WaitlistRequest struct with fields Email string
`json:"email"` and Name string `json:"name,omitempty"`, and a
SecurityUpdateRequest (or SecurityRequest) struct with field Value string
`json:"value"`, then update the `@Param` annotations that currently use
object{email=string,name=string} and object{value=string} to reference these
types (e.g., `@Param` body body WaitlistRequest true "Email and optional name" and
`@Param` body body SecurityUpdateRequest true "...") so swaggo/swag can generate
proper schemas; ensure the handler functions that expect these bodies (the
waiter handler and the security update handler) use or bind to the new structs.
In `@backend/internal/infrastructure/sqlc/queries/users.sql`:
- Around line 21-23: ListUsers currently selects password_hash; remove
password_hash from the SELECT projection in the ListUsers query (the SQL
statement named ListUsers) so it returns id, email, name, role, email_verified,
email_verified_at, stripe_customer_id, created_at, updated_at only, then re-run
sqlc/codegen and update any call sites expecting password_hash on the generated
ListUsers result type (e.g., repository/ListUsers methods) to use the new shape;
ensure no logging or downstream handlers access password_hash from ListUsers
results.
In `@e2e/basic.spec.ts`:
- Around line 3-6: The test named "health endpoint returns 200" currently uses
expect(res.ok()).toBeTruthy(), which accepts any 2xx; change the assertion to
check the exact status code by using the response object `res` returned from
`request.get('/healthz')` and assert `res.status()` equals 200 (i.e., replace
the `res.ok()` assertion with an explicit `res.status() === 200` check).
---
Outside diff comments:
In `@backend/internal/handlers/blog.go`:
- Around line 455-562: The handler uses a mismatched OpenAI contract: it posts
to "https://api.openai.com/v1/responses" with a custom payload (model
"gpt-5.4-mini", "input" array, and "text.format.json_schema") but then parses a
Chat-style response ("output_text"/"output" instead of "choices"), causing
incompatibility; decide whether to target the Responses API or Chat Completions
API, then update the request and parsing accordingly — if you choose Chat
Completions, replace the payload to use "messages" (roles + content), use a
valid model name, POST to "/v1/chat/completions" and parse
"choices[].message.content"; if you choose Responses, align the payload to
Responses API docs (use "input" as string or appropriate array, correct
"modalities"/"format" usage) and parse the official Responses fields (not
"output_text"/"output"); also update the model string ("gpt-5.4-mini") to a
documented model or document the experimental choice. Ensure consistency between
the payload creation (the variable building the payload) and the response
unmarshalling (the anonymous struct using OutputText/Output).
In `@backend/internal/handlers/coupon.go`:
- Around line 100-108: The AdminDeleteCoupon handler is exposing a documented
DELETE endpoint but always returns MethodNotAllowed; either implement deletion
in the repository or remove the route/docs—add a Delete(ctx, id) (or similar)
method to CouponRepository and have CouponHandler.AdminDeleteCoupon parse the
coupon id from fiber.Ctx and call that repository Delete, returning appropriate
200/204 or 404/500 responses, or if deletion is not supported remove the swagger
comment block and the route registration so AdminDeleteCoupon is not advertised.
Ensure you update references to CouponRepository and AdminDeleteCoupon
accordingly.
- Around line 31-58: Before any coupon validation logic, add a guard to reject
negative request subtotals: after parsing the body (the c.BodyParser(&req)
block) validate req.Subtotal and return a fiber.BadRequest error if req.Subtotal
is less than 0. Place this check before using req.Subtotal in downstream checks
(e.g., the MinPurchase comparison) so functions/methods like
h.coupons.FindByCode and the coupon.* validations never run with a negative
subtotal; use the same error style (fiber.NewError with fiber.StatusBadRequest
and an explanatory message).
In `@Makefile`:
- Around line 1-7: The Makefile's .PHONY list is missing the e2e target, so a
file named "e2e" could block the target; update the .PHONY declaration to
include "e2e" (add e2e to the existing .PHONY line that currently lists up down
logs backend frontend ... help) so the e2e target (defined later) is always
treated as phony and cannot be shadowed by a file.
---
Nitpick comments:
In `@backend/internal/handlers/legal.go`:
- Around line 93-99: Add OpenAPI annotations to the admin update/delete
handlers: in the godoc comment blocks for AdminUpdate and AdminDelete, add a
path parameter annotation `@Param id path string true "Legal page ID"` and
appropriate `@Success` annotations indicating the response type(s) (e.g.,
`@Success 200 {object} models.Legal` for a successful update and `@Success 204`
or `@Success 200 {object} models.Message` for delete as appropriate). Place
these annotations alongside the existing `@Summary`, `@Tags`, `@Accept`,
`@Produce`, `@Security`, and `@Router` lines so the OpenAPI generator picks up
the `{id}` param and response schemas.
In `@backend/internal/handlers/user.go`:
- Around line 73-79: The OpenAPI comment block for the UpdateProfile handler is
missing a success response schema; update the handler comment (the block above
UpdateProfile) to include a `@Success` line such as "@Success 200 {object}
profileResponse" and ensure a corresponding profileResponse type (struct) exists
and is documented so the Swagger generator can include the response schema for
UpdateProfile.
In `@backend/internal/infrastructure/sqlc/blog_posts.sql.go`:
- Line 18: The generated methods use anonymous placeholders (dollar_1 in
CountBlogPosts and Column1 fields) because the SQL query lacks named sqlc
arguments; edit the source SQL in
backend/internal/infrastructure/sqlc/queries/blog_posts.sql to use named
arguments (e.g., sqlc.arg(status) or sqlc.arg(your_param_name) in the
WHERE/VALUES), then re-run sqlc to regenerate the Go code so the generated
method signatures and struct fields use semantic names instead of
dollar_1/Column1 (target symbols: CountBlogPosts and any generated Column1
types).
In `@backend/internal/infrastructure/sqlc/products.sql.go`:
- Around line 20-23: The generated param struct CountProductsParams (fields
Column1 and Column2) is ambiguous; update the SQL file
backend/internal/infrastructure/sqlc/queries/products.sql to use explicit sqlc
argument names (e.g., replace anonymous args with sqlc.arg(category_id) and
sqlc.arg(active_only) or similarly descriptive names used in the query), then
re-run sqlc to regenerate the Go types so the struct and any other occurrences
(including the other instance around lines 115-120) become meaningful (e.g.,
CategoryID, ActiveOnly) and update call sites to use the new field names.
In `@e2e/basic.spec.ts`:
- Around line 8-11: The test "frontend loads" is too weak—replace the single
body visibility check with two stronger assertions: capture the result of
page.goto('/') (using the returned Response from page.goto) and assert the
navigation succeeded (response exists and status < 400), and then assert an
application-specific UI marker is present (use page.locator with a stable
selector such as a data-test-id or a unique visible text, e.g., the app root or
welcome heading) instead of just 'body'; update the test function test('frontend
loads', async ({ page }) => { ... }) to perform both checks via page.goto and
page.locator/expect.
In `@renovate.json`:
- Around line 10-13: The current rule enables "automerge": true for all
"matchDepTypes": ["devDependencies"] including majors; change it to a
packageRules entry that only automerges non-major updates by replacing the
simple object with a "packageRules" array and an entry like { "matchDepTypes":
["devDependencies"], "matchUpdateTypes": ["minor","patch"], "automerge": true }
so major updates remain manual; update the JSON to use "packageRules" and
"matchUpdateTypes" alongside the existing keys ("matchDepTypes" and "automerge")
to scope automerge to patch/minor only.
🪄 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: ebebfc13-3c39-4573-b7c2-16b2a611e79f
⛔ Files ignored due to path filters (3)
backend/go.sumis excluded by!**/*.sumfrontend/bun.lockis excluded by!**/*.lockpackage-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (42)
.github/workflows/ci.yml.gitignore.releasercMakefilebackend/cmd/server/main.gobackend/docs/swagger/docs.gobackend/docs/swagger/swagger.jsonbackend/docs/swagger/swagger.yamlbackend/go.modbackend/internal/handlers/admin.gobackend/internal/handlers/auth.gobackend/internal/handlers/blog.gobackend/internal/handlers/coupon.gobackend/internal/handlers/envconfig.gobackend/internal/handlers/handler.gobackend/internal/handlers/jobs.gobackend/internal/handlers/legal.gobackend/internal/handlers/payment.gobackend/internal/handlers/security.gobackend/internal/handlers/store.gobackend/internal/handlers/tools.gobackend/internal/handlers/user.gobackend/internal/handlers/waitlist.gobackend/internal/infrastructure/sqlc/blog_posts.sql.gobackend/internal/infrastructure/sqlc/categories.sql.gobackend/internal/infrastructure/sqlc/db.gobackend/internal/infrastructure/sqlc/models.gobackend/internal/infrastructure/sqlc/products.sql.gobackend/internal/infrastructure/sqlc/querier.gobackend/internal/infrastructure/sqlc/queries/blog_posts.sqlbackend/internal/infrastructure/sqlc/queries/categories.sqlbackend/internal/infrastructure/sqlc/queries/products.sqlbackend/internal/infrastructure/sqlc/queries/users.sqlbackend/internal/infrastructure/sqlc/users.sql.gobackend/sqlc.yamlcommitlint.config.jse2e/basic.spec.tse2e/playwright.config.tsfrontend/package.jsonlefthook.ymlpackage.jsonrenovate.json
Agent-Logs-Url: https://github.com/afa7789/blueprint/sessions/70fc17aa-6173-4c11-8a2f-b5cc627e43b2 Co-authored-by: afa7789 <26887703+afa7789@users.noreply.github.com>
Consegui sim — corrigi os 3 pontos de CI/CD no commit
Não houve alteração de UI neste ajuste, então não há screenshot aplicável. Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
… and improve error handling - Updated sqlc dependency version in CI workflow to v1.31.1. - Improved health check logic in CI workflow to provide clearer failure messages. - Modified E2E test command to run from the frontend directory. - Adjusted paths for uploading Playwright reports in CI workflow. - Added Swagger UI endpoint conditionally based on environment. - Enhanced Swagger documentation with parameters and response schemas for various endpoints. - Updated entity definitions to include swaggertype annotations for JSON fields. - Implemented Delete method in CouponRepository and corresponding handler for coupon deletion. - Refactored AI generation logic in blog handler to align with OpenAI API changes. - Added validation for subtotal in coupon validation handler. - Updated user and product SQL queries to improve filtering and pagination. - Added new request structs for security and waitlist handlers. - Improved E2E tests for health endpoint and frontend loading. - Adjusted frontend package.json for Playwright configuration. - Created a new Playwright configuration file for better test management. - Updated Renovate configuration to automate minor and patch updates for devDependencies.
…nd updated mongo-driver
- move e2e/basic.spec.ts into frontend/e2e/ so @playwright/test resolves - update frontend/playwright.config.ts testDir to ./e2e and bump webServer timeout - simplify e2e CI job: let playwright manage docker compose via webServer - add backend healthcheck and make nginx depends_on backend service_healthy - add nginx healthcheck for compose --wait readiness
- vitest: exclude e2e/** so playwright specs are not picked up - backend healthcheck: use 127.0.0.1 (localhost resolved to ::1 inside the container, but Fiber listens on IPv4 only — caused 180s healthcheck timeout) - nginx healthcheck: same IPv4 fix - nginx depends_on: drop pgweb/grafana/prometheus from the readiness path (they are not needed for /healthz and slowed down --wait) - playwright: bump webServer timeout to 300s for CI cold starts - e2e/basic.spec.ts: use #app.first() — the page renders two #app elements (mount target + App.vue template root), so a bare locator is ambiguous Verified locally: docker compose up -d --wait → all healthy in ~33s, playwright run → 2/2 passing.
adicionando mais tooling p/ o projeto
Summary by CodeRabbit
Release Notes
New Features
Chores