Policy

The policy acts as intermediary between Event and Command. Similar to the Command API, which handles a client request and convert it into a Command, the Policy handels an Event and converts it into a Command. This process enables a system to react to events automatically and remain responsive and consistent across different services.

Plan Policy

Add the Source Event

1
Select Command Policy (CP) use case
  • Click the Command Policy (CP) use case on the Plan.
2
Open the use case menu
  • Click the use case menu icon on left side.
3
Select the source event
  • Select a source event and press the add button.
Take care to add the event of the right aggregate. Other aggregates can have Events with the same name.
Take care to add the event of the right bounded context. You can add Events from all bounded contexts you have access to.

The Command Policy has a Source Event

Connect Source Event

1
Select Command Policy (CP) use case
  • Click the Command Policy (CP) use case on the Plan.
2
Open the use case menu
  • Click the 'copy to command' button.
You need to set the Value Objects the Command properties

The Source Event is connected to the Command

Implement Policy

Policy Class

The CloseTaskPolicy class illustrates how to implement a policy within the Typebricks framework. It listens for specific events, processes them, and triggers the corresponding commands. It can be found under: Task/src/useCases/write/CloseTask/application/CloseTaskPolicy.ts

1import { Policy, ProcessMethods, OverwriteProtectionBody } from "@codebricks/typebricks";
2import { CloseTaskCommand } from "./CloseTaskCommand";
3import { CloseTaskCommandHandler } from "./CloseTaskCommandHandler";
4import { CloseTaskPolicyRepository } from "../infrastructure/CloseTaskPolicyRepository";
5import { UserDeletedEventMessage } from "shared/application/inboundEvents/UserDeletedEventMessage";
6import { AssigneeIdValueObject } from "shared/domain/valueObjects/AssigneeIdValueObject";
7
8export class CloseTaskPolicy extends Policy {
9 readonly useCaseName: string = 'CloseTask';
10 readonly processMethods: ProcessMethods = {
11 'Taskbricks.User.UserDeleted': this.processTaskbricksUserUserDeleted.bind(this)
12 };
13 readonly streamNames: string[] = ['Taskbricks.User'];
14
15 constructor(readonly commandHandler: CloseTaskCommandHandler = new CloseTaskCommandHandler(), readonly repository: CloseTaskPolicyRepository = new CloseTaskPolicyRepository()) {
16 super(repository);
17 }
18
19 @OverwriteProtectionBody(false)
20 async processTaskbricksUserUserDeleted(eventMessage: UserDeletedEventMessage): Promise<void> {
21 try {
22 const command: CloseTaskCommand = new CloseTaskCommand({
23 assigneeId: new AssigneeIdValueObject(eventMessage.aggregateId),
24 });
25 await this.commandHandler.handleCloseTask(command);
26 } catch (error) {
27 console.log(error);
28 }
29 }
30}
  • useCaseName and streamNames Properties: These properties help identify the events that the policy listens for.
  • processMethods Property: Maps events to their respective processing methods.
  • Process Methods: Methods like processTaskbricksUserUserDeleted handle specific events and generate commands based on the event data.

Best Practices

  • Error Handling: Implement robust error handling to avoid silent failures in policy processing.

    By default, all errors are caught and logged to ensure the processing of subsequent events continues. If you wish to stop processing upon encountering an error, modify the catch clause to handle that scenario.


© 2024 Codebricks | All rights reserved.