This repository is a bit of an experimentation I ran over two evenings (mostly). I had wanted for a while to try three unrelated things:
- write some Rust code
- build a small app using HTMX
- see how far I can bootstrap an app using mostly cursor prompting This rule builder, inspired from an interview exercise we run, was just a pretext to do this.
An overwhelming majority of the code within has been generated not written manually, do not judge me too harshly it's just an experimentation.
A fraud detection rule builder built with Rust and HTMX. This project demonstrates building an AST-based rule engine with a dynamic, server-rendered UI.
- 🦀 Rust Backend: Built with Axum, a modern async web framework
- 🔄 HTMX Frontend: Dynamic interactions without JavaScript frameworks
- 🌳 AST-Based Rules: Structured rule representation with validation
- 🎨 Modern UI: Clean, gradient-based design
- ⚡ Real-time Updates: Add/remove conditions dynamically
- ✅ Validation: Built-in rule validation with error reporting
The rule builder uses an Abstract Syntax Tree (AST) approach:
- Rule: Top-level container with name, description, and conditions
- Condition: A single comparison (field, operator, value)
- Field: Available fields from the fraud detection system (transaction amount, user country, etc.)
- Operator: Comparison operators (equals, greater than, contains, etc.)
- Logical Operator: How conditions combine (AND/OR)
- Web Framework: Axum - Ergonomic and modular web framework
- Templating: Askama - Type-safe Jinja2-like templates
- HTMX: For dynamic interactions
- Serialization: Serde for JSON handling
- Async Runtime: Tokio
- Rust 1.70+ (Install Rust)
-
Clone the repository (or you're already here!)
-
Build and run:
cargo run- Open your browser to http://localhost:3000
For hot-reloading during development, you can use cargo-watch:
cargo install cargo-watch
cargo watch -x run- Click "New Rule" button
- Enter a name and description
- Click "Create Rule"
- Click "View Details" on a rule
- Click "+ Add Condition"
- Select a field, operator, and enter a value
- Click "Add Condition"
- Open a rule's details
- Click "Validate Rule"
- See validation results
htmx-builder/
├── src/
│ ├── main.rs # Application entry point
│ ├── handlers.rs # HTTP request handlers
│ └── models.rs # Data structures and business logic
├── templates/ # Askama HTML templates
│ ├── index.html # Main page
│ ├── rule_view.html # Rule details
│ ├── condition_form.html
│ └── ...
├── static/
│ └── style.css # Styling
└── Cargo.toml # Dependencies
GET /- Main pageGET /rules- List all rules (HTMX partial)POST /rules- Create new ruleGET /rules/:id- View rule detailsPOST /rules/:id/validate- Validate ruleGET /rules/:id/conditions/new- Condition formPOST /rules/:id/conditions- Add conditionDELETE /rules/:id/conditions/:condition_id- Remove condition
In src/models.rs, add to the Field enum:
pub enum Field {
// Existing fields...
YourNewField,
}Update the as_str() and display_name() methods accordingly.
In src/models.rs, extend the Rule::validate() method:
impl Rule {
pub fn validate(&self) -> Result<(), Vec<String>> {
// Add your validation logic
}
}Currently uses in-memory storage. To add persistence:
- Replace
RuleStorewith a database client (e.g., SQLx, Diesel) - Update handlers to use async database queries
- Add database connection pool to application state
- Rule engines and pattern matching
- AST-based expression evaluation
- Add rule execution/evaluation
- Support nested conditions (groups)
- Add more operators (regex, between, etc.)
- Implement rule versioning
- Add test data simulation
- Export rules as JSON
- Import rules from JSON
- Add authentication
- Persist to database
- Add rule analytics
MIT License - feel free to use this for learning and experimentation!
This is a learning project, but feel free to fork and experiment!