Skip to content

Commit

Permalink
Remove template from relationship (#301)
Browse files Browse the repository at this point in the history
* refactor: remove template from relationship in transport

* refactor: remove template from relationship in runtime logic

* fix: update more tests

* fix: revocation test

* fix: query relationships

* fix: remove strange check

* fix: template usage

* fix: remove ignore

---------

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
  • Loading branch information
jkoenig134 and mergify[bot] authored Mar 5, 2025
1 parent 01ada4e commit 6cabc83
Show file tree
Hide file tree
Showing 20 changed files with 62 additions and 97 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export class TestObjectFactory {
newStatus: RelationshipStatus.Pending
}
],
template: this.createIncomingRelationshipTemplate()
templateId: { id: "b9uMR7u7lsKLzRfVJNYb" }
})
});
}
Expand Down Expand Up @@ -110,7 +110,7 @@ export class TestObjectFactory {
newStatus: RelationshipStatus.Active
}
],
template: this.createIncomingRelationshipTemplate()
templateId: { id: "b9uMR7u7lsKLzRfVJNYb" }
})
});
}
Expand Down Expand Up @@ -161,7 +161,7 @@ export class TestObjectFactory {
newStatus: RelationshipStatus.Terminated
}
],
template: this.createIncomingRelationshipTemplate()
templateId: { id: "b9uMR7u7lsKLzRfVJNYb" }
})
});
}
Expand Down Expand Up @@ -209,7 +209,7 @@ export class TestObjectFactory {
newStatus: RelationshipStatus.Active
}
],
template: this.createIncomingRelationshipTemplate()
templateId: CoreId.from("aTemplateId")
})
});
}
Expand Down Expand Up @@ -266,7 +266,7 @@ export class TestObjectFactory {
newStatus: RelationshipStatus.DeletionProposed
}
],
template: this.createIncomingRelationshipTemplate()
templateId: CoreId.from("aTemplateId")
})
});
}
Expand Down Expand Up @@ -326,7 +326,7 @@ export class TestObjectFactory {
newStatus: RelationshipStatus.DeletionProposed
}
],
template: this.createIncomingRelationshipTemplate()
templateId: { id: "b9uMR7u7lsKLzRfVJNYb" }
})
});
}
Expand Down
7 changes: 2 additions & 5 deletions packages/runtime/src/dataViews/DataViewExpander.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1698,10 +1698,7 @@ export class DataViewExpander {
}
}

let direction = RelationshipDirection.Incoming;
if (!relationship.template.isOwn) {
direction = RelationshipDirection.Outgoing;
}
const direction = this.identityController.isMe(CoreAddress.from(relationship.auditLog[0].createdBy)) ? RelationshipDirection.Outgoing : RelationshipDirection.Incoming;

