fix(room): add missing stream column to room_ai table

Create migration m20260417_000001_add_stream_to_room_ai that adds
the `stream BOOLEAN NOT NULL DEFAULT true` column to room_ai.
The model definition includes this field but the original migration
was missing it.

Also format libs/api/room/ws.rs and add gitdata.ai to allowed
WS origins.
This commit is contained in:
ZhenYi 2026-04-17 23:09:55 +08:00
parent a171d691c6
commit 4f1ea95b58
3 changed files with 57 additions and 7 deletions

View File

@ -1,7 +1,7 @@
use std::sync::{Arc, LazyLock}; use std::sync::{Arc, LazyLock};
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
use actix_web::{HttpMessage, HttpRequest, HttpResponse, web}; use actix_web::{web, HttpMessage, HttpRequest, HttpResponse};
use actix_ws::Message as WsMessage; use actix_ws::Message as WsMessage;
use serde::Serialize; use serde::Serialize;
use uuid::Uuid; use uuid::Uuid;
@ -232,30 +232,42 @@ pub struct WsOutEvent {
pub(crate) fn validate_origin(req: &HttpRequest) -> bool { pub(crate) fn validate_origin(req: &HttpRequest) -> bool {
static ALLOWED_ORIGINS: LazyLock<Vec<String>> = LazyLock::new(|| { static ALLOWED_ORIGINS: LazyLock<Vec<String>> = LazyLock::new(|| {
// Build default origins from localhost + APP_DOMAIN_URL // Build default origins from localhost + APP_DOMAIN_URL
let domain = std::env::var("APP_DOMAIN_URL") let domain =
.unwrap_or_else(|_| "http://127.0.0.1".to_string()); std::env::var("APP_DOMAIN_URL").unwrap_or_else(|_| "http://127.0.0.1".to_string());
// Normalize: strip trailing slash, derive https/wss variants // Normalize: strip trailing slash, derive https/wss variants
let domain = domain.trim_end_matches('/'); let domain = domain.trim_end_matches('/');
let https_domain = domain.replace("http://", "https://").replace("ws://", "wss://"); let https_domain = domain
let ws_domain = domain.replace("https://", "ws://").replace("http://", "ws://"); .replace("http://", "https://")
.replace("ws://", "wss://");
let ws_domain = domain
.replace("https://", "ws://")
.replace("http://", "ws://");
let mut defaults = vec![ let mut defaults = vec![
"http://localhost".to_string(), "http://localhost".to_string(),
"https://localhost".to_string(), "https://localhost".to_string(),
"http://127.0.0.1".to_string(), "http://127.0.0.1".to_string(),
"http://gitdata.ai".to_string(),
"https://gitdata.ai".to_string(),
"https://127.0.0.1".to_string(), "https://127.0.0.1".to_string(),
"ws://localhost".to_string(), "ws://localhost".to_string(),
"wss://localhost".to_string(), "wss://localhost".to_string(),
"ws://127.0.0.1".to_string(), "ws://127.0.0.1".to_string(),
"ws://gitdata.ai".to_string(),
"wss://gitdata.ai".to_string(),
"wss://127.0.0.1".to_string(), "wss://127.0.0.1".to_string(),
]; ];
// Always include APP_DOMAIN_URL and APP_STATIC_DOMAIN origins // Always include APP_DOMAIN_URL and APP_STATIC_DOMAIN origins
let mut add_origin = |origin: &str| { let mut add_origin = |origin: &str| {
let origin = origin.trim_end_matches('/'); let origin = origin.trim_end_matches('/');
let https_v = origin.replace("http://", "https://").replace("ws://", "wss://"); let https_v = origin
let ws_v = origin.replace("https://", "ws://").replace("http://", "ws://"); .replace("http://", "https://")
.replace("ws://", "wss://");
let ws_v = origin
.replace("https://", "ws://")
.replace("http://", "ws://");
for v in [origin, &https_v, &ws_v] { for v in [origin, &https_v, &ws_v] {
if !defaults.contains(&v.to_string()) && v != domain { if !defaults.contains(&v.to_string()) && v != domain {
defaults.push(v.to_string()); defaults.push(v.to_string());

View File

@ -81,6 +81,7 @@ impl MigratorTrait for Migrator {
Box::new(m20260414_000001_create_agent_task::Migration), Box::new(m20260414_000001_create_agent_task::Migration),
Box::new(m20260415_000001_add_issue_id_to_agent_task::Migration), Box::new(m20260415_000001_add_issue_id_to_agent_task::Migration),
Box::new(m20260416_000001_add_retry_count_to_agent_task::Migration), Box::new(m20260416_000001_add_retry_count_to_agent_task::Migration),
Box::new(m20260417_000001_add_stream_to_room_ai::Migration),
// Repo tables // Repo tables
Box::new(m20250628_000028_create_repo::Migration), Box::new(m20250628_000028_create_repo::Migration),
Box::new(m20250628_000029_create_repo_branch::Migration), Box::new(m20250628_000029_create_repo_branch::Migration),
@ -252,3 +253,4 @@ pub mod m20260413_000001_add_skill_commit_blob;
pub mod m20260414_000001_create_agent_task; pub mod m20260414_000001_create_agent_task;
pub mod m20260415_000001_add_issue_id_to_agent_task; pub mod m20260415_000001_add_issue_id_to_agent_task;
pub mod m20260416_000001_add_retry_count_to_agent_task; pub mod m20260416_000001_add_retry_count_to_agent_task;
pub mod m20260417_000001_add_stream_to_room_ai;

View File

@ -0,0 +1,36 @@
//! SeaORM migration: add `stream` column to `room_ai` table
use sea_orm_migration::prelude::*;
pub struct Migration;
impl MigrationName for Migration {
fn name(&self) -> &str {
"m20260417_000001_add_stream_to_room_ai"
}
}
#[async_trait::async_trait]
impl MigrationTrait for Migration {
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
manager
.get_connection()
.execute_raw(sea_orm::Statement::from_string(
sea_orm::DbBackend::Postgres,
"ALTER TABLE room_ai ADD COLUMN IF NOT EXISTS stream BOOLEAN NOT NULL DEFAULT true;",
))
.await?;
Ok(())
}
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
manager
.get_connection()
.execute_raw(sea_orm::Statement::from_string(
sea_orm::DbBackend::Postgres,
"ALTER TABLE room_ai DROP COLUMN IF EXISTS stream;",
))
.await?;
Ok(())
}
}