slave 0.13.1

CLI for slave, a Laravel-inspired Rust framework for MCP-first apps: scaffold an MCP backend with auth, roles, teams and SurrealDB migrations, add server-rendered web apps, and route them by domain or path
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};

use crate::modules::app::services::app_service::OwnedApp;
use crate::modules::team::Access;

/// Arguments of `app_access`.
#[derive(Debug, Deserialize, JsonSchema)]
pub struct AppRequest {
    /// The app's folder name, e.g. `admin`.
    pub app: String,
}

/// Arguments of `app_assign`.
#[derive(Debug, Deserialize, JsonSchema)]
pub struct AssignAppRequest {
    pub app: String,
    /// The new owner team; omit (or null) to take the app back.
    pub team_id: Option<i64>,
}

#[derive(Debug, Serialize, JsonSchema)]
pub struct OwnerTeam {
    pub id: i64,
    pub name: String,
    pub slug: String,
}

#[derive(Debug, Serialize, JsonSchema)]
pub struct AppResponse {
    pub name: String,
    /// `None` until a super admin assigns a team.
    pub owner: Option<OwnerTeam>,
}

#[derive(Debug, Serialize, JsonSchema)]
pub struct AppListResponse {
    pub apps: Vec<AppResponse>,
}

/// What the caller may do in an app.
#[derive(Debug, Serialize, JsonSchema)]
pub struct AppAccessResponse {
    pub app: AppResponse,
    /// The caller's role in the owner team: `owner`, `admin`, `staff` or
    /// `super_admin`.
    pub role: String,
    /// Modules the caller may use.
    pub modules: Vec<String>,
}

impl From<OwnedApp> for AppResponse {
    fn from(owned: OwnedApp) -> Self {
        Self {
            name: owned.app.name,
            owner: owned.team.map(|team| OwnerTeam {
                id: team.id,
                name: team.name,
                slug: team.slug,
            }),
        }
    }
}

impl From<(OwnedApp, Access)> for AppAccessResponse {
    fn from((owned, access): (OwnedApp, Access)) -> Self {
        Self {
            app: owned.into(),
            role: access.role,
            modules: access.modules,
        }
    }
}