feat: identity PATCH update, alias system, name UNIQUE removal
- Add PATCH /api/v1/identity/:identity_uuid endpoint - Migration 030: remove name UNIQUE, add tmdb_id index - TMDb upsert: ON CONFLICT (name) -> ON CONFLICT (tmdb_id) - get_or_create_identity: pre-check by name - upload_identity: ON CONFLICT (name) -> ON CONFLICT (uuid) - Search: include aliases in identity text search - Add scripts/llm_metadata_enhancer.py - Add DESIGN/IdentityUpdateAndAliasSystem.md
This commit is contained in:
@@ -3210,12 +3210,27 @@ impl PostgresDb {
|
||||
|
||||
pub async fn get_or_create_identity(&self, name: &str) -> Result<i32> {
|
||||
let identities_table = schema::table_name("identities");
|
||||
let id: i32 = sqlx::query_scalar(&format!(
|
||||
"INSERT INTO {} (name, identity_type, source, status) VALUES ($1, 'people', 'user_defined', 'confirmed') \
|
||||
ON CONFLICT (name) DO UPDATE SET updated_at = CURRENT_TIMESTAMP RETURNING id", identities_table
|
||||
// First: try to find existing identity by name
|
||||
if let Some(id) = sqlx::query_scalar::<_, i32>(&format!(
|
||||
"SELECT id FROM {} WHERE name = $1 LIMIT 1",
|
||||
identities_table
|
||||
))
|
||||
.bind(name)
|
||||
.fetch_one(&self.pool).await?;
|
||||
.fetch_optional(&self.pool)
|
||||
.await?
|
||||
{
|
||||
return Ok(id);
|
||||
}
|
||||
// Not found: create new with generated uuid
|
||||
let id: i32 = sqlx::query_scalar(&format!(
|
||||
"INSERT INTO {} (uuid, name, identity_type, source, status) \
|
||||
VALUES (gen_random_uuid(), $1, 'people', 'user_defined', 'confirmed') \
|
||||
RETURNING id",
|
||||
identities_table
|
||||
))
|
||||
.bind(name)
|
||||
.fetch_one(&self.pool)
|
||||
.await?;
|
||||
Ok(id)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,12 +94,11 @@ async fn upsert_identities_from_disk(
|
||||
let result = sqlx::query(&format!(
|
||||
"INSERT INTO {} (uuid, name, identity_type, source, status, tmdb_id, tmdb_profile, metadata) \
|
||||
VALUES ($1::uuid, $2, 'people', 'tmdb', 'confirmed', $3, $4, $5::jsonb) \
|
||||
ON CONFLICT (name) DO UPDATE SET \
|
||||
ON CONFLICT (tmdb_id) WHERE tmdb_id IS NOT NULL DO UPDATE SET \
|
||||
uuid = COALESCE({}.uuid, $1::uuid), \
|
||||
tmdb_id = COALESCE(EXCLUDED.tmdb_id, {}.tmdb_id), \
|
||||
tmdb_profile = COALESCE(EXCLUDED.tmdb_profile, {}.tmdb_profile), \
|
||||
metadata = {}.metadata || $5::jsonb",
|
||||
identities_table, identities_table, identities_table, identities_table, identities_table
|
||||
identities_table, identities_table, identities_table, identities_table
|
||||
))
|
||||
.bind(&identity_file.identity_uuid)
|
||||
.bind(&identity_file.name)
|
||||
@@ -225,12 +224,11 @@ pub async fn create_identities_from_data(
|
||||
let result = sqlx::query_as::<_, (uuid::Uuid,)>(&format!(
|
||||
"INSERT INTO {} (name, identity_type, source, status, tmdb_id, tmdb_profile, metadata) \
|
||||
VALUES ($1, 'people', 'tmdb', 'confirmed', $2, $3, $4::jsonb) \
|
||||
ON CONFLICT (name) DO UPDATE SET \
|
||||
tmdb_id = COALESCE(EXCLUDED.tmdb_id, {}.tmdb_id), \
|
||||
ON CONFLICT (tmdb_id) WHERE tmdb_id IS NOT NULL DO UPDATE SET \
|
||||
tmdb_profile = COALESCE(EXCLUDED.tmdb_profile, {}.tmdb_profile), \
|
||||
metadata = {}.metadata || $4::jsonb \
|
||||
RETURNING uuid",
|
||||
identities_table, identities_table, identities_table, identities_table
|
||||
identities_table, identities_table, identities_table
|
||||
))
|
||||
.bind(&member.name)
|
||||
.bind(member.id as i64)
|
||||
|
||||
Reference in New Issue
Block a user