bourso-api icon indicating copy to clipboard operation
bourso-api copied to clipboard

1.0.0: CLI architecture refactor, typed domain models & new settings/logging stack

Open Mathious6 opened this issue 2 months ago • 1 comments

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-cli and src/bourso_api as members
  • Dependencies

    • Refresh core deps: tokio, anyhow, clap, directories, serde_json, tracing-*, futures-util, rpassword
    • Add tracing-appender on the CLI side
    • Add thiserror + derive_more in bourso_api for typed domain values
  • Architecture

    • New top-level modules in the CLI: commands/, services/, settings/, ux/
    • New AppCtx { settings_store } and run(Cli) entrypoint to decouple CLI wiring from command logic
    • Extract AuthService with CredentialsProvider + ClientFactory to isolate login/MFA handling
    • settings/ split into:
      • consts.rs (app identifiers + filenames)
      • logging.rs (centralized init_logger() using ProjectDirs + tracing-appender)
      • store.rs (SettingsStore trait + FsSettingsStore implementation): ready for Vault support
    • main.rs reduced to: init logger → parse Cli (derive) → run(cli)
  • Domain types (bourso_api::types)

    • New shared module in bourso_api with validated value types:
      • ClientNumber, AccountId, SymbolId
      • OrderQuantity, MoneyAmount, TransferReason
      • MfaCode, Password
      • QuoteLength, QuotePeriod, OrderSide (moved here from trade::order)
    • Central ValueError using thiserror for input/validation errors
    • CLI now uses these types directly via FromStr + value_parser!, reducing primitive obsession and centralizing validation
  • Commands

    • All stateful commands now go through AuthService:
      • accounts
      • trade order new
      • transfer
    • config
      • Persists validated ClientNumber via FsSettingsStore
      • Uses ClientNumber newtype instead of raw String
    • quote
      • Uses typed args:
        • symbol: SymbolId
        • length: QuoteLength (1, 5, 30, 90, 180, 365, 1825, 3650)
        • period: QuotePeriod (currently only 0 is accepted)
    • 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.credentials is now a PathBuf (parsed via value_parser!(PathBuf)) and feeds FsSettingsStore::from_path when provided
  • UX

    • New reusable ux::TextProgressBar
      • Encapsulates the previous inline progress-bar logic used for transfers
      • Safer math (clamp) and handles total == 0 gracefully
  • 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

Main impact?

  • Breaking changes

    • config flag renamed: --username--client-number
    • quote:
      • --interval renamed to --period
      • --length is now a QuoteLength enum (must be one of 1,5,30,90,180,365,1825,3650)
      • --period currently only accepts 0 (validated via QuotePeriod)
    • Stricter validation at the CLI boundary:
      • client_number must be 8 digits
      • account IDs must be 32 hex chars
      • symbol IDs must be 6–12 alphanumeric chars
      • quantity must be a strictly positive integer
      • amount must 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
  • Maintainability

    • Clear separation of concerns:
      • CLI (argument parsing + help)
      • commands/* (orchestration)
      • services/* (Auth, etc.)
      • bourso_api (HTTP/domain)
    • Easier testing/mocking:
      • AuthService takes boxed CredentialsProvider + ClientFactory
      • SettingsStore trait enables in-memory / custom implementations
    • Shared domain types in bourso_api::types ensure CLI and API use the same invariants
    • Reusable UX components and centralized logging initialization

What next?

  • [ ] refactor src/bourso_api
  • [ ] move src/bourso_api/types to dedicated domain folder

Mathious6 avatar Nov 20 '25 03:11 Mathious6

:warning: Please install the 'codecov app svg image' 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.

codecov-commenter avatar Nov 20 '25 03:11 codecov-commenter