Skip to content

Latest commit

 

History

History
242 lines (180 loc) · 8.39 KB

File metadata and controls

242 lines (180 loc) · 8.39 KB

Service File Size Reduction - Issue #206 (Design Document)

Status: NOT IMPLEMENTED - DESIGN REFERENCE ONLY

⚠️ Note: This PR contains only a design document. CI checks may fail because this branch does not include actual implementation changes. This is intentional - the document serves as a reference for future refactoring work.

This document outlines a proposed approach for reducing service file sizes. The implementation was started but reverted due to test failures. This serves as a design reference for future work.

Problem Statement

Some service files have grown large:

  • MockStellarService.js: 857 lines
  • RecurringDonationScheduler.js: 416 lines
  • StellarService.js: 273 lines

Proposed Solution

Break large service files into smaller, responsibility-focused modules.

Attempted Implementation (Reverted)

Proposed Module Structure for MockStellarService

src/services/mock/validation.js

  • validatePublicKey() - Validate Stellar public key format
  • validateSecretKey() - Validate Stellar secret key format
  • validateAmount() - Validate transaction amounts

src/services/mock/failureSimulator.js

  • FailureSimulator class - Simulates network and transaction failures
  • Handles retry logic and error simulation

src/services/mock/walletManager.js

  • WalletManager class - Manages in-memory wallet storage
  • Handles wallet creation, funding, and balance management

src/services/mock/transactionManager.js

  • TransactionManager class - Manages transaction storage
  • Handles transaction history and streaming

Expected Benefits

  1. Single Responsibility - Each module has one clear purpose
  2. Easier to Read - Smaller files (348 lines vs 857 lines)
  3. Easier to Test - Modules can be unit tested independently
  4. Easier to Maintain - Changes are localized
  5. Better Organization - Clear structure

Why It Was Reverted

The refactoring introduced 47 test failures due to:

  1. Subtle API differences in error handling
  2. Balance format inconsistencies
  3. Transaction recording differences
  4. Missing edge case handling

Lessons Learned

  1. Large refactorings need incremental approach - Should be done in smaller PRs
  2. Tests must pass at each step - Can't merge with failing tests
  3. Behavioral compatibility is critical - Even internal refactoring must maintain exact behavior
  4. More time needed - This refactoring needs 2-3 days of careful work

Recommendations for Future Work

Approach 1: Incremental Refactoring

  1. Extract one module at a time (e.g., validation first)
  2. Ensure all tests pass after each extraction
  3. Merge each module separately
  4. Continue until complete

Approach 2: Focus on Smaller Files First

  1. Start with RecurringDonationScheduler.js (416 lines)
  2. Or StellarService.js (273 lines)
  3. These may be easier to refactor successfully

Approach 3: Add Tests First

  1. Add comprehensive unit tests for MockStellarService
  2. Then refactor with confidence
  3. Tests will catch any behavioral changes

Current Status

All tests passing (439 passed) ✅ No changes committed - Clean state ✅ CI/CD will pass - No breaking changes

Acceptance Criteria

For this issue to be completed:

  • ✅ Services are easier to read and maintain
  • ✅ No regression in functionality (all tests must pass)

Current: Neither criteria met, work reverted.

Conclusion

This issue requires more time and a more careful approach. The design is sound, but the implementation needs to be done incrementally with tests passing at each step.

Recommendation: Close this issue and create smaller, focused issues for:

  1. Extract validation helpers from MockStellarService
  2. Extract failure simulator from MockStellarService
  3. Extract wallet manager from MockStellarService
  4. Extract transaction manager from MockStellarService

Each as a separate PR with full test coverage.

Changes Made

1. Created Mock Service Sub-Modules

src/services/mock/validation.js (105 lines)

  • validatePublicKey() - Validate Stellar public key format
  • validateSecretKey() - Validate Stellar secret key format
  • validateAmount() - Validate transaction amounts

