use async_graphql::dynamic::Schema as DynamicSchema; use async_graphql::EmptySubscription; use async_graphql_axum::{GraphQLRequest, GraphQLResponse}; use axum::{ extract::State, response::IntoResponse, routing::{get, post}, Router, }; use sea_orm::DatabaseConnection; use std::sync::Arc; use crate::admin_mutations::{AdminMutation, AdminQuery}; use crate::entities; /// Initialize the Seaography admin GraphQL schema with all entities pub fn build_seaography_schema(db: DatabaseConnection) -> DynamicSchema { use seaography::{Builder, BuilderContext}; // Create a static BuilderContext for Seaography let context: &'static BuilderContext = Box::leak(Box::new(BuilderContext::default())); let mut builder = Builder::new(context, db.clone()); // Register all entities builder.register_entity::(vec![]); builder.register_entity::(vec![]); builder.register_entity::(vec![]); builder.register_entity::(vec![]); builder.register_entity::(vec![]); builder.register_entity::(vec![]); builder.register_entity::(vec![]); builder.register_entity::(vec![]); // Build and return the schema builder.schema_builder().finish().unwrap() } /// Build custom job management GraphQL schema pub fn build_jobs_schema( db: DatabaseConnection, ) -> async_graphql::Schema { async_graphql::Schema::build(AdminQuery, AdminMutation, EmptySubscription) .data(Arc::new(db)) .finish() } #[derive(Clone)] pub struct SeaographyState { pub schema: DynamicSchema, } #[derive(Clone)] pub struct JobsState { pub schema: async_graphql::Schema, } /// Seaography GraphQL POST handler for entity CRUD async fn seaography_handler( State(state): State>, req: GraphQLRequest, ) -> GraphQLResponse { state.schema.execute(req.into_inner()).await.into() } /// Jobs GraphQL POST handler for job management async fn jobs_handler( State(state): State>, req: GraphQLRequest, ) -> GraphQLResponse { state.schema.execute(req.into_inner()).await.into() } /// Seaography GraphQL playground (GraphiQL) handler async fn seaography_playground() -> impl IntoResponse { axum::response::Html( async_graphql::http::GraphiQLSource::build() .endpoint("/admin/graphql") .finish(), ) } /// Jobs GraphQL playground (GraphiQL) handler async fn jobs_playground() -> impl IntoResponse { axum::response::Html( async_graphql::http::GraphiQLSource::build() .endpoint("/admin/jobs") .finish(), ) } /// Create the admin API router with both Seaography and custom job endpoints pub fn router( seaography_schema: DynamicSchema, jobs_schema: async_graphql::Schema, ) -> Router { let seaography_state = Arc::new(SeaographyState { schema: seaography_schema, }); let jobs_state = Arc::new(JobsState { schema: jobs_schema, }); Router::new() // Seaography entity CRUD .route("/admin/graphql", post(seaography_handler)) .route("/admin/playground", get(seaography_playground)) .with_state(seaography_state) // Custom job management .route("/admin/jobs", post(jobs_handler)) .route("/admin/jobs/playground", get(jobs_playground)) .with_state(jobs_state) }