Add pocketbase and other changes

This commit is contained in:
Andras Schmelczer 2026-02-07 19:20:22 +00:00
parent a9717d570d
commit 229150b641
14 changed files with 1178 additions and 91 deletions

View file

@ -1,3 +1,4 @@
mod auth;
mod consts;
mod data;
mod features;
@ -13,7 +14,7 @@ use std::sync::Arc;
use anyhow::{bail, Context};
use axum::middleware;
use axum::routing::get;
use axum::routing::{any, get};
use axum::Router;
use clap::Parser;
use tower_http::compression::CompressionLayer;
@ -59,6 +60,10 @@ struct Cli {
default_value = "https://narrowit.schmelczer.dev"
)]
public_url: String,
/// PocketBase server URL for authentication (e.g. http://localhost:8090)
#[arg(long, env = "POCKETBASE_URL")]
pocketbase_url: Option<String>,
}
#[tokio::main]
@ -117,8 +122,7 @@ async fn main() -> anyhow::Result<()> {
info!(pois = poi_data.lat.len(), "POI data loaded");
info!("Building POI spatial grid index");
let poi_grid =
utils::GridIndex::build(&poi_data.lat, &poi_data.lng, consts::GRID_CELL_SIZE);
let poi_grid = utils::GridIndex::build(&poi_data.lat, &poi_data.lng, consts::GRID_CELL_SIZE);
// Load postcode boundaries
let postcodes_path = &cli.postcodes;
@ -219,6 +223,12 @@ async fn main() -> anyhow::Result<()> {
postcode_data.postcodes.len(),
);
if let Some(ref pb_url) = cli.pocketbase_url {
info!("PocketBase configured: {}", pb_url);
}
let token_cache = Arc::new(auth::TokenCache::new());
let state = Arc::new(AppState {
data: property_data,
grid,
@ -235,6 +245,8 @@ async fn main() -> anyhow::Result<()> {
public_url: cli.public_url,
index_html,
http_client,
pocketbase_url: cli.pocketbase_url,
token_cache,
});
let cors = CorsLayer::new()
@ -251,7 +263,9 @@ async fn main() -> anyhow::Result<()> {
let state_hexagon_properties = state.clone();
let state_hexagon_stats = state.clone();
let state_og_image = state.clone();
let state_export = state.clone();
let state_crawler = state.clone();
let state_pb = state.clone();
let api = Router::new()
.route(
@ -291,7 +305,12 @@ async fn main() -> anyhow::Result<()> {
.route(
"/api/og-image",
get(move |query| routes::get_og_image(state_og_image.clone(), query)),
);
)
.route(
"/api/export",
get(move |query| routes::get_export(state_export.clone(), query)),
)
.route("/api/me", get(routes::get_me));
// Add tile routes
let reader_tile = tile_reader.clone();
@ -307,7 +326,14 @@ async fn main() -> anyhow::Result<()> {
routes::get_style(axum::extract::State(reader_style.clone()), headers, query)
}),
)
.route("/metrics", get(move || metrics::metrics_handler(metrics_handle.clone())));
.route(
"/metrics",
get(move || metrics::metrics_handler(metrics_handle.clone())),
)
.route(
"/pb/{*rest}",
any(move |req| routes::proxy_to_pocketbase(state_pb.clone(), req)),
);
let app = if frontend_dist.exists() {
api.fallback_service(ServeDir::new(&frontend_dist))
@ -317,11 +343,12 @@ async fn main() -> anyhow::Result<()> {
let app = app
.layer(middleware::from_fn(metrics::track_metrics))
.layer(middleware::from_fn(auth::auth_middleware))
.layer(middleware::from_fn(
move |req: axum::extract::Request, next: middleware::Next| {
let st = state_crawler.clone();
async move {
// Inject state into request extensions for the middleware
// Inject state into request extensions for auth + OG middleware
let (mut parts, body) = req.into_parts();
parts.extensions.insert(st);
let req = axum::extract::Request::from_parts(parts, body);