feat(infra): add ServerState, MongoDB, auth middleware, and DaisyUI theme toggle
All checks were successful
CI / Clippy (pull_request) Successful in 2m21s
CI / Security Audit (pull_request) Has been skipped
CI / Tests (pull_request) Has been skipped
CI / Deploy (push) Has been skipped
CI / Deploy (pull_request) Has been skipped
CI / Format (push) Successful in 3s
CI / Clippy (push) Successful in 2m22s
CI / Security Audit (push) Has been skipped
CI / Tests (push) Has been skipped
CI / Format (pull_request) Successful in 2s

Introduce centralized ServerState (Arc-wrapped, Box::leaked configs) loaded
once at startup, replacing per-request dotenvy/env::var calls across all
server functions. Add MongoDB Database wrapper with connection pooling.
Add tower middleware that gates all /api/ server function endpoints behind
session authentication (401 for unauthenticated callers, except check-auth).
Fix DaisyUI theme toggle to use certifai-dark/certifai-light theme names
and replace hardcoded hex colors in main.css with CSS variables.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Sharang Parnerkar
2026-02-20 15:35:59 +01:00
parent 5ce600e32b
commit e130969cd9
22 changed files with 1263 additions and 436 deletions

View File

@@ -112,11 +112,11 @@ mod inner {
/// Returns `ServerFnError` if the SearXNG request fails or response parsing fails
#[post("/api/search")]
pub async fn search_topic(query: String) -> Result<Vec<NewsCard>, ServerFnError> {
dotenvy::dotenv().ok();
use inner::{extract_source, rank_and_deduplicate, SearxngResponse};
let searxng_url =
std::env::var("SEARXNG_URL").unwrap_or_else(|_| "http://localhost:8888".into());
let state: crate::infrastructure::ServerState =
dioxus_fullstack::FullstackContext::extract().await?;
let searxng_url = state.services.searxng_url.clone();
// Enrich the query with "latest news" context for better results,
// similar to how Perplexity reformulates queries before searching.
@@ -198,12 +198,12 @@ pub async fn search_topic(query: String) -> Result<Vec<NewsCard>, ServerFnError>
/// Returns `ServerFnError` if the SearXNG search request fails
#[get("/api/trending")]
pub async fn get_trending_topics() -> Result<Vec<String>, ServerFnError> {
dotenvy::dotenv().ok();
use inner::SearxngResponse;
use std::collections::HashMap;
let searxng_url =
std::env::var("SEARXNG_URL").unwrap_or_else(|_| "http://localhost:8888".into());
let state: crate::infrastructure::ServerState =
dioxus_fullstack::FullstackContext::extract().await?;
let searxng_url = state.services.searxng_url.clone();
// Use POST to match SearXNG's default `method: "POST"` setting
let search_url = format!("{searxng_url}/search");