Contribution Guidelines & RTK
Relevant source files
The following files were used as context for generating this wiki page:
The contribution workflow for Hesabyar is designed to maintain the integrity of a Persian-first, offline-first personal finance application. It encompasses strict architectural constraints, a mandatory post-modification verification loop, and the use of specialized tooling like RTK (Rust Token Killer) to optimize development efficiency. Contributors must interact with a multi-language codebase consisting of Kotlin for the Android UI and Rust for the shared business logic.
Sources: AGENTS.md:1-5, README.md:14-25
Development Environment & Build Process
The project requires a specific setup to handle both the Android application and the native Rust core (hesabyar-core). Developers must ensure they have the Android NDK and the Rust toolchain (1.75+) installed to support cross-compilation for various Android ABIs.
Build and Run Commands
Standard Gradle tasks are used for building, testing, and linting the Android application. Rust-specific tasks are integrated into the Gradle lifecycle to handle the native shared library.
# Debug build and installation
./gradlew installDebug
# Rust core build for Android
./gradlew :app:assembleRust --no-daemon
# Generate Kotlin bindings via UniFFI
./gradlew :app:generateRustBindings --no-daemon
Sources: AGENTS.md:12-25, README.md:148-164, rust/hesabyar-core/README.md:21-41
RTK (Rust Token Killer) Integration
RTK is a command-line wrapper used to optimize context usage during development. It filters shell output to reduce token consumption by up to 99%, specifically for Git, testing, and build tools.
The diagram shows how the rtk utility intercepts standard commands to provide token-optimized feedback, essential for agent-based development environments.
Sources: AGENTS.md:63-100
Mandatory Verification Workflow
Every modification to the codebase requires a strict sequence of checks. Failure to follow this workflow, particularly the use of the --no-daemon flag, can lead to environment instability.
Post-Modification Checklist
- Static Analysis: Run
ktlintCheckanddetektto ensure code style compliance. - Kotlin Unit Tests: Execute the local JUnit/Robolectric suite.
- Rust Unit Tests: Run
cargo testif any native logic was touched. - Auto-Correction: Use
ktlintFormatto resolve minor formatting issues automatically.
Verification Execution
# Combined Linting and Testing
./gradlew ktlintCheck detekt test --no-daemon
Sources: AGENTS.md:105-135
Architectural Constraints & Key Patterns
Contributors must adhere to "Hard Constraints" to prevent regressions in financial accuracy or localization support.
Technical Safeguards
| Constraint | Description |
|---|---|
| No Floating Point | Never use Float or Double for money; use Long (Rial) or BigDecimal. |
| Room Migrations | Schema changes must be non-destructive to preserve user data. |
| Secrets Management | API keys must never be hardcoded; use .env files or Keystore. |
| Jalali Calendar | All date logic must use JalaliCalendarHelper or the Rust calendar.rs module. |
| Coroutines | No GlobalScope; use structured concurrency with specific scopes. |
Sources: AGENTS.md:32-41, README.md:95-103
Data Flow and Core Logic
The application follows an MVVM pattern where the Android UI communicates with the hesabyar-core via the RustBridge. This bridge uses UniFFI to generate Kotlin bindings for native Rust functions.
The sequence diagram illustrates the boundary crossing between the JVM and native layers for critical business logic like transaction parsing and currency formatting.
Sources: README.md:105-115, app/src/test/java/io/github/mojri/hesabyar/rust/RustBridgeTest.kt:18-60
AI & Validation Logic
When contributing to AI features (Gemini/OpenRouter), developers must use the validation logic defined in the Rust core to sanitize outputs. This ensures that AI-generated JSON or advice text does not contain malicious code or invalid financial data.
Validation Functions
parse_ai_transaction_json: Validates and coerces AI-generated JSON into structuredParsedResult.validate_ai_advice: Sanitizes free-form text, stripping dangerous patterns like<script>orjavascript:.normalize_category: Maps diverse AI-generated categories to the 8 core database categories.
Sources: rust/hesabyar-core/src/ai_validation.rs:104-120, rust/hesabyar-core/src/ai_validation.rs:248-260
Testing Infrastructure
The project utilizes a hybrid testing strategy to cover both layers of the application.
Test Suites
| Layer | Tools | Directory |
|---|---|---|
| Android/Kotlin | JUnit, Robolectric, Roborazzi | app/src/test/ |
| Rust Core | Cargo, Criterion (Bench), Proptest | rust/hesabyar-core/src/, rust/hesabyar-core/benches/ |
Sources: AGENTS.md:52-57, README.md:167-185, rust/hesabyar-core/Cargo.toml:21-30
Conclusion
Contributing to Hesabyar requires strict adherence to architectural standards that prioritize financial precision and Persian localization. By utilizing the RTK-optimized command set and following the mandatory verification workflow with the --no-daemon flag, developers can ensure that both the Android UI and the native Rust logic remain performant, secure, and robust across all releases.
Sources: AGENTS.md:124-131, README.md:213-220