Backend (Rust): - Create proto/auth.proto with Login and RefreshToken RPCs - Implement AuthGrpcService in services/api with JWT issuance - Register as unauthenticated service in main.rs (pre-auth) - Update JWT issuer from foxhunt-api-gateway to foxhunt-api Dashboard (TypeScript): - Install @connectrpc/connect-web + @bufbuild/protobuf - Generate TypeScript proto clients via buf (src/gen/) - Create grpc.ts transport with JWT interceptor - Rewrite all useApi hooks to typed gRPC calls - Replace WebSocket with useGrpcStream server-streaming hooks - Migrate all 6 pages + 6 components to grpc-web - Delete api.ts, websocket.ts, useWebSocket.ts Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
212 lines
9.1 KiB
Rust
212 lines
9.1 KiB
Rust
//! Build script for API Gateway service
|
|
//!
|
|
//! Compiles protobuf definitions from the canonical proto/ directory at workspace root.
|
|
//! Proto packages:
|
|
//! - `foxhunt.tli` (fxt_trading.proto) - Fat-client unified interface (server+client)
|
|
//! - `trading` (trading.proto) - Backend trading service (client-only)
|
|
//! - `risk` (risk.proto) - Risk service (client-only)
|
|
//! - `monitoring` (monitoring.proto) - Monitoring service (server+client)
|
|
//! - `config` (config.proto) - Config service (server+client)
|
|
//! - `ml_training` (ml_training.proto) - ML Training service (server+client)
|
|
//! - `trading_agent` (trading_agent.proto) - Trading Agent service (server+client)
|
|
|
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
// NOTE: Tonic 0.14+ uses tonic_prost_build instead of tonic_build
|
|
let config = tonic_prost_build::configure();
|
|
|
|
let out_dir = std::path::PathBuf::from(std::env::var("OUT_DIR")?);
|
|
|
|
// Compile fat-client TLI proto (package: foxhunt.tli) — server+client
|
|
// Contains TradingService, BacktestingService, and MLService
|
|
// API Gateway acts as server for incoming client requests
|
|
config
|
|
.clone()
|
|
.build_server(true)
|
|
.build_client(true)
|
|
.file_descriptor_set_path(out_dir.join("tli_descriptor.bin"))
|
|
.compile_well_known_types(true)
|
|
.extern_path(".google.protobuf", "::prost_types")
|
|
.type_attribute(".", "#[derive(serde::Serialize, serde::Deserialize)]")
|
|
.server_mod_attribute(".", "#[allow(unused_qualifications)]")
|
|
.client_mod_attribute(".", "#[allow(unused_qualifications)]")
|
|
.compile_protos(
|
|
&["../../proto/fxt_trading.proto"],
|
|
&["../../proto"],
|
|
)?;
|
|
|
|
// Compile Trading Service backend proto (package: trading) — server+client
|
|
// API Gateway serves trading.TradingService and forwards to Trading Service backend
|
|
config
|
|
.clone()
|
|
.build_server(true)
|
|
.build_client(true)
|
|
.file_descriptor_set_path(out_dir.join("trading_descriptor.bin"))
|
|
.compile_well_known_types(true)
|
|
.extern_path(".google.protobuf", "::prost_types")
|
|
.type_attribute(".", "#[derive(serde::Serialize, serde::Deserialize)]")
|
|
.server_mod_attribute(".", "#[allow(unused_qualifications)]")
|
|
.client_mod_attribute(".", "#[allow(unused_qualifications)]")
|
|
.compile_protos(
|
|
&["../../proto/trading.proto"],
|
|
&["../../proto"],
|
|
)?;
|
|
|
|
// Compile Risk Service proto (package: risk) — server+client
|
|
config
|
|
.clone()
|
|
.build_server(true)
|
|
.build_client(true)
|
|
.file_descriptor_set_path(out_dir.join("risk_descriptor.bin"))
|
|
.compile_well_known_types(true)
|
|
.extern_path(".google.protobuf", "::prost_types")
|
|
.type_attribute(".", "#[derive(serde::Serialize, serde::Deserialize)]")
|
|
.server_mod_attribute(".", "#[allow(unused_qualifications)]")
|
|
.client_mod_attribute(".", "#[allow(unused_qualifications)]")
|
|
.compile_protos(
|
|
&["../../proto/risk.proto"],
|
|
&["../../proto"],
|
|
)?;
|
|
|
|
// Compile Monitoring Service proto (package: monitoring) — server+client
|
|
config
|
|
.clone()
|
|
.build_server(true)
|
|
.build_client(true)
|
|
.file_descriptor_set_path(out_dir.join("monitoring_descriptor.bin"))
|
|
.compile_well_known_types(true)
|
|
.extern_path(".google.protobuf", "::prost_types")
|
|
.type_attribute(".", "#[derive(serde::Serialize, serde::Deserialize)]")
|
|
.server_mod_attribute(".", "#[allow(unused_qualifications)]")
|
|
.client_mod_attribute(".", "#[allow(unused_qualifications)]")
|
|
.compile_protos(
|
|
&["../../proto/monitoring.proto"],
|
|
&["../../proto"],
|
|
)?;
|
|
|
|
// Compile Config backend proto (package: config) — server+client
|
|
config
|
|
.clone()
|
|
.build_server(true)
|
|
.build_client(true)
|
|
.file_descriptor_set_path(out_dir.join("config_descriptor.bin"))
|
|
.compile_well_known_types(true)
|
|
.extern_path(".google.protobuf", "::prost_types")
|
|
.type_attribute(".", "#[derive(serde::Serialize, serde::Deserialize)]")
|
|
.server_mod_attribute(".", "#[allow(unused_qualifications)]")
|
|
.client_mod_attribute(".", "#[allow(unused_qualifications)]")
|
|
.compile_protos(
|
|
&["../../proto/config.proto"],
|
|
&["../../proto"],
|
|
)?;
|
|
|
|
// Compile ML Training Service proto (package: ml_training) — server+client
|
|
config
|
|
.clone()
|
|
.build_server(true)
|
|
.build_client(true)
|
|
.file_descriptor_set_path(out_dir.join("ml_training_descriptor.bin"))
|
|
.compile_well_known_types(true)
|
|
.extern_path(".google.protobuf", "::prost_types")
|
|
.type_attribute(".", "#[derive(serde::Serialize, serde::Deserialize)]")
|
|
.server_mod_attribute(".", "#[allow(unused_qualifications)]")
|
|
.client_mod_attribute(".", "#[allow(unused_qualifications)]")
|
|
.compile_protos(
|
|
&["../../proto/ml_training.proto"],
|
|
&["../../proto"],
|
|
)?;
|
|
|
|
// Compile Trading Agent Service proto (package: trading_agent) — server+client
|
|
config
|
|
.clone()
|
|
.build_server(true)
|
|
.build_client(true)
|
|
.file_descriptor_set_path(out_dir.join("trading_agent_descriptor.bin"))
|
|
.compile_well_known_types(true)
|
|
.extern_path(".google.protobuf", "::prost_types")
|
|
.type_attribute(".", "#[derive(serde::Serialize, serde::Deserialize)]")
|
|
.server_mod_attribute(".", "#[allow(unused_qualifications)]")
|
|
.client_mod_attribute(".", "#[allow(unused_qualifications)]")
|
|
.compile_protos(
|
|
&["../../proto/trading_agent.proto"],
|
|
&["../../proto"],
|
|
)?;
|
|
|
|
// Compile Broker Gateway Service proto (package: broker_gateway) — server+client
|
|
config
|
|
.clone()
|
|
.build_server(true)
|
|
.build_client(true)
|
|
.file_descriptor_set_path(out_dir.join("broker_gateway_descriptor.bin"))
|
|
.compile_well_known_types(true)
|
|
.extern_path(".google.protobuf", "::prost_types")
|
|
.type_attribute(".", "#[derive(serde::Serialize, serde::Deserialize)]")
|
|
.server_mod_attribute(".", "#[allow(unused_qualifications)]")
|
|
.client_mod_attribute(".", "#[allow(unused_qualifications)]")
|
|
.compile_protos(
|
|
&["../../proto/broker_gateway.proto"],
|
|
&["../../proto"],
|
|
)?;
|
|
|
|
// Compile Data Acquisition Service proto (package: data_acquisition) — server+client
|
|
config
|
|
.clone()
|
|
.build_server(true)
|
|
.build_client(true)
|
|
.file_descriptor_set_path(out_dir.join("data_acquisition_descriptor.bin"))
|
|
.compile_well_known_types(true)
|
|
.extern_path(".google.protobuf", "::prost_types")
|
|
.type_attribute(".", "#[derive(serde::Serialize, serde::Deserialize)]")
|
|
.server_mod_attribute(".", "#[allow(unused_qualifications)]")
|
|
.client_mod_attribute(".", "#[allow(unused_qualifications)]")
|
|
.compile_protos(
|
|
&["../../proto/data_acquisition.proto"],
|
|
&["../../proto"],
|
|
)?;
|
|
|
|
// Compile ML Inference Service proto (package: ml) — server+client
|
|
config
|
|
.clone()
|
|
.build_server(true)
|
|
.build_client(true)
|
|
.file_descriptor_set_path(out_dir.join("ml_descriptor.bin"))
|
|
.compile_well_known_types(true)
|
|
.extern_path(".google.protobuf", "::prost_types")
|
|
.type_attribute(".", "#[derive(serde::Serialize, serde::Deserialize)]")
|
|
.server_mod_attribute(".", "#[allow(unused_qualifications)]")
|
|
.client_mod_attribute(".", "#[allow(unused_qualifications)]")
|
|
.compile_protos(
|
|
&["../../proto/ml.proto"],
|
|
&["../../proto"],
|
|
)?;
|
|
|
|
// Compile Auth Service proto (package: auth) — server only (no client needed)
|
|
config
|
|
.clone()
|
|
.build_server(true)
|
|
.build_client(false)
|
|
.file_descriptor_set_path(out_dir.join("auth_descriptor.bin"))
|
|
.compile_well_known_types(true)
|
|
.extern_path(".google.protobuf", "::prost_types")
|
|
.type_attribute(".", "#[derive(serde::Serialize, serde::Deserialize)]")
|
|
.server_mod_attribute(".", "#[allow(unused_qualifications)]")
|
|
.client_mod_attribute(".", "#[allow(unused_qualifications)]")
|
|
.compile_protos(
|
|
&["../../proto/auth.proto"],
|
|
&["../../proto"],
|
|
)?;
|
|
|
|
println!("cargo:rerun-if-changed=../../proto/fxt_trading.proto");
|
|
println!("cargo:rerun-if-changed=../../proto/trading.proto");
|
|
println!("cargo:rerun-if-changed=../../proto/risk.proto");
|
|
println!("cargo:rerun-if-changed=../../proto/monitoring.proto");
|
|
println!("cargo:rerun-if-changed=../../proto/config.proto");
|
|
println!("cargo:rerun-if-changed=../../proto/ml_training.proto");
|
|
println!("cargo:rerun-if-changed=../../proto/trading_agent.proto");
|
|
println!("cargo:rerun-if-changed=../../proto/broker_gateway.proto");
|
|
println!("cargo:rerun-if-changed=../../proto/data_acquisition.proto");
|
|
println!("cargo:rerun-if-changed=../../proto/ml.proto");
|
|
println!("cargo:rerun-if-changed=../../proto/auth.proto");
|
|
|
|
Ok(())
|
|
}
|