Repository navigation
Conversation
- 移除 /api/charts、/api/composite/create、/api/transit/create 強制登入限制 未登入可計算分析,結果不存 DB(chartId: null);登入後仍自動儲存 - 新增 /api/composite/create、/api/transit/create 端點(含流日影響分析) - 修復合圖 meta 缺漏:personB 補存 birthTime 與 timezone - 抽取 computeImpact 至 lib/transitImpact.ts 消除重複 - 修正 account/page.tsx 合圖偵測邏輯(chart.type → chart.chartKind) 並從 meta 讀取 personA/personB 出生資料供重新計算 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning Review limit reached
More reviews will be available in 27 minutes and 10 seconds. Learn how PR review limits work. Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file). ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits. 🚦 How do rate limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (7)
📝 WalkthroughWalkthroughAdds transit chart routes ( ChangesTransit & Composite Chart Features
Sequence Diagram(s)sequenceDiagram
participant Client
participant TransitCreate as POST /api/transit/create
participant computeHdResult
participant SwissEphemeris
participant computeImpact
participant Prisma
Client->>TransitCreate: birth fields
par HD calculation
TransitCreate->>computeHdResult: birth inputs
computeHdResult-->>TransitCreate: hdResult
and Ephemeris calculation
TransitCreate->>SwissEphemeris: current JD + planet indices
SwissEphemeris-->>TransitCreate: longitudes
end
TransitCreate->>TransitCreate: derive transit gates/centers/channels + combined
TransitCreate->>computeImpact: personal sets + transit sets
computeImpact-->>TransitCreate: ImpactLayer[]
alt unauthenticated
TransitCreate-->>Client: chartId null + result
else authenticated
TransitCreate->>Prisma: chart.create chartKind transit meta transitSnapshot
Prisma-->>TransitCreate: chart.id
TransitCreate-->>Client: chartId + result
end
sequenceDiagram
participant Client
participant CompositeCreate as POST /api/composite/create
participant computeHdResult
participant analyzeComposite
participant Prisma
Client->>CompositeCreate: personA + personB birth fields
par
CompositeCreate->>computeHdResult: personA inputs
computeHdResult-->>CompositeCreate: hdA
and
CompositeCreate->>computeHdResult: personB inputs
computeHdResult-->>CompositeCreate: hdB
end
CompositeCreate->>analyzeComposite: hdToCompositeInput(hdA) + hdToCompositeInput(hdB)
analyzeComposite-->>CompositeCreate: composite analysis
alt unauthenticated
CompositeCreate-->>Client: chartId null + analysis + metaA/metaB
else authenticated
CompositeCreate->>Prisma: chart.create chartKind composite meta personA/B
Prisma-->>CompositeCreate: chart.id
CompositeCreate-->>Client: chartId + analysis + metaA/metaB
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Poem
🚥 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.
Actionable comments posted: 8
🧹 Nitpick comments (2)
lib/transitImpact.ts (1)
16-64: ⚡ Quick winDocument the calculation principles inside
computeImpact.This function encodes three domain rules, but lacks comments explaining why each rule classifies impacts the way it does, which makes future changes brittle.
As per coding guidelines, "Each functionality should be implemented as an independent, reusable function with complete comments including calculation principles."
🤖 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 `@lib/transitImpact.ts` around lines 16 - 64, The computeImpact function contains three distinct domain rules for classifying impacts (center-activated, new-channel, and completing-channel) but lacks explanatory comments describing the calculation principles behind each rule. Add comment blocks above each of the three main loops (the transitCenterIds loop, the transitChannels loop, and the CHANNEL_DEFS loop) that clearly explain what principle or condition triggers each impact type and why that classification makes sense from a domain perspective. This will make the logic transparent and help future maintainers understand the business rules without reverse-engineering the code.Source: Coding guidelines
app/api/transit/route.ts (1)
5-42: 🏗️ Heavy liftExtract transit snapshot computation into one reusable helper with calculation comments.
Lines 5-42 duplicate the same body constants and longitude→gate/center/channel pipeline also implemented in
app/api/transit/create/route.tsandapp/api/transit/impact/route.ts. Centralizing this into a shared server utility will prevent drift and keep transit semantics consistent.As per coding guidelines, "Each functionality should be implemented as an independent, reusable function with complete comments including calculation principles."
🤖 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 `@app/api/transit/route.ts` around lines 5 - 42, Extract the transit snapshot computation pipeline (Swiss Ephemeris body constants SUN through PLUTO, the dateToJulianDay/calculatePosition/calculatePlanetGates chain, and the calculateCentersAndChannels call) from lines 5-42 into a dedicated reusable server utility function. Create a new function that accepts a Date parameter and returns an object containing the computed planets array, allGates set, and center/channel calculations. Move all body constants into this utility module, add detailed comments explaining the Swiss Ephemeris calculation principles and gate/center/channel logic, then replace the duplicated implementation in route.ts, create/route.ts, and impact/route.ts with calls to this shared helper function.Source: Coding guidelines
🤖 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 `@app/account/page.tsx`:
- Around line 227-231: The composite chart detection is inconsistent between two
locations in the file. Line 227 checks chart.chartKind === 'composite' to
compute HD results for both participants, but the UI gating at line 580 still
checks activeChart.type === 'composite' instead. Since new composite charts
created by app/api/composite/create/route.ts have chartKind set to 'composite'
but type set to an HD type, the UI gating at line 580 will fail to recognize
them. Update the condition at line 580 to check activeChart.chartKind ===
'composite' to match the detection logic at line 227, ensuring both the
computation and UI rendering use the same property for identifying composite
charts.
In `@app/api/charts/route.ts`:
- Around line 43-54: The error handling in the `computeHdResultServer` function
call (around line 106) needs to distinguish between input/domain validation
errors and actual server errors. Instead of returning a generic "伺服器錯誤" message
for all errors, wrap the `computeHdResultServer` call in a try-catch block that
catches and categorizes different error types. For validation or domain errors
(such as invalid birth data or chart computation issues), return a user-friendly
error message that explains what went wrong. Only return the generic server
error message for unexpected system-level errors. This allows unauthenticated
users to understand and correct their input rather than seeing an opaque error
message.
- Around line 11-12: Add validation for the `chartKind` variable immediately
after it is destructured from the request body in the line where you extract
`birthDate, birthTime, birthCity, timezone, name, chartKind`. The validation
should ensure that `chartKind` is not an empty string and contains only valid
chart type values that align with the contract expected by
account/composite/transit flows. Return an appropriate error response if the
validation fails, before any persistence operations occur.
In `@app/api/composite/create/route.ts`:
- Around line 31-37: The route handler uses an unsafe type assertion on the JSON
body without runtime validation of the actual structure and types. Before
accessing personA, personB, and name fields, add comprehensive validation to
ensure the body matches the expected shape and that all required fields are the
correct types (strings for birthDate, birthTime, birthCity, timezone, etc.).
Implement checks that verify not just the existence of these fields but also
their types and formats, returning a descriptive 400 error with field-level
guidance if any validation fails, rather than allowing the code to proceed with
potentially malformed data that could throw unhandled errors later in the
computeHdResultServer call.
In `@app/api/composite/route.ts`:
- Around line 24-27: The validation check for chartAId and chartBId in the
composite route handler only verifies their presence but does not validate that
they are strings, allowing invalid types to pass through and cause 500 errors in
Prisma operations. Enhance the validation condition to additionally check that
both chartAId and chartBId are of type string using typeof operator, ensuring
non-string values are rejected with a 400 status code and appropriate error
message before any database access occurs.
- Around line 9-17: In the toHdResult function, replace the unsafe type casts
with proper validation logic. For the chart.gates, chart.centers, and
chart.channels fields (all typed as unknown), add guard checks to verify they
are not null and are actually arrays before converting them to Sets. For the
profile property assignment on the return statement, remove the as any cast by
properly typing the profile object structure instead of relying on the unsafe
cast. Ensure each field is validated to prevent runtime crashes from malformed
or null Prisma Json data.
In `@app/api/transit/create/route.ts`:
- Around line 26-29: The Promise.all block calling
computeHdResultServer(birthDate, birthTime, timezone) can throw domain or input
validation errors (like unsupported birth years), but the error handling at
lines 148-150 converts all errors to HTTP 500 status codes. To fix this, wrap
the Promise.all block in a try-catch, and in the catch block distinguish between
validation/domain errors (which should return a 4xx status with a clear
user-friendly error message) and unexpected server errors (which should return
500). Check for specific error types or error properties to classify whether the
failure is due to invalid user input or an actual server issue, then respond
accordingly with the appropriate HTTP status code and error message.
In `@app/api/transit/impact/route.ts`:
- Around line 43-46: The code at lines 43-46 constructs Sets from untyped DB
JSON fields (chart.gates, chart.centers, chart.channels) using unsafe type casts
without validation. Add validation logic before constructing each Set to verify
that chart.gates is an array of numbers, chart.centers is an array of strings
corresponding to valid CenterName values, and chart.channels is an array of
strings. If any field fails validation, either throw an error with a descriptive
message or return early with an appropriate error response. This ensures that
malformed or legacy data from the database is caught before being used to
compute impact calculations.
---
Nitpick comments:
In `@app/api/transit/route.ts`:
- Around line 5-42: Extract the transit snapshot computation pipeline (Swiss
Ephemeris body constants SUN through PLUTO, the
dateToJulianDay/calculatePosition/calculatePlanetGates chain, and the
calculateCentersAndChannels call) from lines 5-42 into a dedicated reusable
server utility function. Create a new function that accepts a Date parameter and
returns an object containing the computed planets array, allGates set, and
center/channel calculations. Move all body constants into this utility module,
add detailed comments explaining the Swiss Ephemeris calculation principles and
gate/center/channel logic, then replace the duplicated implementation in
route.ts, create/route.ts, and impact/route.ts with calls to this shared helper
function.
In `@lib/transitImpact.ts`:
- Around line 16-64: The computeImpact function contains three distinct domain
rules for classifying impacts (center-activated, new-channel, and
completing-channel) but lacks explanatory comments describing the calculation
principles behind each rule. Add comment blocks above each of the three main
loops (the transitCenterIds loop, the transitChannels loop, and the CHANNEL_DEFS
loop) that clearly explain what principle or condition triggers each impact type
and why that classification makes sense from a domain perspective. This will
make the logic transparent and help future maintainers understand the business
rules without reverse-engineering the code.
🪄 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 Plus
Run ID: 938e240f-a8ec-43b0-9f18-639e5dd7958d
📒 Files selected for processing (8)
app/account/page.tsxapp/api/charts/route.tsapp/api/composite/create/route.tsapp/api/composite/route.tsapp/api/transit/create/route.tsapp/api/transit/impact/route.tsapp/api/transit/route.tslib/transitImpact.ts
| const { birthDate, birthTime, birthCity, timezone, name, chartKind } = body | ||
| let { type, authority, profile, definition, centers, channels, gates } = body |
There was a problem hiding this comment.
Validate chartKind before persisting.
chartKind is accepted as arbitrary input and can be stored as any string (including empty string), which weakens the cross-file contract used by account/composite/transit flows.
Suggested fix
- const { birthDate, birthTime, birthCity, timezone, name, chartKind } = body
+ const { birthDate, birthTime, birthCity, timezone, name, chartKind } = body
+ const allowedChartKinds = new Set(['personal', 'composite', 'transit'] as const)
+ const normalizedChartKind =
+ typeof chartKind === 'string' && allowedChartKinds.has(chartKind as 'personal' | 'composite' | 'transit')
+ ? chartKind
+ : 'personal'
@@
- chartKind: chartKind ?? 'personal',
+ chartKind: normalizedChartKind,Also applies to: 98-98
🤖 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 `@app/api/charts/route.ts` around lines 11 - 12, Add validation for the
`chartKind` variable immediately after it is destructured from the request body
in the line where you extract `birthDate, birthTime, birthCity, timezone, name,
chartKind`. The validation should ensure that `chartKind` is not an empty string
and contains only valid chart type values that align with the contract expected
by account/composite/transit flows. Return an appropriate error response if the
validation fails, before any persistence operations occur.
| const personalGates = new Set<number>(chart.gates as number[]) | ||
| const personalCenterIds = new Set<CenterName>((chart.centers as string[]) as CenterName[]) | ||
| const channelIdSet = new Set<string>(chart.channels as string[]) | ||
| const personalChannels = CHANNEL_DEFS.filter(ch => channelIdSet.has(ch.id)) |
There was a problem hiding this comment.
Validate persisted JSON shapes before constructing Sets.
Lines 43-46 trust untyped DB JSON via casts. If any row contains malformed/legacy gates/centers/channels, this can throw at runtime or produce invalid impact output.
Proposed fix
- const personalGates = new Set<number>(chart.gates as number[])
- const personalCenterIds = new Set<CenterName>((chart.centers as string[]) as CenterName[])
- const channelIdSet = new Set<string>(chart.channels as string[])
+ const gates = Array.isArray(chart.gates) && chart.gates.every(g => typeof g === 'number')
+ ? chart.gates
+ : null
+ const centers = Array.isArray(chart.centers) && chart.centers.every(c => typeof c === 'string')
+ ? chart.centers
+ : null
+ const channels = Array.isArray(chart.channels) && chart.channels.every(c => typeof c === 'string')
+ ? chart.channels
+ : null
+
+ if (!gates || !centers || !channels) {
+ return NextResponse.json({ error: '圖表資料格式錯誤,請重新計算後再試' }, { status: 422 })
+ }
+
+ const personalGates = new Set<number>(gates)
+ const personalCenterIds = new Set<CenterName>(centers as CenterName[])
+ const channelIdSet = new Set<string>(channels)🤖 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 `@app/api/transit/impact/route.ts` around lines 43 - 46, The code at lines
43-46 constructs Sets from untyped DB JSON fields (chart.gates, chart.centers,
chart.channels) using unsafe type casts without validation. Add validation logic
before constructing each Set to verify that chart.gates is an array of numbers,
chart.centers is an array of strings corresponding to valid CenterName values,
and chart.channels is an array of strings. If any field fails validation, either
throw an error with a descriptive message or return early with an appropriate
error response. This ensures that malformed or legacy data from the database is
caught before being used to compute impact calculations.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- account/page.tsx: 合圖 UI 判斷改用 chartKind 而非 type - api/charts: 新增 chartKind 白名單驗證;計算域錯誤回傳 400 - api/composite/create: BirthPayload 欄位型別驗證;計算錯誤回傳 400 - api/composite: chartAId/chartBId 補 typeof 檢查;toHdResult 加 Array.isArray 防護並移除 as any - api/transit/create: 計算域錯誤回傳 400 而非 500 - api/transit/impact: DB JSON 欄位加 Array.isArray 前置驗證 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Summary by CodeRabbit