systemprompt-models
Shared data models, types, and repository patterns for SystemPrompt OS.
Overview
This crate provides common data models, error types, and repository patterns used throughout SystemPrompt OS. It includes API models, authentication types, configuration, database models, and service-layer error handling.
Modules
api - API Response Models
Standard JSON API response structures:
use ;
let response = success;
let error = not_found;
auth - Authentication Models
use ;
let user = AuthenticatedUser ;
config - Configuration Models
use Config;
use ConfigProvider;
let config = from_env?;
let db_url = config.database_url; // ConfigProvider trait
errors - Error Handling
RepositoryError - Database/repository layer errors:
use RepositoryError;
let err = NotFound;
// Automatically converts to ApiError
let api_err: ApiError = err.into;
ServiceError - Business logic layer errors:
use ServiceError;
let err = Validation;
let api_err: ApiError = err.into; // Converts to HTTP 400
Error Conversion Flow:
RepositoryError → ServiceError → ApiError → HTTP Response
repository - Repository Patterns
Service Lifecycle Trait:
use ServiceLifecycle;
Query Builder:
use WhereClause;
let = new
.eq
.is_not_null
.build;
let query = format!;
Repository Macros:
use impl_repository_base;
impl_repository_base!;
// Expands to:
// impl Repository for MyRepository {
// type Pool = DbPool;
// type Error = RepositoryError;
// fn pool(&self) -> &Self::Pool { &self.db_pool }
// }
execution - Execution Context
use RequestContext;
let req_ctx = RequestContext ;
Error Handling Pattern
SystemPrompt uses a layered error handling approach:
Layer 1: Repository (Database)
use RepositoryError;
async
Layer 2: Service (Business Logic)
use ServiceError;
async
Layer 3: API (HTTP)
use ApiError;
async
Repository Pattern
All repositories should implement the Repository trait from systemprompt-traits:
use ;
use DbPool;
const GET_USER_QUERY: &str = "SELECT * FROM users WHERE id = ?";
Query Helpers
WhereClause Builder
use WhereClause;
let = new
.eq
.is_not_null
.like
.in_list
.build;
// clause = "WHERE status = ? AND deleted_at IS NOT NULL AND name LIKE ? AND role IN (?, ?)"
// params = vec!["active", "%john%", "admin", "user"]
Repository Macros
// Base trait implementation
impl_repository_base!;
// Query execution
let users = repository_query!?;
// Execute statement
repository_execute!?;
Module Models
use ;
let module = Module ;
Dependencies
serde/serde_json- Serializationsqlx- Database typesanyhow/thiserror- Error handlingchrono/uuid- Common typesaxum- Request types for analyticsasync-trait- Async traitssystemprompt-traits- Core trait definitionssystemprompt-core-logging- Logging context
Best Practices
1. Use Shared Error Types
// ✅ Good
async
// ❌ Bad
async
2. Layer Your Errors
// Repository layer
// Service layer
// API layer
3. Use Query Builders
// ✅ Good
let = new.eq.build;
// ❌ Bad
let clause = format!; // SQL injection risk!
4. Implement Repository Trait
// ✅ Good - Consistent pattern
// ❌ Bad - No trait, inconsistent
Testing
Mock repositories using traits: