Initial commit
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
153
claude.md
Normal file
153
claude.md
Normal file
@@ -0,0 +1,153 @@
|
||||
# CLAUDE.md — BEDS Rust Rewrite
|
||||
|
||||
This file provides guidance to Claude Code when working in this repository.
|
||||
|
||||
## What This Project Is
|
||||
|
||||
**BEDS (Back End Data System)** is a Rust rewrite of a proven PHP microservice backend framework (codenamed Namaste). The PHP version ran 952 days in production without error, handled 40,000+ transactions per second on a single node, and demonstrated ~200ms round-trip latency from Baja California to West Virginia for destructive CRUD operations fanning out into dozens of concurrent DB calls.
|
||||
|
||||
This is not a greenfield project. The architecture is proven. The Rust rewrite exists to:
|
||||
1. Eliminate PHP memory leak workarounds (planned broker obsolescence via SIGCHLD)
|
||||
2. Dramatically increase throughput (5-10x expected)
|
||||
3. Enable single binary deployment with no runtime dependency
|
||||
4. Protect IP through compilation
|
||||
5. Add an AI-driven database object generation layer
|
||||
|
||||
## Core Architecture Principles
|
||||
|
||||
**Never violate these — they are the product:**
|
||||
|
||||
1. **AMQP-first** — all data access flows through RabbitMQ message brokers. No direct database connections from the application layer. Ever.
|
||||
2. **Database agnostic** — the framework supports MySQL/MariaDB, MongoDB, and DynamoDB through a unified trait/factory pattern. No database-specific logic leaks into the broker or factory layers.
|
||||
3. **DBA-owned schema** — developers never write queries. All data access goes through named database objects (views, stored procedures, functions). The application layer calls template names, not SQL.
|
||||
4. **Template-driven CRUD** — each data domain is a Rust struct implementing the `NamasteCore` trait. Adding a domain means adding a struct. Nothing else changes.
|
||||
5. **Single codebase, config-driven nodes** — all service nodes run the same binary. Node role (appServer, admin, segundo, tercero) is determined entirely by startup configuration.
|
||||
|
||||
## Project Structure (Target)
|
||||
|
||||
```
|
||||
beds/
|
||||
├── src/
|
||||
│ ├── core/
|
||||
│ │ ├── trait.rs # NamasteCore trait definition
|
||||
│ │ ├── factory.rs # Template name → adapter dispatch
|
||||
│ │ └── meta.rs # Request metadata parsing
|
||||
│ ├── adapters/
|
||||
│ │ ├── mysql.rs # gacPDO equivalent
|
||||
│ │ ├── mongodb.rs # gacMongoDB equivalent
|
||||
│ │ └── dynamodb.rs # gacDdb equivalent
|
||||
│ ├── brokers/
|
||||
│ │ ├── pool.rs # Broker pool management
|
||||
│ │ └── broker.rs # Individual broker task
|
||||
│ ├── templates/ # Domain-specific structs (one per data domain)
|
||||
│ ├── config/
|
||||
│ │ └── loader.rs # TOML config loading and merging
|
||||
│ └── main.rs
|
||||
├── config/
|
||||
│ ├── beds.toml # Base production config
|
||||
│ └── env.toml # Environment overrides
|
||||
├── Cargo.toml
|
||||
└── CLAUDE.md
|
||||
```
|
||||
|
||||
## Key Rust Mappings from PHP
|
||||
|
||||
| PHP | Rust |
|
||||
|-----|------|
|
||||
| `gaaNamasteCore` abstract class | `NamasteCore` trait |
|
||||
| `gacMongoDB`, `gacPDO`, `gacDdb` | Structs implementing `NamasteCore` |
|
||||
| `gacFactory::grabWidget()` | Match/dispatch returning `Box<dyn NamasteCore>` |
|
||||
| Broker process pool | `tokio::spawn` task pool |
|
||||
| SIGCHLD/planned obsolescence | Eliminated — Tokio tasks don't leak |
|
||||
| XML config layering | TOML with environment override file |
|
||||
| `.class.inc` template files | Rust modules in `src/templates/` |
|
||||
| `gasResourceManager` | Connection pool via `sqlx`/`deadpool` |
|
||||
|
||||
## NamasteCore Trait Interface
|
||||
|
||||
The core CRUD interface. Every database adapter and every template must implement this:
|
||||
|
||||
```rust
|
||||
pub trait NamasteCore {
|
||||
async fn create_record(&self, payload: &Payload) -> Result<Response, BEDSError>;
|
||||
async fn fetch_records(&self, query: &Query) -> Result<Vec<Response>, BEDSError>;
|
||||
async fn update_record(&self, payload: &Payload) -> Result<Response, BEDSError>;
|
||||
async fn delete_record(&self, id: &str) -> Result<Response, BEDSError>;
|
||||
}
|
||||
```
|
||||
|
||||
## Dependencies (Cargo.toml)
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
lapin = "2" # AMQP/RabbitMQ
|
||||
sqlx = { version = "0.7", features = ["mysql", "runtime-tokio-native-tls"] }
|
||||
mongodb = "2" # MongoDB async driver
|
||||
aws-sdk-dynamodb = "1" # DynamoDB
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
config = "0.14" # TOML config management
|
||||
thiserror = "1"
|
||||
tracing = "1"
|
||||
tracing-subscriber = "1"
|
||||
```
|
||||
|
||||
## Service Nodes
|
||||
|
||||
All nodes run the same binary. Startup config determines role:
|
||||
|
||||
| Node | Role | Brokers |
|
||||
|------|------|---------|
|
||||
| appServer | Main application | rBroker, wBroker, mBroker |
|
||||
| admin | Administration | adminBrokerIn/Out, adminLogsBroker, adminSyslogBroker, adminGraphBroker |
|
||||
| segundo | Warehouse/cool storage | whBroker, cBroker |
|
||||
| tercero | User management | uBroker, sBroker |
|
||||
|
||||
## Scaling Model
|
||||
|
||||
- **Horizontal** — increase broker count in config when node has available resources
|
||||
- **Vertical** — add nodes to broker pool when a node saturates
|
||||
- **Hot-swap** — nodes can be replaced without touching application code; broker pool absorbs the change
|
||||
|
||||
## AI Admin Layer (Planned — Phase 2)
|
||||
|
||||
A DBA describes a data domain in natural language. The AI layer generates:
|
||||
1. Database schema (table/collection definitions)
|
||||
2. Views and stored procedures/functions
|
||||
3. BEDS template struct implementing `NamasteCore`
|
||||
4. API documentation (markdown)
|
||||
|
||||
This is the primary market differentiator. No competitor combines database-agnostic transport + AMQP broker layer + DBA-enforced schema gatekeeping + AI-driven object generation.
|
||||
|
||||
## Development Conventions
|
||||
|
||||
- All errors use `thiserror` — no `.unwrap()` in production paths
|
||||
- All database operations are async — no blocking calls on the Tokio runtime
|
||||
- Broker tasks are supervised — a failed task is logged and replaced, not silently dropped
|
||||
- Config is loaded once at startup and passed as shared state — no runtime config reads
|
||||
- One template per file in `src/templates/` — file name matches domain name
|
||||
|
||||
## Performance Baseline
|
||||
|
||||
The PHP implementation achieved:
|
||||
- 40,000+ tp/s single node
|
||||
- ~200ms round-trip Baja → West Virginia with dozens of concurrent DB fanout calls
|
||||
- 952 days continuous production uptime
|
||||
|
||||
The Rust rewrite must meet or exceed these numbers. Run benchmarks before any architectural change that touches the broker pool or factory dispatch path.
|
||||
|
||||
## Prior Art
|
||||
|
||||
The PHP implementation lives in the `namaste` repository. Refer to it for:
|
||||
- Domain template patterns (`classes/templates/*.class.inc`)
|
||||
- Config structure (`config/namaste.xml`)
|
||||
- Error catalog (`common/errorCatalog.php`)
|
||||
- DB catalog (`common/dbCatalog.php`)
|
||||
- Schema definitions (`schema/pdo/`)
|
||||
|
||||
Do not copy PHP code into this repository. Use it as architectural reference only.
|
||||
|
||||
## Author
|
||||
|
||||
gramps@llamachile.shop
|
||||
Reference in New Issue
Block a user