let statusText = "";
switch (relationship.status) {
Expand Down Expand Up @@ -1760,7 +1757,7 @@ export class DataViewExpander {
attributeMap: attributesByType,
items: expandedAttributes,
nameMap: stringByType,
templateId: relationship.template.id,
templateId: relationship.templateId,
auditLog: relationship.auditLog,
creationContent: relationship.creationContent
};
Expand Down
16 changes: 13 additions & 3 deletions packages/runtime/src/modules/RequestModule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -333,10 +333,20 @@ export class RequestModule extends RuntimeModule {
}

// only trigger for new relationships that were created from an own template
if (createdRelationship.status !== RelationshipStatus.Pending || !createdRelationship.template.isOwn) return;
const relationshipIsNotPending = createdRelationship.status !== RelationshipStatus.Pending;
const relationshipIsCreatedByCurrentAccount = createdRelationship.auditLog[0].createdBy === event.eventTargetAddress;
if (relationshipIsNotPending || relationshipIsCreatedByCurrentAccount) return;

const templateId = createdRelationship.templateId;

const templateResult = await services.transportServices.relationshipTemplates.getRelationshipTemplate({ id: templateId });
if (templateResult.isError) {
this.logger.error(`Could not get template with id '${templateId}'. Root error:`, templateResult.error);
return;
}

const template = templateResult.value;

const template = createdRelationship.template;
const templateId = template.id;
// do not trigger for templates without the correct content type
if (template.content["@type"] !== "RelationshipTemplateContent") return;
if (createdRelationship.creationContent["@type"] !== "RelationshipCreationContent") {
Expand Down
3 changes: 1 addition & 2 deletions packages/runtime/src/types/transport/RelationshipDTO.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { ArbitraryRelationshipCreationContentJSON, RelationshipCreationContentJSON } from "@nmshd/content";
import { IdentityDTO } from "./IdentityDTO";
import { RelationshipTemplateDTO } from "./RelationshipTemplateDTO";

export enum RelationshipStatus {
Pending = "Pending",
Expand Down Expand Up @@ -50,7 +49,7 @@ export interface PeerDeletionInfoDTO {

export interface RelationshipDTO {
id: string;
template: RelationshipTemplateDTO;
templateId: string;
status: RelationshipStatus;
peer: string;
peerIdentity: IdentityDTO;
Expand Down
2 changes: 1 addition & 1 deletion packages/runtime/src/useCases/common/Schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21250,7 +21250,7 @@ export const GetRelationshipsRequest: any = {
}
]
},
"template.id": {
"templateId": {
"anyOf": [
{
"type": "string"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { QueryTranslator } from "@js-soft/docdb-querytranslator";
import { Result } from "@js-soft/ts-utils";
import { CachedRelationship, Identity, Relationship, RelationshipsController, RelationshipTemplate } from "@nmshd/transport";
import { CachedRelationship, Identity, Relationship, RelationshipsController } from "@nmshd/transport";
import { Inject } from "@nmshd/typescript-ioc";
import { nameof } from "ts-simple-nameof";
import { RelationshipDTO, RelationshipTemplateDTO } from "../../../types";
import { RelationshipDTO } from "../../../types";
import { SchemaRepository, SchemaValidator, UseCase } from "../../common";
import { RelationshipMapper } from "./RelationshipMapper";

export interface GetRelationshipsQuery {
peer?: string | string[];
status?: string | string[];
"template.id"?: string | string[];
templateId?: string | string[];
}

export interface GetRelationshipsRequest {
Expand All @@ -28,12 +28,10 @@ export class GetRelationshipsUseCase extends UseCase<GetRelationshipsRequest, Re
whitelist: {
[nameof<RelationshipDTO>((r) => r.peer)]: true,
[nameof<RelationshipDTO>((r) => r.status)]: true,
[`${nameof<RelationshipDTO>((r) => r.template)}.${nameof<RelationshipTemplateDTO>((t) => t.id)}`]: true
[`${nameof<RelationshipDTO>((r) => r.templateId)}`]: true
},
alias: {
[`${nameof<RelationshipDTO>((r) => r.template)}.${nameof<RelationshipTemplateDTO>((r) => r.id)}`]: `${nameof<Relationship>(
(r) => r.cache
)}.${nameof<CachedRelationship>((r) => r.template)}.${nameof<RelationshipTemplate>((r) => r.id)}`,
[`${nameof<RelationshipDTO>((r) => r.templateId)}`]: `${nameof<Relationship>((r) => r.cache)}.${nameof<CachedRelationship>((r) => r.templateId)}`,
[nameof<RelationshipDTO>((r) => r.status)]: nameof<Relationship>((r) => r.status),
[nameof<RelationshipDTO>((r) => r.peer)]: `${nameof<Relationship>((r) => r.peer)}.${nameof<Identity>((r) => r.address)}`
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { ArbitraryRelationshipCreationContent, RelationshipCreationContent } fro
import { Relationship, RelationshipAuditLogEntry } from "@nmshd/transport";
import { RelationshipAuditLogEntryDTO, RelationshipDTO } from "../../../types";
import { RuntimeErrors } from "../../common";
import { RelationshipTemplateMapper } from "../relationshipTemplates/RelationshipTemplateMapper";

export class RelationshipMapper {
public static toRelationshipDTO(relationship: Relationship): RelationshipDTO {
Expand All @@ -13,7 +12,7 @@ export class RelationshipMapper {

return {
id: relationship.id.toString(),
template: RelationshipTemplateMapper.toRelationshipTemplateDTO(relationship.cache.template),
templateId: relationship.cache.templateId.toString(),
status: relationship.status,
peer: relationship.peer.address.toString(),
peerDeletionInfo: relationship.peerDeletionInfo?.toJSON(),
Expand Down
2 changes: 1 addition & 1 deletion packages/runtime/test/consumption/requests.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,7 @@ describe("Requests", () => {
const completionResult = await sConsumptionServices.outgoingRequests.createAndCompleteFromRelationshipTemplateResponse({
responseSourceId: sRelationship.id,
response: (sRelationship.creationContent as RelationshipCreationContentJSON).response,
templateId: relationship!.template.id
templateId: relationship!.templateId
});

expect(completionResult).toBeSuccessful();
Expand Down
4 changes: 2 additions & 2 deletions packages/runtime/test/dataViews/RelationshipDVO.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ describe("RelationshipDVO", () => {
expect(dvo.relationship!.status).toBe("Active");
expect(dvo.relationship!.statusText).toBe("i18n://dvo.relationship.Active");

expect(dvo.relationship!.templateId).toBe(dto.template.id);
expect(dvo.relationship!.templateId).toBe(dto.templateId);
});

test("check the relationship dvo for the requestor", async () => {
Expand All @@ -82,7 +82,7 @@ describe("RelationshipDVO", () => {
expect(dvo.relationship!.status).toBe("Active");
expect(dvo.relationship!.statusText).toBe("i18n://dvo.relationship.Active");

expect(dvo.relationship!.templateId).toBe(dto.template.id);
expect(dvo.relationship!.templateId).toBe(dto.templateId);
});

test("check the relationship dvo for the templator with active relationshipSetting", async () => {
Expand Down
3 changes: 2 additions & 1 deletion packages/runtime/test/lib/testUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -517,7 +517,8 @@ export async function ensureActiveRelationship(sTransportServices: TransportServ
await rTransportServices.relationships.decomposeRelationship({ relationshipId: relationship.id });
await establishRelationship(sTransportServices, rTransportServices);
} else if (sRelationships[0].status === RelationshipStatus.Pending) {
if (sRelationships[0].template.isOwn) {
const sRelationshipTemplate = await sTransportServices.relationshipTemplates.getRelationshipTemplate({ id: sRelationships[0].templateId });
if (sRelationshipTemplate.value.isOwn) {
const relationship = sRelationships[0];
await sTransportServices.relationships.acceptRelationship({ relationshipId: relationship.id });
await syncUntilHasRelationships(rTransportServices, 1);
Expand Down
6 changes: 3 additions & 3 deletions packages/runtime/test/transport/relationships.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -609,7 +609,7 @@ describe("Relationships query", () => {
const conditions = new QueryParamConditions<GetRelationshipsQuery>(relationship, services1.transport)
.addStringSet("peer")
.addStringSet("status")
.addStringSet("template.id");
.addStringSet("templateId");
await conditions.executeTests((c, q) => c.relationships.getRelationships({ query: q }));
});
});
Expand Down Expand Up @@ -1105,15 +1105,15 @@ describe("RelationshipDecomposition", () => {
beforeAll(async () => {
const relationship = await ensureActiveRelationship(services1.transport, services2.transport);
relationshipId = relationship.id;
templateId = relationship.template.id;
templateId = relationship.templateId;

await createRelationshipData(services1, services2);

const runtimeServices = await serviceProvider.launch(1, { enableRequestModule: true, enableDeciderModule: true, enableNotificationModule: true });
services3 = runtimeServices[0];
const relationship2 = await establishRelationship(services1.transport, services3.transport);
relationshipId2 = relationship2.id;
templateId2 = relationship2.template.id;
templateId2 = relationship2.templateId;

await createRelationshipData(services1, services3);
multipleRecipientsMessageId = (await sendMessageToMultipleRecipients(services1.transport, [services2.address, services3.address])).value.id;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -344,9 +344,8 @@ export class RelationshipTemplateController extends TransportController {
}

public async cleanupTemplatesOfDecomposedRelationship(relationship: Relationship): Promise<void> {
const templateOfRelationship = relationship.cache!.template;

if (!templateOfRelationship.isOwn || templateOfRelationship.cache!.maxNumberOfAllocations === 1) {
const templateOfRelationship = await this.getRelationshipTemplate(relationship.cache!.templateId);
if (templateOfRelationship && (!templateOfRelationship.isOwn || templateOfRelationship.cache!.maxNumberOfAllocations === 1)) {
await this.templates.delete(templateOfRelationship);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ export class RelationshipsController extends TransportController {

const backboneResponse = result.value;

const newRelationship = Relationship.fromBackboneAndCreationContent(backboneResponse, template, template.cache.identity, parameters.creationContent, secretId);
const newRelationship = Relationship.fromBackboneAndCreationContent(backboneResponse, template.cache.identity, parameters.creationContent, secretId);

await this.relationships.create(newRelationship);

Expand Down Expand Up @@ -400,19 +400,13 @@ export class RelationshipsController extends TransportController {

const templateId = CoreId.from(response.relationshipTemplateId);

this._log.trace(`Parsing relationship template ${templateId} for ${response.id}...`);
const template = await this.parent.relationshipTemplates.getRelationshipTemplate(templateId);
if (!template) {
throw TransportCoreErrors.general.recordNotFound(RelationshipTemplate, templateId.toString());
}

this._log.trace(`Parsing relationship creation content of ${response.id}...`);

const creationContent = await this.decryptCreationContent(response.creationContent, CoreAddress.from(response.from), relationshipSecretId);

const cachedRelationship = CachedRelationship.from({
creationContent: creationContent.content,
template,
templateId,
auditLog: RelationshipAuditLog.fromBackboneAuditLog(response.auditLog)
});

Expand Down Expand Up @@ -518,7 +512,7 @@ export class RelationshipsController extends TransportController {
await this.secrets.createTemplatorSecrets(secretId, template.cache, creationContentCipher.publicCreationContentCrypto);

const creationContent = await this.decryptCreationContent(backboneRelationship.creationContent, CoreAddress.from(backboneRelationship.from), secretId);
const relationship = Relationship.fromBackboneAndCreationContent(backboneRelationship, template, creationContent.identity, creationContent.content, secretId);
const relationship = Relationship.fromBackboneAndCreationContent(backboneRelationship, creationContent.identity, creationContent.content, secretId);

await this.relationships.create(relationship);
return relationship;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { ISerializable, Serializable, serialize, type, validate } from "@js-soft/ts-serval";
import { CoreDate, ICoreDate } from "@nmshd/core-types";
import { IRelationshipTemplate, RelationshipTemplate } from "../../relationshipTemplates/local/RelationshipTemplate";
import { CoreDate, CoreId, ICoreDate, ICoreId } from "@nmshd/core-types";
import { IRelationshipAuditLogEntry, RelationshipAuditLogEntry } from "./RelationshipAuditLogEntry";

export interface ICachedRelationship extends ISerializable {
template: IRelationshipTemplate;
templateId: ICoreId;
creationContent: ISerializable;

lastMessageSentAt?: ICoreDate;
Expand All @@ -16,7 +15,7 @@ export interface ICachedRelationship extends ISerializable {
export class CachedRelationship extends Serializable implements ICachedRelationship {
@validate()
@serialize()
public template: RelationshipTemplate;
public templateId: CoreId;

@validate()
@serialize()
Expand All @@ -34,6 +33,15 @@ export class CachedRelationship extends Serializable implements ICachedRelations
@serialize({ type: RelationshipAuditLogEntry })
public auditLog: RelationshipAuditLogEntry[];

public static override preFrom(value: any): any {
if (typeof value.template !== "undefined") {
value.templateId = value.template.id;
delete value.template;
}

return value;
}

public static from(value: ICachedRelationship): CachedRelationship {
return this.fromAny(value);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { CoreDate, CoreId, ICoreId } from "@nmshd/core-types";
import { nameof } from "ts-simple-nameof";
import { CoreSynchronizable, ICoreSynchronizable, TransportError } from "../../../core";
import { Identity, IIdentity } from "../../accounts/data/Identity";
import { IRelationshipTemplate } from "../../relationshipTemplates/local/RelationshipTemplate";
import { BackboneGetRelationshipResponse } from "../backbone/BackboneGetRelationships";
import { RelationshipStatus } from "../transmission/RelationshipStatus";
import { CachedRelationship, ICachedRelationship } from "./CachedRelationship";
Expand Down Expand Up @@ -74,23 +73,23 @@ export class Relationship extends CoreSynchronizable implements IRelationship {
// Adds flattened peerAddress and templateId to the JSON stored in the database.
// This helps us to boost the performance of database queries that include these fields.
json.peerAddress = this.peer.address.toString();
json.templateId = this.cache?.template.id.toString();
json.templateId = this.cache?.templateId.toString();

return json;
}

public static fromBackboneAndCreationContent(
response: BackboneGetRelationshipResponse,
template: IRelationshipTemplate,
peer: IIdentity,
creationContent: ISerializable,
relationshipSecretId: CoreId
): Relationship {
const cache = CachedRelationship.from({
creationContent,
template: template,
templateId: CoreId.from(response.relationshipTemplateId),
auditLog: RelationshipAuditLog.fromBackboneAuditLog(response.auditLog)
});

return Relationship.from({
id: CoreId.from(response.id),
relationshipSecretId: relationshipSecretId,
Expand Down
Loading

0 comments on commit 6cabc83

Please sign in to comment.