diff --git a/src/modules/annotations/domain/aggregates/Annotation.ts b/src/modules/annotations/domain/aggregates/Annotation.ts index 254ae060..c22d39fb 100644 --- a/src/modules/annotations/domain/aggregates/Annotation.ts +++ b/src/modules/annotations/domain/aggregates/Annotation.ts @@ -6,12 +6,11 @@ import { UpdateAnnotationErrors } from "../../application/use-cases/errors"; import { UniqueEntityID } from "src/shared/domain/UniqueEntityID"; import { Guard, IGuardArgument } from "src/shared/core/Guard"; import { - AnnotationFieldId, AnnotationFieldId, AnnotationId, AnnotationNote, AnnotationTemplateId, - CuratorId, // Import the new value object + CuratorId, PublishedRecordId, } from "../value-objects"; @@ -21,7 +20,7 @@ export type UpdateAnnotationValueResult = Either< >; export interface AnnotationProps { - curatorId: CuratorId; // Add the curator ID + curatorId: CuratorId; url: URI; annotationFieldId: AnnotationFieldId; value: AnnotationValue; @@ -81,7 +80,7 @@ export class Annotation extends AggregateRoot { id?: UniqueEntityID ): Result { const guardArgs: IGuardArgument[] = [ - { argument: props.curatorId, argumentName: "curatorId" }, // Add curatorId to guard + { argument: props.curatorId, argumentName: "curatorId" }, { argument: props.url, argumentName: "url" }, { argument: props.annotationFieldId, argumentName: "annotationFieldId" }, { argument: props.value, argumentName: "value" }, diff --git a/src/modules/annotations/domain/aggregates/AnnotationField.ts b/src/modules/annotations/domain/aggregates/AnnotationField.ts index 3fb5a617..b001fa34 100644 --- a/src/modules/annotations/domain/aggregates/AnnotationField.ts +++ b/src/modules/annotations/domain/aggregates/AnnotationField.ts @@ -6,23 +6,27 @@ import { AnnotationFieldId } from "../value-objects/AnnotationFieldId"; // Assum import { AnnotationFieldName } from "../value-objects/AnnotationFieldName"; import { AnnotationFieldDescription } from "../value-objects/AnnotationFieldDescription"; import { AnnotationFieldDefinition } from "../value-objects/AnnotationFieldDefinition"; // Renamed and refactored +import { CuratorId, PublishedRecordId } from "../value-objects"; // Properties required to construct an AnnotationField export interface AnnotationFieldProps { + curatorId: CuratorId; name: AnnotationFieldName; description: AnnotationFieldDescription; definition: AnnotationFieldDefinition; - createdAt?: Date; // Optional on creation, will default - // Add other properties like owner DID, etc. if needed + createdAt?: Date; + publishedRecordId?: PublishedRecordId; } export class AnnotationField extends AggregateRoot { - get fieldId(): AnnotationFieldId { - // Assuming AnnotationFieldId.create takes UniqueEntityID return AnnotationFieldId.create(this._id).getValue(); } + get curatorId(): CuratorId { + return this.props.curatorId; + } + get name(): AnnotationFieldName { return this.props.name; } @@ -36,10 +40,13 @@ export class AnnotationField extends AggregateRoot { } get createdAt(): Date { - // createdAt is guaranteed by the create method's default return this.props.createdAt!; } + public updatePublishedRecordId(publishedRecordId: PublishedRecordId): void { + this.props.publishedRecordId = publishedRecordId; + } + private constructor(props: AnnotationFieldProps, id?: UniqueEntityID) { super(props, id); } @@ -60,9 +67,6 @@ export class AnnotationField extends AggregateRoot { return Result.fail(guardResult.getErrorValue()); } - // Additional validation can be done here on the value objects themselves if needed, - // although their own `create` methods should handle internal consistency. - const defaultValues: AnnotationFieldProps = { ...props, createdAt: props.createdAt || new Date(), diff --git a/src/modules/annotations/domain/value-objects/FieldDefinition.ts b/src/modules/annotations/domain/value-objects/AnnotationFieldDefinition.ts similarity index 100% rename from src/modules/annotations/domain/value-objects/FieldDefinition.ts rename to src/modules/annotations/domain/value-objects/AnnotationFieldDefinition.ts diff --git a/src/modules/annotations/domain/value-objects/AnnotationFieldDescription.ts b/src/modules/annotations/domain/value-objects/AnnotationFieldDescription.ts index ebdd5fb6..4e7b8c22 100644 --- a/src/modules/annotations/domain/value-objects/AnnotationFieldDescription.ts +++ b/src/modules/annotations/domain/value-objects/AnnotationFieldDescription.ts @@ -17,16 +17,23 @@ export class AnnotationFieldDescription extends ValueObject { + public static create( + description: string + ): Result { // Description can potentially be empty, so only check length if provided const descriptionTrimmed = description?.trim(); - const guardResult = Guard.againstNullOrUndefined(descriptionTrimmed, "description"); - if (guardResult.isFailure) { - // Allow null/undefined to pass through, representing an empty description - // If description MUST exist, change this logic - return Result.ok(new AnnotationFieldDescription({ value: "" })); - } + const guardResult = Guard.againstNullOrUndefined( + descriptionTrimmed, + "description" + ); + if (guardResult.isFailure) { + // Allow null/undefined to pass through, representing an empty description + // If description MUST exist, change this logic + return Result.ok( + new AnnotationFieldDescription({ value: "" }) + ); + } if (descriptionTrimmed.length > this.MAX_LENGTH) { return Result.fail( @@ -34,6 +41,8 @@ export class AnnotationFieldDescription extends ValueObject(new AnnotationFieldDescription({ value: descriptionTrimmed })); + return Result.ok( + new AnnotationFieldDescription({ value: descriptionTrimmed }) + ); } } diff --git a/src/modules/annotations/domain/value-objects/AnnotationType.ts b/src/modules/annotations/domain/value-objects/AnnotationType.ts index c3ebc1d0..a55dc2db 100644 --- a/src/modules/annotations/domain/value-objects/AnnotationType.ts +++ b/src/modules/annotations/domain/value-objects/AnnotationType.ts @@ -4,12 +4,11 @@ interface AnnotationTypeProps { value: string; } -// Define known annotation type strings as constants -const DYAD_VALUE_TYPE = "app.annos.annotation#dyadValue"; -const TRIAD_VALUE_TYPE = "app.annos.annotation#triadValue"; -const RATING_VALUE_TYPE = "app.annos.annotation#ratingValue"; -const SINGLE_SELECT_VALUE_TYPE = "app.annos.annotation#singleSelectValue"; -const MULTI_SELECT_VALUE_TYPE = "app.annos.annotation#multiSelectValue"; +const DYAD_VALUE_TYPE = "dyad"; +const TRIAD_VALUE_TYPE = "triad"; +const RATING_VALUE_TYPE = "rating"; +const SINGLE_SELECT_VALUE_TYPE = "singleSelect"; +const MULTI_SELECT_VALUE_TYPE = "multiSelect"; const VALID_TYPES = new Set([ DYAD_VALUE_TYPE, @@ -36,10 +35,17 @@ export class AnnotationType extends ValueObject { return new AnnotationType({ value: type }); } - // Pre-create instances for known types for convenience and potential performance public static readonly DYAD = new AnnotationType({ value: DYAD_VALUE_TYPE }); - public static readonly TRIAD = new AnnotationType({ value: TRIAD_VALUE_TYPE }); - public static readonly RATING = new AnnotationType({ value: RATING_VALUE_TYPE }); - public static readonly SINGLE_SELECT = new AnnotationType({ value: SINGLE_SELECT_VALUE_TYPE }); - public static readonly MULTI_SELECT = new AnnotationType({ value: MULTI_SELECT_VALUE_TYPE }); + public static readonly TRIAD = new AnnotationType({ + value: TRIAD_VALUE_TYPE, + }); + public static readonly RATING = new AnnotationType({ + value: RATING_VALUE_TYPE, + }); + public static readonly SINGLE_SELECT = new AnnotationType({ + value: SINGLE_SELECT_VALUE_TYPE, + }); + public static readonly MULTI_SELECT = new AnnotationType({ + value: MULTI_SELECT_VALUE_TYPE, + }); } diff --git a/src/modules/annotations/domain/value-objects/AnnotationValue.ts b/src/modules/annotations/domain/value-objects/AnnotationValue.ts index 687701ed..8a5926dd 100644 --- a/src/modules/annotations/domain/value-objects/AnnotationValue.ts +++ b/src/modules/annotations/domain/value-objects/AnnotationValue.ts @@ -1,4 +1,6 @@ +import e from "express"; import { ValueObject } from "../../../../shared/domain/ValueObject"; +import { Annotation } from "../aggregates"; import { AnnotationType } from "./AnnotationType"; // Define interfaces for the props of each value object type @@ -22,7 +24,7 @@ interface IMultiSelectValueProps { // Abstract base class for all annotation values, extending the shared ValueObject export abstract class AnnotationValueBase< - T extends object + T extends object, > extends ValueObject { abstract readonly type: AnnotationType; @@ -33,7 +35,6 @@ export abstract class AnnotationValueBase< * @returns True if the types match, false otherwise. */ public isSameType(other?: AnnotationValueBase): boolean { - // Use the equals method of the AnnotationType value object return !!other && this.type.equals(other.type); } } @@ -57,8 +58,6 @@ export class DyadValue extends AnnotationValueBase { } return new DyadValue({ value }); } - - // Base ValueObject.equals should suffice as it compares props } export class TriadValue extends AnnotationValueBase { @@ -73,7 +72,6 @@ export class TriadValue extends AnnotationValueBase { get vertexC(): number { return this.props.vertexC; } - // sum is an invariant checked at creation, not stored state private constructor(props: ITriadValueProps) { super(props); @@ -92,8 +90,6 @@ export class TriadValue extends AnnotationValueBase { } return new TriadValue({ vertexA, vertexB, vertexC }); } - - // Base ValueObject.equals should suffice } export class RatingValue extends AnnotationValueBase { @@ -115,8 +111,6 @@ export class RatingValue extends AnnotationValueBase { } return new RatingValue({ rating }); } - - // Base ValueObject.equals should suffice } export class SingleSelectValue extends AnnotationValueBase { @@ -138,8 +132,6 @@ export class SingleSelectValue extends AnnotationValueBase { @@ -167,14 +159,6 @@ export class MultiSelectValue extends AnnotationValueBase; diff --git a/src/modules/annotations/domain/value-objects/CuratorId.ts b/src/modules/annotations/domain/value-objects/CuratorId.ts index 53191fd2..e26338fc 100644 --- a/src/modules/annotations/domain/value-objects/CuratorId.ts +++ b/src/modules/annotations/domain/value-objects/CuratorId.ts @@ -31,11 +31,13 @@ export class CuratorId extends ValueObject { const didTrimmed = did.trim(); if (didTrimmed.length === 0) { - return Result.fail("CuratorId cannot be empty."); + return Result.fail("CuratorId cannot be empty."); } if (!DID_REGEX.test(didTrimmed)) { - return Result.fail(`Invalid CuratorId format (must be a valid DID): ${didTrimmed}`); + return Result.fail( + `Invalid CuratorId format (must be a valid DID): ${didTrimmed}` + ); } return Result.ok(new CuratorId({ value: didTrimmed })); diff --git a/src/modules/annotations/domain/value-objects/index.ts b/src/modules/annotations/domain/value-objects/index.ts index 7b46240b..815fad8d 100644 --- a/src/modules/annotations/domain/value-objects/index.ts +++ b/src/modules/annotations/domain/value-objects/index.ts @@ -1,5 +1,5 @@ export * from "./AnnotationValue"; -export * from "./FieldDefinition"; +export * from "./AnnotationFieldDefinition"; export * from "./Identifier"; export * from "./URI"; export * from "./AnnotationFieldId"; @@ -7,3 +7,4 @@ export * from "./AnnotationTemplateId"; export * from "./AnnotationNote"; export * from "./AnnotationId"; export * from "./PublishedRecordId"; +export * from "./CuratorId"; diff --git a/src/shared/domain/ValueObject.ts b/src/shared/domain/ValueObject.ts index 259ca0ca..70a7996d 100644 --- a/src/shared/domain/ValueObject.ts +++ b/src/shared/domain/ValueObject.ts @@ -1,4 +1,3 @@ - interface ValueObjectProps { [index: string]: any; } @@ -11,15 +10,15 @@ interface ValueObjectProps { export abstract class ValueObject { public props: T; - constructor (props: T) { + constructor(props: T) { let baseProps: any = { - ...props, - } + ...props, + }; this.props = baseProps; } - public equals (vo?: ValueObject) : boolean { + public equals(vo?: ValueObject): boolean { if (vo === null || vo === undefined) { return false; } @@ -28,4 +27,4 @@ export abstract class ValueObject { } return JSON.stringify(this.props) === JSON.stringify(vo.props); } -} \ No newline at end of file +} diff --git a/src/user/domain/value-objects/DID.ts b/src/user/domain/value-objects/DID.ts index 1f7a1b8d..64d411b4 100644 --- a/src/user/domain/value-objects/DID.ts +++ b/src/user/domain/value-objects/DID.ts @@ -30,7 +30,7 @@ export class DID extends ValueObject { const didTrimmed = did.trim(); if (didTrimmed.length === 0) { - return Result.fail("DID cannot be empty."); + return Result.fail("DID cannot be empty."); } if (!DID_REGEX.test(didTrimmed)) {