Skip to content

refactor: core code cleanup and handler modularization#113

Open
sujitn wants to merge 5 commits into
mainfrom
refactor-core-cleanliness
Open

refactor: core code cleanup and handler modularization#113
sujitn wants to merge 5 commits into
mainfrom
refactor-core-cleanliness

Conversation

@sujitn

@sujitn sujitn commented May 31, 2026

Copy link
Copy Markdown
Owner

This PR applies several code review cleanups to the codebase:

  1. Replaced hand-rolled LU decomposition in convex-math with nalgebra::LU solver.
  2. Removed redundant validation tests mocks in convex-core.
  3. Simplified Date wrapper using std::ops::Deref.
  4. Modularized request handlers in convex-server by splitting analytics handlers from the main handler module.
  5. Removed unused reactive sharding types, methods, and tests from the calculation graph in convex-engine.

Summary by CodeRabbit

Release Notes

  • New Features
    • Added HTTP handlers for bond quote pricing with optional settlement date queries.
    • Added curve management endpoints: retrieve, list, create, delete curves and calculate zero/discount/forward rates.
    • Added bond reference data management: CRUD operations, batch creation, and lookups by ISIN/CUSIP.
    • Added portfolio management: full CRUD, position add/remove/update, and batch creation.
    • Added health check endpoint.

@coderabbitai

coderabbitai Bot commented May 31, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@sujitn, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 58 minutes. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 483067dd-25a0-45b9-9e3d-ce0e0d4ffbc3

📥 Commits

Reviewing files that changed from the base of the PR and between 05c99ca and 9b9fc42.

📒 Files selected for processing (4)
  • crates/convex-engine/src/calc_graph.rs
  • crates/convex-engine/src/lib.rs
  • crates/convex-server/src/handlers/analytics.rs
  • crates/convex-server/src/handlers/mod.rs
📝 Walkthrough

Walkthrough

This PR consolidates handler implementations, removes calculation-engine sharding surface, simplifies linear algebra by delegating to nalgebra, adds a Deref trait to Date for ergonomics, and trims the validation test suite. All handlers migrate from analytics.rs to a centralized mod.rs module with shared AppState infrastructure.

Changes

Core Refactoring and Handler Consolidation

Layer / File(s) Summary
Date type Deref trait
crates/convex-core/src/types/date.rs
Date now implements std::ops::Deref to NaiveDate, allowing direct deref access to the inner chrono type.
Sharding removal
crates/convex-engine/src/calc_graph.rs, crates/convex-engine/src/lib.rs
Public sharding types (ShardStrategy, ShardAssignment, ShardConfig) and their query/config methods are removed from CalculationGraph; re-export surface is narrowed to CalculationGraph, NodeId, and NodeValue.
LU decomposition refactoring
crates/convex-math/src/linear_algebra/mod.rs
solve_linear_system now uses nalgebra's built-in lu().solve() instead of custom LU decomposition; the standalone lu_decomposition function and its test are removed.
Validation test suite cleanup
crates/convex-core/src/validation_tests.rs
Removes validation test modules for price/yield, duration/convexity, spreads, periodicity conversion, callable bonds, FRNs, and sinking funds; file ends after accrued_interest_validation.
HTTP handler consolidation
crates/convex-server/src/handlers/mod.rs, crates/convex-server/src/handlers/analytics.rs
All HTTP handlers (bond quoting, curve CRUD/rates, bond reference-data, portfolio/position management) migrate to mod.rs with shared AppState containing PricingEngine, bond/portfolio stores, and websocket state; analytics.rs is stripped to import from parent; includes date/currency parsing helpers.

🎯 4 (Complex) | ⏱️ ~45 minutes

🐰 Handlers hop from one nest to the other,
Shards depart, but the graph still flutters,
LU math now trusts the nalgebra way,
Dates dereference with elegant sway, 🐇

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'refactor: core code cleanup and handler modularization' accurately summarizes the main changes: code cleanup across multiple modules and handler modularization, reflecting the PR's objectives.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor-core-cleanliness

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.

❤️ Share

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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 (2)
crates/convex-engine/src/calc_graph.rs (1)

