This commit is contained in:
2025-10-05 21:47:49 +02:00
parent 04c2750f0b
commit a6626571fa
29 changed files with 681 additions and 677 deletions

89
.idea/workspace.xml generated
View File

@@ -12,56 +12,27 @@
</component>
<component name="ChangeListManager">
<list default="true" id="b2b598c9-ef0b-4cbc-8852-cfbc8ce3920e" name="Changes" comment="init">
<change afterPath="$PROJECT_DIR$/src/utils/config.rs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/utils/logger.rs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/utils/toolbox.rs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/db/mod.rs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/db/models/_channel_user.rs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/db/models/_server_user.rs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/db/models/attachment.rs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/db/models/category.rs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/db/models/channel.rs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/db/models/message.rs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/db/models/mod.rs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/db/models/server.rs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/db/models/user.rs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/db/repositories/_server_user_repository.rs" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/db/repositories/mod.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Cargo.lock" beforeDir="false" afterPath="$PROJECT_DIR$/Cargo.lock" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Cargo.toml" beforeDir="false" afterPath="$PROJECT_DIR$/Cargo.toml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/README.md" beforeDir="false" afterPath="$PROJECT_DIR$/README.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/app/app.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/app/app.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/app/conf.rs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/app/mod.rs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/core/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/app/http/mod.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/domain/client.rs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/domain/event.rs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/domain/mod.rs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/domain/models.rs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/domain/user.rs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/lib.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/lib.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/main.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/network/http.rs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/network/http_routes/channel.rs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/network/http_routes/master.rs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/network/http_routes/message.rs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/network/http_routes/mod.rs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/network/http_routes/sub_server.rs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/network/http_routes/user.rs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/network/http_routes/websocket.rs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/network/mod.rs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/network/protocol.rs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/network/udp.rs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/network/udp_back.rs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/runtime/dispatcher.rs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/runtime/mod.rs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/store/migrations/001_init.sqlite.sql" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/store/mod.rs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/store/models/channel.rs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/store/models/link_sub_server_user.rs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/store/models/message.rs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/store/models/mod.rs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/store/models/sub_server.rs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/store/models/user.rs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/store/repositories/channel_repository.rs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/store/repositories/link_sub_server_user_repository.rs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/store/repositories/message_repository.rs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/store/repositories/mod.rs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/store/repositories/sub_server_repository.rs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/store/repositories/user_repository.rs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/store/session/client.rs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/store/session/mod.rs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/store/store_service.rs" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/utils/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/utils/mod.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/network/http/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/network/http/mod.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/network/http/server.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/network/http/server.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/network/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/network/mod.rs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/store/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/db/repositories/_channel_user_repository.rs" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
@@ -115,13 +86,15 @@
&quot;org.rust.cargo.project.model.PROJECT_DISCOVERY&quot;: &quot;true&quot;,
&quot;org.rust.cargo.project.model.impl.CargoExternalSystemProjectAware.subscribe.first.balloon&quot;: &quot;&quot;,
&quot;org.rust.first.attach.projects&quot;: &quot;true&quot;,
&quot;settings.editor.selected.configurable&quot;: &quot;ml.llm.LLMConfigurable&quot;,
&quot;settings.editor.selected.configurable&quot;: &quot;preferences.pluginManager&quot;,
&quot;to.speed.mode.migration.done&quot;: &quot;true&quot;,
&quot;vue.rearranger.settings.migration&quot;: &quot;true&quot;
}
}</component>
<component name="RecentsManager">
<key name="MoveFile.RECENT_KEYS">
<recent name="\\wsl.localhost\Debian\home\Nell\linux_dev\ox_speak_server\src" />
<recent name="\\wsl.localhost\Debian\home\Nell\linux_dev\ox_speak_server\src\store\db" />
<recent name="\\wsl.localhost\Debian\home\Nell\linux_dev\ox_speak_server\src\app\http" />
<recent name="\\wsl.localhost\Debian\home\Nell\linux_dev\ox_speak_server\src\network" />
</key>
@@ -180,7 +153,11 @@
<workItem from="1758380522178" duration="7468000" />
<workItem from="1758439568539" duration="4787000" />
<workItem from="1758951672825" duration="25708000" />
<workItem from="1759042700460" duration="11051000" />
<workItem from="1759042700460" duration="16518000" />
<workItem from="1759562385229" duration="218000" />
<workItem from="1759562619209" duration="13323000" />
<workItem from="1759649037947" duration="3578000" />
<workItem from="1759657715670" duration="10824000" />
</task>
<task id="LOCAL-00001" summary="init">
<option name="closed" value="true" />
@@ -190,7 +167,23 @@
<option name="project" value="LOCAL" />
<updated>1756218076891</updated>
</task>
<option name="localTasksCounter" value="2" />
<task id="LOCAL-00002" summary="init">
<option name="closed" value="true" />
<created>1759077528343</created>
<option name="number" value="00002" />
<option name="presentableId" value="LOCAL-00002" />
<option name="project" value="LOCAL" />
<updated>1759077528343</updated>
</task>
<task id="LOCAL-00003" summary="init">
<option name="closed" value="true" />
<created>1759077533456</created>
<option name="number" value="00003" />
<option name="presentableId" value="LOCAL-00003" />
<option name="project" value="LOCAL" />
<updated>1759077533456</updated>
</task>
<option name="localTasksCounter" value="4" />
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">

