refactor: remove all dev.* and public.* schema hardcodes from runtime code

14 files updated to use schema::table_name() instead of hardcoded schema
prefixes. Only src/bin/release.rs intentionally retains dev.* references.
This commit is contained in:
Accusys
2026-05-14 14:40:14 +08:00
parent 261d134fee
commit 301a95e2bc
14 changed files with 184 additions and 139 deletions

View File

@@ -1,4 +1,5 @@
use crate::core::config::OUTPUT_DIR;
use crate::core::db::schema;
use crate::core::llm::client::generate_5w1h_summary;
use anyhow::{Context, Result};
use serde::Deserialize;
@@ -71,13 +72,15 @@ pub async fn ingest_rule3(pool: &PgPool, file_uuid: &str) -> Result<usize> {
}
// Query chunks table for Rule 1 sentence chunks
let chunk_table = schema::table_name("chunk");
let rule1_rows: Vec<(String,)> = sqlx::query_as(
r#"
SELECT chunk_id FROM dev.chunk
WHERE file_uuid = $1 AND chunk_type = 'sentence'
AND start_frame >= $2
AND end_frame <= $3
"#,
&format!(
"SELECT chunk_id FROM {} \
WHERE file_uuid = $1 AND chunk_type = 'sentence' \
AND start_frame >= $2 \
AND end_frame <= $3",
chunk_table
),
)
.bind(file_uuid)
.bind(scene.start_frame as i64)
@@ -97,13 +100,14 @@ pub async fn ingest_rule3(pool: &PgPool, file_uuid: &str) -> Result<usize> {
}
let texts: Vec<String> = sqlx::query_scalar(
r#"
SELECT text_content FROM dev.chunk
WHERE file_uuid = $1 AND chunk_type = 'sentence'
AND start_frame >= $2
AND end_frame <= $3
ORDER BY start_frame ASC
"#,
&format!(
"SELECT text_content FROM {} \
WHERE file_uuid = $1 AND chunk_type = 'sentence' \
AND start_frame >= $2 \
AND end_frame <= $3 \
ORDER BY start_frame ASC",
chunk_table
),
)
.bind(file_uuid)
.bind(scene.start_frame as i64)
@@ -149,14 +153,14 @@ pub async fn ingest_rule3(pool: &PgPool, file_uuid: &str) -> Result<usize> {
});
sqlx::query(
r#"
INSERT INTO dev.chunk (
file_uuid, chunk_id, chunk_type,
start_time, end_time, fps, start_frame, end_frame,
content, text_content, summary_text, metadata, child_chunk_ids
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)
ON CONFLICT (file_uuid, chunk_id) DO NOTHING
"#,
&format!(
"INSERT INTO {} (file_uuid, chunk_id, chunk_type, \
start_time, end_time, fps, start_frame, end_frame, \
content, text_content, summary_text, metadata, child_chunk_ids) \
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13) \
ON CONFLICT (file_uuid, chunk_id) DO NOTHING",
chunk_table
),
)
.bind(file_uuid)
.bind(&chunk_id)

View File