6-30: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Remove the stale sharding rustdoc.

The module docs still advertise CalculationGraph::with_sharding, ShardConfig, and owns_node, but those APIs were removed in this refactor. That leaves the public docs pointing at code that no longer 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 `@crates/convex-engine/src/calc_graph.rs` around lines 6 - 30, The module docs
reference removed APIs (CalculationGraph::with_sharding, ShardConfig,
owns_node); remove or rewrite the sharding section so docs no longer mention
these symbols. Update the top-level rustdoc in calc_graph.rs to either delete
the entire "Sharding" block or replace it with current sharding guidance that
references existing APIs (or a note that sharding was removed), and remove the
example code snippets that call the nonexistent methods to keep public docs
consistent with the refactor.
crates/convex-server/src/handlers/analytics.rs (1)

2276-2285: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Reuse a single currency parser here.

This match table only recognizes a subset of the currencies accepted elsewhere and silently remaps the rest to USD. For example, valid codes like NZD, NOK, or SEK will be misclassified in analytics requests. Please route this through the shared currency parsing path instead of maintaining a second mapping.

🤖 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 `@crates/convex-server/src/handlers/analytics.rs` around lines 2276 - 2285, The
inline match in convert_portfolio_input duplicates currency mapping and silently
maps unknown codes to USD; replace it with the shared currency parsing path
(e.g., call the central parser such as parse_currency(&input.currency) or
Currency::from_str(&input.currency)) and use its return value (handling
Option/Result the same way other callers do) instead of the local match, falling
back to Currency::USD only if the shared parser indicates an unknown/invalid
code; keep the rest of convert_portfolio_input unchanged and reference the
Currency type for the final assignment.
🤖 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 `@crates/convex-server/src/handlers/analytics.rs`:
- Line 92: There is a name collision because this module defines its own fn
parse_date while mod.rs exports pub(crate) fn parse_date; remove or rename the
local helper and replace calls with super::parse_date to avoid duplicate
definitions, ensuring all date parsing uses the shared function. Also update
convert_portfolio_input to stop using its limited inline currency match and
instead call super::parse_currency (the shared mapping) so currency
normalization is consistent across analytics handlers; change the local currency
logic to delegate to super::parse_currency and handle its return accordingly.

In `@crates/convex-server/src/handlers/mod.rs`:
- Around line 317-331: The handler delete_curve currently returns
(StatusCode::NO_CONTENT, Json({})) which sends a body with 204; change the
success branch to return just StatusCode::NO_CONTENT (no body) — e.g. return
StatusCode::NO_CONTENT; — and keep the NotFound branch unchanged; apply the same
removal of Json({}) for the other delete handlers referenced (the handlers
around the ranges 632-645 and 851-863) so all success 204 responses send no
body.
- Around line 566-585: The existence check using
state.bond_store.get_by_id(&bond.instrument_id).await currently treats Err(_)
the same as not-found and proceeds to upsert, which hides read failures; update
the logic in the create handler (around get_by_id and before
state.bond_store.upsert) to explicitly handle Err from get_by_id by returning an
appropriate error response (e.g., StatusCode::INTERNAL_SERVER_ERROR with a JSON
error) or propagating the error instead of continuing to upsert, and apply the
same fix to the other create path referenced (the block around lines 657-673) so
both code paths distinguish Ok(None), Ok(Some(_)) and Err(_) correctly.
- Around line 976-997: The parse_currency function currently coerces unknown
codes to Currency::USD which hides bad input; change parse_currency(s: &str) to
be fallible (e.g., return Result<Currency, ParseCurrencyError> or
Option<Currency>) instead of defaulting to USD, map recognized uppercase codes
to the corresponding Currency variants and return an Err/None for the _ case (do
not return Currency::USD), and update callers of parse_currency (wherever
parse_currency is invoked) to handle the error by returning a 400 Bad Request or
appropriate validation response. Ensure the new error type or None is
descriptive so handlers can produce a clear client-facing error message.
- Around line 354-362: The code currently maps unknown query.compounding values
to Compounding::Continuous which silently changes behavior and still echoes the
caller's original value; instead, validate the input and return a client error
for unsupported values. In the handler where you build `compounding` from
`query.compounding`, change the match to explicitly accept only the known
strings
("simple","annual","semiannual"/"semi_annual","quarterly","monthly","daily") and
for the `_` arm return an HTTP 400/BadRequest (or propagate a validation error)
indicating the unsupported compounding value; ensure any response uses the
parsed enum (Compounding::...) only when validation succeeds. Use the existing
identifiers `query.compounding` and `Compounding`/`compounding` to locate and
update the logic.
- Around line 140-168: get_bond_quote currently reads from
state.engine.reference_data().bonds.get_by_id(...) but the CRUD handlers
(create_bond, update_bond, batch_create_bonds) only modify state.bond_store, so
newly created/updated bonds aren't visible to the quote endpoint; fix by making
get_bond_quote first check state.bond_store for the InstrumentId (and return
that if present) and only fall back to
state.engine.reference_data().bonds.get_by_id(...) when not found, or
alternatively update the CRUD handlers to also write the same bond data into the
engine.reference_data() bond cache after persisting to state.bond_store so both
stores stay in sync (refer to get_bond_quote, create_bond, update_bond,
batch_create_bonds, state.bond_store and state.engine.reference_data().bonds).

