feat: Initial v0.9 release with API Key authentication

## v0.9.20260325_144654

### Features
- API Key Authentication System
- Job Worker System
- V2 Backup Versioning

### Bug Fixes
- get_processor_results_by_job column mapping

Co-authored-by: OpenCode
This commit is contained in:
accusys
2026-03-25 14:52:51 +08:00
parent 47e86b696f
commit 383201cacd
193 changed files with 40268 additions and 422 deletions
+9 -2
View File
@@ -1,14 +1,15 @@
use super::types::{Chunk, ChunkType};
use anyhow::Result;
use super::types::{Chunk, ChunkRule, ChunkType};
pub struct ChunkSplitter {
time_based_duration: f64,
fps: f64,
}
impl ChunkSplitter {
pub fn new(time_based_duration_seconds: f64) -> Self {
Self {
time_based_duration: time_based_duration_seconds,
fps: 24.0,
}
}
@@ -20,11 +21,14 @@ impl ChunkSplitter {
while current_time < duration {
let end_time = (current_time + self.time_based_duration).min(duration);
chunks.push(Chunk::new(
0, // file_id
uuid.to_string(),
index,
ChunkType::TimeBased,
ChunkRule::Rule1,
current_time,
end_time,
self.fps,
serde_json::json!({
"source": "time_based",
"duration": self.time_based_duration,
@@ -42,11 +46,14 @@ impl ChunkSplitter {
for (index, segment) in asr_segments.iter().enumerate() {
chunks.push(Chunk::new(
0, // file_id
uuid.to_string(),
index as u32,
ChunkType::Sentence,
ChunkRule::Rule1,
segment.start,
segment.end,
self.fps,
serde_json::json!({
"text": segment.text,
"speaker_id": segment.speaker_id,
+94 -1
View File
@@ -6,47 +6,140 @@ pub enum ChunkType {
TimeBased,
Sentence,
Cut,
Trace,
Story, // Parent chunk from story analysis
}
impl ChunkType {
pub fn as_str(&self) -> &'static str {
match self {
ChunkType::TimeBased => "time_based",
ChunkType::TimeBased => "time",
ChunkType::Sentence => "sentence",
ChunkType::Cut => "cut",
ChunkType::Trace => "trace",
ChunkType::Story => "story",
}
}
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum ChunkRule {
Rule1, // 直接轉換
Rule2, // 集合內容
}
impl ChunkRule {
pub fn as_str(&self) -> &'static str {
match self {
ChunkRule::Rule1 => "rule_1",
ChunkRule::Rule2 => "rule_2",
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Chunk {
pub file_id: i32,
pub uuid: String,
pub chunk_id: String,
pub chunk_index: u32,
pub chunk_type: ChunkType,
pub rule: ChunkRule,
pub start_time: f64,
pub end_time: f64,
pub fps: f64,
pub start_frame: i64,
pub end_frame: i64,
pub text_content: Option<String>,
pub content: serde_json::Value,
pub metadata: Option<serde_json::Value>,
pub vector_id: Option<String>,
pub frame_count: i32,
pub pre_chunk_ids: Vec<i32>,
pub parent_chunk_id: Option<String>, // For parent-child chunk hierarchy
pub child_chunk_ids: Vec<String>, // Child chunk IDs (for parent chunks)
}
impl Chunk {
#[allow(clippy::too_many_arguments)]
pub fn new(
file_id: i32,
uuid: String,
chunk_index: u32,
chunk_type: ChunkType,
rule: ChunkRule,
start_time: f64,
end_time: f64,
fps: f64,
content: serde_json::Value,
) -> Self {
let start_frame = (start_time * fps) as i64;
let end_frame = (end_time * fps) as i64;
let chunk_id = format!("{}_{:04}", chunk_type.as_str(), chunk_index);
Self {
file_id,
uuid,
chunk_id: chunk_id.clone(),
chunk_index,
chunk_type,
rule,
start_time,
end_time,
fps,
start_frame,
end_frame,
text_content: None,
content,
metadata: None,
vector_id: None,
frame_count: 0,
pre_chunk_ids: vec![],
parent_chunk_id: None,
child_chunk_ids: vec![],
}
}
pub fn with_metadata(mut self, metadata: serde_json::Value) -> Self {
self.metadata = Some(metadata);
self
}
pub fn with_vector_id(mut self, vector_id: String) -> Self {
self.vector_id = Some(vector_id);
self
}
pub fn with_text_content(mut self, text: String) -> Self {
self.text_content = Some(text);
self
}
pub fn with_frame_count(mut self, count: i32) -> Self {
self.frame_count = count;
self
}
pub fn with_pre_chunk_ids(mut self, ids: Vec<i32>) -> Self {
self.pre_chunk_ids = ids;
self
}
pub fn with_parent_chunk_id(mut self, parent_id: String) -> Self {
self.parent_chunk_id = Some(parent_id);
self
}
pub fn with_child_chunk_ids(mut self, child_ids: Vec<String>) -> Self {
self.child_chunk_ids = child_ids;
self
}
pub fn is_parent_chunk(&self) -> bool {
!self.child_chunk_ids.is_empty()
}
pub fn is_child_chunk(&self) -> bool {
self.parent_chunk_id.is_some()
}
}