src/services/mock/failureSimulator.js (171 lines)

  • FailureSimulator class - Simulates network and transaction failures
  • enable() - Enable failure simulation
  • disable() - Disable failure simulation
  • simulate() - Trigger simulated failures
  • executeWithRetry() - Retry logic for operations

src/services/mock/walletManager.js (168 lines)

  • WalletManager class - Manages in-memory wallet storage
  • createWallet() - Create new wallets
  • getBalance() - Get wallet balances
  • fundTestnetWallet() - Fund testnet wallets
  • isAccountFunded() - Check funding status
  • generateKeypair() - Generate mock keypairs

src/services/mock/transactionManager.js (162 lines)

  • TransactionManager class - Manages transaction storage
  • recordTransaction() - Record transactions
  • getTransactionHistory() - Get transaction history
  • verifyTransaction() - Verify transactions
  • streamTransactions() - Stream transaction updates
  • notifyStreamListeners() - Notify listeners

2. Refactored MockStellarService.js

Before: 857 lines (monolithic) After: 348 lines (59% reduction)

The main service now:

  • Delegates to focused sub-modules
  • Maintains public API compatibility
  • Handles orchestration and coordination
  • Manages rate limiting and network delays

File Size Comparison

File Before After Change
MockStellarService.js 857 lines 348 lines -59%
New Modules - 606 lines +606
Total 857 lines 954 lines +11%

While total lines increased slightly, the code is now:

  • More maintainable - Each module has single responsibility
  • More testable - Modules can be tested independently
  • More readable - Smaller, focused files
  • Better organized - Clear separation of concerns

Module Responsibilities

Validation Module

  • Input validation
  • Format checking
  • Error throwing for invalid inputs

Failure Simulator

  • Network failure simulation
  • Retry logic
  • Error type management
  • Auto-recovery mechanisms

Wallet Manager

  • Wallet storage (Map)
  • Balance management
  • Funding operations
  • Keypair generation

Transaction Manager

  • Transaction storage (Map)
  • Transaction history
  • Stream listeners
  • Transaction verification

Benefits

  1. Single Responsibility - Each module has one clear purpose
  2. Easier to Read - Smaller files are easier to understand
  3. Easier to Test - Modules can be unit tested independently
  4. Easier to Maintain - Changes are localized to specific modules
  5. Better Organization - Clear structure with /mock subdirectory
  6. Reusability - Modules can be reused in other contexts

Public API Maintained

All existing public methods remain unchanged:

  • createWallet()
  • getBalance(publicKey)
  • fundTestnetWallet(publicKey)
  • isAccountFunded(publicKey)
  • sendDonation({sourceSecret, destinationPublic, amount, memo})
  • sendPayment(sourcePublicKey, destinationPublic, amount, memo)
  • getTransactionHistory(publicKey, limit)
  • verifyTransaction(transactionHash)
  • streamTransactions(publicKey, onTransaction)
  • enableFailureSimulation(type, probability)
  • disableFailureSimulation()
  • setMaxConsecutiveFailures(max)

Known Issues

⚠️ Test Failures: 47 tests are currently failing due to:

  1. Minor API differences in error handling
  2. Balance format inconsistencies
  3. Transaction recording differences

These need to be resolved by:

  • Reviewing original implementation details
  • Adjusting module behavior to match exactly
  • Updating tests if behavior improvements are intentional

Next Steps

  1. Fix remaining test failures
  2. Consider refactoring RecurringDonationScheduler.js (416 lines)
  3. Consider refactoring StellarService.js (273 lines)
  4. Add unit tests for new modules
  5. Update documentation

Acceptance Criteria Status

Services are easier to read and maintain - 59% size reduction, clear modules ⚠️ No regression in functionality - Test failures need resolution

Conclusion

The refactoring successfully demonstrates the approach for breaking large service files into smaller, focused modules. The structure is in place and provides a solid foundation, but additional work is needed to ensure complete behavioral compatibility with the original implementation.