---

Outside diff comments:
In `@crates/convex-engine/src/calc_graph.rs`:
- Around line 6-30: The module docs reference removed APIs
(CalculationGraph::with_sharding, ShardConfig, owns_node); remove or rewrite the
sharding section so docs no longer mention these symbols. Update the top-level
rustdoc in calc_graph.rs to either delete the entire "Sharding" block or replace
it with current sharding guidance that references existing APIs (or a note that
sharding was removed), and remove the example code snippets that call the
nonexistent methods to keep public docs consistent with the refactor.

In `@crates/convex-server/src/handlers/analytics.rs`:
- Around line 2276-2285: The inline match in convert_portfolio_input duplicates
currency mapping and silently maps unknown codes to USD; replace it with the
shared currency parsing path (e.g., call the central parser such as
parse_currency(&input.currency) or Currency::from_str(&input.currency)) and use
its return value (handling Option/Result the same way other callers do) instead
of the local match, falling back to Currency::USD only if the shared parser
indicates an unknown/invalid code; keep the rest of convert_portfolio_input
unchanged and reference the Currency type for the final assignment.
🪄 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: 551892ce-fc00-47d0-ab87-bead9a1a9bed

📥 Commits

Reviewing files that changed from the base of the PR and between 540a9ff and 05c99ca.

📒 Files selected for processing (7)
  • crates/convex-core/src/types/date.rs
  • crates/convex-core/src/validation_tests.rs
  • crates/convex-engine/src/calc_graph.rs
  • crates/convex-engine/src/lib.rs
  • crates/convex-math/src/linear_algebra/mod.rs
  • crates/convex-server/src/handlers/analytics.rs
  • crates/convex-server/src/handlers/mod.rs
💤 Files with no reviewable changes (1)
  • crates/convex-core/src/validation_tests.rs

Comment thread crates/convex-engine/src/lib.rs Outdated
Comment thread crates/convex-server/src/handlers/analytics.rs
Comment thread crates/convex-server/src/handlers/mod.rs
Comment thread crates/convex-server/src/handlers/mod.rs
Comment thread crates/convex-server/src/handlers/mod.rs
Comment thread crates/convex-server/src/handlers/mod.rs
Comment thread crates/convex-server/src/handlers/mod.rs Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

5 issues found across 7 files

Tip: cubic can generate docs of your entire codebase and keep them up to date. Try it here.

Re-trigger cubic

Comment thread crates/convex-server/src/handlers/mod.rs Outdated
Comment thread crates/convex-server/src/handlers/mod.rs Outdated
Comment thread crates/convex-server/src/handlers/mod.rs Outdated
Comment thread crates/convex-server/src/handlers/mod.rs Outdated
Comment thread crates/convex-server/src/handlers/mod.rs Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant