Fair Supply LogoFair Supply - Docs

Engagements Domain

The Engagements domain handles ESG assessment workflows, where organisations are evaluated against compliance frameworks.

Entity Hierarchy

Key Concepts

EntityDescription
EngagementAssessment request sent to an organisation. Has respondents who answer.
FrameworkESG framework structure (e.g., Modern Slavery Act). Contains pillars.
PillarCategory within framework (e.g., Governance, Due Diligence). Contains controls.
ControlSpecific requirement to verify. Tested by one or more tests.
TestQuestion with multiple-choice options. May require evidence.
TestResponseUser's answer to a test, linking selected options.

Scoring System

Scores roll up hierarchically from individual test responses to the overall engagement score:

LevelCalculation
Test ScoreBased on selected option values
Control ScoreAverage of its test scores
Pillar ScoreAverage of its control scores
Framework ScoreAverage of its pillar scores
Engagement ScoreAverage of all framework scores

Domain services for scoring live in packages/core/src/domain/services/scoring/.

Business Rules

  1. Only invited respondents can answer tests
  2. At least one framework required per engagement
  3. Submitted responses cannot be modified (finality)
  4. Scores are only calculated after submission
  5. Engagements can have optional due dates
  6. Test options have associated score values

Common Operations

Creating an Engagement

The CreateEngagement use case demonstrates the platform's transaction support pattern. All database operations are wrapped in a single transaction to ensure atomicity.

import { CreateEngagement } from '@repo/core';

const useCase = new CreateEngagement();
const engagement = await useCase.execute({
  organisationId: 'org-123',
  frameworkIds: ['framework-1', 'framework-2'],
  respondentIds: ['user-1', 'user-2'],
  dueDate: new Date('2025-03-01'),
});

Transaction Flow:

  1. Validation phase (outside transaction - reads only)
  2. Transactional operations (all database writes within withTransaction)
  3. Side effects (emails sent after transaction commits)

Submitting a Test Response

import { SubmitTestResponse } from '@repo/core';

const useCase = new SubmitTestResponse();
await useCase.execute({
  testId: 'test-123',
  selectedOptionIds: ['option-1'],
  evidenceUrls: ['https://example.com/evidence.pdf'],
});

Transaction Support

The Engagements domain uses the platform's transaction support for atomic multi-step operations. This ensures data consistency when creating engagements with multiple respondents.

Using Transactions

import { withTransaction } from '@repo/core';
import { EngagementRepository, UserRepository } from '@repo/core';

const result = await withTransaction(async (tx) => {
  // All operations share the same transaction
  const engagement = await EngagementRepository.create({
    status: EngagementStatus.NotStarted,
    accountId,
    organisationId,
  }, { tx });

  await EngagementRepository.addRespondent({
    engagementId: engagement.id,
    userId: respondent.id,
    status: RespondentStatus.Pending,
  }, { tx });

  return engagement;
});

Transaction Guidelines

GuidelineDescription
Validation firstPerform read operations outside the transaction
Side effects lastSend emails/notifications after transaction commits
External APIsAuth0 calls cannot be rolled back - handle orphaned records if needed
DataLoadersDataLoaders participate in transactions when executionContext is provided

Error Handling

await withTransaction(async (tx) => {
  // If any operation throws, all changes roll back
  const engagement = await EngagementRepository.create(data, { tx });

  if (!engagement) {
    throw new Error('Failed to create engagement');
    // Transaction automatically rolls back
  }

  return engagement;
});
TypeLocation
GraphQL Schemapackages/core/src/infrastructure/neo4j/schemas/engagement.graphql
Repositorypackages/core/src/infrastructure/repositories/engagement-repository.ts
Use Casespackages/core/src/application/use-cases/engagement/
Scoring Servicespackages/core/src/domain/services/scoring/
Transaction Typespackages/core/src/infrastructure/graphql/transaction.ts
Transaction Utilitypackages/core/src/infrastructure/graphql/with-transaction.ts