Added basic axum server

This commit is contained in:
xeovalyte 2025-01-15 23:20:17 +01:00
parent cd51cd539c
commit f2e7d9f431
Signed by: xeovalyte
SSH Key Fingerprint: SHA256:kSQDrQDmKzljJzfGYcd3m9RqHi4h8rSwkZ3sQ9kBURo
14 changed files with 8660 additions and 5 deletions

View File

@ -1,5 +1,6 @@
<template> <template>
<p>Hi</p> <div>
<NuxtRouteAnnouncer />
<NuxtWelcome />
</div>
</template> </template>
<script setup></script>

Binary file not shown.

View File

@ -13,5 +13,6 @@
"nuxt": "^3.15.1", "nuxt": "^3.15.1",
"vue": "latest", "vue": "latest",
"vue-router": "latest" "vue-router": "latest"
} },
"packageManager": "pnpm@9.15.4+sha512.b2dc20e2fc72b3e18848459b37359a32064663e5627a51e4c74b2c29dd8e8e0491483c3abb40789cfd578bf362fb6ba8261b05f0387d76792ed6e23ea3b1b6a0"
} }

6413
client/pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -5,10 +5,18 @@
languages.javascript = { languages.javascript = {
enable = true; enable = true;
bun.enable = true; pnpm.enable = true;
}; };
services.postgres = { services.postgres = {
enable = true; enable = true;
listen_addresses = "127.0.0.1";
initialDatabases = [
{
name = "wrbapp";
pass = "password";
user = "wrbapp";
}
];
}; };
} }

1
server/.env Normal file
View File

@ -0,0 +1 @@
DATABASE_URL="postgres://wrbapp:password@localhost/wrbapp"

1
server/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
target

2100
server/Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

16
server/Cargo.toml Normal file
View File

@ -0,0 +1,16 @@
[package]
name = "wrbapp_server"
version = "0.1.0"
edition = "2021"
[dependencies]
axum = { version = "0.8", features = [ "macros" ] }
tokio = { version = "1.43", features = [ "rt-multi-thread", "macros" ] }
sqlx = { version = "0.8", features = [ "runtime-tokio", "postgres" ] }
serde = "1.0"
dotenvy = "0.15.7"
# Tracing
tracing = "0.1"
tracing-subscriber = "0.3"

View File

@ -0,0 +1,28 @@
CREATE TABLE user (
id bigint NOT NULL PRIMARY KEY,
email text NOT NULL UNIQUE,
password text NOT NULL,
admin boolean NOT NULL
);
CREATE TABLE member (
id varchar(7) NOT NULL PRIMARY KEY,
call_sign text NOT NULL,
name text NOT NULL,
registration_token text NOT NULL UNIQUE,
diploma text,
hours text[] NOT NULL,
groups text[] NOT NULL
);
CREATE TABLE session (
id bigint NOT NULL PRIMARY KEY,
user_id bigint NOT NULL,
token text NOT NULL UNIQUE,
expires timestamp NOT NULL
);
ALTER TABLE session ADD CONSTRAINT session_user_id_fk FOREIGN KEY (user_id) REFERENCES user (id);

3
server/src/database.rs Normal file
View File

@ -0,0 +1,3 @@
mod postgres;
pub use postgres::apply_migrations;
pub use postgres::connect;

View File

@ -0,0 +1,37 @@
use sqlx::{
migrate::MigrateDatabase, postgres::PgPoolOptions, Connection, PgConnection, PgPool, Postgres,
};
pub async fn connect() -> Result<PgPool, sqlx::Error> {
tracing::info!("Initializing database connection");
let database_url =
dotenvy::var("DATABASE_URL").expect("`DATABASE_URL` environment variable not set");
let pool = PgPoolOptions::new()
.max_connections(5)
.connect(&database_url)
.await?;
Ok(pool)
}
pub async fn apply_migrations() -> Result<(), sqlx::Error> {
let uri = dotenvy::var("DATABASE_URL").expect("`DATABASE_URL` environment variable not set");
let uri = uri.as_str();
if !Postgres::database_exists(uri).await? {
tracing::info!("Creating database...");
Postgres::create_database(uri).await?;
}
tracing::info!("Applying migrations...");
let mut conn = PgConnection::connect(uri).await?;
sqlx::migrate!()
.run(&mut conn)
.await
.expect("Error while running database migrations");
Ok(())
}

1
server/src/lib.rs Normal file
View File

@ -0,0 +1 @@
pub mod database;

45
server/src/main.rs Normal file
View File

@ -0,0 +1,45 @@
use axum::{http::StatusCode, routing::get, Router};
use tokio::net::TcpListener;
use tracing::Level;
use tracing_subscriber::FmtSubscriber;
use wrbapp_server::database;
#[tokio::main]
async fn main() {
dotenvy::dotenv().ok();
// Initialize logging
let subscriber = FmtSubscriber::builder()
.with_max_level(Level::INFO)
.finish();
tracing::subscriber::set_global_default(subscriber)
.expect("Error while initialized tracing subscriber");
// Initialize database connection
database::apply_migrations()
.await
.expect("Database migrations failed");
database::connect()
.await
.expect("Database connection failed");
// Serve app
let app = Router::new().route("/", get(hello_world));
let listener = TcpListener::bind("127.0.0.1:3000")
.await
.expect("Error while initializing listener");
tracing::info!("Listening on {}", listener.local_addr().unwrap());
axum::serve(listener, app)
.await
.expect("Error while serving axum application");
}
async fn hello_world() -> Result<String, (StatusCode, String)> {
Ok("Hello world".to_string())
}