botserver/PROMPT.md

259 lines
5.7 KiB
Markdown
Raw Normal View History

2026-01-22 20:24:05 -03:00
# botserver Development Guide
2026-01-22 20:24:05 -03:00
**Version:** 6.2.0
**Purpose:** Main API server for General Bots (Axum + Diesel + Rhai BASIC + HTMX in botui)
---
2025-12-21 23:40:43 -03:00
## ZERO TOLERANCE POLICY
**EVERY SINGLE WARNING MUST BE FIXED. NO EXCEPTIONS.**
2025-12-21 23:40:43 -03:00
---
2026-01-22 20:24:05 -03:00
## ❌ ABSOLUTE PROHIBITIONS
2025-12-21 23:40:43 -03:00
```
2025-12-28 19:29:18 -03:00
❌ NEVER use #![allow()] or #[allow()] in source code
2025-12-21 23:40:43 -03:00
❌ NEVER use .unwrap() - use ? or proper error handling
❌ NEVER use .expect() - use ? or proper error handling
2025-12-28 19:29:18 -03:00
❌ 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
2025-12-21 23:40:43 -03:00
❌ NEVER use CDN links - all assets must be local
2025-12-28 19:29:18 -03:00
❌ 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
2025-12-21 23:40:43 -03:00
```
---
2026-01-22 20:24:05 -03:00
## 🔐 SECURITY REQUIREMENTS
2025-12-28 19:29:18 -03:00
### Error Handling
2025-12-21 23:40:43 -03:00
```rust
// ❌ WRONG
let value = something.unwrap();
let value = something.expect("msg");
2025-12-21 23:40:43 -03:00
// ✅ CORRECT
let value = something?;
let value = something.ok_or_else(|| Error::NotFound)?;
2025-12-28 19:29:18 -03:00
let value = something.unwrap_or_default();
2025-12-21 23:40:43 -03:00
```
2025-12-28 19:29:18 -03:00
### Rhai Syntax Registration
2025-12-21 23:40:43 -03:00
```rust
// ❌ WRONG
2025-12-28 19:29:18 -03:00
engine.register_custom_syntax([...], false, |...| {...}).unwrap();
2025-12-21 23:40:43 -03:00
// ✅ CORRECT
2025-12-28 19:29:18 -03:00
if let Err(e) = engine.register_custom_syntax([...], false, |...| {...}) {
log::warn!("Failed to register syntax: {e}");
2025-12-21 23:40:43 -03:00
}
```
2025-12-28 19:29:18 -03:00
### Regex Patterns
2025-12-21 23:40:43 -03:00
```rust
// ❌ WRONG
2025-12-28 19:29:18 -03:00
let re = Regex::new(r"pattern").unwrap();
2025-12-21 23:40:43 -03:00
// ✅ CORRECT
2025-12-28 19:29:18 -03:00
static RE: LazyLock<Regex> = LazyLock::new(|| {
Regex::new(r"pattern").expect("invalid regex")
});
2025-12-21 23:40:43 -03:00
```
2025-12-28 19:29:18 -03:00
### Tokio Runtime
2025-12-21 23:40:43 -03:00
```rust
// ❌ WRONG
2025-12-28 19:29:18 -03:00
let rt = tokio::runtime::Runtime::new().unwrap();
2025-12-21 23:40:43 -03:00
// ✅ CORRECT
2025-12-28 19:29:18 -03:00
let Ok(rt) = tokio::runtime::Runtime::new() else {
return Err("Failed to create runtime".into());
};
2025-12-21 23:40:43 -03:00
```
2025-12-28 19:29:18 -03:00
### SQL Injection Prevention
2025-12-21 23:40:43 -03:00
```rust
// ❌ WRONG
2025-12-28 19:29:18 -03:00
let query = format!("SELECT * FROM {}", table_name);
2025-12-21 23:40:43 -03:00
2025-12-28 19:29:18 -03:00
// ✅ CORRECT - whitelist validation
const ALLOWED_TABLES: &[&str] = &["users", "sessions"];
if !ALLOWED_TABLES.contains(&table_name) {
return Err(Error::InvalidTable);
2025-12-21 23:40:43 -03:00
}
```
2025-12-28 19:29:18 -03:00
### Command Injection Prevention
2025-12-21 23:40:43 -03:00
```rust
// ❌ WRONG
2025-12-28 19:29:18 -03:00
Command::new("tool").arg(user_input).output()?;
2025-12-21 23:40:43 -03:00
// ✅ CORRECT
2025-12-28 19:29:18 -03:00
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()?;
2025-12-21 23:40:43 -03:00
```
2025-12-28 19:29:18 -03:00
---
2026-01-22 20:24:05 -03:00
## ✅ CODE PATTERNS
2025-12-28 19:29:18 -03:00
### Format Strings - Inline Variables
2025-12-23 15:52:35 -03:00
```rust
2025-12-28 19:29:18 -03:00
// ❌ WRONG
format!("Hello {}", name)
2025-12-23 15:52:35 -03:00
2025-12-28 19:29:18 -03:00
// ✅ CORRECT
format!("Hello {name}")
2025-12-23 15:52:35 -03:00
```
2025-12-28 19:29:18 -03:00
### Self Usage in Impl Blocks
2025-12-21 23:40:43 -03:00
```rust
2025-12-28 19:29:18 -03:00
// ❌ WRONG
impl MyStruct {
fn new() -> MyStruct { MyStruct { } }
}
2025-12-21 23:40:43 -03:00
// ✅ CORRECT
2025-12-28 19:29:18 -03:00
impl MyStruct {
fn new() -> Self { Self { } }
}
```
2025-12-28 19:29:18 -03:00
### Derive Eq with PartialEq
2025-12-21 23:40:43 -03:00
```rust
2025-12-28 19:29:18 -03:00
// ❌ WRONG
#[derive(PartialEq)]
struct MyStruct { }
2025-12-21 23:40:43 -03:00
// ✅ CORRECT
2025-12-28 19:29:18 -03:00
#[derive(PartialEq, Eq)]
struct MyStruct { }
2025-12-21 23:40:43 -03:00
```
2025-12-28 19:29:18 -03:00
### Option Handling
2025-12-21 23:40:43 -03:00
```rust
// ✅ CORRECT
2025-12-28 19:29:18 -03:00
opt.unwrap_or(default)
opt.unwrap_or_else(|| compute_default())
opt.map_or(default, |x| transform(x))
```
2025-12-28 19:29:18 -03:00
### Chrono DateTime
2025-12-21 23:40:43 -03:00
```rust
// ❌ WRONG
2025-12-28 19:29:18 -03:00
date.with_hour(9).unwrap().with_minute(0).unwrap()
2025-12-21 23:40:43 -03:00
// ✅ CORRECT
2025-12-28 19:29:18 -03:00
date.with_hour(9).and_then(|d| d.with_minute(0)).unwrap_or(date)
```
2025-12-21 23:40:43 -03:00
---
2026-01-22 20:24:05 -03:00
## 📁 KEY DIRECTORIES
2026-01-22 20:24:05 -03:00
```
src/
├── core/ # Bootstrap, config, routes
├── basic/ # Rhai BASIC interpreter
│ └── keywords/ # BASIC keyword implementations
├── security/ # Security modules
├── shared/ # Shared types, models
├── tasks/ # AutoTask system
└── auto_task/ # App generator
```
---
## 🗄️ DATABASE STANDARDS
- **TABLES AND INDEXES ONLY** (no views, triggers, functions)
- **JSON columns:** use TEXT with `_json` suffix
- **ORM:** Use diesel - no sqlx
- **Migrations:** Located in `botserver/migrations/`
---
2026-01-22 20:24:05 -03:00
## 🎨 FRONTEND RULES
2026-01-22 20:24:05 -03:00
- **Use HTMX** - minimize JavaScript
- **NO external CDN** - all assets local
- **Server-side rendering** with Askama templates
---
2026-01-22 20:24:05 -03:00
## 📦 KEY DEPENDENCIES
| Library | Version | Purpose |
|---------|---------|---------|
| axum | 0.7.5 | Web framework |
2025-12-21 23:40:43 -03:00
| 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 |
---
## 🚀 CI/CD WORKFLOW
When configuring CI/CD pipelines (e.g., Forgejo Actions):
- **Minimal Checkout**: Clone only the root `gb` and the `botlib` submodule. Do NOT recursively clone everything.
- **BotServer Context**: Replace the empty `botserver` directory with the current set of files being tested.
**Example Step:**
```yaml
- name: Setup Workspace
run: |
# 1. Clone only the root workspace configuration
git clone --depth 1 <your-git-repo-url> workspace
# 2. Setup only the necessary dependencies (botlib)
cd workspace
git submodule update --init --depth 1 botlib
cd ..
# 3. Inject current BotServer code
rm -rf workspace/botserver
mv botserver workspace/botserver
```
---
2026-01-22 20:24:05 -03:00
## 🔑 REMEMBER
2025-12-28 19:29:18 -03:00
- **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
- **INLINE FORMAT ARGS** - `format!("{name}")` not `format!("{}", name)`
2026-01-22 20:24:05 -03:00
- **USE SELF** - in impl blocks, use Self not type name
- **Version 6.2.0** - do not change without approval