740
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -29,4 +29,6 @@ tower = "0.5"
tower-http = "0.6"
hyper = "1.7"
sea-orm = { version = "1.1", features = [ "sqlx-sqlite", "runtime-tokio", "macros" ] }
sqlx = { version = "0.8", features = ["runtime-tokio", "tls-rustls", "sqlite", "postgres", "mysql", "uuid", "chrono", "migrate"] }
uuid = { version = "1.18", features = ["v4", "v7", "serde"] }
chrono = { version = "0.4", features = ["serde"] }

View File

@@ -1,6 +1,8 @@
use std::io;
use std::sync::Arc;
use std::net::SocketAddr;
use crate::app::http::router::configure_routes;
use crate::network::http::server::HttpServer;
use crate::network::udp::server::UdpServer;
use crate::utils::config::Config;
use crate::utils::logger::ContextLogger;
@@ -24,8 +26,16 @@ impl App {
}
};
let http_server = match HttpServer::new("127.0.0.1:8080") {
Ok(http_server) => http_server,
Err(e) => {
return Err(io::Error::new(io::ErrorKind::Other, format!("Failed to create HTTP server: {}", e)))
}
};
let context = Context {
udp_server
udp_server,
http_server,
};
Ok(Self {
@@ -34,8 +44,18 @@ impl App {
logger
})
}
pub async fn run(self) -> io::Result<()> {
self.logger.info("Starting application");
self.context.udp_server.run().await?;
self.context.http_server.run().await?;
Ok(())
}
}
struct Context {
udp_server: UdpServer
udp_server: UdpServer,
http_server: HttpServer
}

57
src/db/context.rs Normal file
View File

@@ -0,0 +1,57 @@
use std::sync::Arc;
use sqlx::SqlitePool;
use crate::db::{AttachmentRepository, CategoryRepository, ChannelRepository, ChannelUser, ChannelUserRepository, MessageRepository, ServerRepository, ServerUser, ServerUserRepository, UserRepository};
use crate::utils::logger::ContextLogger;
struct Repositories {
server_repository: ServerRepository,
category_repository: CategoryRepository,
channel_repository: ChannelRepository,
user_repository: UserRepository,
message_repository: MessageRepository,
attachment_repository: AttachmentRepository,
server_user: ServerUserRepository,
channel_user: ChannelUserRepository
}
pub struct DbContext {
pool: Arc<SqlitePool>,
repositories: Arc<Repositories>,
// logger
logger: ContextLogger,
}
impl DbContext {
pub async fn new(database_url: &str) -> Result<Self, sqlx::Error> {
let logger = ContextLogger::new("DB");
logger.info(&format!("Creating DB context on {}", database_url));
let pool = SqlitePool::connect(database_url).await?;
logger.info("DB context created");
let pool = Arc::new(pool);
let repositories = Arc::new(Repositories {
server_repository: ServerRepository::new(pool.clone()),
category_repository: CategoryRepository::new(pool.clone()),
channel_repository: ChannelRepository::new(pool.clone()),
user_repository: UserRepository::new(pool.clone()),
message_repository: MessageRepository::new(pool.clone()),
attachment_repository: AttachmentRepository::new(pool.clone()),
server_user: ServerUserRepository::new(pool.clone()),
channel_user: ChannelUserRepository::new(pool.clone())
});
Ok(Self {
pool,
repositories,
logger,
})
}
pub fn repositories(&self) -> Arc<Repositories> {
self.repositories.clone()
}
}

