Skip to content

Commit f8775da

Browse files
docs: reorganize decisions for better logical order, add intro to each section
1 parent 795caa4 commit f8775da

2 files changed

Lines changed: 92 additions & 11 deletions

File tree

447 KB
Loading

docs/decisions/0003-runtime-architecture.rst

Lines changed: 92 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,36 +9,57 @@ Status
99
Context
1010
*******
1111

12-
The :doc:`0002-user-groups-model-foundations` introduced a unified model for user grouping based on configurable, pluggable criteria. The foundational model defines the data structure, scope constraints, and the decision to use registry-based criterion types that can be dynamically evaluated against user data.
12+
The :doc:`0002-user-groups-model-foundations` introduced a unified model for user groups based on configurable, pluggable criteria. The foundational model defines the data structure, scope constraints, and the decision to use registry-based criterion types that can be dynamically evaluated against user data.
1313

1414
To make this foundation functional, we need a runtime architecture that enables dynamic evaluation, plugin discovery, and backend integration for data retrieval. This ADR defines how the pluggable criterion system works in practice, ensuring a flexible, scalable, and extensible runtime system that supports new criteria types, reusable data access patterns, and consistent evaluation performance.
1515

1616
The chosen approach prioritizes extensibility and operational efficiency through runtime registration while accepting increased runtime overhead as a necessary trade-off for long-term maintainability and plugin ecosystem support.
1717

18-
Key Concepts
19-
============
18+
Architectural Overview
19+
======================
2020

21-
Visit :doc:`0002-user-groups-model-foundations` for the foundational model details.
21+
The runtime architecture orchestrates four main components to transform static group definitions into dynamic user membership:
2222

23-
The runtime architecture builds upon the foundational model and introduces several key components:
23+
**High-Level Flow:**
2424

25-
* **Criterion Type Class**: A pluggable Python class implementing evaluation and validation logic for a specific rule type defined in the user groups model. Each criterion type is registered in a centralized registry for runtime resolution.
26-
* **Criteria Registry (Manager)**: A centralized runtime registry for resolving available criterion types by their string identifiers.
27-
* **Evaluation Engine**: A core component responsible for computing a group's dynamic membership by orchestrating criterion evaluation.
28-
* **Backend Clients**: Abstraction layer for data sources (e.g., MySQL via Django ORM, Superset API) that provide reusable data access methods.
25+
.. figure:: ../_images/runtime-architecture-flow.png
26+
:alt: User Groups Runtime Architecture Flow
27+
:align: center
28+
:width: 100%
29+
30+
Complete runtime flow showing the interaction between pluggable criteria, backend data retrieval, evaluation engine, and user group service. This example demonstrates creating a group for "students who have not logged in for more than 10 days AND have less than 40% course progress."
31+
32+
**Component Interaction:**
33+
34+
1. **Plugin Discovery**: The Criteria Registry loads and validates all available criterion types at startup, making them available for group configuration.
35+
36+
2. **Group Configuration**: When creating a group, the system validates that specified criterion types exist in the registry and are compatible with the group's scope.
37+
38+
3. **Dynamic Evaluation**: The Evaluation Engine orchestrates membership computation by:
39+
40+
* Loading criterion instances from the registry
41+
* Using Backend Clients to access required data (users, enrollments, etc.)
42+
* Combining individual criterion results using boolean logic
43+
* Updating the membership storage
44+
45+
4. **Data Abstraction**: Backend Clients provide a unified interface to different data sources, allowing criteria to focus on business logic rather than data access details.
46+
47+
This architecture enables the system to scale from simple manual groups to complex dynamic segmentation while maintaining consistent interfaces and extensibility points.
2948

3049
Decision
3150
********
3251

3352
I. Extensible Parts of the Model
3453
=================================
3554

55+
This section establishes the foundation for extensibility by defining how new data sources and criterion types can be added to the system without modifying core. The key insight is separating data access concerns from business logic through backend abstraction.
56+
3657
Define extensible data sources and criteria types
3758
-------------------------------------------------
3859

3960
To enable extensibility without modifying core platform code, we will support two main extension points:
4061

41-
* **Data Sources**: Developers will be able to connect new data sources by providing backend clients and registering them through a standard entry point. The system will provide reusable tools (e.g., query helpers) to make it easier to get the needed data.
62+
* **Data Sources**: Developers will be able to connect new data sources by providing backend clients and registering them through configurations. The system will provide reusable tools (e.g., query helpers) to make it easier to get the needed data.
4263
* **Criteria Types**: Developers will be able to define new ways of selecting users (e.g., "Visited unit X") along with the logic and fields needed to evaluate them, following the Registry-Based Criteria Subtypes approach from :doc:`ADR 0002 <0002-user-groups-model-foundations>`.
4364

4465
Adopt backend-managed data access with scope-aware abstraction
@@ -63,12 +84,14 @@ To support extensibility of data sources, we will:
6384

6485
* Allow registration of new backend clients through Django configuration settings, enabling developers to define their own backend clients that inherit from the base ``BackendClient`` class.
6586
* Support configuration of multiple backends for different data sources, with each backend registered and discoverable through Django's configuration system.
66-
* Enable the same base backend type to be configured differently for different deployment environments or data source variations.
87+
* Enable the same base backend type to be configured differently for different deployment environments.
6788
* Provide a registry mechanism that allows the evaluation engine to discover and select appropriate backends based on criterion type requirements.
6889

