From b717e6867178fa030e35d2317288a6ecf5fecb55 Mon Sep 17 00:00:00 2001 From: Zoe Maas Date: Wed, 12 Mar 2025 17:14:31 +0100 Subject: [PATCH 01/10] chore: Removed NON NULL from the icon column in CredentialDefinition --- .../src/database/migrations/0000_credential-showcase-api.sql | 2 +- .../src/database/schema/credentialDefinition.ts | 3 +-- packages/credential-showcase-openapi/openapi/openapi.yaml | 1 - pnpm-lock.yaml | 3 --- 4 files changed, 2 insertions(+), 7 deletions(-) diff --git a/apps/credential-showcase-api-server/src/database/migrations/0000_credential-showcase-api.sql b/apps/credential-showcase-api-server/src/database/migrations/0000_credential-showcase-api.sql index 6b4fd0e..6935c0e 100644 --- a/apps/credential-showcase-api-server/src/database/migrations/0000_credential-showcase-api.sql +++ b/apps/credential-showcase-api-server/src/database/migrations/0000_credential-showcase-api.sql @@ -43,7 +43,7 @@ CREATE TABLE "credentialDefinition" ( "identifier_type" "IdentifierType", "identifier" text, "credential_schema" uuid NOT NULL, - "icon" uuid NOT NULL, + "icon" uuid, "type" "CredentialType" NOT NULL, "created_at" timestamp DEFAULT now() NOT NULL, "updated_at" timestamp DEFAULT now() NOT NULL diff --git a/apps/credential-showcase-api-server/src/database/schema/credentialDefinition.ts b/apps/credential-showcase-api-server/src/database/schema/credentialDefinition.ts index fe5ea87..81c07f6 100644 --- a/apps/credential-showcase-api-server/src/database/schema/credentialDefinition.ts +++ b/apps/credential-showcase-api-server/src/database/schema/credentialDefinition.ts @@ -19,8 +19,7 @@ export const credentialDefinitions = pgTable('credentialDefinition', { .references(() => credentialSchemas.id) .notNull(), icon: uuid() - .references(() => assets.id) - .notNull(), + .references(() => assets.id), type: CredentialTypePg().notNull().$type(), createdAt: timestamp('created_at').defaultNow().notNull(), updatedAt: timestamp('updated_at') diff --git a/packages/credential-showcase-openapi/openapi/openapi.yaml b/packages/credential-showcase-openapi/openapi/openapi.yaml index 88266cd..fc1cc37 100644 --- a/packages/credential-showcase-openapi/openapi/openapi.yaml +++ b/packages/credential-showcase-openapi/openapi/openapi.yaml @@ -2535,7 +2535,6 @@ components: - version - type - credentialSchema - - icon # TODO enable back in SHOWCASE-81 # - representations - createdAt diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 923b013..361d568 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -108,9 +108,6 @@ importers: drizzle-kit: specifier: ^0.30.4 version: 0.30.4 - testcontainers: - specifier: ^10.18.0 - version: 10.18.0 packages/credential-showcase-openapi: dependencies: From 08652f507ef9edf6dda98eb106a985ae5092e66c Mon Sep 17 00:00:00 2001 From: Zoe Maas Date: Wed, 12 Mar 2025 17:14:53 +0100 Subject: [PATCH 02/10] chore: Removed NON NULL from the icon column in CredentialDefinition --- .../src/database/schema/credentialDefinition.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/credential-showcase-api-server/src/database/schema/credentialDefinition.ts b/apps/credential-showcase-api-server/src/database/schema/credentialDefinition.ts index 81c07f6..7b1a71a 100644 --- a/apps/credential-showcase-api-server/src/database/schema/credentialDefinition.ts +++ b/apps/credential-showcase-api-server/src/database/schema/credentialDefinition.ts @@ -18,8 +18,7 @@ export const credentialDefinitions = pgTable('credentialDefinition', { credentialSchema: uuid('credential_schema') .references(() => credentialSchemas.id) .notNull(), - icon: uuid() - .references(() => assets.id), + icon: uuid().references(() => assets.id), type: CredentialTypePg().notNull().$type(), createdAt: timestamp('created_at').defaultNow().notNull(), updatedAt: timestamp('updated_at') From e2c588662ec124338a5e621cd6998650d53c587d Mon Sep 17 00:00:00 2001 From: Zoe Maas Date: Wed, 12 Mar 2025 17:19:38 +0100 Subject: [PATCH 03/10] chore: Made icon nullable --- apps/credential-showcase-api-server/src/types/schema/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/credential-showcase-api-server/src/types/schema/index.ts b/apps/credential-showcase-api-server/src/types/schema/index.ts index dcfb463..2c6454e 100644 --- a/apps/credential-showcase-api-server/src/types/schema/index.ts +++ b/apps/credential-showcase-api-server/src/types/schema/index.ts @@ -33,7 +33,7 @@ export type NewPersona = Omit & { export type CredentialDefinition = Omit & { type: CredentialType - icon: Asset + icon?: Asset credentialSchema: CredentialSchema representations: CredentialRepresentation[] revocation?: RevocationInfo | null From 62451900130468dab9ad6790675d9af2c71f6773 Mon Sep 17 00:00:00 2001 From: Zoe Maas Date: Thu, 13 Mar 2025 17:45:01 +0100 Subject: [PATCH 04/10] chore: Fixed issues with undefined assets --- .../repositories/CredentialDefinitionRepository.ts | 8 ++++++++ apps/credential-showcase-api-server/src/utils/mappers.ts | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/apps/credential-showcase-api-server/src/database/repositories/CredentialDefinitionRepository.ts b/apps/credential-showcase-api-server/src/database/repositories/CredentialDefinitionRepository.ts index 7fe5c6f..61b84bc 100644 --- a/apps/credential-showcase-api-server/src/database/repositories/CredentialDefinitionRepository.ts +++ b/apps/credential-showcase-api-server/src/database/repositories/CredentialDefinitionRepository.ts @@ -16,6 +16,9 @@ class CredentialDefinitionRepository implements RepositoryDefinition { + if (!credentialDefinition.icon) { + return Promise.reject('Icon is required') + } const iconResult = await this.assetRepository.findById(credentialDefinition.icon) const credentialSchemaResult = await this.credentialSchemaRepository.findById(credentialDefinition.credentialSchema) @@ -59,6 +62,10 @@ class CredentialDefinitionRepository implements RepositoryDefinition { await this.findById(id) + if (!credentialDefinition.icon) { + return Promise.reject('Icon is required') + } + const iconResult = await this.assetRepository.findById(credentialDefinition.icon) const credentialSchemaResult = await this.credentialSchemaRepository.findById(credentialDefinition.credentialSchema) return (await this.databaseService.getConnection()).transaction(async (tx): Promise => { @@ -123,6 +130,7 @@ class CredentialDefinitionRepository implements RepositoryDefinition Date: Thu, 13 Mar 2025 17:45:14 +0100 Subject: [PATCH 05/10] chore: Fixed issues with undefined assets --- apps/credential-showcase-api-server/src/utils/mappers.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/credential-showcase-api-server/src/utils/mappers.ts b/apps/credential-showcase-api-server/src/utils/mappers.ts index 97bca54..4b574ee 100644 --- a/apps/credential-showcase-api-server/src/utils/mappers.ts +++ b/apps/credential-showcase-api-server/src/utils/mappers.ts @@ -61,7 +61,7 @@ export const credentialDefinitionDTOFrom = (credentialDefinition: CredentialDefi credentialSchema: credentialSchemaDTOFrom(credentialDefinition.credentialSchema), representations: credentialDefinition.representations, revocation: credentialDefinition.revocation || undefined, - icon: credentialDefinition.icon ? assetDTOFrom(credentialDefinition?.icon) : undefined + icon: credentialDefinition.icon ? assetDTOFrom(credentialDefinition?.icon) : undefined, } } From 478124c5746b98e0563f3f664d5380205def926d Mon Sep 17 00:00:00 2001 From: Zoe Maas Date: Thu, 13 Mar 2025 18:01:02 +0100 Subject: [PATCH 06/10] chore: Fixed issues with undefined assets in tests and made icon optional in the credential definition request in Open API --- .../credentialDefinition.repository.test.ts | 30 +++++++++---------- .../openapi/openapi.yaml | 1 - 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/apps/credential-showcase-api-server/src/database/repositories/__tests__/credentialDefinition.repository.test.ts b/apps/credential-showcase-api-server/src/database/repositories/__tests__/credentialDefinition.repository.test.ts index a8c906e..dc73071 100644 --- a/apps/credential-showcase-api-server/src/database/repositories/__tests__/credentialDefinition.repository.test.ts +++ b/apps/credential-showcase-api-server/src/database/repositories/__tests__/credentialDefinition.repository.test.ts @@ -102,11 +102,11 @@ describe('Database credential definition repository tests', (): void => { expect(savedCredentialDefinition.name).toEqual(credentialDefinition.name) expect(savedCredentialDefinition.version).toEqual(credentialDefinition.version) expect(savedCredentialDefinition.icon).toBeDefined() - expect(savedCredentialDefinition.icon.id).toBeDefined() - expect(savedCredentialDefinition.icon.mediaType).toEqual(asset.mediaType) - expect(savedCredentialDefinition.icon.fileName).toEqual(asset.fileName) - expect(savedCredentialDefinition.icon.description).toEqual(asset.description) - expect(savedCredentialDefinition.icon.content).toStrictEqual(asset.content) + expect(savedCredentialDefinition.icon!.id).toBeDefined() + expect(savedCredentialDefinition.icon!.mediaType).toEqual(asset.mediaType) + expect(savedCredentialDefinition.icon!.fileName).toEqual(asset.fileName) + expect(savedCredentialDefinition.icon!.description).toEqual(asset.description) + expect(savedCredentialDefinition.icon!.content).toStrictEqual(asset.content) // TODO SHOWCASE-81 representations //expect(savedCredentialDefinition.representations.length).toEqual(2) @@ -169,11 +169,11 @@ describe('Database credential definition repository tests', (): void => { expect(fromDb.name).toEqual(credentialDefinition.name) expect(fromDb.version).toEqual(credentialDefinition.version) expect(fromDb.icon).toBeDefined() - expect(fromDb.icon.id).toBeDefined() - expect(fromDb.icon.mediaType).toEqual(asset.mediaType) - expect(fromDb.icon.fileName).toEqual(asset.fileName) - expect(fromDb.icon.description).toEqual(asset.description) - expect(fromDb.icon.content).toStrictEqual(asset.content) + expect(fromDb.icon!.id).toBeDefined() + expect(fromDb.icon!.mediaType).toEqual(asset.mediaType) + expect(fromDb.icon!.fileName).toEqual(asset.fileName) + expect(fromDb.icon!.description).toEqual(asset.description) + expect(fromDb.icon!.content).toStrictEqual(asset.content) // TODO SHOWCASE-81 representations //expect(fromDb.representations.length).toEqual(2) // expect(fromDb.revocation).not.toBeNull() @@ -278,11 +278,11 @@ describe('Database credential definition repository tests', (): void => { expect(updatedCredentialDefinition.name).toEqual(newName) expect(updatedCredentialDefinition.version).toEqual(credentialDefinition.version) expect(updatedCredentialDefinition.icon).toBeDefined() - expect(updatedCredentialDefinition.icon.id).toBeDefined() - expect(updatedCredentialDefinition.icon.mediaType).toEqual(asset.mediaType) - expect(updatedCredentialDefinition.icon.fileName).toEqual(asset.fileName) - expect(updatedCredentialDefinition.icon.description).toEqual(asset.description) - expect(updatedCredentialDefinition.icon.content).toStrictEqual(asset.content) + expect(updatedCredentialDefinition.icon!.id).toBeDefined() + expect(updatedCredentialDefinition.icon!.mediaType).toEqual(asset.mediaType) + expect(updatedCredentialDefinition.icon!.fileName).toEqual(asset.fileName) + expect(updatedCredentialDefinition.icon!.description).toEqual(asset.description) + expect(updatedCredentialDefinition.icon!.content).toStrictEqual(asset.content) // TODO SHOWCASE-81 representations //expect(updatedCredentialDefinition.representations.length).toEqual(2) // TODO SHOWCASE-80 AnonCredRevocation diff --git a/packages/credential-showcase-openapi/openapi/openapi.yaml b/packages/credential-showcase-openapi/openapi/openapi.yaml index fc1cc37..e6c5303 100644 --- a/packages/credential-showcase-openapi/openapi/openapi.yaml +++ b/packages/credential-showcase-openapi/openapi/openapi.yaml @@ -2590,7 +2590,6 @@ components: - name - version - type - - icon - credentialSchema # TODO enable back in SHOWCASE-81 # - representations From e6d499ec6c80556ba675ba4bc43d843cda4dace3 Mon Sep 17 00:00:00 2001 From: Zoe Maas Date: Fri, 14 Mar 2025 14:14:05 +0100 Subject: [PATCH 07/10] chore: Created new migration for database changes --- .../src/database/migrations/0000_credential-showcase-api.sql | 2 +- .../src/database/migrations/0003_credential-showcase-api.sql | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 apps/credential-showcase-api-server/src/database/migrations/0003_credential-showcase-api.sql diff --git a/apps/credential-showcase-api-server/src/database/migrations/0000_credential-showcase-api.sql b/apps/credential-showcase-api-server/src/database/migrations/0000_credential-showcase-api.sql index 6935c0e..6b4fd0e 100644 --- a/apps/credential-showcase-api-server/src/database/migrations/0000_credential-showcase-api.sql +++ b/apps/credential-showcase-api-server/src/database/migrations/0000_credential-showcase-api.sql @@ -43,7 +43,7 @@ CREATE TABLE "credentialDefinition" ( "identifier_type" "IdentifierType", "identifier" text, "credential_schema" uuid NOT NULL, - "icon" uuid, + "icon" uuid NOT NULL, "type" "CredentialType" NOT NULL, "created_at" timestamp DEFAULT now() NOT NULL, "updated_at" timestamp DEFAULT now() NOT NULL diff --git a/apps/credential-showcase-api-server/src/database/migrations/0003_credential-showcase-api.sql b/apps/credential-showcase-api-server/src/database/migrations/0003_credential-showcase-api.sql new file mode 100644 index 0000000..4cfbd08 --- /dev/null +++ b/apps/credential-showcase-api-server/src/database/migrations/0003_credential-showcase-api.sql @@ -0,0 +1 @@ +ALTER TABLE "credentialDefinition" ALTER COLUMN "icon" DROP NOT NULL; From 27c750923ed2807856c826957c3a258d00a538ee Mon Sep 17 00:00:00 2001 From: Zoe Maas Date: Fri, 14 Mar 2025 14:39:59 +0100 Subject: [PATCH 08/10] chore: Removed icon undefined check and added an integration test --- .../0003_credential-showcase-api.sql | 2 +- .../database/migrations/meta/_journal.json | 7 +++++ .../CredentialDefinitionRepository.ts | 7 ++--- .../credentialDefinition.repository.test.ts | 31 +++++++++++++++++++ 4 files changed, 41 insertions(+), 6 deletions(-) diff --git a/apps/credential-showcase-api-server/src/database/migrations/0003_credential-showcase-api.sql b/apps/credential-showcase-api-server/src/database/migrations/0003_credential-showcase-api.sql index 4cfbd08..fb4306d 100644 --- a/apps/credential-showcase-api-server/src/database/migrations/0003_credential-showcase-api.sql +++ b/apps/credential-showcase-api-server/src/database/migrations/0003_credential-showcase-api.sql @@ -1 +1 @@ -ALTER TABLE "credentialDefinition" ALTER COLUMN "icon" DROP NOT NULL; +ALTER TABLE "credentialDefinition" ALTER COLUMN "icon" DROP NOT NULL; \ No newline at end of file diff --git a/apps/credential-showcase-api-server/src/database/migrations/meta/_journal.json b/apps/credential-showcase-api-server/src/database/migrations/meta/_journal.json index bb663fb..3520e7a 100644 --- a/apps/credential-showcase-api-server/src/database/migrations/meta/_journal.json +++ b/apps/credential-showcase-api-server/src/database/migrations/meta/_journal.json @@ -22,6 +22,13 @@ "when": 1741865311197, "tag": "0002_credential-showcase-api", "breakpoints": true + }, + { + "idx": 3, + "version": "7", + "when": 1741959277068, + "tag": "0003_credential-showcase-api", + "breakpoints": true } ] } diff --git a/apps/credential-showcase-api-server/src/database/repositories/CredentialDefinitionRepository.ts b/apps/credential-showcase-api-server/src/database/repositories/CredentialDefinitionRepository.ts index 61b84bc..981cf9b 100644 --- a/apps/credential-showcase-api-server/src/database/repositories/CredentialDefinitionRepository.ts +++ b/apps/credential-showcase-api-server/src/database/repositories/CredentialDefinitionRepository.ts @@ -16,10 +16,7 @@ class CredentialDefinitionRepository implements RepositoryDefinition { - if (!credentialDefinition.icon) { - return Promise.reject('Icon is required') - } - const iconResult = await this.assetRepository.findById(credentialDefinition.icon) + const iconResult = credentialDefinition.icon && (await this.assetRepository.findById(credentialDefinition.icon)) const credentialSchemaResult = await this.credentialSchemaRepository.findById(credentialDefinition.credentialSchema) return (await this.databaseService.getConnection()).transaction(async (tx): Promise => { @@ -47,7 +44,7 @@ class CredentialDefinitionRepository implements RepositoryDefinition { // expect(savedCredentialDefinition.revocation!.description).toEqual(credentialDefinition.revocation!.description) }) + it('Should save the credential definition without icon to database', async (): Promise => { + const credentialDefinition: NewCredentialDefinition = { + name: 'example_name', + version: 'example_version', + identifierType: IdentifierType.DID, + identifier: 'did:sov:XUeUZauFLeBNofY3NhaZCB', + type: CredentialType.ANONCRED, + credentialSchema: credentialSchema.id, + // representations: [ + // { // TODO SHOWCASE-81 OCARepresentation + // + // }, + // { // TODO SHOWCASE-81 OCARepresentation + // + // } + // ], + //revocation: { + // TODO SHOWCASE-80 AnonCredRevocation + //title: 'example_revocation_title', + // description: 'example_revocation_description', + // }, + } + + const savedCredentialDefinition = await credentialDefinitionRepository.create(credentialDefinition) + + expect(savedCredentialDefinition).toBeDefined() + expect(savedCredentialDefinition.name).toEqual(credentialDefinition.name) + expect(savedCredentialDefinition.version).toEqual(credentialDefinition.version) + expect(savedCredentialDefinition.icon).toBeUndefined() + }) + it('Should throw error when saving credential definition with invalid icon id', async (): Promise => { const unknownIconId = 'a197e5b2-e4e5-4788-83b1-ecaa0e99ed3a' const credentialDefinition: NewCredentialDefinition = { From 035a3991586a178484fb2ad6ebe2ce4824eb9b74 Mon Sep 17 00:00:00 2001 From: Zoe Maas Date: Tue, 18 Mar 2025 11:55:09 +0100 Subject: [PATCH 09/10] chore: Changed the update credential definition repository to allow the insertion of undefined credentialDefinitions --- .../CredentialDefinitionRepository.ts | 8 +--- .../credentialDefinition.repository.test.ts | 47 +++++++++++++++++++ 2 files changed, 49 insertions(+), 6 deletions(-) diff --git a/apps/credential-showcase-api-server/src/database/repositories/CredentialDefinitionRepository.ts b/apps/credential-showcase-api-server/src/database/repositories/CredentialDefinitionRepository.ts index 981cf9b..41c2e9b 100644 --- a/apps/credential-showcase-api-server/src/database/repositories/CredentialDefinitionRepository.ts +++ b/apps/credential-showcase-api-server/src/database/repositories/CredentialDefinitionRepository.ts @@ -59,11 +59,7 @@ class CredentialDefinitionRepository implements RepositoryDefinition { await this.findById(id) - if (!credentialDefinition.icon) { - return Promise.reject('Icon is required') - } - - const iconResult = await this.assetRepository.findById(credentialDefinition.icon) + const iconResult = credentialDefinition.icon && (await this.assetRepository.findById(credentialDefinition.icon)) const credentialSchemaResult = await this.credentialSchemaRepository.findById(credentialDefinition.credentialSchema) return (await this.databaseService.getConnection()).transaction(async (tx): Promise => { const [credentialDefinitionResult] = await tx @@ -97,7 +93,7 @@ class CredentialDefinitionRepository implements RepositoryDefinition { // expect(updatedCredentialDefinition.revocation!.description).toEqual(credentialDefinition.revocation!.description) }) + it('Should update credential definition in database passing in an undefined icon', async (): Promise => { + const credentialDefinition: NewCredentialDefinition = { + name: 'example_name', + version: 'example_version', + identifierType: IdentifierType.DID, + identifier: 'did:sov:XUeUZauFLeBNofY3NhaZCB', + icon: asset.id, + type: CredentialType.ANONCRED, + credentialSchema: credentialSchema.id, + // representations: [ + // { // TODO SHOWCASE-81 OCARepresentation + // + // }, + // { // TODO SHOWCASE-81 OCARepresentation + // + // } + // ], + //revocation: { + // TODO SHOWCASE-80 AnonCredRevocation + //title: 'example_revocation_title', + // description: 'example_revocation_description', + // }, + } + + const savedCredentialDefinition = await credentialDefinitionRepository.create(credentialDefinition) + expect(savedCredentialDefinition).toBeDefined() + + const newName = 'new_name' + const updatedCredentialDefinition = await credentialDefinitionRepository.update(savedCredentialDefinition.id, { + ...credentialDefinition, + icon: undefined, + credentialSchema: credentialSchema.id, + name: newName, + }) + + expect(updatedCredentialDefinition).toBeDefined() + expect(updatedCredentialDefinition.name).toEqual(newName) + expect(updatedCredentialDefinition.version).toEqual(credentialDefinition.version) + expect(updatedCredentialDefinition.icon).toBeUndefined() + // TODO SHOWCASE-81 representations + //expect(updatedCredentialDefinition.representations.length).toEqual(2) + // TODO SHOWCASE-80 AnonCredRevocation + // expect(updatedCredentialDefinition.revocation).not.toBeNull() + // expect(updatedCredentialDefinition.revocation!.title).toEqual(credentialDefinition.revocation!.title) + // expect(updatedCredentialDefinition.revocation!.description).toEqual(credentialDefinition.revocation!.description) + }) + it('Should throw error when updating credential definition with invalid icon id', async (): Promise => { const unknownIconId = 'a197e5b2-e4e5-4788-83b1-ecaa0e99ed3a' const credentialDefinition: NewCredentialDefinition = { From 7aeebfabd67b495b1226b60af32bbcfc2f7a164b Mon Sep 17 00:00:00 2001 From: Zoe Maas Date: Fri, 21 Mar 2025 18:51:37 +0100 Subject: [PATCH 10/10] chore: Fixed merging issues --- .../src/database/migrations/0003_credential-showcase-api.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/credential-showcase-api-server/src/database/migrations/0003_credential-showcase-api.sql b/apps/credential-showcase-api-server/src/database/migrations/0003_credential-showcase-api.sql index fbed4d5..dbd5e28 100644 --- a/apps/credential-showcase-api-server/src/database/migrations/0003_credential-showcase-api.sql +++ b/apps/credential-showcase-api-server/src/database/migrations/0003_credential-showcase-api.sql @@ -1,2 +1,2 @@ -ALTER TABLE "step" ADD COLUMN "screenId" text; +ALTER TABLE "step" ADD COLUMN "screenId" text;--> statement-breakpoint ALTER TABLE "credentialDefinition" ALTER COLUMN "icon" DROP NOT NULL; \ No newline at end of file