feat(api): on-write search reindex after catalogue writes (#17)
Wire best-effort Meilisearch index sync into the admin write paths (create/update/delete/set_fields/set_visibility). Adds SearchClient::sync_object (reindex if the object exists, remove if gone — one uniform path), an optional AppState.search client, and a reindex helper that logs failures via tracing without failing the committed write. Server gains MEILI_URL/MEILI_MASTER_KEY/MEILI_INDEX config; search stays disabled (no-op) when unset. reindex_all remains the recovery path. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -27,4 +27,19 @@ pub struct Config {
|
||||
default_value_t = true
|
||||
)]
|
||||
pub cookie_secure: bool,
|
||||
|
||||
/// Meilisearch base URL (e.g. `http://localhost:7700`). On-write search indexing
|
||||
/// is enabled only when both this and `--meili-master-key` are set; otherwise
|
||||
/// search is disabled (best-effort feature) and `reindex_all` remains the rebuild
|
||||
/// path.
|
||||
#[arg(long = "meili-url", env = "MEILI_URL")]
|
||||
pub meili_url: Option<String>,
|
||||
|
||||
/// Meilisearch API key (master or a scoped key).
|
||||
#[arg(long = "meili-master-key", env = "MEILI_MASTER_KEY")]
|
||||
pub meili_master_key: Option<String>,
|
||||
|
||||
/// Meilisearch index name for catalogue objects.
|
||||
#[arg(long = "meili-index", env = "MEILI_INDEX", default_value = "objects")]
|
||||
pub meili_index: String,
|
||||
}
|
||||
|
||||
@@ -22,10 +22,34 @@ pub async fn run(config: Config) -> anyhow::Result<()> {
|
||||
.await
|
||||
.context("creating the session store")?;
|
||||
|
||||
let search = match (&config.meili_url, &config.meili_master_key) {
|
||||
(Some(url), Some(key)) => {
|
||||
let client = search::SearchClient::connect(url, key, &config.meili_index)
|
||||
.context("connecting to Meilisearch")?;
|
||||
|
||||
client
|
||||
.ensure_index()
|
||||
.await
|
||||
.context("ensuring the search index exists")?;
|
||||
|
||||
tracing::info!(index = %config.meili_index, "search indexing enabled");
|
||||
|
||||
Some(client)
|
||||
}
|
||||
_ => {
|
||||
tracing::warn!(
|
||||
"MEILI_URL/MEILI_MASTER_KEY not set — search indexing disabled (reindex_all remains the rebuild path)"
|
||||
);
|
||||
|
||||
None
|
||||
}
|
||||
};
|
||||
|
||||
let state = AppState {
|
||||
db,
|
||||
app_name: config.app_name.clone(),
|
||||
cookie_secure: config.cookie_secure,
|
||||
search,
|
||||
};
|
||||
|
||||
let listener = TcpListener::bind(&config.bind_addr)
|
||||
|
||||
Reference in New Issue
Block a user