platform_module/admin_data.rs
1//! Schema-admin behavior seams: a module's read access to its admin entities
2//! and host-owned invocation of declared admin actions.
3
4use async_trait::async_trait;
5use platform_core::AppResult;
6use serde_json::Value;
7
8/// A module's read access to its admin entities. Optional capability — only
9/// modules with an admin surface implement it. Records cross as `Value` (the
10/// only shape a generic renderer handles); strong types stay inside the impl.
11#[async_trait]
12pub trait AdminDataSource: std::fmt::Debug + Send + Sync {
13 /// List records for `entity`, paginated. Returns a page of JSON objects.
14 async fn list(&self, entity: &str, query: &AdminListQuery) -> AppResult<AdminPage>;
15
16 /// Fetch one record by id. `Ok(None)` if not found.
17 async fn get(&self, entity: &str, id: &str) -> AppResult<Option<Value>>;
18}
19
20/// A module's executable admin actions. Action declarations stay in
21/// [`crate::AdminSurface`]; this seam only carries the behavior that varies by
22/// loading source.
23#[async_trait]
24pub trait AdminActionSource: std::fmt::Debug + Send + Sync {
25 /// Invoke a manifest-declared action by name with arbitrary JSON input.
26 async fn invoke(&self, action: &str, input: Value) -> AppResult<Value>;
27}
28
29/// A module's read-only declarative query source. Query declarations stay in
30/// [`crate::AdminSurface`]; this seam only returns the JSON value to render.
31#[async_trait]
32pub trait AdminQuerySource: std::fmt::Debug + Send + Sync {
33 /// Execute a manifest-declared query by name.
34 async fn query(&self, query: &str) -> AppResult<Value>;
35}
36
37/// Structured query — fields reserved for future filter/sort without changing
38/// the method signature.
39#[derive(Debug, Clone)]
40#[non_exhaustive]
41pub struct AdminListQuery {
42 pub limit: i64,
43 /// Opaque pagination cursor (NOT a timestamp — no entity-shape assumption).
44 pub cursor: Option<String>,
45}
46
47/// One page of records.
48#[derive(Debug, Clone)]
49pub struct AdminPage {
50 pub records: Vec<Value>,
51 /// Opaque cursor for the next page; `None` at the end.
52 pub next_cursor: Option<String>,
53}
54
55impl AdminListQuery {
56 /// Convenience constructor.
57 #[must_use]
58 pub fn new(limit: i64, cursor: Option<String>) -> Self {
59 Self { limit, cursor }
60 }
61}