Conversation
|
Warning Rate limit exceeded
To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing. ⌛ 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: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughウォークスルーQuestionnaire のレスポンス取得でドラフトアクセスの判定を局所変数 変更内容
見積もりコード審査工数🎯 4 (複雑) | ⏱️ ~45 分 🚥 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. Review rate limit: 0/1 reviews remaining, refill in 48 minutes and 22 seconds.Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1543 +/- ##
==========================================
+ Coverage 63.83% 63.93% +0.10%
==========================================
Files 27 27
Lines 4040 4046 +6
==========================================
+ Hits 2579 2587 +8
+ Misses 1073 1071 -2
Partials 388 388 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
controller/questionnaire_test.go (1)
166-181: 並列テスト向けに fixture 初期化をsync.Onceで保護すると安全です。
newSampleQuestionnaire()はt.Parallel()なテストから多数呼ばれるため、初回呼び出しが並行するとsetupSampleQuestionnaire()の package-level 変数更新が競合し得ます。sampleQuestionnaire.Titleの手動ガードよりsync.Onceに寄せる方が堅いです。修正案
import ( "bytes" "context" "encoding/json" "errors" "fmt" "net/http" "net/http/httptest" "net/url" "sort" "strings" + "sync" "testing" "time" @@ sampleQuestionSettingsMultipleChoice = openapi.NewQuestion{} sampleQeustionsettingsScale = openapi.NewQuestion{} sampleQuestionnaire = openapi.PostQuestionnaireJSONRequestBody{} + sampleQuestionnaireOnce sync.Once ) func setupSampleQuestionnaire() { - if sampleQuestionnaire.Title != "" { - return - } + sampleQuestionnaireOnce.Do(func() { sampleQuestionSettingsText = openapi.NewQuestion{ Title: "質問(テキスト)", IsRequired: true, } @@ sampleQuestionnaire = openapi.PostQuestionnaireJSONRequestBody{ Admin: sampleAdmin, Description: "第1回集会らん☆ぷろ参加者募集", @@ Target: sampleTarget, Title: "第1回集会らん☆ぷろ募集アンケート", } + }) }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@controller/questionnaire_test.go` around lines 166 - 181, The setup of package-level fixtures is racy when newSampleQuestionnaire() is called from parallel tests; change setupSampleQuestionnaire() invocation to run exactly once using sync.Once to protect sampleQuestionnaire initialization. Add a package-level sync.Once (e.g., var initSampleQuestionnaire sync.Once) and call initSampleQuestionnaire.Do(setupSampleQuestionnaire) inside newSampleQuestionnaire() before marshalling, leaving the deep-copy/unmarshal logic intact so parallel callers get isolated copies of sampleQuestionnaire.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@controller/questionnaire_test.go`:
- Around line 2589-2618: Add a test case to cover the non-administrator default
(IsDraft == nil) path: in the test table inside questionnaire_test.go add an
entry similar to the existing "non administrator cannot view other respondents
draft responses" case but leave params.IsDraft nil (omit IsDraft) and
OnlyMyResponse set to &constFalse; assert the call to GetQuestionnaireResponses
(using args.userID userTwo and args.questionnaireID
questionnaireDetail.QuestionnaireId) returns an error or does not include the
draft response ID (response03.ResponseId) just like the explicit IsDraft=true
case, ensuring the default behavior does not leak draft IDs.
In `@controller/questionnaire.go`:
- Around line 1132-1143: The code currently skips the admin check when
params.IsDraft == nil allowing non-admins to retrieve others' drafts; update the
block around params.IsDraft/onlyMyResponse to treat a nil IsDraft as "not
explicitly requesting drafts" by performing the same admin check (use
q.IAdministrator.CheckQuestionnaireAdmin and also consider the local
adminUserIDs bypass used in controller/middleware.go), and then ensure you pass
an explicit non-nil *bool (true/false as appropriate) into GetRespondentDetails
so nil no longer implies draft-including behavior for non-admins; reference
params.IsDraft, onlyMyResponse, q.IAdministrator.CheckQuestionnaireAdmin,
GetRespondentDetails and adminUserIDs when making the change.
---
Nitpick comments:
In `@controller/questionnaire_test.go`:
- Around line 166-181: The setup of package-level fixtures is racy when
newSampleQuestionnaire() is called from parallel tests; change
setupSampleQuestionnaire() invocation to run exactly once using sync.Once to
protect sampleQuestionnaire initialization. Add a package-level sync.Once (e.g.,
var initSampleQuestionnaire sync.Once) and call
initSampleQuestionnaire.Do(setupSampleQuestionnaire) inside
newSampleQuestionnaire() before marshalling, leaving the deep-copy/unmarshal
logic intact so parallel callers get isolated copies of sampleQuestionnaire.
🪄 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: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 1e493a3a-dbe3-449a-8af7-d06260e779b3
📒 Files selected for processing (3)
controller/questionnaire.gocontroller/questionnaire_test.gocontroller/response_test.go
There was a problem hiding this comment.
🧹 Nitpick comments (1)
controller/questionnaire.go (1)
1132-1143: ロジックは正しいですが、ネストを解消して意図を明示するとより読みやすくなります。現状のロジックを (
onlyMyResponse,params.IsDraft) の組合せで検証したところ、期待通りに動作することを確認できました(!onlyMyResponse && IsDraft==nil→ 提出済みのみ、!onlyMyResponse && *IsDraft==true→ 403、onlyMyResponseの場合はユーザー自身の下書きが見える)。一方で以下の点が気になります:
submittedOnlyはparams.IsDraft == nilのときのみ使用されるため、外側のif内で宣言する必要がありません。ネストしたifを1つにまとめると意図が明確になります。- 過去レビューで提案されていた「管理者は他ユーザーの下書きを閲覧可」というバイパスが無く、テスト(L2572「administrator cannot view other respondents draft responses」)でも
isErr: trueを期待しているので、管理者であっても他者の下書きをこのエンドポイントから閲覧できない という仕様になっています。意図通りであれば問題ありませんが、UI側で管理者の下書き確認フローが存在する場合は別途影響確認をお願いします。♻️ 提案する簡素化
- isDraft := params.IsDraft - if !onlyMyResponse { - submittedOnly := false - if params.IsDraft == nil { - isDraft = &submittedOnly - } - } - if isDraft != nil && *isDraft && !onlyMyResponse { + isDraft := params.IsDraft + if !onlyMyResponse && isDraft == nil { + submittedOnly := false + isDraft = &submittedOnly + } + if !onlyMyResponse && isDraft != nil && *isDraft { c.Logger().Infof("user %s is not allowed to view other respondents' drafts for questionnaire %d", userID, questionnaireID) return res, echo.NewHTTPError(http.StatusForbidden, "you do not have permission to view other respondents' drafts") }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@controller/questionnaire.go` around lines 1132 - 1143, The current nested ifs around params.IsDraft and onlyMyResponse make intent unclear; simplify by computing isDraft once: if onlyMyResponse then set isDraft = params.IsDraft (allow nil) else if params.IsDraft == nil set a local submittedOnly := false and set isDraft = &submittedOnly else set isDraft = params.IsDraft; then keep the existing permission check that if isDraft != nil && *isDraft && !onlyMyResponse returns 403; update references to isDraft in the call to q.GetRespondentDetails and confirm that there is no administrator bypass required for viewing other users' drafts (adjust tests or UI flow if that is a mismatch).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@controller/questionnaire.go`:
- Around line 1132-1143: The current nested ifs around params.IsDraft and
onlyMyResponse make intent unclear; simplify by computing isDraft once: if
onlyMyResponse then set isDraft = params.IsDraft (allow nil) else if
params.IsDraft == nil set a local submittedOnly := false and set isDraft =
&submittedOnly else set isDraft = params.IsDraft; then keep the existing
permission check that if isDraft != nil && *isDraft && !onlyMyResponse returns
403; update references to isDraft in the call to q.GetRespondentDetails and
confirm that there is no administrator bypass required for viewing other users'
drafts (adjust tests or UI flow if that is a mismatch).
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 004d517b-1e0e-419d-9157-6735c3785f08
📒 Files selected for processing (2)
controller/questionnaire.gocontroller/questionnaire_test.go
| isDraft := params.IsDraft | ||
| if !onlyMyResponse { | ||
| submittedOnly := false | ||
| if params.IsDraft == nil { | ||
| isDraft = &submittedOnly | ||
| } | ||
| } | ||
| if isDraft != nil && *isDraft && !onlyMyResponse { | ||
| c.Logger().Infof("user %s is not allowed to view other respondents' drafts for questionnaire %d", userID, questionnaireID) | ||
| return res, echo.NewHTTPError(http.StatusForbidden, "you do not have permission to view other respondents' drafts") | ||
| } | ||
| respondentDetails, err := q.GetRespondentDetails(c.Request().Context(), questionnaireID, sort, onlyMyResponse, userID, isDraft) |
There was a problem hiding this comment.
| isDraft := params.IsDraft | |
| if !onlyMyResponse { | |
| submittedOnly := false | |
| if params.IsDraft == nil { | |
| isDraft = &submittedOnly | |
| } | |
| } | |
| if isDraft != nil && *isDraft && !onlyMyResponse { | |
| c.Logger().Infof("user %s is not allowed to view other respondents' drafts for questionnaire %d", userID, questionnaireID) | |
| return res, echo.NewHTTPError(http.StatusForbidden, "you do not have permission to view other respondents' drafts") | |
| } | |
| respondentDetails, err := q.GetRespondentDetails(c.Request().Context(), questionnaireID, sort, onlyMyResponse, userID, isDraft) | |
| if params.IsDraft != nil && *params.IsDraft { | |
| onlyMyResponse = true | |
| } | |
| respondentDetails, err := q.GetRespondentDetails(c.Request().Context(), questionnaireID, sort, onlyMyResponse, userID, params.IsDraft) |
ここはGET /questionnairesの実装に合わせて欲しいです
| MinLabel: &sampleQeustionsettingsScaleMinLabel, | ||
| MinValue: 1, | ||
| QuestionType: openapi.QuestionSettingsScaleQuestionTypeScale, | ||
| sampleQuestionnaireOnce.Do(func() { |
There was a problem hiding this comment.
[nit]
deep copyになるので、sampleQuestionnaireはグローバル変数にする必要がなさそう
ローカル変数にすることで、sampleQuestionnaireOnceが不要になり、よりシンプルでクリーンな実装になると思います
Summary by CodeRabbit
リリースノート
バグ修正
テスト