feat: add meeting transcription app scaffolding
Security Scan and Upload / Security & DefectDojo Upload (pull_request) Successful in 48s
CI / Lint & Test (pull_request) Successful in 14m18s
CI / Build Linux (pull_request) Successful in 14m19s
CI / Build Windows (cross-compile) (pull_request) Failing after 19m39s

- Add Python backend structure with FastAPI for transcription/summarization
- Add React UI with audio recording, transcript, and summary views
- Configure Tauri to manage Python backend lifecycle
- Set up Windows cross-compilation with cargo-xwin
- Add Gitea CI workflow for lint, test, and multi-platform builds
- Configure ESLint, Prettier, and Vitest for code quality

Note: App scaffolding only - Python env and models not yet set up
This commit is contained in:
2026-01-21 20:18:03 -08:00
parent 96494a9997
commit 3c8a46e5a6
41 changed files with 2679 additions and 1797 deletions
+58 -4
View File
@@ -1,14 +1,68 @@
// Learn more about Tauri commands at https://tauri.app/develop/calling-rust/
use std::process::{Child, Command};
use std::sync::Mutex;
use tauri::{Manager, State};
struct PythonBackend {
process: Mutex<Option<Child>>,
}
#[tauri::command]
fn greet(name: &str) -> String {
format!("Hello, {}! You've been greeted from Rust!", name)
fn start_backend(backend: State<PythonBackend>) -> Result<String, String> {
let mut process_lock = backend.process.lock().map_err(|e| e.to_string())?;
if process_lock.is_some() {
return Ok("Backend already running".to_string());
}
// Get the resource path for the bundled Python executable
let python_cmd = if cfg!(windows) {
"python"
} else {
"python3"
};
// Start the Python backend
let child = Command::new(python_cmd)
.args(["-m", "uvicorn", "backend.main:app", "--host", "127.0.0.1", "--port", "8000"])
.spawn()
.map_err(|e| format!("Failed to start backend: {}", e))?;
*process_lock = Some(child);
Ok("Backend started successfully".to_string())
}
#[tauri::command]
fn stop_backend(backend: State<PythonBackend>) -> Result<String, String> {
let mut process_lock = backend.process.lock().map_err(|e| e.to_string())?;
if let Some(mut child) = process_lock.take() {
child.kill().map_err(|e| format!("Failed to stop backend: {}", e))?;
Ok("Backend stopped".to_string())
} else {
Ok("Backend not running".to_string())
}
}
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.plugin(tauri_plugin_opener::init())
.invoke_handler(tauri::generate_handler![greet])
.manage(PythonBackend {
process: Mutex::new(None),
})
.invoke_handler(tauri::generate_handler![start_backend, stop_backend])
.on_window_event(|window, event| {
// Stop backend when window closes
if let tauri::WindowEvent::CloseRequested { .. } = event {
if let Some(backend) = window.try_state::<PythonBackend>() {
if let Ok(mut process_lock) = backend.process.lock() {
if let Some(mut child) = process_lock.take() {
let _ = child.kill();
}
}
}
}
})
.run(tauri::generate_context!())
.expect("error while running tauri application");
}