|
| 1 | +# GitHub Copilot Instructions for AimDB |
| 2 | + |
| 3 | +## Project Overview |
| 4 | +AimDB is an async, in-memory database designed for real-time data synchronization across MCU → edge → cloud environments. This project focuses on millisecond-level reactivity, lock-free data structures, and platform portability. |
| 5 | + |
| 6 | +## Core Architecture Principles |
| 7 | + |
| 8 | +### 1. Async-First Design |
| 9 | +- All operations should be async/await compatible |
| 10 | +- Support for multiple async runtimes (Tokio, async-std, Embassy for embedded) |
| 11 | +- Use `no_std` compatibility where applicable for MCU targets |
| 12 | +- Prefer non-blocking algorithms and lock-free data structures |
| 13 | + |
| 14 | +### 2. Performance Requirements |
| 15 | +- Target <50ms reactivity for data operations |
| 16 | +- Use ring buffers for high-throughput streaming |
| 17 | +- Minimize allocations in hot paths |
| 18 | +- Optimize for zero-copy operations where possible |
| 19 | + |
| 20 | +### 3. Platform Targets |
| 21 | +- **MCU**: `no_std` environments with Embassy executor |
| 22 | +- **Edge**: Linux-class devices with standard async runtimes |
| 23 | +- **Cloud**: Container/VM deployments with full std library |
| 24 | + |
| 25 | +## Coding Standards |
| 26 | + |
| 27 | +### Rust-Specific Guidelines |
| 28 | +- Use `rustfmt` with default settings |
| 29 | +- Follow Clippy recommendations with `-D warnings` |
| 30 | +- Prefer explicit error handling with `Result<T, E>` |
| 31 | +- Use `thiserror` for error types, `anyhow` for error contexts |
| 32 | +- Document public APIs with comprehensive doc comments |
| 33 | +- Include examples in doc comments for public functions |
| 34 | + |
| 35 | +### Code Organization |
| 36 | +```rust |
| 37 | +// Preferred module structure |
| 38 | +pub mod core { |
| 39 | + pub mod engine; |
| 40 | + pub mod database; |
| 41 | + pub mod notifications; |
| 42 | +} |
| 43 | +pub mod connectors { |
| 44 | + pub mod mqtt; |
| 45 | + pub mod kafka; |
| 46 | + pub mod dds; |
| 47 | +} |
| 48 | +pub mod adapters { |
| 49 | + pub mod embassy; |
| 50 | + pub mod tokio; |
| 51 | + pub mod async_std; |
| 52 | +} |
| 53 | +``` |
| 54 | + |
| 55 | +### Naming Conventions |
| 56 | +- Use descriptive names that reflect AimDB domain concepts |
| 57 | +- Prefer `stream_handler` over generic names like `handler` |
| 58 | +- Use `_tx` / `_rx` suffixes for channel endpoints |
| 59 | +- Use `_buf` suffix for buffer types |
| 60 | +- Use `Config` suffix for configuration structs |
| 61 | + |
| 62 | +### Error Handling Patterns |
| 63 | +```rust |
| 64 | +// Preferred error handling |
| 65 | +use thiserror::Error; |
| 66 | + |
| 67 | +#[derive(Error, Debug)] |
| 68 | +pub enum AimDbError { |
| 69 | + #[error("Stream operation failed: {0}")] |
| 70 | + StreamError(String), |
| 71 | + #[error("Protocol bridge error: {protocol}")] |
| 72 | + BridgeError { protocol: String }, |
| 73 | + #[error("Runtime error")] |
| 74 | + RuntimeError(#[from] RuntimeError), |
| 75 | +} |
| 76 | +``` |
| 77 | + |
| 78 | +### Async Patterns |
| 79 | +```rust |
| 80 | +// Preferred async patterns |
| 81 | +pub async fn process_stream<T>(&mut self, mut stream: T) -> Result<(), AimDbError> |
| 82 | +where |
| 83 | + T: Stream<Item = DataEvent> + Unpin, |
| 84 | +{ |
| 85 | + while let Some(event) = stream.next().await { |
| 86 | + self.handle_event(event).await?; |
| 87 | + } |
| 88 | + Ok(()) |
| 89 | +} |
| 90 | +``` |
| 91 | + |
| 92 | +## Testing Guidelines |
| 93 | + |
| 94 | +### Unit Tests |
| 95 | +- Test each component in isolation |
| 96 | +- Use `tokio-test` for async test utilities |
| 97 | +- Mock external dependencies |
| 98 | +- Test error conditions explicitly |
| 99 | + |
| 100 | +### Integration Tests |
| 101 | +- Test protocol bridges end-to-end |
| 102 | +- Verify cross-platform compatibility |
| 103 | +- Test performance characteristics |
| 104 | +- Include benchmarks for critical paths |
| 105 | + |
| 106 | +### Test Organization |
| 107 | +```rust |
| 108 | +#[cfg(test)] |
| 109 | +mod tests { |
| 110 | + use super::*; |
| 111 | + use tokio_test::{assert_ok, assert_err}; |
| 112 | + |
| 113 | + #[tokio::test] |
| 114 | + async fn test_stream_processing() { |
| 115 | + // Test implementation |
| 116 | + } |
| 117 | +} |
| 118 | +``` |
| 119 | + |
| 120 | +## Performance Considerations |
| 121 | + |
| 122 | +### Memory Management |
| 123 | +- Prefer stack allocation for small, fixed-size data |
| 124 | +- Use `Box<[T]>` for heap-allocated arrays |
| 125 | +- Consider `Rc<T>` / `Arc<T>` for shared data |
| 126 | +- Use memory pools for frequently allocated objects |
| 127 | + |
| 128 | +### Concurrency |
| 129 | +- Use `tokio::sync` primitives for async coordination |
| 130 | +- Prefer channels over shared mutable state |
| 131 | +- Use `DashMap` for concurrent hash maps |
| 132 | +- Consider `crossbeam` for lock-free data structures |
| 133 | + |
| 134 | +### Platform-Specific Optimizations |
| 135 | +- Use feature flags for platform-specific code |
| 136 | +- Optimize allocation patterns for embedded targets |
| 137 | +- Leverage SIMD instructions where applicable |
| 138 | +- Consider cache-friendly data layouts |
| 139 | + |
| 140 | +## Documentation Standards |
| 141 | + |
| 142 | +### Public API Documentation |
| 143 | +```rust |
| 144 | +/// Processes incoming data streams and maintains synchronized state. |
| 145 | +/// |
| 146 | +/// The `StreamProcessor` handles real-time data ingestion from various |
| 147 | +/// protocol bridges and ensures consistent state across all connected |
| 148 | +/// nodes in the AimDB network. |
| 149 | +/// |
| 150 | +/// # Examples |
| 151 | +/// |
| 152 | +/// ```rust |
| 153 | +/// use aimdb::StreamProcessor; |
| 154 | +/// |
| 155 | +/// let processor = StreamProcessor::new(); |
| 156 | +/// processor.start_processing(stream).await?; |
| 157 | +/// ``` |
| 158 | +/// |
| 159 | +/// # Performance |
| 160 | +/// |
| 161 | +/// This implementation targets <50ms latency for data processing |
| 162 | +/// operations and supports throughput of up to 100k events/second. |
| 163 | +pub struct StreamProcessor { |
| 164 | + // Implementation |
| 165 | +} |
| 166 | +``` |
| 167 | + |
| 168 | +### Module Documentation |
| 169 | +- Include module-level documentation explaining purpose |
| 170 | +- Document feature flags and their effects |
| 171 | +- Explain relationships to other modules |
| 172 | +- Include architecture diagrams where helpful |
| 173 | + |
| 174 | +## Dependencies |
| 175 | + |
| 176 | +### Core Dependencies |
| 177 | +- `tokio` or `async-std` for async runtime |
| 178 | +- `embassy-executor` for embedded async |
| 179 | +- `serde` for serialization |
| 180 | +- `thiserror` for error handling |
| 181 | +- `tracing` for observability |
| 182 | + |
| 183 | +### Protocol Dependencies |
| 184 | +- `rumqttc` for MQTT |
| 185 | +- `rdkafka` for Kafka |
| 186 | +- `cyclors` for DDS |
| 187 | + |
| 188 | +### Development Dependencies |
| 189 | +- `criterion` for benchmarking |
| 190 | +- `proptest` for property-based testing |
| 191 | +- `tokio-test` for async testing utilities |
| 192 | + |
| 193 | +## Feature Flags |
| 194 | + |
| 195 | +### Runtime Selection |
| 196 | +```toml |
| 197 | +[features] |
| 198 | +default = ["tokio-runtime"] |
| 199 | +tokio-runtime = ["tokio"] |
| 200 | +async-std-runtime = ["async-std"] |
| 201 | +embassy-runtime = ["embassy-executor"] |
| 202 | +``` |
| 203 | + |
| 204 | +### Protocol Support |
| 205 | +```toml |
| 206 | +mqtt-bridge = ["rumqttc"] |
| 207 | +kafka-bridge = ["rdkafka"] |
| 208 | +dds-bridge = ["cyclors"] |
| 209 | +``` |
| 210 | + |
| 211 | +### Platform Features |
| 212 | +```toml |
| 213 | +embedded = ["no-std-compat"] |
| 214 | +observability = ["tracing", "metrics"] |
| 215 | +``` |
| 216 | + |
| 217 | +## Git Commit Guidelines |
| 218 | + |
| 219 | +### Commit Message Format |
| 220 | +``` |
| 221 | +type(scope): brief description |
| 222 | +
|
| 223 | +Detailed explanation of changes, focusing on why |
| 224 | +rather than what was changed. |
| 225 | +
|
| 226 | +- Bullet points for multiple changes |
| 227 | +- Reference issue numbers: Fixes #123 |
| 228 | +``` |
| 229 | + |
| 230 | +### Types |
| 231 | +- `feat`: New feature implementation |
| 232 | +- `fix`: Bug fixes |
| 233 | +- `perf`: Performance improvements |
| 234 | +- `refactor`: Code restructuring |
| 235 | +- `test`: Test additions or modifications |
| 236 | +- `docs`: Documentation updates |
| 237 | +- `ci`: CI/CD pipeline changes |
| 238 | + |
| 239 | +### Scopes |
| 240 | +- `core`: Core engine components |
| 241 | +- `connectors`: Protocol connector implementations |
| 242 | +- `adapters`: Async runtime integrations |
| 243 | +- `embedded`: MCU-specific code |
| 244 | +- `perf`: Performance optimizations |
| 245 | + |
| 246 | +## Code Generation Preferences |
| 247 | + |
| 248 | +When generating code for AimDB: |
| 249 | + |
| 250 | +1. **Always consider async/await patterns** - This is an async-first project |
| 251 | +2. **Include comprehensive error handling** - Use Result types and proper error propagation |
| 252 | +3. **Add performance considerations** - Comment on allocation patterns and performance implications |
| 253 | +4. **Consider platform compatibility** - Include feature flags for different target platforms |
| 254 | +5. **Include documentation** - Generate doc comments for public APIs |
| 255 | +6. **Add tests** - Include unit tests for new functionality |
| 256 | +7. **Use domain-specific naming** - Prefer AimDB-specific terminology over generic names |
| 257 | +8. **Consider observability** - Add tracing spans for important operations |
| 258 | + |
| 259 | +## Example Code Templates |
| 260 | + |
| 261 | +### New Module Template |
| 262 | +```rust |
| 263 | +//! Module description and purpose within AimDB |
| 264 | +//! |
| 265 | +//! This module handles [specific functionality] and integrates with |
| 266 | +//! [related components]. |
| 267 | + |
| 268 | +extern crate alloc; |
| 269 | + |
| 270 | +use alloc::sync::Arc; |
| 271 | +use tracing::{debug, info, warn, error}; |
| 272 | + |
| 273 | +use crate::core::AimDbError; |
| 274 | + |
| 275 | +/// Main struct documentation |
| 276 | +pub struct ModuleName { |
| 277 | + // Fields with descriptive names |
| 278 | +} |
| 279 | + |
| 280 | +impl ModuleName { |
| 281 | + /// Constructor with comprehensive documentation |
| 282 | + pub fn new() -> Self { |
| 283 | + Self { |
| 284 | + // Initialization |
| 285 | + } |
| 286 | + } |
| 287 | + |
| 288 | + /// Async method template |
| 289 | + pub async fn process(&self) -> Result<(), AimDbError> { |
| 290 | + // Implementation with error handling |
| 291 | + Ok(()) |
| 292 | + } |
| 293 | +} |
| 294 | + |
| 295 | +#[cfg(test)] |
| 296 | +mod tests { |
| 297 | + use super::*; |
| 298 | + |
| 299 | + #[tokio::test] |
| 300 | + async fn test_basic_functionality() { |
| 301 | + // Test implementation |
| 302 | + } |
| 303 | +} |
| 304 | +``` |
0 commit comments