bourso-api
bourso-api copied to clipboard
1.0.0: CLI architecture refactor, typed domain models & new settings/logging stack
Why?
The CLI had tightly coupled parsing, IO, and domain logic in a single flow, making it hard to test & extend.
What?
-
Version
- Bump CLI to
1.0.0 - Turn the repo into a Cargo workspace with
bourso-cliandsrc/bourso_apias members
- Bump CLI to
-
Dependencies
- Refresh core deps:
tokio,anyhow,clap,directories,serde_json,tracing-*,futures-util,rpassword - Add
tracing-appenderon the CLI side - Add
thiserror+derive_moreinbourso_apifor typed domain values
- Refresh core deps:
-
Architecture
- New top-level modules in the CLI:
commands/,services/,settings/,ux/ - New
AppCtx { settings_store }andrun(Cli)entrypoint to decouple CLI wiring from command logic - Extract AuthService with
CredentialsProvider+ClientFactoryto isolate login/MFA handling -
settings/split into:-
consts.rs(app identifiers + filenames) -
logging.rs(centralizedinit_logger()usingProjectDirs+tracing-appender) -
store.rs(SettingsStoretrait +FsSettingsStoreimplementation): ready for Vault support
-
-
main.rsreduced to: init logger → parseCli(derive) →run(cli)
- New top-level modules in the CLI:
-
Domain types (
bourso_api::types)- New shared module in
bourso_apiwith validated value types:-
ClientNumber,AccountId,SymbolId -
OrderQuantity,MoneyAmount,TransferReason -
MfaCode,Password -
QuoteLength,QuotePeriod,OrderSide(moved here fromtrade::order)
-
- Central
ValueErrorusingthiserrorfor input/validation errors - CLI now uses these types directly via
FromStr+value_parser!, reducing primitive obsession and centralizing validation
- New shared module in
-
Commands
- All stateful commands now go through AuthService:
-
accounts -
trade order new -
transfer
-
-
config- Persists validated
ClientNumberviaFsSettingsStore - Uses
ClientNumbernewtype instead of rawString
- Persists validated
-
quote- Uses typed args:
-
symbol: SymbolId -
length: QuoteLength(1, 5, 30, 90, 180, 365, 1825, 3650) -
period: QuotePeriod(currently only0is accepted)
-
- Uses typed args:
-
trade order new-
account: AccountId -
side: OrderSide(with default"buy") -
symbol: SymbolId -
quantity: OrderQuantity
-
-
transfer-
from_account: AccountId,to_account: AccountId -
amount: MoneyAmount -
reason: Option<TransferReason>
-
- Root command:
-
Cli.credentialsis now aPathBuf(parsed viavalue_parser!(PathBuf)) and feedsFsSettingsStore::from_pathwhen provided
-
- All stateful commands now go through AuthService:
-
UX
- New reusable
ux::TextProgressBar- Encapsulates the previous inline progress-bar logic used for transfers
- Safer math (
clamp) and handlestotal == 0gracefully
- New reusable
-
Logging
- Structured JSON log file via
tracing-subscriber+tracing-appender::rolling::never - Log file under platform data dir (e.g.
~/.local/share/bourso/bourso-cli/bourso.log) - Console layer:
- Compact, no timestamps
- Respects
RUST_LOG - Still prints a friendly CLI-style message stream
- Structured JSON log file via
Main impact?
-
Breaking changes
-
configflag renamed:--username➜--client-number -
quote:-
--intervalrenamed to--period -
--lengthis now aQuoteLengthenum (must be one of1,5,30,90,180,365,1825,3650) -
--periodcurrently only accepts0(validated viaQuotePeriod)
-
- Stricter validation at the CLI boundary:
-
client_numbermust be 8 digits -
accountIDs must be 32 hex chars -
symbolIDs must be 6–12 alphanumeric chars -
quantitymust be a strictly positive integer -
amountmust be positive with up to 2 decimals - MFA codes and password are also validated newtypes
- Invalid inputs now fail early with explicit error messages
-
-
-
Paths
-
Settings: platform config dir
e.g.
~/.config/bourso/bourso-cli/settings.json -
Logs: platform data dir
e.g.
~/.local/share/bourso/bourso-cli/bourso.log
-
Settings: platform config dir
e.g.
-
Maintainability
- Clear separation of concerns:
- CLI (argument parsing + help)
-
commands/*(orchestration) -
services/*(Auth, etc.) -
bourso_api(HTTP/domain)
- Easier testing/mocking:
-
AuthServicetakes boxedCredentialsProvider+ClientFactory -
SettingsStoretrait enables in-memory / custom implementations
-
- Shared domain types in
bourso_api::typesensure CLI and API use the same invariants - Reusable UX components and centralized logging initialization
- Clear separation of concerns:
What next?
- [ ] refactor
src/bourso_api - [ ] move
src/bourso_api/typesto dedicated domain folder
:warning: Please install the to ensure uploads and comments are reliably processed by Codecov.
Codecov Report
:x: Patch coverage is 0% with 142 lines in your changes missing coverage. Please review.
:white_check_mark: Project coverage is 22.86%. Comparing base (e7ec1e3) to head (b98de70).
| Files with missing lines | Patch % | Lines |
|---|---|---|
| src/bourso_api/src/types.rs | 0.00% | 78 Missing :warning: |
| src/services/auth.rs | 0.00% | 54 Missing :warning: |
| src/lib.rs | 0.00% | 10 Missing :warning: |
| :exclamation: Your organization needs to install the Codecov GitHub app to enable full functionality. |
Additional details and impacted files
@@ Coverage Diff @@
## 1.0 #56 +/- ##
===========================================
- Coverage 33.55% 22.86% -10.69%
===========================================
Files 9 12 +3
Lines 304 446 +142
===========================================
Hits 102 102
- Misses 202 344 +142
:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.
:rocket: New features to boost your workflow:
- :snowflake: Test Analytics: Detect flaky tests, report on failures, and find test suite problems.