# botserver Development Prompt Guide

**Version:** 6.1.0

---

## ZERO TOLERANCE POLICY

**EVERY SINGLE WARNING MUST BE FIXED. NO EXCEPTIONS.**

---

## ABSOLUTE PROHIBITIONS

```
❌ NEVER use #![allow()] or #[allow()] in source code
❌ NEVER use .unwrap() - use ? or proper error handling
❌ NEVER use .expect() - use ? or proper error handling  
❌ NEVER use panic!() or unreachable!()
❌ NEVER use todo!() or unimplemented!()
❌ NEVER leave unused imports or dead code
❌ NEVER use approximate constants - use std::f64::consts
❌ NEVER use CDN links - all assets must be local
❌ NEVER add comments - code must be self-documenting
❌ NEVER build SQL queries with format! - use parameterized queries
❌ NEVER pass user input to Command::new() without validation
❌ NEVER log passwords, tokens, API keys, or PII
```

---

## SECURITY REQUIREMENTS

### Error Handling

```rust
// ❌ WRONG
let value = something.unwrap();
let value = something.expect("msg");

// ✅ CORRECT
let value = something?;
let value = something.ok_or_else(|| Error::NotFound)?;
let value = something.unwrap_or_default();
```

### Rhai Syntax Registration

```rust
// ❌ WRONG
engine.register_custom_syntax([...], false, |...| {...}).unwrap();

// ✅ CORRECT
if let Err(e) = engine.register_custom_syntax([...], false, |...| {...}) {
    log::warn!("Failed to register syntax: {e}");
}
```

### Regex Patterns

```rust
// ❌ WRONG
let re = Regex::new(r"pattern").unwrap();

// ✅ CORRECT
static RE: LazyLock<Regex> = LazyLock::new(|| {
    Regex::new(r"pattern").expect("invalid regex")
});
```

### Tokio Runtime

```rust
// ❌ WRONG
let rt = tokio::runtime::Runtime::new().unwrap();

// ✅ CORRECT
let Ok(rt) = tokio::runtime::Runtime::new() else {
    return Err("Failed to create runtime".into());
};
```

### SQL Injection Prevention

```rust
// ❌ WRONG
let query = format!("SELECT * FROM {}", table_name);

// ✅ CORRECT - whitelist validation
const ALLOWED_TABLES: &[&str] = &["users", "sessions"];
if !ALLOWED_TABLES.contains(&table_name) {
    return Err(Error::InvalidTable);
}
```

### Command Injection Prevention

```rust
// ❌ WRONG
Command::new("tool").arg(user_input).output()?;

// ✅ CORRECT
fn validate_input(s: &str) -> Result<&str, Error> {
    if s.chars().all(|c| c.is_alphanumeric() || c == '.') {
        Ok(s)
    } else {
        Err(Error::InvalidInput)
    }
}
let safe = validate_input(user_input)?;
Command::new("/usr/bin/tool").arg(safe).output()?;
```

---

## CODE PATTERNS

### Format Strings - Inline Variables

```rust
// ❌ WRONG
format!("Hello {}", name)

// ✅ CORRECT
format!("Hello {name}")
```

### Self Usage in Impl Blocks

```rust
// ❌ WRONG
impl MyStruct {
    fn new() -> MyStruct { MyStruct { } }
}

// ✅ CORRECT
impl MyStruct {
    fn new() -> Self { Self { } }
}
```

### Derive Eq with PartialEq

```rust
// ❌ WRONG
#[derive(PartialEq)]
struct MyStruct { }

// ✅ CORRECT
#[derive(PartialEq, Eq)]
struct MyStruct { }
```

### Option Handling

```rust
// ✅ CORRECT
opt.unwrap_or(default)
opt.unwrap_or_else(|| compute_default())
opt.map_or(default, |x| transform(x))
```

### Chrono DateTime

```rust
// ❌ WRONG
date.with_hour(9).unwrap().with_minute(0).unwrap()

// ✅ CORRECT
date.with_hour(9).and_then(|d| d.with_minute(0)).unwrap_or(date)
```

---

## DATABASE STANDARDS

- TABLES AND INDEXES ONLY (no views, triggers, functions)
- JSON columns: use TEXT with `_json` suffix
- Use diesel - no sqlx

---

## FRONTEND RULES

- Use HTMX - minimize JavaScript
- NO external CDN - all assets local
- Server-side rendering with Askama templates

---

## DEPENDENCIES

| Library | Version | Purpose |
|---------|---------|---------|
| axum | 0.7.5 | Web framework |
| diesel | 2.1 | PostgreSQL ORM |
| tokio | 1.41 | Async runtime |
| rhai | git | BASIC scripting |
| reqwest | 0.12 | HTTP client |
| serde | 1.0 | Serialization |
| askama | 0.12 | HTML Templates |

---

## COMPILATION POLICY - CRITICAL

**NEVER compile during development. NEVER run `cargo build`. Use static analysis only.**

### Workflow

1. Make all code changes
2. Use `diagnostics` tool for static analysis (NOT compilation)
3. Fix any errors found by diagnostics
4. **At the end**, inform user what needs restart

### After All Changes Complete

| Change Type | User Action Required |
|-------------|----------------------|
| Rust code (`.rs` files) | "Recompile and restart **botserver**" |
| HTML templates (`.html` in botui) | "Browser refresh only" |
| CSS/JS files | "Browser refresh only" |
| Askama templates (`.html` in botserver) | "Recompile and restart **botserver**" |
| Database migrations | "Run migration, then restart **botserver**" |
| Cargo.toml changes | "Recompile and restart **botserver**" |

**Format:** At the end of your response, always state:
- ✅ **No restart needed** - browser refresh only
- 🔄 **Restart botserver** - recompile required

---

## KEY REMINDERS

- **ZERO WARNINGS** - fix every clippy warning
- **ZERO COMMENTS** - no comments, no doc comments
- **NO ALLOW IN CODE** - configure exceptions in Cargo.toml only
- **NO DEAD CODE** - delete unused code
- **NO UNWRAP/EXPECT** - use ? or combinators
- **PARAMETERIZED SQL** - never format! for queries
- **VALIDATE COMMANDS** - never pass raw user input
- **USE DIAGNOSTICS** - never call cargo clippy directly
- **INLINE FORMAT ARGS** - `format!("{name}")` not `format!("{}", name)`
- **USE SELF** - in impl blocks, use Self not type name