-
Notifications
You must be signed in to change notification settings - Fork 0
api: migrate exchange rate & market to Decimal #92
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
api: migrate exchange rate & market to Decimal #92
Conversation
… and currency_service
…or dynamic SQLx reads for accounts + currency/exchange
…x IF NOT EXISTS for indexes/triggers
Summary of ChangesHello @zensgit, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly improves the numerical precision of financial data within the API by transitioning key fields from floating-point numbers ( Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request successfully migrates exchange rate and market data from f64 to Decimal to improve precision, which is a great improvement. The changes also refactor sqlx::query! macros to sqlx::query() calls to support offline compilation, though this has introduced a potential issue with error handling. The most critical issue is an unresolved merge conflict in jive-api/src/handlers/accounts.rs that must be fixed. Additionally, a widespread pattern of using .try_get(...).unwrap_or(None) silently swallows database errors, which could hide bugs. I've provided a suggestion to address this.
| <<<<<<< HEAD | ||
| currency, current_balance, available_balance, credit_limit, status, | ||
| is_manual, color, notes, created_at, updated_at | ||
| ======= | ||
| currency, current_balance, available_balance, credit_limit, | ||
| status, is_manual, color, notes, created_at, updated_at | ||
| >>>>>>> 46ef8086 (api: unify Decimal mapping in accounts handler; fix clippy in metrics and currency_service) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| currency: row | ||
| .try_get::<Option<String>, _>("currency") | ||
| .unwrap_or(None) | ||
| .unwrap_or_else(|| "CNY".to_string()), | ||
| current_balance: row | ||
| .try_get::<Option<Decimal>, _>("current_balance") | ||
| .unwrap_or(None) | ||
| .unwrap_or(Decimal::ZERO), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The pattern .try_get(...).unwrap_or(None) is used here and in several other places in this PR (e.g., create_account, get_account_statistics, and in currency_handler_enhanced.rs). This pattern can hide bugs by swallowing potential database errors. If try_get fails (for instance, due to a column name typo or a type mismatch), the Err is silently converted to None, and a default value is used. This prevents the API from reporting a server-side problem. It's safer to handle the Result from try_get explicitly, for example by using the ? operator to propagate the error, which will then be converted into a proper API error response.
| currency: row | |
| .try_get::<Option<String>, _>("currency") | |
| .unwrap_or(None) | |
| .unwrap_or_else(|| "CNY".to_string()), | |
| current_balance: row | |
| .try_get::<Option<Decimal>, _>("current_balance") | |
| .unwrap_or(None) | |
| .unwrap_or(Decimal::ZERO), | |
| currency: row | |
| .try_get::<Option<String>, _>("currency")? | |
| .unwrap_or_else(|| "CNY".to_string()), | |
| current_balance: row | |
| .try_get::<Option<Decimal>, _>("current_balance")? | |
| .unwrap_or(Decimal::ZERO), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Migrate exchange rate and related market paths from f64 to Decimal and switch several SQLx typed macros to dynamic queries for Decimal compatibility.
- Replace sqlx::query! with sqlx::query and Row accessors to support Decimal columns.
- Normalize timestamps with fallback defaults and minor logging/env handling tweaks.
- Add migration hardening (IF NOT EXISTS for indexes/triggers and pgcrypto extension).
Reviewed Changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| jive-api/src/services/exchange_rate_api.rs | Adjusted updated_at handling for age calculation. |
| jive-api/src/services/currency_service.rs | Switched to dynamic Row accessors and standardized time fallbacks. |
| jive-api/src/metrics.rs | Minor env var handling cleanup. |
| jive-api/src/handlers/currency_handler_enhanced.rs | Switched to dynamic query and Decimal handling for crypto prices. |
| jive-api/src/handlers/accounts.rs | Converted to dynamic queries, Decimal mapping; added casts in update; response mapping via Row getters. |
| jive-api/migrations/037_add_net_worth_tracking.sql | Hardened migration with IF NOT EXISTS and conditional trigger creation; ensured pgcrypto extension. |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| <<<<<<< HEAD | ||
| currency, current_balance, available_balance, credit_limit, status, | ||
| is_manual, color, notes, created_at, updated_at | ||
| ======= | ||
| currency, current_balance, available_balance, credit_limit, | ||
| status, is_manual, color, notes, created_at, updated_at | ||
| >>>>>>> 46ef8086 (api: unify Decimal mapping in accounts handler; fix clippy in metrics and currency_service) |
Copilot
AI
Oct 15, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unresolved merge conflict markers are present inside the SQL string in the RETURNING clause. This will send invalid SQL to the database and fail at runtime. Remove the conflict markers and keep a single consistent RETURNING list.
| <<<<<<< HEAD | |
| currency, current_balance, available_balance, credit_limit, status, | |
| is_manual, color, notes, created_at, updated_at | |
| ======= | |
| currency, current_balance, available_balance, credit_limit, | |
| status, is_manual, color, notes, created_at, updated_at | |
| >>>>>>> 46ef8086 (api: unify Decimal mapping in accounts handler; fix clippy in metrics and currency_service) | |
| currency, current_balance, available_balance, credit_limit, status, | |
| is_manual, color, notes, created_at, updated_at |
| color: row.get("color"), | ||
| icon: row.get("icon"), | ||
| notes: row.get("notes"), |
Copilot
AI
Oct 15, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The SELECT statement above does not include the icon column, but the response attempts to read icon from the row. Either add icon to the SELECT list or set icon to None in the response to avoid a runtime 'no such column' error.
| color: row.get("color"), | ||
| icon: row.get("icon"), | ||
| notes: row.get("notes"), |
Copilot
AI
Oct 15, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In create_account, the RETURNING clause does not include icon, but the response reads icon from the returned row. Add icon to the RETURNING columns or set icon to None to prevent a runtime error.
…Decimal dynamic stats)
…Option<DateTime> handling
Purpose
Scope
Validation
SQLX_OFFLINE=true cargo clippy -- -D warningspasses locallyNotes