use std::sync::Arc;
use tracing::warn;
use crate::control::catalog_entry::CatalogEntry;
use crate::control::state::SharedState;
use super::super::wire::{CollectionSchemaSyncMsg, SyncFrame};
use super::state::SyncSession;
impl SyncSession {
pub fn handle_collection_schema(
&mut self,
msg: &CollectionSchemaSyncMsg,
shared: Option<&Arc<SharedState>>,
) -> Option<SyncFrame> {
let Some(shared) = shared else {
warn!(
session = %self.session_id,
collection = %msg.descriptor.name,
"CollectionSchema received without SharedState (permissive/test path); dropping"
);
return None;
};
let Some(tenant) = self.tenant_id else {
warn!(
session = %self.session_id,
collection = %msg.descriptor.name,
"CollectionSchema received before handshake established a tenant; dropping"
);
return None;
};
if msg.descriptor.tenant_id != tenant.as_u64() {
warn!(
session = %self.session_id,
collection = %msg.descriptor.name,
descriptor_tenant = msg.descriptor.tenant_id,
session_tenant = tenant.as_u64(),
"CollectionSchema tenant mismatch; refusing to materialize"
);
return None;
}
let owner = self.username.as_deref().unwrap_or("sync");
let stored =
crate::control::security::catalog::collection_descriptor_convert::stored_from_descriptor(
&msg.descriptor,
owner,
);
let entry = CatalogEntry::PutCollectionIfAbsent(Box::new(stored));
let log_index =
match crate::control::metadata_proposer::propose_catalog_entry(shared, &entry) {
Ok(idx) => idx,
Err(e) => {
warn!(
session = %self.session_id,
collection = %msg.descriptor.name,
error = %e,
"CollectionSchema: failed to propose PutCollectionIfAbsent; \
collection not materialized"
);
return None;
}
};
crate::control::catalog_entry::apply::local::apply_locally_if_needed(
shared, &entry, log_index,
);
None
}
}