6990
II. Criteria Template Classes and Base Framework
7091
================================================
7192

93+
This section defines how criterion type templates from :doc:`0002-user-groups-model-foundations` become functional criteria types. The focus is on creating a consistent interface that enables validation, configuration, and evaluation while maintaining flexibility for diverse criterion types.
94+
7295
Adopt runtime framework approach for criterion type templates
7396
-------------------------------------------------------------
7497

@@ -93,9 +116,41 @@ To ensure configuration correctness and provide structured validation, we will:
93116
* Allow configuration validation to fail gracefully with clear error messages for invalid configurations.
94117
* Allow developers to define configuration fields for the criterion in the criterion type Python class itself.
95118

119+
Delegate all criteria-specific logic to the criterion type class
120+
----------------------------------------------------------------
121+
122+
To implement the schema-light database design established in ADR 0002 while ensuring complete encapsulation of criterion behavior, we will:
123+
124+
* Delegate all criteria-specific logic to the criterion type class, making it responsible for:
125+
126+
* **Configuration validation**: Define accepted operators (e.g., >, !=, in) and expected configuration schema (e.g., integer days, list of strings)
127+
* **Data access**: Handle retrieval of user data needed for evaluation
128+
* **Evaluation logic**: Implement the core logic that determines which users match the criterion
129+
* **Schema definition**: Expose machine-readable configuration requirements for UI generation
130+
* **Error handling**: Provide clear error messages for invalid configurations
131+
132+
* Keep the model schema minimal and extensible by not enforcing structure or constraints on the config field at the database level.
133+
* Execute validation when groups are created or updated, ensuring criterion configurations are validated before being saved to the database.
134+
* Enable extension without schema migrations by shifting all enforcement to the type layer.
135+
* Ensure consistent behavior across all criterion types by requiring each type class to implement the complete interface.
136+
96137
III. Runtime Registry System
97138
============================
98139

140+
This section establishes how the system discovers and manages available criterion types at runtime. The registry serves as the central authority for criterion types, enabling dynamic loading, conflict detection, and plugin ecosystem support.
141+
142+
Implement registry-based criterion types with runtime resolution
143+
---------------------------------------------------------------
144+
145+
To provide runtime implementation of the string-based criterion type storage established in ADR 0002, we will:
146+
147+
* Load criterion type classes at application startup through a plugin discovery mechanism and register them in a centralized registry.
148+
* Map criterion type string identifiers (stored in the database) to their corresponding Python classes at runtime.
149+
* Encapsulate evaluation logic, schema validation, supported operators, and configuration handling within each criterion type class.
150+
* Enable dynamic binding of behavior without requiring schema changes or migrations when new criterion types are added.
151+
* Support plugin-based development workflows where third-party packages can register new criterion types through entry points.
152+
* Implement graceful fallback when criterion type classes are missing or unregistered to preserve application stability.
153+
99154
Adopt centralized criteria registry for runtime resolution
100155
----------------------------------------------------------
101156

@@ -139,6 +194,8 @@ To manage criterion type registration and detect conflicts systematically, we wi
139194
IV. Evaluation Engine and Membership Computation
140195
================================================
141196

197+
This section defines the core runtime component that transforms group criteria into actual user membership. The evaluation engine orchestrates the entire process from criterion loading to membership storage, supporting both simple AND logic and complex boolean expressions.
198+
142199
Introduce an evaluation engine to resolve dynamic group membership
143200
------------------------------------------------------------------
144201

@@ -161,9 +218,33 @@ To support complex boolean expressions in group membership rules as defined in t
161218
* Optimize the combination of criteria using query planning mechanisms, allowing for efficient execution of AND/OR combinations.
162219
* Allow backend clients to share query logic across criteria types to minimize duplicate database operations.
163220

221+
Evaluate dynamic groups through criterion-based computation
222+
-----------------------------------------------------------
223+
224+
To implement the materialized membership storage established in ADR 0002, we will:
225+
226+
* Treat dynamic group membership as derived data, computed by evaluating the group's criteria against the available user data.
227+
* Store the evaluation result in the ``UserGroupMembership`` table, replacing any previous members for that group.
228+
* Evaluate dynamic groups periodically or on demand to keep their membership current with changing user attributes and behaviors.
229+
* Use the same membership storage model for both manual and dynamic groups to ensure consistent downstream access patterns.
230+
* Coordinate with the backend client system to efficiently retrieve user data for evaluation.
231+
232+
Provide unified evaluation interface for all group types
233+
--------------------------------------------------------
234+
235+
To implement the unified group type approach established in ADR 0002, we will:
236+
237+
* Design all group types to use the same evaluation interface, whether they are manual or dynamic.
238+
* Implement manual groups through a special criterion type that handles explicit user assignment.
239+
* Enable consistent access patterns across all group types by using the same ``UserGroupMembership`` table and evaluation workflow.
240+
* Ensure the evaluation engine can process any group type without requiring special handling based on the group's population method.
241+
* Support the derived group type classification by determining type based on the configured criterion types.
242+
164243
V. Orchestration Layer and Integration
165244
======================================
166245

246+
This section defines how all the runtime components work together through high-level orchestration functions. It establishes clean separation between business logic and data models while enabling dynamic UI generation and flexible group management workflows.
247+
167248
Use orchestrator functions for group operations management
168249
----------------------------------------------------------
169250

0 commit comments

Comments
 (0)