Projects Design
Status: Work in progress
| Version | Date | Author | Status | Description |
|---|---|---|---|---|
| 0.1 | 2025-01-07 | isierra | WIP | Initial version |
Introduction
- Implements: Projects Functional Requirements
The Projects module belongs to the core domain of the system and is responsible for managing modules, projects, licenses, contracts, etc.
The main concepts of the Projects module are:
Design
Service Architecture
Module Design
- Implements: Module Requirements
- Pattern: Entity Event Sourcing
The Module entity represents a service or module in the system, like users, booking, maintenance, etc. Each module has a set of entities, parameters, and permissions that define the functionality of the module.
Module Value Objects
ModuleElementId
- Implements Permission hierarchy
The module element identifier is a unique key that represents a module element in the system. It is used to assign operations to roles and users, to reference dependent modules, etc.
It allows to implement the hierarchical structure of permissions, where each permission is composed of a series of elements that represent the area, module, resource, category, and operation of the permission.
The hierarchy usually should contain the following elements, but this could change depending on the complexity of each module:
| Element | Prefix | Description |
|---|---|---|
| Area | A: | The area of the application where the element belongs to |
| Module | M: | The module of the application where the element belongs to |
| Resource | R: | The resource or entity type that the element is related to |
| Operation | O: | The operation that the element allows to perform |
| Parameter | P: | The parameter that the element is related to |
The areas in the system are: core, support, business, etc.
The modules in the system are: users, projects, zones, booking, etc.
The resources or entities in the system are: module, user, role, project, zone, room, meeting, work_order, etc.
The categories of the resources only apply to some complex resources, like work_order. Some examples of sub-resources are: preventive, corrective, etc.
The operations in the system are: create, read, modify, delete, etc.
Examples of permission ids at different levels of the hierarchy are:
| Permission | ID |
|---|---|
| Facility Management | A:fm. |
| Booking Module | A:fm.M:booking. |
| Meeting Rooms | A:fm.M:booking.R:room. |
| Create Room | A:fm.M:booking.R:room.O:create. |
| Read/List Rooms | A:fm.M:booking.R:room.O:read. |
| Show Security Code | A:fm.M:booking.R:room.O:passcode. |
| Meetings | A:fm.M:booking.R:meeting. |
| Create Meeting | A:fm.M:booking.R:meeting.O:create. |
| Read/List Meetings | A:fm.M:booking.R:meeting.O:read. |
| Core | A:core. |
| Users Module | A:core.M:users. |
| User | A:core.M:users.R:user. |
| Delete User | A:core.M:users.R:user.O:delete. |
PermissionId: Type: string Constraints: MinLength: 2 MaxLength: 255 Regex: "^((?<type>[AMROP])\:(?<key>[a-z_]+)\.)*$"ModuleElementKey
- Implements Operation permissions
The operation key is a key that represents the kind of operation that a permission allows to perform, if it is an operation permission.
The operation key DOES NOT include the type or the separator, only the key.
The known operation types are:
readfor Readcreatefor Createmodifyfor Modifydeletefor Delete
Other less-known operations could be defined like approve, print, cancel, etc.
OperationKey: Type: string Constraints: MinLength: 1 MaxLength: 20 Regex: "^[a-z_]+$"Module Fields
To define the classes that define this module element hierarchy, the following classes and fields are used:
ModuleElementDefinition
The fields with their data types are described below:
| Field | Type | Constraints |
|---|---|---|
ElementId | ModuleElementId | |
ElementKey | ModuleElementKey | |
DisplayName | DisplayName | |
Description | Description? |
ModuleDefinition
The fields with their data types are described below:
| Field | Type | Constraints |
|---|---|---|
ActiveByDefault | Boolean | |
DependsOn | ModuleElementId[] | |
ProjectId | EntityId? | prefix:proj |
Versions | ModuleVersionDescription[] | |
Parameters | ModuleParameterDefinition[] | |
Resources | ModuleResourceDefinition[] |
ModuleVersionDescription
The fields with their data types are described below:
| Field | Type | Constraints |
|---|---|---|
Version | String | length:1,20 |
Changes | Description |
ModuleResourceDefinition
The fields with their data types are described below:
| Field | Type | Constraints |
|---|---|---|
Resources | ModuleResourceDefinition[] | |
Operations | ModuleOperationDefinition[] |
ModuleOperationDefinition
The fields with their data types are described below:
| Field | Type | Constraints |
|---|---|---|
Order | Integer | |
AccessTypes | ModuleAccessType[] |
ModuleParameterDefinition
The fields with their data types are described below:
| Field | Type | Constraints |
|---|---|---|
DataType | JsonSchema | |
DefaultValue | String | valid serialized json |
Module Shared Domain Models
ModuleElementDefinition: ElementId: ElementKey: DisplayName: Description:ModuleDefinition: ...ModuleElementDefinition: ActiveByDefault: bool DependsOn: ModuleElementId list ProjectId: EntityId? Versions: ModuleVersionDescription list Parameters: ModuleParameterDefinition list Resources: ModuleResourceDefinition listModuleVersionDescription: Version: string Changes: stringModuleResourceDefinition: ...ModuleElementDefinition: Resources: ModuleResourceDefinition list Operations: ModuleOperationDefinition listModuleOperationDefinition: ...ModuleElementDefinition: Order: int AccessTypes: ModuleAccessType listModuleParameterDefinition: ...ModuleElementDefinition: DataType: JsonSchema DefaultValue: stringModule Domain Events
Event ModuleWasDefined is triggered when a module is created or updated in the system. It should be a very rare event, as the module definition should be stable.
ModuleWasDefined: module: ModuleDefinitionModule Use Cases
Define Module Use Case
- Implements: Module Definition
- Permission:
Administrator - Pattern: Command Atomicity
This command overwrite the module definition in the system, independent of whether the module is already defined or not. It is used to define the modules that are available in the system. Each service should have a startup workflow that uses this operation to publish any changes to the module definitions.
ModuleCommandDefine: Module: ModuleDefinitionModuleCommandDefineSuccess: Created: bool # True if the module definition has been created. False otherwise Updated: bool # True if the module definition has been updated. False otherwiseModuleWasDefined: # when the module definition has been created or updatedList Modules Use Case
- Implements: Module List
- Permission:
Administrator - Pattern: Marten Asynchronous List Projection
- Pattern: Marten Offset Pagination
This query returns the list of modules that are defined in the system.
ModuleQueryList: Filter: SearchText: string # On Id, DisplayName, Description Id: EntityIdFilter DisplayName: StringFilter ActiveByDefault: BooleanFilter Sorting: Id: DisplayName: Paging: # See pattern for detailsModuleQueryListSuccess: ItemsPage: # List ElementId: ElementKey: DisplayName: Description: CreatedAt: ModifiedAt: # See paging pattern for detailsModuleWasDefined:Fetch Module Details Use Case
- Implements: Module Details
- Permission:
Administrator - Pattern: Marten Event Sourcing Aggregate
This query returns the details of multiple modules in the system.
ModuleQueryFetch: ModuleIds: ModuleElementId listModuleQueryFetchSuccess: Items: ModuleDefinition listCulture Design
Culture Fields
The fields with their data types are described below:
| Field | Type | Constraints |
|---|---|---|
CultureCode | String | length:1,20 |
EnglishName | DisplayName | |
NativeName | DisplayName |
Culture Events
CultureWasDefined: CultureCode: string # StreamKey EnglishName: string NativeName: stringCultureWasDeleted: CultureCode: string # StreamKeyCulture Commands
CultureCommandDefine
- Implements: Culture Definition
- Permission:
Administrator - Pattern: Command Atomicity
- Pattern: Marten Event Sourcing Aggregate
The CultureCommandDefine command is used to define a culture in the system.
CultureCommandDefine: CultureCode: string # StreamKey EnglishName: string NativeName: stringCultureCommandDefineSuccess: Updated: boolCultureWasDefined: # when the culture has been created or updatedCultureCommandDelete
- Implements: Culture Deletion
- Permission:
Administrator - Pattern: Command Atomicity
- Pattern: Marten Event Sourcing Aggregate
The CultureCommandDelete command is used to delete a culture in the system.
CultureCommandDelete: CultureCode: string # StreamKeyCultureCommandDeleteSuccess: Deleted: boolCultureWasDeleted: # when the culture has been deletedCulture Queries
CultureQueryList
- Implements: Culture List
- Permission:
Administrator - Pattern: Marten Asynchronous List Projection
- Pattern: Marten Offset Pagination
The CultureQueryList query is used to list the cultures that are defined in the system.
CultureQueryList: Filter: SearchText: string # On CultureCode, EnglishName, NativeName Sorting: CultureCode: EnglishName: NativeName:CultureQueryListSuccess: ItemsPage: # List CultureCode: EnglishName: NativeName: # See paging pattern for detailsCultureWasDefined:CultureWasDeleted:CultureQueryFetch
- Implements: Culture Details
- Permission:
Administrator - Pattern: Marten Event Sourcing Aggregate
- Pattern: Marten Event Sourcing Aggregate
Project Design
:::caution[TBD]I. Event fan out rules, even. Fan out rules even. Sign out. We leverage Alba an exit. Docker. Setup System under Test fixture. Turn your system under test. The host is boss. Connection feast. I host, I hope. I know, I know. Destiny’s that sexy? Test this 10. Oh well. :::
Module License Design
Usage License Design
Identity Provider Design
Module Definition
This is the definition of the Projects module in the system. It includes the entities, parameters, and permissions that are part of the current module. This service has to publish this information at startup to the corresponding Define Module command, using the published client for it.
- kind: Module moduleId: A:core.M:projects. displayName: Projects description: Manages projects, licenses, infrastructure, etc. activeByDefault: true
dependsOn: - A:support.M:authorization. - A:support.M:communication. - A:support.M:datacollector. - A:support.M:processes.
entities: - kind: ModuleEntity entityId: A:core.M:projects.E:module. displayName: Module description: Represents a module of functionality on the system that can be enabled or disabled for a given project. - kind: ModuleEntity entityId: A:core.M:projects.E:culture. displayName: Culture description: Represents the different cultures that can be used in the system, defining the language, the date format, and other cultural data. - kind: ModuleEntity entityId: A:core.M:projects.E:project. displayName: Project description: Represents a project, which is a set of resources that belong to a given client and they need to manage them as a cohesive unit. - kind: ModuleEntity entityId: A:core.M:projects.E:project. displayName: Project description: Represents a project, which is a set of resources that belong to a given client and they need to manage them as a cohesive unit.
parameters: - kind: ModuleParameter parameterId: mprmImportExportProject displayName: Enable Import/Export Project description: Enable the import/export functionality for projects dataType: | { type: "boolean" } defaultValue: "false"
permissions: []