Skip to content

Commit

Permalink
Initial Use Case implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
mlhaufe committed Jun 15, 2024
1 parent 7b467ad commit 6a6b2cf
Show file tree
Hide file tree
Showing 6 changed files with 362 additions and 11 deletions.
4 changes: 3 additions & 1 deletion modules/environment/domain/Invariant.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import Requirement from "~/domain/Requirement";

/**
* Environment property that must be maintained
* Environment property that must be maintained.
* It exists as both an assumption and an effect.
* (precondition and postcondition)
*/
export default class Invariant extends Requirement { }
61 changes: 61 additions & 0 deletions modules/system/application/UseCaseInteractor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import Interactor from "~/application/Interactor"
import UseCase from "../domain/UseCase"
import type { Uuid } from "~/domain/Uuid"

type In = Pick<UseCase, 'id' | 'name' | 'primaryActorId' | 'parentId' | 'extensions' | 'goalInContext' | 'level' | 'mainSuccessScenario' | 'preCondition' | 'scope' | 'stakeHoldersAndInterests' | 'successGuarantee' | 'trigger' | 'solutionId'>

export default class UseCaseInteractor extends Interactor<UseCase> {
async create(
props: Omit<In, 'id'>
): Promise<Uuid> {
return await this.repository.add(new UseCase({
id: crypto.randomUUID(),
extensions: props.extensions,
goalInContext: props.goalInContext,
level: props.level,
mainSuccessScenario: props.mainSuccessScenario,
name: props.name,
parentId: props.parentId,
preCondition: props.preCondition,
primaryActorId: props.primaryActorId,
property: '',
scope: props.scope,
solutionId: props.solutionId,
stakeHoldersAndInterests: props.stakeHoldersAndInterests,
successGuarantee: props.successGuarantee,
statement: '',
trigger: props.trigger
}))
}

async delete(id: Uuid): Promise<void> {
await this.repository.delete(id)
}

async getAll(solutionId: Uuid): Promise<UseCase[]> {
return await this.repository.getAll(
useCase => useCase.solutionId === solutionId
)
}

async update(props: In): Promise<void> {
await this.repository.update(new UseCase({
id: props.id,
extensions: props.extensions,
goalInContext: props.goalInContext,
level: props.level,
mainSuccessScenario: props.mainSuccessScenario,
name: props.name,
parentId: props.parentId,
preCondition: props.preCondition,
primaryActorId: props.primaryActorId,
property: '',
scope: props.scope,
solutionId: props.solutionId,
stakeHoldersAndInterests: props.stakeHoldersAndInterests,
successGuarantee: props.successGuarantee,
statement: '',
trigger: props.trigger
}))
}
}
5 changes: 5 additions & 0 deletions modules/system/domain/TestCase.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
import Example from "./Example";

/**
* A TestCase is a specification of the inputs, execution conditions,
* testing procedure, and expected results that define a single test to
* be executed to achieve a particular goal.,
*/
export default class TestCase extends Example { }
68 changes: 67 additions & 1 deletion modules/system/domain/UseCase.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,73 @@
import Scenario from "./Scenario";
import type { Uuid } from "~/domain/Uuid";
import type { Properties } from "~/domain/Properties";

/**
* A Use Case specifies the scenario of a complete
* interaction of a user through a system.
*/
export default class UseCase extends Scenario { }
export default class UseCase extends Scenario {
/**
* TODO: <https://github.com/final-hill/cathedral/issues/154>
*/
scope: string

/**
* TODO: <https://github.com/final-hill/cathedral/issues/154>
*/
level: string

/**
* TODO: is this just the Goal.description?
*/
goalInContext: string

/**
* The preCondition is an Assumption that must be true before the use case can start.
*/
preCondition: Uuid

// the action upon the system that starts the use case
// A Responsibility? Functional Requirement?
trigger: Uuid

/**
* The main success scenario is the most common path through the system.
* It takes the form of a sequence of steps that describe the interaction:
* 1. The use case starts when <Actor> <does something>.
* 2. The system <does something in response>.
* 3. The <Actor name> does something else.
* ...
*/
//mainSuccessScenario: [FunctionalRequirement | Constraint | Role | Responsibility][]
mainSuccessScenario: string

/**
* An Effect that is guaranteed to be true after the use case is completed.
*/
successGuarantee: Uuid

/**
*
*/
// extensions: [FunctionalRequirement | Constraint | Role | Responsibility][]
extensions: string

/**
*
*/
stakeHoldersAndInterests: Uuid[] // Actor[]

constructor(props: Properties<UseCase>) {
super(props)
this.scope = props.scope
this.level = props.level
this.goalInContext = props.goalInContext
this.preCondition = props.preCondition
this.trigger = props.trigger
this.mainSuccessScenario = props.mainSuccessScenario
this.successGuarantee = props.successGuarantee
this.extensions = props.extensions
this.stakeHoldersAndInterests = props.stakeHoldersAndInterests
}
}
24 changes: 22 additions & 2 deletions modules/system/mappers/UseCaseToJsonMapper.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
import ScenarioToJsonMapper, { type ScenarioJson } from "./ScenarioToJsonMapper";
import UseCase from "../domain/UseCase";
import type { Uuid } from "~/domain/Uuid";

export interface UseCaseJson extends ScenarioJson { }
export interface UseCaseJson extends ScenarioJson {
scope: string
level: string
goalInContext: string
preCondition: Uuid
trigger: Uuid
mainSuccessScenario: string
successGuarantee: Uuid
extensions: string
stakeHoldersAndInterests: Uuid[]
}

export default class UseCaseToJsonMapper extends ScenarioToJsonMapper {
override mapFrom(target: UseCaseJson): UseCase {
Expand All @@ -10,7 +21,16 @@ export default class UseCaseToJsonMapper extends ScenarioToJsonMapper {

override mapTo(source: UseCase): UseCaseJson {
return {
...super.mapTo(source)
...super.mapTo(source),
scope: source.scope,
level: source.level,
goalInContext: source.goalInContext,
preCondition: source.preCondition,
trigger: source.trigger,
mainSuccessScenario: source.mainSuccessScenario,
successGuarantee: source.successGuarantee,
extensions: source.extensions,
stakeHoldersAndInterests: source.stakeHoldersAndInterests
};
}
}
Loading

0 comments on commit 6a6b2cf

Please sign in to comment.