diff --git a/prompts/dev/add-keyword.md b/prompts/dev/add-keyword.md new file mode 100644 index 00000000..5aa90571 --- /dev/null +++ b/prompts/dev/add-keyword.md @@ -0,0 +1,151 @@ +Create a new Rhai custom keyword implementation with these specifications: + +- When generating new Rhai keyword handlers in Rust, always design them to be thread-safe and fully compatible with async execution. Use Arc for shared state, perform heavy or async operations with tokio::task::block_in_place and Handle::current().block_on, and return results as rhai::Dynamic to maintain safe cross-thread communication between Rust and the Rhai engine. + +1. DATABASE REQUIREMENTS: +- No enums in database schema (only in Rust code) +- Use direct integer values for enum variants in queries +- Follow existing connection pooling pattern with AppState +- Include proper error handling and logging + +2. RUST IMPLEMENTATION: +- Enum definition (Rust-only, no DB enum): +```rust +#[repr(i32)] +pub enum KeywordAction { + Action1 = 0, + Action2 = 1, + Action3 = 2 +} +``` + +3. KEYWORD TEMPLATE: +```rust +pub fn {keyword_name}_keyword(state: &AppState, engine: &mut Engine) { + let db = state.db_custom.clone(); + + engine.register_custom_syntax( + {syntax_pattern}, + {is_raw}, + { + let db = db.clone(); + move |context, inputs| { + // Input processing + {input_processing} + + let binding = db.as_ref().unwrap(); + let fut = execute_{keyword_name}(binding, {params}); + + let result = tokio::task::block_in_place(|| + tokio::runtime::Handle::current().block_on(fut)) + .map_err(|e| format!("DB error: {}", e))?; + + {result_handling} + } + } + ).unwrap(); +} + +pub async fn execute_{keyword_name}( + pool: &PgPool, + {params_with_types} +) -> Result> { + info!("Executing {keyword_name} with: {debug_params}"); + + let result = sqlx::query( + "{sql_query_with_i32_enum}" + ) + .bind({enum_value} as i32) + {additional_binds} + .execute(pool) + .await?; + + Ok(json!({ + "command": "{keyword_name}", + {result_fields} + "rows_affected": result.rows_affected() + })) +} +``` + +4. EXAMPLE IMPLEMENTATION (SET SCHEDULE): +```rust +// Enum (Rust-only) +#[repr(i32)] +pub enum TriggerKind { + Scheduled = 0, + TableUpdate = 1, + TableInsert = 2, + TableDelete = 3 +} + +// Keyword implementation +pub fn set_schedule_keyword(state: &AppState, engine: &mut Engine) { + let db = state.db_custom.clone(); + + engine.register_custom_syntax( + ["SET", "SCHEDULE", "$string$"], + true, + { + let db = db.clone(); + move |context, inputs| { + let cron = context.eval_expression_tree(&inputs[0])?.to_string(); + let script_name = format!("cron_{}.rhai", cron.replace(' ', "_")); + + let binding = db.as_ref().unwrap(); + let fut = execute_set_schedule(binding, &cron, &script_name); + + let result = tokio::task::block_in_place(|| + tokio::runtime::Handle::current().block_on(fut)) + .map_err(|e| format!("DB error: {}", e))?; + + if let Some(rows_affected) = result.get("rows_affected") { + Ok(Dynamic::from(rows_affected.as_i64().unwrap_or(0))) + } else { + Err("No rows affected".into()) + } + } + } + ).unwrap(); +} + +pub async fn execute_set_schedule( + pool: &PgPool, + cron: &str, + script_name: &str, +) -> Result> { + info!("Executing schedule: {}, {}", cron, script_name); + + let result = sqlx::query( + "INSERT INTO system_automations + (kind, schedule, script_name) + VALUES ($1, $2, $3)" + ) + .bind(TriggerKind::Scheduled as i32) + .bind(cron) + .bind(script_name) + .execute(pool) + .await?; + + Ok(json!({ + "command": "set_schedule", + "schedule": cron, + "script_name": script_name, + "rows_affected": result.rows_affected() + })) +} +``` + +5. ADDITIONAL REQUIREMENTS: +- Maintain consistent tokio runtime handling +- Include parameter validation +- Follow existing JSON response format +- Ensure proper script name generation +- Include debug logging for all operations + +6. OUTPUT FORMAT: +Provide complete implementation with: +1. Rust enum definition +2. Keyword registration function +3. Execution function +4. Example usage in Rhai diff --git a/prompts/dev/add-model.md b/prompts/dev/add-model.md new file mode 100644 index 00000000..c3c462ef --- /dev/null +++ b/prompts/dev/add-model.md @@ -0,0 +1,94 @@ + +Create a Rust data model for database storage with optimal size and performance characteristics. Follow these specifications: + +**REQUIREMENTS:** +1. Use appropriate integer types (i32, i16, i8, etc.) based on expected value ranges +2. Use `Option` for nullable fields to avoid memory overhead +3. Use `Vec` for binary data instead of strings when appropriate +4. Prefer enum representations as integers rather than strings +5. Use `chrono::DateTime` for timestamps +6. Use `uuid::Uuid` for unique identifiers +7. Implement necessary traits: `Debug`, `Clone`, `Serialize`, `Deserialize`, `FromRow` +8. Include validation where appropriate +9. Consider database index strategy in field design + +**CONTEXT:** +- Database: PostgreSQL/SQLx compatible +- Serialization: Serde for JSON +- ORM: SQLx for database operations + +**OUTPUT FORMAT:** +Provide the complete Rust struct with: +- Struct definition with fields +- Enum definitions with integer representations +- Conversion implementations +- Basic validation if needed + +**EXAMPLE REFERENCE:** +```rust +use chrono::{DateTime, Utc}; +use serde::{Deserialize, Serialize}; +use sqlx::FromRow; +use uuid::Uuid; + +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum Status { + Pending = 0, + Active = 1, + Inactive = 2, +} + +impl Status { + pub fn from_i16(value: i16) -> Option { + match value { + 0 => Some(Self::Pending), + 1 => Some(Self::Active), + 2 => Some(Self::Inactive), + _ => None, + } + } +} + +#[derive(Debug, FromRow, Serialize, Deserialize)] +pub struct User { + pub id: Uuid, + pub status: i16, // Using i16 for enum storage + pub email: String, + pub age: Option, // Nullable small integer + pub metadata: Vec, // Binary data for flexibility + pub created_at: DateTime, +} +``` + +Generate a similar model for: [YOUR DOMAIN HERE] +``` + +## Specialized Variants + +### For High-Performance Applications +``` +Add these additional requirements: +- Use `#[repr(u8)]` for enums to ensure minimal size +- Consider `Box` instead of `String` for reduced heap overhead +- Use `arrayvec::ArrayString` for fixed-size short strings +- Implement `PartialEq` and `Eq` for hash-based operations +- Include `#[derive(Default)]` where appropriate +``` + +### For Embedded/Memory-Constrained Systems +``` +Add these constraints: +- Prefer `i16` over `i32` where possible +- Use `u32` instead of `Uuid` if sequential IDs are acceptable +- Consider `bitflags` for multiple boolean flags in single byte +- Use `smol_str::SmolStr` for string optimization +- Avoid `Vec` in favor of arrays with capacity limits +``` + +### For Time-Series Data +``` +Add time-series specific optimizations: +- Use `i64` for timestamps as nanoseconds since epoch +- Use `f32` instead of `f64` for measurements where precision allows +- Consider `ordered_float::OrderedFloat` for floating-point comparisons +- Use `#[serde(with = "chrono::serde::ts_seconds")]` for compact serialization diff --git a/prompts/dev/add-service.md b/prompts/dev/add-service.md new file mode 100644 index 00000000..002e2286 --- /dev/null +++ b/prompts/dev/add-service.md @@ -0,0 +1,57 @@ +Generate a Rust service module following these patterns: + +Core Structure: + +Use actix-web for HTTP endpoints (get, post, etc.) + +Isolate shared resources (DB, clients, config) in AppState + +Split logic into reusable helper functions + +do not create main logic + +Endpoints: + +Follow REST conventions (e.g., POST /{resource}/create) use anotations in methods. + +Use web::Path for route parameters, web::Json for payloads + +Return consistent responses (e.g., HttpResponse::Ok().json(data)) + +Error Handling: + +Wrap fallible operations in Result + +Use map_err to convert errors to actix_web::Error + +Provide clear error messages (e.g., ErrorInternalServerError) + +Async Patterns: + +Use async/await for I/O (DB, external APIs) + +Leverage streams for pagination/large datasets + +Isolate blocking ops in spawn_blocking if needed + +Configuration: + +Load settings (e.g., URLs, credentials) from AppConfig + +Initialize clients (DB, SDKs) at startup (e.g., init_*() helpers) + +Documentation: + +Add brief doc comments for public functions + +Note safety assumptions (e.g., #[post] invariants) +postgres sqlx +Omit domain-specific logic (e.g., file/email details), focusing on the scaffolding." + +Key Features: + +Generic (applies to any service: auth, payments, etc.) + +KISS (avoids over-engineering) + +Copy-paste friendly (clear patterns without verbosity) diff --git a/prompts/dev/fix-errors.md b/prompts/dev/fix-errors.md new file mode 100644 index 00000000..d171d3f5 --- /dev/null +++ b/prompts/dev/fix-errors.md @@ -0,0 +1,35 @@ +You are fixing Rust code in a Cargo project. The user is providing problematic code that needs to be corrected. + +## Your Task +Fix ALL compiler errors and logical issues while maintaining the original intent. +Use Cargo.toml as reference, do not change it. +Only return input files, all other files already exists. +If something, need to be added to a external file, inform it separated. + +## Critical Requirements +3. **Respect Cargo.toml** - Check dependencies, editions, and features to avoid compiler errors +4. **Type safety** - Ensure all types match and trait bounds are satisfied +5. **Ownership rules** - Fix borrowing, ownership, and lifetime issues + + +MORE RULES: +- Return only the modified files as a single `.sh` script using `cat`, so the - code can be restored directly. +- You MUST return exactly this example format: +```sh +#!/bin/bash + +# Restore fixed Rust project + +cat > src/.rs << 'EOF' +use std::io; + +// test + +cat > src/.rs << 'EOF' +// Fixed library code +pub fn add(a: i32, b: i32) -> i32 { + a + b +} +EOF + +----