pub mod onetable;
use serde::Serialize;
#[derive(Debug, Clone, Serialize)]
pub struct DataModel {
pub schema_format: String,
pub type_attribute: String,
pub entities: Vec<EntityDefinition>,
}
#[derive(Debug, Clone, Serialize)]
pub struct EntityDefinition {
pub name: String,
pub pk_template: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub sk_template: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub type_attribute: Option<String>,
pub gsi_mappings: Vec<GsiMapping>,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
}
#[derive(Debug, Clone, Serialize)]
pub struct GsiMapping {
pub index_name: String,
pub pk_template: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub sk_template: Option<String>,
}
impl DataModel {
pub fn instructions_summary(&self, limit: usize) -> Option<String> {
if limit == 0 {
return None;
}
let entity_count = self.entities.len();
let shown = self.entities.iter().take(limit);
let entity_parts: Vec<String> = shown
.map(|e| {
if e.gsi_mappings.is_empty() {
e.name.clone()
} else {
let gsis: Vec<&str> = e
.gsi_mappings
.iter()
.map(|g| g.index_name.as_str())
.collect();
format!("{} ({})", e.name, gsis.join(", "))
}
})
.collect();
let mut summary = format!(
"## Data model\n\n\
Schema: {} ({} entities, type attribute: \"{}\")\n\
Entities: {}",
self.schema_format,
entity_count,
self.type_attribute,
entity_parts.join(", "),
);
if entity_count > limit {
summary.push_str(&format!("...and {} more", entity_count - limit));
}
summary.push_str(
"\n\nCall get_database_info for full entity definitions with key templates.\n\
Note: Data model definitions describe the intended schema but are not enforced. \
Actual database contents may differ.",
);
Some(summary)
}
}