Skip to main content

platform_module/
lib.rs

1//! Module framework contracts: the data/behavior split a module exposes to the
2//! composition root.
3//!
4//! - [`ModuleManifest`]: serializable data (name, story display, reserved
5//!   seams). Produced by every loading source.
6//! - [`ModuleBinding`]: behavior (register functions/event handlers). One impl
7//!   per loading source; [`LinkedBinding`] is the compile-time one.
8//! - [`Module`]: a loaded module bundling manifest + binding + internal config.
9//! - [`AdminDataSource`]: the schema-admin read seam — a module's read access
10//!   to its admin entities. [`AdminSchema`] is the declared admin surface data.
11//! - [`AdminActionSource`]: executable behavior for manifest-declared admin
12//!   actions.
13//! - [`AdminQuerySource`]: read-only behavior for manifest-declared admin
14//!   queries.
15
16mod admin_data;
17mod binding;
18mod host;
19mod linked;
20mod module;
21
22pub use admin_data::{
23    AdminActionSource, AdminDataSource, AdminListQuery, AdminPage, AdminQuerySource,
24};
25pub use binding::{EventHandlerRegistrationContext, EventHandlerRuntimeContext, ModuleBinding};
26pub use host::{HostContribution, HostLinkedModule};
27pub use lenso_contracts::{
28    AdminAction, AdminActionConfirmation, AdminActionDangerLevel, AdminActionInputField,
29    AdminActionInputSchema, AdminDeclarativeComponent, AdminDeclarativePage,
30    AdminDeclarativeSection, AdminDeclarativeSurface, AdminEmbeddedEntry, AdminEmbeddedRuntime,
31    AdminEmbeddedSurface, AdminMetricBinding, AdminPermission, AdminSandboxPolicy, AdminSchema,
32    AdminSurface, ConsoleActionInputBinding, ConsoleActionInputValue, ConsoleArea,
33    ConsoleContribution, ConsoleContributionAction, ConsoleContributionKind, ConsoleNavigation,
34    ConsoleNavigationGroup, ConsolePackage, ConsoleSlot, ConsoleSlotContext,
35    ConsoleSlotContextField, ConsoleSlotContextFieldType, ConsoleSurface, ConsoleWorkspaceRef,
36    CronParseError, CronSchedule, EntitySchema, EventHandlerDeclaration, EventSurface, FieldSchema,
37    FieldType, LifecycleActivationJobDeclaration, LifecycleActivationRunPolicy,
38    LifecycleStartupCheckDeclaration, LifecycleStartupCheckKind, LifecycleSurface,
39    ModuleCapabilityReference, ModuleHttpMethod, ModuleHttpRoute, ModuleManifest,
40    ModuleManifestBuilder, ModuleManifestLint, ModuleManifestLintSeverity, ModuleRouteLint,
41    ModuleRouteLintSeverity, ModuleSource, RuntimeFunctionDeclaration,
42    RuntimeRetryPolicyDeclaration, RuntimeSurface, StoryDisplayDescriptor, StoryDisplaySource,
43    lint_module_http_routes, lint_module_manifest, lint_module_manifest_parts,
44    module_capability_references, validate_cron_expression,
45};
46pub use linked::{
47    LinkedBinding, LinkedBindingBuilder, LinkedHttpContribution, LinkedHttpRouteMerger,
48};
49pub use module::{Module, ModuleLoadStatus};
50
51#[cfg(test)]
52mod tests {
53    use super::*;
54    use platform_core::{AppContext, Migration};
55
56    #[derive(Debug, Clone, PartialEq, Eq)]
57    struct TestContribution(&'static str);
58
59    const TEST_MIGRATIONS: &[Migration] = &[Migration {
60        name: "test/0001_init",
61        sql: "select 1;",
62    }];
63
64    fn manifest() -> ModuleManifest {
65        ModuleManifest::builder("test").build()
66    }
67
68    fn module(_ctx: &AppContext) -> Module {
69        Module::linked(manifest(), LinkedBinding::builder().build())
70    }
71
72    #[test]
73    fn host_linked_module_keeps_typed_contributions() {
74        let linked_module = HostLinkedModule::linked("test", manifest, module, TEST_MIGRATIONS)
75            .with_contribution(TestContribution("wired"));
76
77        let contributions = linked_module
78            .contributions::<TestContribution>()
79            .collect::<Vec<_>>();
80
81        assert_eq!(contributions, vec![&TestContribution("wired")]);
82    }
83}