Conversation
📝 WalkthroughWalkthroughThis PR adds comprehensive Swagger and OpenAPI documentation for a new poll and voting API surface tied to trip management. The changes include endpoint specifications for poll CRUD operations, poll option management, vote casting, and pagination structures, along with documentation markers in internal database models. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 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.
Actionable comments posted: 6
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@backend/docs/docs.go`:
- Around line 2382-2446: The OpenAPI docs for the poll DELETE endpoints
currently return 200 with a response body (operationId "deletePoll" and the
other poll DELETE entry at 2622-2700, likely "deletePollOption"); change these
to follow the API convention used elsewhere by replacing the 200 response with a
204 No Content response that has no response schema, and remove the response
body/schema entries for the 200 case; if returning the deleted resource was
intentional, instead add an explicit comment in the spec noting the deliberate
deviation.
- Around line 2570-2576: Update the response type for the addPollOption and
deletePollOption handlers from models.PollOption to models.PollOptionAPIResponse
to avoid serializing the ORM back-reference; locate the OpenAPI/Swagger response
annotation for the addPollOption and deletePollOption handlers (currently
referencing "$ref": "#/definitions/models.PollOption") and change it to "$ref":
"#/definitions/models.PollOptionAPIResponse", ensuring the handlers still return
the API response struct shape (vote_count, voted) so the docs and serialization
match the existing models.PollOptionAPIResponse.
- Around line 2335-2341: Update the swagger path-parameter names to use
uppercase "ID" for consistency: replace occurrences of "@Param pollId" with
"@Param pollID" and "@Param optionId" with "@Param optionID" in the poll
controller swagger annotations (check backend/internal/controllers/polls.go),
and ensure any corresponding route/path parameter names and generated docs
(e.g., entries in docs.go) match the new "pollID" and "optionID" identifiers so
the annotation names and actual path parameter names stay identical.
- Around line 4217-4247: The PollOption struct's Poll field is causing a
circular Swagger reference; add the struct tag `swaggerignore:"true"` to the
Poll field in backend/internal/models/polls.go (the PollOption struct) to
prevent serialization of the back-reference, and update the PollController
endpoint docs for AddOption and DeleteOption to `@Success {object}
models.PollOptionAPIResponse` (replace the existing `models.PollOption`) and
adjust the service/controller return value to return a
models.PollOptionAPIResponse instance instead of models.PollOption so the
documented and actual response types match.
In `@backend/docs/swagger.json`:
- Around line 4129-4240: The public OpenAPI schema currently creates a circular
reference between models.Poll and models.PollOption because models.Poll
references models.PollOption and models.PollOption contains a "poll" property
that $ref's models.Poll; remove that back-reference or replace it with a
non-circular alternative: update the models.PollOption definition to drop the
"poll" property (leave poll_id only) or change its "poll" $ref to point to a
one-way response type such as models.PollAPIResponse (or
models.PollOptionAPIResponse where appropriate) so only Poll -> PollOption
exists in the public spec and generators won’t encounter circular schemas.
In `@backend/docs/swagger.yaml`:
- Around line 665-737: The public swagger spec contains a circular reference
between models.Poll and models.PollOption (models.Poll.options ->
models.PollOption, and models.PollOption.poll -> models.Poll); remove the
back-reference to break the cycle by deleting or replacing the poll property
inside models.PollOption (the "poll" allOf/$ref entry) and instead ensure Poll's
options use a one-way response type (e.g., change models.Poll.options to
reference models.PollOptionAPIResponse or models.PollOptionAPIResponse in
models.PollAPIResponse) so consumers see options without embedding the parent
Poll; update any corresponding models.PollAPIResponse and
models.PollCursorPageResult references to the APIResponse variant to keep
consistency.
| { | ||
| "type": "string", | ||
| "description": "Poll ID", | ||
| "name": "pollId", | ||
| "in": "path", | ||
| "required": true | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Find parameter naming patterns in Go source code handlers
rg -n 'pollId|pollID|optionId|optionID' --type=go -g '!docs.go' 2>/dev/null | head -50Repository: GenerateNU/toggo
Length of output: 5602
🏁 Script executed:
#!/bin/bash
# Check the actual pattern used in docs.go for path parameters
rg -A2 '"name": "(poll|option|trip|comment|activity)' backend/docs/docs.go | grep -E '"name"|"in"' | head -30Repository: GenerateNU/toggo
Length of output: 1281
🏁 Script executed:
#!/bin/bash
# Search for swagger annotations in Go handler files
fd -e go -g '!docs.go' --path '*handler*' . && find . -name '*handler*.go' -type f 2>/dev/null | head -10Repository: GenerateNU/toggo
Length of output: 300
🏁 Script executed:
#!/bin/bash
# Find the poll handler functions with their swagger annotations
fd -e go '!docs.go' -type f | xargs grep -l "GetPoll\|UpdatePoll\|DeletePoll\|AddOption\|DeleteOption" | grep -i handlerRepository: GenerateNU/toggo
Length of output: 230
🏁 Script executed:
#!/bin/bash
# Search for swagger annotations on poll-related handlers
rg -B5 'func.*GetPoll|func.*UpdatePoll|func.*DeletePoll|func.*AddOption|func.*DeleteOption' --type=go -g '!docs.go' | head -80Repository: GenerateNU/toggo
Length of output: 5724
🏁 Script executed:
#!/bin/bash
# Find the controller file for polls handlers with swagger annotations
find . -name "*controller*" -o -name "*handler*" | grep -i pollRepository: GenerateNU/toggo
Length of output: 42
🏁 Script executed:
#!/bin/bash
# Search for swagger annotations `@Param` for poll endpoints
rg -B10 'func.*\(.*GetPoll\|UpdatePoll\|DeletePoll\|AddOption\|DeleteOption\)' . -A2 | grep -E '@Param|@Router|func \(|pollI|optionI' | head -60Repository: GenerateNU/toggo
Length of output: 42
🏁 Script executed:
#!/bin/bash
# Find all go files in the server/handlers or controllers directory
find . -type f -name "*.go" | grep -E '(controller|handler)' | grep -v docsRepository: GenerateNU/toggo
Length of output: 568
🏁 Script executed:
#!/bin/bash
# Extract the poll controller functions with their swagger annotations
cat ./backend/internal/controllers/polls.go | head -200Repository: GenerateNU/toggo
Length of output: 5901
🏁 Script executed:
#!/bin/bash
# Search for `@Param` annotations in the polls controller
rg -n '@Param.*pollI|@Param.*optionI' ./backend/internal/controllers/polls.goRepository: GenerateNU/toggo
Length of output: 448
Use uppercase ID for poll and option path parameters to match the existing naming convention.
The swagger annotations in backend/internal/controllers/polls.go use pollId and optionId, but all other path parameters in the API use uppercase ID (tripID, commentID, activityID, userID). Change @Param pollId to @Param pollID and @Param optionId to @Param optionID for consistency.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@backend/docs/docs.go` around lines 2335 - 2341, Update the swagger
path-parameter names to use uppercase "ID" for consistency: replace occurrences
of "@Param pollId" with "@Param pollID" and "@Param optionId" with "@Param
optionID" in the poll controller swagger annotations (check
backend/internal/controllers/polls.go), and ensure any corresponding route/path
parameter names and generated docs (e.g., entries in docs.go) match the new
"pollID" and "optionID" identifiers so the annotation names and actual path
parameter names stay identical.
| "delete": { | ||
| "description": "Deletes a poll and all associated options and votes, returns the deleted poll", | ||
| "produces": [ | ||
| "application/json" | ||
| ], | ||
| "tags": [ | ||
| "polls" | ||
| ], | ||
| "summary": "Delete a poll", | ||
| "operationId": "deletePoll", | ||
| "parameters": [ | ||
| { | ||
| "type": "string", | ||
| "description": "Trip ID", | ||
| "name": "tripID", | ||
| "in": "path", | ||
| "required": true | ||
| }, | ||
| { | ||
| "type": "string", | ||
| "description": "Poll ID", | ||
| "name": "pollId", | ||
| "in": "path", | ||
| "required": true | ||
| } | ||
| ], | ||
| "responses": { | ||
| "200": { | ||
| "description": "OK", | ||
| "schema": { | ||
| "$ref": "#/definitions/models.PollAPIResponse" | ||
| } | ||
| }, | ||
| "400": { | ||
| "description": "Bad Request", | ||
| "schema": { | ||
| "$ref": "#/definitions/errs.APIError" | ||
| } | ||
| }, | ||
| "401": { | ||
| "description": "Unauthorized", | ||
| "schema": { | ||
| "$ref": "#/definitions/errs.APIError" | ||
| } | ||
| }, | ||
| "403": { | ||
| "description": "Forbidden", | ||
| "schema": { | ||
| "$ref": "#/definitions/errs.APIError" | ||
| } | ||
| }, | ||
| "404": { | ||
| "description": "Not Found", | ||
| "schema": { | ||
| "$ref": "#/definitions/errs.APIError" | ||
| } | ||
| }, | ||
| "500": { | ||
| "description": "Internal Server Error", | ||
| "schema": { | ||
| "$ref": "#/definitions/errs.APIError" | ||
| } | ||
| } | ||
| } | ||
| }, |
There was a problem hiding this comment.
DELETE poll and poll option return 200 with a body, breaking convention with all other DELETE endpoints.
Every other DELETE endpoint in this API returns 204 No Content (deleteComment, deleteTrip, deleteActivity, removeMember, removeCategoryFromActivity). The poll DELETE endpoints return 200 with the deleted resource. If this is intentional, it should be documented as a deliberate deviation. Otherwise, align with the existing convention and return 204.
Also applies to: 2622-2700
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@backend/docs/docs.go` around lines 2382 - 2446, The OpenAPI docs for the poll
DELETE endpoints currently return 200 with a response body (operationId
"deletePoll" and the other poll DELETE entry at 2622-2700, likely
"deletePollOption"); change these to follow the API convention used elsewhere by
replacing the 200 response with a 204 No Content response that has no response
schema, and remove the response body/schema entries for the 200 case; if
returning the deleted resource was intentional, instead add an explicit comment
in the spec noting the deliberate deviation.
| "responses": { | ||
| "201": { | ||
| "description": "Created", | ||
| "schema": { | ||
| "$ref": "#/definitions/models.PollOption" | ||
| } | ||
| }, |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# Find Go source files (excluding docs.go and tests)
find . -name "*.go" -type f ! -path "*/docs/*" ! -name "*_test.go" ! -name "docs.go" | head -20Repository: GenerateNU/toggo
Length of output: 835
🏁 Script executed:
# Search for handler definitions related to poll endpoints
rg -n "addPollOption|deletePollOption" --type=go -g '!docs.go' -g '!*_test.go' -B3 -A10Repository: GenerateNU/toggo
Length of output: 2239
🏁 Script executed:
# Search for PollOptionAPIResponse definition
rg -n "type PollOptionAPIResponse" --type=go -g '!docs.go' -B2 -A15Repository: GenerateNU/toggo
Length of output: 1443
🏁 Script executed:
# Check the docs.go file at the mentioned lines
sed -n '2565,2580p' backend/docs/docs.go
sed -n '2650,2665p' backend/docs/docs.goRepository: GenerateNU/toggo
Length of output: 1290
🏁 Script executed:
# Check models.PollOption definition to see if circular reference exists
rg -n "type PollOption struct" --type=go -g '!docs.go' -A20Repository: GenerateNU/toggo
Length of output: 1808
Change addPollOption and deletePollOption handlers to return models.PollOptionAPIResponse.
The handler annotations in backend/internal/controllers/polls.go (lines 230 and 274) currently specify models.PollOption as the response type. This model includes an ORM back-reference to Poll (line 53), which creates a circular reference when serialized. Use models.PollOptionAPIResponse instead—it already exists with the appropriate fields (vote_count, voted) and avoids exposing internal ORM relationships.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@backend/docs/docs.go` around lines 2570 - 2576, Update the response type for
the addPollOption and deletePollOption handlers from models.PollOption to
models.PollOptionAPIResponse to avoid serializing the ORM back-reference; locate
the OpenAPI/Swagger response annotation for the addPollOption and
deletePollOption handlers (currently referencing "$ref":
"#/definitions/models.PollOption") and change it to "$ref":
"#/definitions/models.PollOptionAPIResponse", ensuring the handlers still return
the API response struct shape (vote_count, voted) so the docs and serialization
match the existing models.PollOptionAPIResponse.
| "models.PollOption": { | ||
| "type": "object", | ||
| "properties": { | ||
| "entity_id": { | ||
| "type": "string" | ||
| }, | ||
| "entity_type": { | ||
| "type": "string" | ||
| }, | ||
| "id": { | ||
| "type": "string" | ||
| }, | ||
| "name": { | ||
| "type": "string" | ||
| }, | ||
| "option_type": { | ||
| "$ref": "#/definitions/models.OptionType" | ||
| }, | ||
| "poll": { | ||
| "description": "Relations", | ||
| "allOf": [ | ||
| { | ||
| "$ref": "#/definitions/models.Poll" | ||
| } | ||
| ] | ||
| }, | ||
| "poll_id": { | ||
| "type": "string" | ||
| } | ||
| } | ||
| }, |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Find the polls model file
fd 'polls\.go' --type=f | grep -E '(models|backend)'Repository: GenerateNU/toggo
Length of output: 279
🏁 Script executed:
#!/bin/bash
# Check the PollOption struct definition
rg -A 30 'type\s+PollOption\s+struct' --type goRepository: GenerateNU/toggo
Length of output: 2507
🏁 Script executed:
#!/bin/bash
# Check if there's a PollOptionAPIResponse
rg 'PollOptionAPIResponse' --type goRepository: GenerateNU/toggo
Length of output: 703
🏁 Script executed:
#!/bin/bash
# Find and examine the addPollOption and deletePollOption functions
rg -B 2 -A 10 'func.*addPollOption|func.*deletePollOption' --type goRepository: GenerateNU/toggo
Length of output: 42
🏁 Script executed:
#!/bin/bash
# Check the Poll struct definition
rg -A 50 'type\s+Poll\s+struct' backend/internal/models/polls.go | head -80Repository: GenerateNU/toggo
Length of output: 2423
🏁 Script executed:
#!/bin/bash
# Check PollOptionAPIResponse definition
rg -A 15 'type\s+PollOptionAPIResponse\s+struct' backend/internal/models/polls.goRepository: GenerateNU/toggo
Length of output: 663
🏁 Script executed:
#!/bin/bash
# Find controllers for poll options - likely POST/DELETE endpoints
rg 'func.*Poll.*Option|CreateOption|DeleteOption' backend/internal/controllers/polls.go -i -B 2 -A 5Repository: GenerateNU/toggo
Length of output: 800
🏁 Script executed:
#!/bin/bash
# Check docs.go to see if circular reference is actually generated
rg -A 5 'models.PollOption' backend/docs/docs.go | head -50Repository: GenerateNU/toggo
Length of output: 1358
🏁 Script executed:
#!/bin/bash
# Verify the exact location of PollOption definition in docs.go and check for circular ref
rg -n '"models.PollOption"' backend/docs/docs.go | head -20Repository: GenerateNU/toggo
Length of output: 95
🏁 Script executed:
#!/bin/bash
# Get the full PollOption schema definition from docs.go to see the poll field
sed -n '4217,4280p' backend/docs/docs.goRepository: GenerateNU/toggo
Length of output: 1890
🏁 Script executed:
#!/bin/bash
# Check what the AddOption and DeleteOption endpoints actually return
rg -B 5 -A 15 'func.*\(pc \*PollController\) AddOption' backend/internal/controllers/polls.goRepository: GenerateNU/toggo
Length of output: 706
🏁 Script executed:
#!/bin/bash
# Check the service layer to see what's returned
rg -B 2 -A 10 'func.*\(ps \*PollService\) AddOption|func.*\(ps \*PollService\) DeleteOption' backend/internal/services/polls.goRepository: GenerateNU/toggo
Length of output: 42
🏁 Script executed:
#!/bin/bash
# Get the full AddOption and DeleteOption implementations to see what they return
rg -B 2 -A 30 'func.*\(pc \*PollController\) AddOption|func.*\(pc \*PollController\) DeleteOption' backend/internal/controllers/polls.go | head -100Repository: GenerateNU/toggo
Length of output: 1704
🏁 Script executed:
#!/bin/bash
# Check the Poll struct in docs.go to see if it references PollOption
sed -n '4135,4220p' backend/docs/docs.go | grep -A 50 '"models.Poll"'Repository: GenerateNU/toggo
Length of output: 1574
Add swaggerignore:"true" to the Poll field in PollOption struct and update endpoint return types.
The Poll field in PollOption (backend/internal/models/polls.go) lacks the swaggerignore:"true" tag. This causes the Swagger spec to include a back-reference that creates a circular dependency: models.Poll references models.PollOption via the options array, and models.PollOption references back to models.Poll. Client code generators (swagger-codegen, openapi-generator) fail or produce infinite recursion with this circular structure.
Additionally, the AddOption and DeleteOption endpoints in PollController document their return type as models.PollOption, but should return models.PollOptionAPIResponse (which exists and is designed without back-references). Update the Swagger doc comments to @Success {object} models.PollOptionAPIResponse and ensure the service layer returns the correct type.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@backend/docs/docs.go` around lines 4217 - 4247, The PollOption struct's Poll
field is causing a circular Swagger reference; add the struct tag
`swaggerignore:"true"` to the Poll field in backend/internal/models/polls.go
(the PollOption struct) to prevent serialization of the back-reference, and
update the PollController endpoint docs for AddOption and DeleteOption to
`@Success {object} models.PollOptionAPIResponse` (replace the existing
`models.PollOption`) and adjust the service/controller return value to return a
models.PollOptionAPIResponse instance instead of models.PollOption so the
documented and actual response types match.
| "models.Poll": { | ||
| "type": "object", | ||
| "properties": { | ||
| "created_at": { | ||
| "type": "string" | ||
| }, | ||
| "created_by": { | ||
| "type": "string" | ||
| }, | ||
| "deadline": { | ||
| "type": "string" | ||
| }, | ||
| "id": { | ||
| "type": "string" | ||
| }, | ||
| "options": { | ||
| "description": "Relations", | ||
| "type": "array", | ||
| "items": { | ||
| "$ref": "#/definitions/models.PollOption" | ||
| } | ||
| }, | ||
| "poll_type": { | ||
| "$ref": "#/definitions/models.PollType" | ||
| }, | ||
| "question": { | ||
| "type": "string" | ||
| }, | ||
| "trip_id": { | ||
| "type": "string" | ||
| } | ||
| } | ||
| }, | ||
| "models.PollAPIResponse": { | ||
| "type": "object", | ||
| "properties": { | ||
| "created_at": { | ||
| "type": "string" | ||
| }, | ||
| "created_by": { | ||
| "type": "string" | ||
| }, | ||
| "deadline": { | ||
| "type": "string" | ||
| }, | ||
| "id": { | ||
| "type": "string" | ||
| }, | ||
| "options": { | ||
| "type": "array", | ||
| "items": { | ||
| "$ref": "#/definitions/models.PollOptionAPIResponse" | ||
| } | ||
| }, | ||
| "poll_type": { | ||
| "$ref": "#/definitions/models.PollType" | ||
| }, | ||
| "question": { | ||
| "type": "string" | ||
| }, | ||
| "trip_id": { | ||
| "type": "string" | ||
| } | ||
| } | ||
| }, | ||
| "models.PollCursorPageResult": { | ||
| "type": "object", | ||
| "properties": { | ||
| "items": { | ||
| "type": "array", | ||
| "items": { | ||
| "$ref": "#/definitions/models.PollAPIResponse" | ||
| } | ||
| }, | ||
| "limit": { | ||
| "type": "integer" | ||
| }, | ||
| "next_cursor": { | ||
| "type": "string" | ||
| } | ||
| } | ||
| }, | ||
| "models.PollOption": { | ||
| "type": "object", | ||
| "properties": { | ||
| "entity_id": { | ||
| "type": "string" | ||
| }, | ||
| "entity_type": { | ||
| "type": "string" | ||
| }, | ||
| "id": { | ||
| "type": "string" | ||
| }, | ||
| "name": { | ||
| "type": "string" | ||
| }, | ||
| "option_type": { | ||
| "$ref": "#/definitions/models.OptionType" | ||
| }, | ||
| "poll": { | ||
| "description": "Relations", | ||
| "allOf": [ | ||
| { | ||
| "$ref": "#/definitions/models.Poll" | ||
| } | ||
| ] | ||
| }, | ||
| "poll_id": { | ||
| "type": "string" | ||
| } | ||
| } |
There was a problem hiding this comment.
Avoid circular Poll ↔ PollOption schemas in the public spec.
models.Poll includes models.PollOption, and models.PollOption includes models.Poll. This circular reference can break some Swagger/OpenAPI code generators and can mislead API consumers. Prefer a one-way schema for responses (for example, PollOptionAPIResponse) or remove the back-reference from models.PollOption in the docs.
Proposed doc adjustment
- "poll": {
- "description": "Relations",
- "allOf": [
- {
- "$ref": "#/definitions/models.Poll"
- }
- ]
- },🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@backend/docs/swagger.json` around lines 4129 - 4240, The public OpenAPI
schema currently creates a circular reference between models.Poll and
models.PollOption because models.Poll references models.PollOption and
models.PollOption contains a "poll" property that $ref's models.Poll; remove
that back-reference or replace it with a non-circular alternative: update the
models.PollOption definition to drop the "poll" property (leave poll_id only) or
change its "poll" $ref to point to a one-way response type such as
models.PollAPIResponse (or models.PollOptionAPIResponse where appropriate) so
only Poll -> PollOption exists in the public spec and generators won’t encounter
circular schemas.
| models.Poll: | ||
| properties: | ||
| created_at: | ||
| type: string | ||
| created_by: | ||
| type: string | ||
| deadline: | ||
| type: string | ||
| id: | ||
| type: string | ||
| options: | ||
| description: Relations | ||
| items: | ||
| $ref: '#/definitions/models.PollOption' | ||
| type: array | ||
| poll_type: | ||
| $ref: '#/definitions/models.PollType' | ||
| question: | ||
| type: string | ||
| trip_id: | ||
| type: string | ||
| type: object | ||
| models.PollAPIResponse: | ||
| properties: | ||
| created_at: | ||
| type: string | ||
| created_by: | ||
| type: string | ||
| deadline: | ||
| type: string | ||
| id: | ||
| type: string | ||
| options: | ||
| items: | ||
| $ref: '#/definitions/models.PollOptionAPIResponse' | ||
| type: array | ||
| poll_type: | ||
| $ref: '#/definitions/models.PollType' | ||
| question: | ||
| type: string | ||
| trip_id: | ||
| type: string | ||
| type: object | ||
| models.PollCursorPageResult: | ||
| properties: | ||
| items: | ||
| items: | ||
| $ref: '#/definitions/models.PollAPIResponse' | ||
| type: array | ||
| limit: | ||
| type: integer | ||
| next_cursor: | ||
| type: string | ||
| type: object | ||
| models.PollOption: | ||
| properties: | ||
| entity_id: | ||
| type: string | ||
| entity_type: | ||
| type: string | ||
| id: | ||
| type: string | ||
| name: | ||
| type: string | ||
| option_type: | ||
| $ref: '#/definitions/models.OptionType' | ||
| poll: | ||
| allOf: | ||
| - $ref: '#/definitions/models.Poll' | ||
| description: Relations | ||
| poll_id: | ||
| type: string | ||
| type: object |
There was a problem hiding this comment.
Avoid circular Poll ↔ PollOption schemas in the public spec.
models.Poll includes models.PollOption, and models.PollOption includes models.Poll. This circular reference can break some Swagger/OpenAPI code generators and can mislead API consumers. Prefer a one-way schema for responses (for example, PollOptionAPIResponse) or remove the back-reference from models.PollOption in the docs.
Proposed doc adjustment
models.PollOption:
properties:
entity_id:
type: string
entity_type:
type: string
id:
type: string
name:
type: string
option_type:
$ref: '#/definitions/models.OptionType'
- poll:
- allOf:
- - $ref: '#/definitions/models.Poll'
- description: Relations
poll_id:
type: string📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| models.Poll: | |
| properties: | |
| created_at: | |
| type: string | |
| created_by: | |
| type: string | |
| deadline: | |
| type: string | |
| id: | |
| type: string | |
| options: | |
| description: Relations | |
| items: | |
| $ref: '#/definitions/models.PollOption' | |
| type: array | |
| poll_type: | |
| $ref: '#/definitions/models.PollType' | |
| question: | |
| type: string | |
| trip_id: | |
| type: string | |
| type: object | |
| models.PollAPIResponse: | |
| properties: | |
| created_at: | |
| type: string | |
| created_by: | |
| type: string | |
| deadline: | |
| type: string | |
| id: | |
| type: string | |
| options: | |
| items: | |
| $ref: '#/definitions/models.PollOptionAPIResponse' | |
| type: array | |
| poll_type: | |
| $ref: '#/definitions/models.PollType' | |
| question: | |
| type: string | |
| trip_id: | |
| type: string | |
| type: object | |
| models.PollCursorPageResult: | |
| properties: | |
| items: | |
| items: | |
| $ref: '#/definitions/models.PollAPIResponse' | |
| type: array | |
| limit: | |
| type: integer | |
| next_cursor: | |
| type: string | |
| type: object | |
| models.PollOption: | |
| properties: | |
| entity_id: | |
| type: string | |
| entity_type: | |
| type: string | |
| id: | |
| type: string | |
| name: | |
| type: string | |
| option_type: | |
| $ref: '#/definitions/models.OptionType' | |
| poll: | |
| allOf: | |
| - $ref: '#/definitions/models.Poll' | |
| description: Relations | |
| poll_id: | |
| type: string | |
| type: object | |
| models.Poll: | |
| properties: | |
| created_at: | |
| type: string | |
| created_by: | |
| type: string | |
| deadline: | |
| type: string | |
| id: | |
| type: string | |
| options: | |
| description: Relations | |
| items: | |
| $ref: '#/definitions/models.PollOption' | |
| type: array | |
| poll_type: | |
| $ref: '#/definitions/models.PollType' | |
| question: | |
| type: string | |
| trip_id: | |
| type: string | |
| type: object | |
| models.PollAPIResponse: | |
| properties: | |
| created_at: | |
| type: string | |
| created_by: | |
| type: string | |
| deadline: | |
| type: string | |
| id: | |
| type: string | |
| options: | |
| items: | |
| $ref: '#/definitions/models.PollOptionAPIResponse' | |
| type: array | |
| poll_type: | |
| $ref: '#/definitions/models.PollType' | |
| question: | |
| type: string | |
| trip_id: | |
| type: string | |
| type: object | |
| models.PollCursorPageResult: | |
| properties: | |
| items: | |
| items: | |
| $ref: '#/definitions/models.PollAPIResponse' | |
| type: array | |
| limit: | |
| type: integer | |
| next_cursor: | |
| type: string | |
| type: object | |
| models.PollOption: | |
| properties: | |
| entity_id: | |
| type: string | |
| entity_type: | |
| type: string | |
| id: | |
| type: string | |
| name: | |
| type: string | |
| option_type: | |
| $ref: '#/definitions/models.OptionType' | |
| poll_id: | |
| type: string | |
| type: object |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@backend/docs/swagger.yaml` around lines 665 - 737, The public swagger spec
contains a circular reference between models.Poll and models.PollOption
(models.Poll.options -> models.PollOption, and models.PollOption.poll ->
models.Poll); remove the back-reference to break the cycle by deleting or
replacing the poll property inside models.PollOption (the "poll" allOf/$ref
entry) and instead ensure Poll's options use a one-way response type (e.g.,
change models.Poll.options to reference models.PollOptionAPIResponse or
models.PollOptionAPIResponse in models.PollAPIResponse) so consumers see options
without embedding the parent Poll; update any corresponding
models.PollAPIResponse and models.PollCursorPageResult references to the
APIResponse variant to keep consistency.
There was a problem hiding this comment.
nit: Do you mind deleting the bun.BaseModel for Poll and using the Poll struct in the returned object?
// Poll represents a voting poll attached to a trip.
type Poll struct {
bun.BaseModel `bun:"table:polls,alias:p"`
ID uuid.UUID `bun:"id,pk,type:uuid" json:"id"`
TripID uuid.UUID `bun:"trip_id,type:uuid,notnull" json:"trip_id"`
CreatedBy uuid.UUID `bun:"created_by,type:uuid,notnull" json:"created_by"`
Question string `bun:"question,notnull" json:"question"`
PollType PollType `bun:"poll_type,notnull" json:"poll_type"`
CreatedAt time.Time `bun:"created_at,nullzero,default:now()" json:"created_at"`
Deadline *time.Time `bun:"deadline,nullzero" json:"deadline,omitempty"`
// Relations
Options []PollOption `bun:"rel:has-many,join:id=poll_id" json:"options,omitempty"`
}
// PollAPIResponse is the external representation of a poll with vote data.
type PollAPIResponse struct {
ID uuid.UUID `json:"id"`
TripID uuid.UUID `json:"trip_id"`
CreatedBy uuid.UUID `json:"created_by"`
Question string `json:"question"`
PollType PollType `json:"poll_type"`
CreatedAt time.Time `json:"created_at"`
Deadline *time.Time `json:"deadline,omitempty"`
Options []PollOptionAPIResponse `json:"options"`
}
I appreciate that you actually used bun the way it was meant to be 😭 but I think the duplication for (s *PollService) toAPIResponse and similarly for PollOption might be off.
PLEASE do lmk if you have any strong feelings on this. If you think it's a heavy lift, we could keep the duplication and rename in the frontend. However, we might as well just use the same structs if they're identical.
i don’t have an issue with that. The breaking trail just poisons so far i haven’t been able to figure it out |
Summary (by bart and not the clanker)
just added "swaggoignore: true" to the models. The docs seems to generate, but might need someone to double check just to be sure. Otherwise, then like I might need help debugging the middleware. Lowk impossible
Description
How has this been tested?
Checklist
User-Visible Changes
swaggerignore:"true"tags to database models (Poll, PollOption, PollVote) to prevent them from appearing in Swagger documentation while preserving ORM mappings.Changes by Category
Infra
Author Contribution
Note: This commit includes the initial addition of the backend codebase with 355 files. The core changes to models.go are minimal (3 lines): adding
swaggerignore:"true"to three embeddedbun.BaseModelstruct tags. The documentation files are auto-generated artifacts that were regenerated following these model changes.