@@ -1233,7 +1233,7 @@ impl PostgresDb {
let tx = self.pool.begin().await?;
let chunk_vectors = schema::table_name("chunk_vectors");
let chunks = "dev.chunk";
let chunks = schema::table_name("chunk");
let processor_results = schema::table_name("processor_results");
let videos = schema::table_name("videos");
@@ -1255,7 +1255,8 @@ impl PostgresDb {
.execute(&self.pool)
.await?;
sqlx::query(&format!("DELETE FROM dev.pre_chunks WHERE file_uuid = $1"))
let pre_chunks = schema::table_name("pre_chunks");
sqlx::query(&format!("DELETE FROM {} WHERE file_uuid = $1", pre_chunks))
.bind(uuid)
.execute(&self.pool)
.await?;
@@ -1283,7 +1284,7 @@ impl PostgresDb {
}
pub async fn get_chunk_count(&self, uuid: &str) -> Result<(i64, i64)> {
let chunks = "dev.chunk";
let chunks = schema::table_name("chunk");
let sentence_count: i64 = sqlx::query_scalar(&format!(
"SELECT COUNT(*) FROM {} WHERE file_uuid = $1 AND chunk_type = 'sentence'",
chunks
@@ -2508,21 +2509,23 @@ impl PostgresDb {
limit: i32,
offset: i64,
) -> Result<Vec<IdentityChunkRecord>> {
let query = r#"
SELECT c.id, c.file_uuid, c.chunk_id, c.chunk_type,
c.start_time, c.end_time, c.text_content, c.content
FROM dev.chunk c
WHERE c.file_uuid IN (
SELECT DISTINCT fd.file_uuid
FROM face_detections fd
JOIN identities i ON fd.identity_id = i.id
WHERE i.uuid = $1
)
ORDER BY c.start_time ASC
LIMIT $2 OFFSET $3
"#;
let chunk_table = schema::table_name("chunk");
let query = format!(
"SELECT c.id, c.file_uuid, c.chunk_id, c.chunk_type, \
c.start_time, c.end_time, c.text_content, c.content \
FROM {} c \
WHERE c.file_uuid IN ( \
SELECT DISTINCT fd.file_uuid \
FROM face_detections fd \
JOIN identities i ON fd.identity_id = i.id \
WHERE i.uuid = $1 \
) \
ORDER BY c.start_time ASC \
LIMIT $2 OFFSET $3",
chunk_table
);
let rows = sqlx::query_as(query)
let rows = sqlx::query_as(&query)
.bind(identity_id)
.bind(limit)
.bind(offset)
@@ -2552,7 +2555,7 @@ impl PostgresDb {
}
pub async fn store_chunk(&self, chunk: &Chunk) -> Result<()> {
let table = "dev.chunk";
let table = schema::table_name("chunk");
let content_with_rule = serde_json::json!({
"rule": chunk.rule.as_str(),
"data": chunk.content
@@ -2629,7 +2632,7 @@ impl PostgresDb {
chunk: &Chunk,
tx: &mut sqlx::Transaction<'_, sqlx::Postgres>,
) -> Result<()> {
let table = "dev.chunk";
let table = schema::table_name("chunk");
let content_with_rule = serde_json::json!({
"rule": chunk.rule.as_str(),
"data": chunk.content
@@ -2699,7 +2702,7 @@ impl PostgresDb {
}
pub async fn get_chunks_by_uuid(&self, uuid: &str) -> Result<Vec<Chunk>> {
let table = "dev.chunk";
let table = schema::table_name("chunk");
let rows = sqlx::query(&format!(
"SELECT COALESCE(file_id, 0) as file_id, file_uuid as uuid, chunk_id, chunk_type, COALESCE(fps, 24.0) as fps, COALESCE(start_frame, 0) as start_frame, COALESCE(end_frame, 0) as end_frame, text_content, content, metadata, vector_id, COALESCE(frame_count, 0) as frame_count, pre_chunk_ids, parent_chunk_id::text as parent_chunk_id, child_chunk_ids, visual_stats FROM {} WHERE file_uuid = $1 ORDER BY id",
table
@@ -2779,7 +2782,7 @@ impl PostgresDb {
chunk_id: &str,
uuid: &str,
) -> Result<Option<Chunk>> {
let table = "dev.chunk";
let table = schema::table_name("chunk");
let row = sqlx::query(&format!(
"SELECT COALESCE(file_id, 0) as file_id, file_uuid, chunk_id, chunk_type, COALESCE(fps, 24.0) as fps, COALESCE(start_frame, 0) as start_frame, COALESCE(end_frame, 0) as end_frame, text_content, content, metadata, vector_id, COALESCE(frame_count, 0) as frame_count, pre_chunk_ids, parent_chunk_id, child_chunk_ids, visual_stats FROM {} WHERE chunk_id = $1 AND file_uuid = $2",
table
@@ -3006,7 +3009,7 @@ impl PostgresDb {
start_time: f64,
end_time: f64,
) -> Result<Vec<Chunk>> {
let table = "dev.chunk";
let table = schema::table_name("chunk");
let rows = sqlx::query(&format!(
"SELECT file_id, uuid, chunk_id, chunk_type, start_time, end_time, fps, start_frame, end_frame, text_content, content, metadata, vector_id, frame_count, pre_chunk_ids, parent_chunk_id::text as parent_chunk_id, child_chunk_ids
FROM {}
@@ -3091,7 +3094,7 @@ impl PostgresDb {
return Ok(vec![]);
}
let table = "dev.chunk";
let table = schema::table_name("chunk");
let rows = sqlx::query(&format!(
"SELECT file_id, uuid, chunk_id, chunk_type, fps, start_frame, end_frame, text_content, content, metadata, vector_id, frame_count, pre_chunk_ids, parent_chunk_id::text as parent_chunk_id, child_chunk_ids FROM {} WHERE chunk_id = ANY($1) ORDER BY id",
table
@@ -3200,7 +3203,7 @@ impl PostgresDb {
}
pub async fn update_vector_id(&self, chunk_id: &str, vector_id: &str) -> Result<()> {
let table = "dev.chunk";
let table = schema::table_name("chunk");
sqlx::query(&format!(
"UPDATE {} SET vector_id = $1 WHERE chunk_id = $2",
table
@@ -3222,7 +3225,7 @@ impl PostgresDb {
}
pub async fn search_text(&self, query: &str, chunk_type: Option<&str>) -> Result<Vec<Chunk>> {
let table = "dev.chunk";
let table = schema::table_name("chunk");
let query_pattern = format!("%{}%", query);
let sql = match chunk_type {
@@ -3327,7 +3330,7 @@ impl PostgresDb {
uuid: Option<&str>,
limit: usize,
) -> Result<Vec<Bm25Result>> {
let table = "dev.chunk";
let table = schema::table_name("chunk");
let tsquery = self.prepare_tsquery(query).await?;
let sql = match uuid {
@@ -4447,7 +4450,7 @@ impl PostgresDb {
total_frames: u64,
) -> Result<()> {
let table = schema::table_name("videos");
let chunks_table = "dev.chunk";
let chunks_table = schema::table_name("chunk");
let pre_chunks_table = schema::table_name("pre_chunks");
// Query chunks count and frames
@@ -4623,18 +4626,20 @@ impl PostgresDb {
let vector_json = serde_json::to_string(query_vector)
.map_err(|e| anyhow::anyhow!("Vector serialize error: {}", e))?;
let chunk_table = schema::table_name("chunk");
let results = sqlx::query_as::<_, SemanticSearchResult>(
r#"
SELECT
id as scene_order, start_time, end_time,
COALESCE(summary_text, text_content, '') as summary,
metadata,
(1 - (embedding <=> $1::vector)) as similarity
FROM dev.chunk
WHERE file_uuid = $2 AND chunk_type = 'cut' AND embedding IS NOT NULL
ORDER BY embedding <=> $1::vector
LIMIT $3
"#,
&format!(
"SELECT \
id as scene_order, start_time, end_time, \
COALESCE(summary_text, text_content, '') as summary, \
metadata, \
(1 - (embedding <=> $1::vector)) as similarity \
FROM {} \
WHERE file_uuid = $2 AND chunk_type = 'cut' AND embedding IS NOT NULL \
ORDER BY embedding <=> $1::vector \
LIMIT $3",
chunk_table
),
)
.bind(&vector_json)
.bind(uuid)

View File

@@ -4,7 +4,7 @@ use sqlx;
use std::path::Path;
use tracing::{info, warn};
use crate::core::db::{PostgresDb, VideoRecord, VideoStatus};
use crate::core::db::{schema, PostgresDb, VideoRecord, VideoStatus};
use crate::core::probe;
use crate::core::storage::uuid as uuid_utils;
use crate::core::storage::FileManager;
@@ -37,8 +37,9 @@ impl IngestionService {
// 1. Look for existing Birthday (Identity Anchor)
// If the file (by name) was registered before, use its original birth time.
let videos_table = schema::table_name("videos");
let birthday = sqlx::query_scalar::<_, chrono::DateTime<chrono::Utc>>(
"SELECT registration_time FROM dev.videos WHERE file_name = $1 AND registration_time IS NOT NULL LIMIT 1"
&format!("SELECT registration_time FROM {} WHERE file_name = $1 AND registration_time IS NOT NULL LIMIT 1", videos_table)
)
.bind(&filename)
.fetch_optional(self.db.pool())

View File

@@ -4,6 +4,8 @@ use sqlx::PgPool;
use std::path::Path;
use tracing::info;
use crate::core::db::schema;
/// Heuristic scene metadata derived from YOLO + Face + luminance data.
/// Runs as a post-processing trigger, not a standalone processor.
/// Replaces the removed Places365 Scene classifier.
@@ -110,12 +112,13 @@ pub async fn build_heuristic_scene_meta(
}
// Get face counts grouped by frame
let fd_table = schema::table_name("face_detections");
let face_rows: Vec<(i64, i64)> = sqlx::query_as(
"SELECT frame_number, COUNT(*) as fc \
FROM dev.face_detections \
&format!("SELECT frame_number, COUNT(*) as fc \
FROM {} \
WHERE file_uuid = $1 AND frame_number IS NOT NULL \
GROUP BY frame_number \
ORDER BY frame_number",
ORDER BY frame_number", fd_table),
)
.bind(file_uuid)
.fetch_all(pool)
@@ -255,8 +258,9 @@ pub async fn generate_scene_meta(db: &crate::core::db::PostgresDb, file_uuid: &s
.collect()
} else {
// Fallback: query DB for video duration, make one segment
let videos_table = schema::table_name("videos");
let (total_frames, duration): (Option<i64>, Option<f64>) = sqlx::query_as(
"SELECT total_frames, duration FROM dev.videos WHERE file_uuid = $1",
&format!("SELECT total_frames, duration FROM {} WHERE file_uuid = $1", videos_table),
)
.bind(file_uuid)
.fetch_optional(pool)

View File

@@ -3,7 +3,7 @@ use serde::Deserialize;
use std::collections::HashMap;
use tracing::{error, info, warn};
use crate::core::db::PostgresDb;
use crate::core::db::{schema, PostgresDb};
#[derive(Debug, Deserialize)]
struct TmdbIdentity {
@@ -34,7 +34,7 @@ pub async fn match_faces_against_tmdb(db: &PostgresDb, file_uuid: &str) -> Resul
// Step 1: Load TMDb identities with face embeddings
let tmdb_rows = sqlx::query_as::<_, (i32, String, Vec<f32>)>(
"SELECT id, name, face_embedding::real[] FROM dev.identities WHERE source='tmdb' AND face_embedding IS NOT NULL"
&format!("SELECT id, name, face_embedding::real[] FROM {} WHERE source='tmdb' AND face_embedding IS NOT NULL", schema::table_name("identities"))
)
.fetch_all(pool).await?;
@@ -45,10 +45,11 @@ pub async fn match_faces_against_tmdb(db: &PostgresDb, file_uuid: &str) -> Resul
info!("[TKG-MATCH] {} TMDb seeds loaded", tmdb_rows.len());
// Step 2: Load face_detections grouped by trace_id
let fd_table = schema::table_name("face_detections");
let fd_rows = sqlx::query_as::<_, (i32, Vec<f32>)>(
"SELECT trace_id, embedding FROM dev.face_detections \
&format!("SELECT trace_id, embedding FROM {} \
WHERE file_uuid=$1 AND trace_id IS NOT NULL AND embedding IS NOT NULL \
ORDER BY trace_id",
ORDER BY trace_id", fd_table),
)
.bind(file_uuid)
.fetch_all(pool)
@@ -152,10 +153,11 @@ pub async fn match_faces_against_tmdb(db: &PostgresDb, file_uuid: &str) -> Resul
// Step 4: Quality control
// 4a: Remove low-confidence traces (fewer than 4 face detections)
let fd_table = schema::table_name("face_detections");
let mut after_qc = HashMap::new();
for (&tid, &(id, ref name)) in &matched {
let cnt: i64 = sqlx::query_scalar(
"SELECT COUNT(*) FROM dev.face_detections WHERE file_uuid=$1 AND trace_id=$2",
&format!("SELECT COUNT(*) FROM {} WHERE file_uuid=$1 AND trace_id=$2", fd_table),
)
.bind(file_uuid)
.bind(tid)
@@ -193,7 +195,7 @@ pub async fn match_faces_against_tmdb(db: &PostgresDb, file_uuid: &str) -> Resul
let mut updated = 0usize;
for (&tid, &(id, _)) in &matched {
let r = sqlx::query(
"UPDATE dev.face_detections SET identity_id=$1 WHERE file_uuid=$2 AND trace_id=$3",
&format!("UPDATE {} SET identity_id=$1 WHERE file_uuid=$2 AND trace_id=$3", fd_table),
)
.bind(id)
.bind(file_uuid)
@@ -219,20 +221,22 @@ pub async fn match_faces_against_tmdb(db: &PostgresDb, file_uuid: &str) -> Resul
/// Unbind the lower-confidence trace from the conflicting pair.
/// RCA reference: docs_v1.0/API_V1.0.0/INTERNAL/RCA_TRACE39_TRACE45_COLLISION_V1.0.0.md
async fn quality_check_temporal_collisions(pool: &sqlx::PgPool, file_uuid: &str) -> Result<usize> {
let fd_table = schema::table_name("face_detections");
// Find all collision pairs: same identity, same frame, different trace
let collisions = sqlx::query_as::<_, (i32, i32, i32, i32)>(
r#"
SELECT a.identity_id, a.trace_id, b.trace_id, a.frame_number
FROM dev.face_detections a
JOIN dev.face_detections b
ON a.file_uuid = b.file_uuid
AND a.frame_number = b.frame_number
AND a.trace_id < b.trace_id
WHERE a.file_uuid = $1
AND a.identity_id IS NOT NULL
AND a.identity_id = b.identity_id
ORDER BY a.identity_id, a.frame_number
"#,
&format!(
"SELECT a.identity_id, a.trace_id, b.trace_id, a.frame_number \
FROM {} a \
JOIN {} b \
ON a.file_uuid = b.file_uuid \
AND a.frame_number = b.frame_number \
AND a.trace_id < b.trace_id \
WHERE a.file_uuid = $1 \
AND a.identity_id IS NOT NULL \
AND a.identity_id = b.identity_id \
ORDER BY a.identity_id, a.frame_number",
fd_table, fd_table
),
)
.bind(file_uuid)
.fetch_all(pool)
@@ -253,13 +257,13 @@ async fn quality_check_temporal_collisions(pool: &sqlx::PgPool, file_uuid: &str)
for ((id, ta, tb), overlap_frames) in &collision_groups {
// Get face detection count for each trace
let cnt_a: i64 = sqlx::query_scalar(
"SELECT COUNT(*) FROM dev.face_detections WHERE file_uuid=$1 AND trace_id=$2 AND identity_id=$3"
&format!("SELECT COUNT(*) FROM {} WHERE file_uuid=$1 AND trace_id=$2 AND identity_id=$3", fd_table)
)
.bind(file_uuid).bind(ta).bind(id)
.fetch_one(pool).await.unwrap_or(0);
let cnt_b: i64 = sqlx::query_scalar(
"SELECT COUNT(*) FROM dev.face_detections WHERE file_uuid=$1 AND trace_id=$2 AND identity_id=$3"
&format!("SELECT COUNT(*) FROM {} WHERE file_uuid=$1 AND trace_id=$2 AND identity_id=$3", fd_table)
)
.bind(file_uuid).bind(tb).bind(id)
.fetch_one(pool).await.unwrap_or(0);
@@ -269,7 +273,7 @@ async fn quality_check_temporal_collisions(pool: &sqlx::PgPool, file_uuid: &str)
let victim_cnt = if cnt_a <= cnt_b { cnt_a } else { cnt_b };
sqlx::query(
"UPDATE dev.face_detections SET identity_id=NULL WHERE file_uuid=$1 AND trace_id=$2",
&format!("UPDATE {} SET identity_id=NULL WHERE file_uuid=$1 AND trace_id=$2", fd_table),
)
.bind(file_uuid)
.bind(victim)