Update backend implementation to fit spec

This commit is contained in:
Jon Staab
2026-03-25 11:43:09 -07:00
parent 2e0740910c
commit cb2e37c74a
19 changed files with 1798 additions and 2341 deletions
+19 -71
View File
@@ -1,29 +1,18 @@
mod api;
mod auth;
mod billing;
mod config;
mod db;
mod infra;
mod models;
mod notifications;
mod platform;
mod provisioning;
mod repo;
use std::net::SocketAddr;
mod robot;
use anyhow::Result;
use axum::{Router, routing::get};
use tokio::net::TcpListener;
use tower_http::cors::CorsLayer;
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
use crate::billing::BillingService;
use crate::config::Config;
use crate::db::init_pool;
use crate::notifications::Nip17Notifier;
use crate::platform::publish_platform_identity;
use crate::provisioning::Provisioner;
use crate::api::Api;
use crate::billing::Billing;
use crate::infra::Infra;
use crate::repo::Repo;
use crate::robot::Robot;
#[tokio::main]
async fn main() -> Result<()> {
@@ -34,61 +23,20 @@ async fn main() -> Result<()> {
.with(tracing_subscriber::fmt::layer())
.init();
let config = Config::from_env();
ensure_sqlite_dir(&config.database_url)?;
let repo = Repo::new().await?;
repo.migrate().await?;
let robot = Robot::new().await?;
let billing = Billing::new(repo.clone(), robot.clone());
let infra = Infra::new(repo.clone());
let api = Api::new(repo);
let pool = init_pool(&config.database_url).await?;
let repo = Repo::new(pool);
publish_platform_identity(
&config.platform_secret,
&config.indexer_relays,
&config.platform_name,
&config.platform_description,
&config.platform_picture,
&config.platform_messaging_relays,
)
.await?;
let notifier = Nip17Notifier::new(
config.platform_secret.clone(),
config.indexer_relays.clone(),
)
.await?;
let billing = BillingService::new(repo.clone(), notifier, config.platform_nwc_url.clone());
tokio::spawn(billing.run());
let provisioner = Provisioner::new(
config.zooid_api_url.clone(),
config.relay_domain.clone(),
config.platform_secret.clone(),
)?;
let state = api::AppState {
repo,
admin_pubkeys: std::sync::Arc::new(config.admin_pubkeys.clone()),
provisioner,
};
tokio::spawn(async move {
billing.start().await;
});
let app = Router::new()
.merge(api::router(state))
.route("/healthz", get(healthz))
.layer(CorsLayer::permissive());
tokio::spawn(async move {
infra.start().await;
});
let addr: SocketAddr = format!("{}:{}", config.host, config.port).parse()?;
let listener = TcpListener::bind(addr).await?;
tracing::info!("listening on {}", addr);
axum::serve(listener, app).await?;
Ok(())
}
fn ensure_sqlite_dir(database_url: &str) -> Result<()> {
if let Some(path) = database_url.strip_prefix("sqlite://")
&& let Some(dir) = std::path::Path::new(path).parent()
&& !dir.as_os_str().is_empty()
{
std::fs::create_dir_all(dir)?;
}
Ok(())
}
async fn healthz() -> &'static str {
"ok"
api.serve().await
}