6
src/db/mod.rs Normal file
View File

@@ -0,0 +1,6 @@
pub mod models;
pub mod repositories;
mod context;
pub use models::*;
pub use repositories::*;

View File

@@ -0,0 +1,29 @@
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use sqlx::FromRow;
use uuid::Uuid;
#[derive(Debug, Clone, FromRow, Serialize, Deserialize)]
pub struct ChannelUser {
pub id: Uuid,
pub channel_id: Uuid,
pub user_id: Uuid,
pub username: Option<String>,
pub joined_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
pub last_read_at: DateTime<Utc>,
}
impl ChannelUser {
pub fn new(channel_id: Uuid, user_id: Uuid) -> Self {
Self {
id: Uuid::now_v7(),
channel_id,
user_id,
username: None,
joined_at: Utc::now(),
updated_at: Utc::now(),
last_read_at: Utc::now(),
}
}
}

View File

@@ -0,0 +1,28 @@
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use sqlx::FromRow;
use uuid::Uuid;
#[derive(Debug, Clone, FromRow, Serialize, Deserialize)]
pub struct ServerUser {
pub id: Uuid,
pub server_id: Uuid,
pub user_id: Uuid,
#[sqlx(default)]
pub username: Option<String>,
pub joined_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
impl ServerUser {
pub fn new(server_id: Uuid, user_id: Uuid) -> Self {
Self {
id: Uuid::now_v7(),
server_id,
user_id,
username: None,
joined_at: Utc::now(),
updated_at: Utc::now(),
}
}
}

View File

@@ -0,0 +1,27 @@
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use sqlx::FromRow;
use uuid::Uuid;
#[derive(Debug, Clone, FromRow, Serialize, Deserialize)]
pub struct Attachment {
pub id: Uuid,
pub message_id: Uuid,
pub filename: String,
pub file_size: i64,
pub mime_type: String,
pub created_at: DateTime<Utc>,
}
impl Attachment {
pub fn new(message_id: Uuid, filename: String, file_size: i64, mime_type: String) -> Self {
Self {
id: Uuid::new_v4(),
message_id,
filename,
file_size,
mime_type,
created_at: Utc::now(),
}
}
}

25
src/db/models/category.rs Normal file
View File

@@ -0,0 +1,25 @@
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use sqlx::FromRow;
use uuid::Uuid;
#[derive(Debug, Clone, FromRow, Serialize, Deserialize)]
pub struct Category {
pub id: Uuid,
pub server_id: Uuid,
pub name: String,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
impl Category {
pub fn new(server_id: Uuid, name: String) -> Self {
Self {
id: Uuid::now_v7(),
server_id,
name,
created_at: Utc::now(),
updated_at: Utc::now(),
}
}
}

56
src/db/models/channel.rs Normal file
View File

@@ -0,0 +1,56 @@
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, sqlx::FromRow, Serialize, Deserialize)]
pub struct Channel {
pub id: Uuid, // Blob(16) sqlite
#[sqlx(default)]
pub server_id: Option<Uuid>,
#[sqlx(default)]
pub category_id: Option<Uuid>,
#[sqlx(default)]
pub position: i32,
#[sqlx(rename = "type")]
pub channel_type: ChannelType,
pub name: Option<String>, // Not necessary for DMs
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
#[derive(Debug, Clone, Serialize, Deserialize, sqlx::Type)]
#[sqlx(type_name = "text")]
#[serde(rename_all = "snake_case")]
pub enum ChannelType {
Text,
Voice,
Dm
}
impl Channel {
pub fn new_server_channel(server_id: Uuid, name: String, channel_type: ChannelType) -> Self {
Self {
id: Uuid::now_v7(),
server_id: Some(server_id),
category_id: None,
position: 0,
channel_type,
name: Some(name),
created_at: Utc::now(),
updated_at: Utc::now()
}
}
pub fn new_dm_channel() -> Self {
Self {
id: Uuid::now_v7(),
server_id: None,
category_id: None,
channel_type: ChannelType::Dm,
name: None,
position: 0,
created_at: Utc::now(),
updated_at: Utc::now(),
}
}
}

41
src/db/models/message.rs Normal file
View File

@@ -0,0 +1,41 @@
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use sqlx::FromRow;
use uuid::Uuid;
#[derive(Debug, Clone, FromRow, Serialize, Deserialize)]
pub struct Message {
pub id: Uuid,
pub channel_id: Uuid,
pub user_id: Uuid,
pub content: String,
pub created_at: DateTime<Utc>,
pub edited_at: DateTime<Utc>,
pub reply_to_id: Option<Uuid>,
}
impl Message {
pub fn new(channel_id: Uuid, user_id: Uuid, content: String) -> Self {
Self {
id: Uuid::now_v7(),
channel_id,
user_id,
content,
created_at: Utc::now(),
edited_at: Utc::now(),
reply_to_id: None,
}
}
pub fn with_reply(channel_id: Uuid, user_id: Uuid, content: String, reply_to_id: Uuid) -> Self {
Self {
id: Uuid::now_v7(),
channel_id,
user_id,
content,
created_at: Utc::now(),
edited_at: Utc::now(),
reply_to_id: Some(reply_to_id),
}
}
}

17
src/db/models/mod.rs Normal file
View File

@@ -0,0 +1,17 @@
mod user;
mod server;
mod _server_user;
mod channel;
mod category;
mod _channel_user;
mod message;
mod attachment;
pub use user::*;
pub use server::*;
pub use channel::*;
pub use category::*;
pub use message::*;
pub use attachment::*;
pub use _server_user::*;
pub use _channel_user::*;

25
src/db/models/server.rs Normal file
View File

@@ -0,0 +1,25 @@
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use sqlx::FromRow;
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, FromRow, Serialize, Deserialize)]
pub struct Server {
pub id: Uuid, // Blob(16) sqlite
pub username: String,
pub password: Option<String>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
impl Server {
pub fn new(username: String, password: Option<String>) -> Self {
Self {
id: Uuid::now_v7(),
username,
password,
created_at: Utc::now(),
updated_at: Utc::now(),
}
}
}

25
src/db/models/user.rs Normal file
View File

@@ -0,0 +1,25 @@
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use sqlx::FromRow;
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, FromRow, Serialize, Deserialize)]
pub struct User {
pub id: Uuid, // Blob(16) sqlite
pub username: String,
pub pub_key: String, // TEXT
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
impl User {
pub fn new(username: String, pub_key: String) -> Self {
Self {
id: Uuid::now_v7(),
username,
pub_key,
created_at: Utc::now(),
updated_at: Utc::now(),
}
}
}

View File

@@ -0,0 +1,14 @@
use std::sync::Arc;
use sqlx::SqlitePool;
pub struct ChannelUserRepository {
pool: Arc<SqlitePool>
}
impl ChannelUserRepository {
pub fn new(pool: Arc<SqlitePool>) -> Self {
Self {
pool
}
}
}

View File

@@ -0,0 +1,14 @@
use std::sync::Arc;
use sqlx::SqlitePool;
pub struct ServerUserRepository {
pool: Arc<SqlitePool>
}
impl ServerUserRepository {
pub fn new(pool: Arc<SqlitePool>) -> Self {
Self {
pool
}
}
}

View File

@@ -0,0 +1,14 @@
use std::sync::Arc;
use sqlx::SqlitePool;
pub struct AttachmentRepository {
pool: Arc<SqlitePool>
}
impl AttachmentRepository {
pub fn new(pool: Arc<SqlitePool>) -> Self {
Self {
pool
}
}
}

View File

@@ -0,0 +1,14 @@
use std::sync::Arc;
use sqlx::SqlitePool;
pub struct CategoryRepository{
pool: Arc<SqlitePool>
}
impl CategoryRepository {
pub fn new(pool: Arc<SqlitePool>) -> Self {
Self {
pool
}
}
}

View File

@@ -0,0 +1,15 @@
use std::sync::Arc;
use sqlx::SqlitePool;
pub struct ChannelRepository {
pool: Arc<SqlitePool>
}
impl ChannelRepository {
pub fn new(pool: Arc<SqlitePool>) -> Self {
Self {
pool
}
}
}

View File

@@ -0,0 +1,15 @@
use std::sync::Arc;
use sqlx::SqlitePool;
pub struct MessageRepository{
pool: Arc<SqlitePool>
}
impl MessageRepository {
pub fn new(pool: Arc<SqlitePool>) -> Self {
Self {
pool
}
}
}

View File

@@ -0,0 +1,17 @@
mod _channel_user_repository;
mod _server_user_repository;
mod user_repository;
mod server_repository;
mod channel_repository;
mod category_repository;
mod message_repository;
mod attachment_repository;
pub use user_repository::*;
pub use server_repository::*;
pub use channel_repository::*;
pub use category_repository::*;
pub use message_repository::*;
pub use attachment_repository::*;
pub use _server_user_repository::*;
pub use _channel_user_repository::*;

View File

@@ -0,0 +1,15 @@
use std::sync::Arc;
use sqlx::SqlitePool;
pub struct ServerRepository{
pool: Arc<SqlitePool>
}
impl ServerRepository {
pub fn new(pool: Arc<SqlitePool>) -> Self {
Self{
pool
}
}
}

View File

@@ -0,0 +1,14 @@
use std::sync::Arc;
use sqlx::{SqlitePool};
pub struct UserRepository {
pool: Arc<SqlitePool>
}
impl UserRepository {
pub fn new(pool: Arc<SqlitePool>) -> Self {
Self {
pool
}
}
}

View File

@@ -2,4 +2,4 @@
pub mod utils;
pub mod network;
pub mod app;
pub mod store;
pub mod db;

View File

@@ -1 +1 @@
mod server;
pub mod server;

View File

@@ -1,6 +1,6 @@
use std::io;
use std::net::SocketAddr;
use axum::{Router, routing::get, http::StatusCode, Json};
use axum::{Router};
use tokio::net::TcpListener;
use crate::utils::logger::ContextLogger;
@@ -20,34 +20,13 @@ impl HttpServer {
Ok(Self { bind_addr, logger })
}
pub async fn run(self) -> io::Result<()> {
pub async fn run(self, router: Router) -> io::Result<()> {
self.logger.info(&format!("Starting HTTP server on {}", self.bind_addr));
let listener = TcpListener::bind(self.bind_addr).await?;
let app = create_app(self.logger.clone());
axum::serve(listener, app)
axum::serve(listener, router)
.await
.map_err(|e| io::Error::new(io::ErrorKind::Other, e))
}
}
fn create_app(logger: ContextLogger) -> Router {
Router::new()
.route("/", get(|| async { "OX Speak Server - HTTP API" }))
.route("/health", get(|| async { StatusCode::OK }))
.route("/api/status", get(status_handler))
.with_state(logger)
}
async fn status_handler(
axum::extract::State(logger): axum::extract::State<ContextLogger>
) -> Json<serde_json::Value> {
logger.info("Status endpoint called");
Json(serde_json::json!({
"status": "ok",
"service": "ox-speak-server",
"workers": tokio::runtime::Handle::current().metrics().num_workers()
}))
}

View File

@@ -1,2 +1,2 @@
pub mod udp;
mod http;
pub mod http;

View File