Skip to content

Commit

Permalink
feat: Link collections (#761)
Browse files Browse the repository at this point in the history
* feat: Link collections

* feat: Link collections to contracts

* fix: Use amoy in the third party id
  • Loading branch information
LautaroPetaccio authored Jul 29, 2024
1 parent 119f446 commit fe43e60
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 5 deletions.
55 changes: 55 additions & 0 deletions migrations/1722019983190_add-linked-collection-data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/* eslint-disable @typescript-eslint/naming-convention */
import { MigrationBuilder } from 'node-pg-migrate'
import { Collection } from '../src/Collection'

const linkedContractAddressColumn = 'linked_contract_address'
const linkedContractNetworkColumn = 'linked_contract_network'
const linkedContractUniqueConstraintName = 'linkedContract_linkedNetwork_unique'
const unlinkContractTriggerName =
'prevent_null_update_if_previous_not_null_trigger'
const unlinkContractFunctionName = 'prevent_null_update_if_previous_not_null'

export async function up(pgm: MigrationBuilder): Promise<void> {
pgm.addColumn(Collection.tableName, {
[linkedContractAddressColumn]: { type: 'string', notNull: false },
[linkedContractNetworkColumn]: { type: 'string', notNull: false },
})
pgm.addConstraint(Collection.tableName, linkedContractUniqueConstraintName, {
unique: [linkedContractAddressColumn, linkedContractNetworkColumn],
})
// Create the trigger function
pgm.createFunction(
unlinkContractFunctionName,
[],
{
returns: 'TRIGGER',
language: 'plpgsql',
},
`
BEGIN
IF (OLD.${linkedContractAddressColumn} IS NOT NULL AND NEW.${linkedContractAddressColumn} IS NULL) OR
(OLD.${linkedContractNetworkColumn} IS NOT NULL AND NEW.${linkedContractNetworkColumn} IS NULL) THEN
RAISE EXCEPTION 'Columns ${linkedContractAddressColumn}, ${linkedContractNetworkColumn} cannot be set to null if they were previously not null';
END IF;
RETURN NEW;
END;
`
)
// Attach the trigger to the table
pgm.createTrigger(Collection.tableName, unlinkContractTriggerName, {
when: 'BEFORE',
operation: 'UPDATE',
level: 'ROW',
function: unlinkContractFunctionName,
})
}

export async function down(pgm: MigrationBuilder): Promise<void> {
pgm.dropConstraint(Collection.tableName, linkedContractUniqueConstraintName)
pgm.dropColumn(Collection.tableName, [
linkedContractAddressColumn,
linkedContractNetworkColumn,
])
pgm.dropTrigger(Collection.tableName, unlinkContractTriggerName)
pgm.dropFunction(unlinkContractFunctionName, [])
}
7 changes: 5 additions & 2 deletions spec/mocks/collections.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ export const dbCollectionMock: CollectionAttributes = {
lock: null,
urn_suffix: null,
third_party_id: null,
linked_contract_address: null,
linked_contract_network: null,
reviewed_at: new Date(),
created_at: new Date(),
updated_at: new Date(),
Expand All @@ -40,8 +42,9 @@ export const dbTPCollectionMock: ThirdPartyCollectionAttributes = {
eth_address: '',
contract_address: null,
urn_suffix: 'test-collection',
third_party_id:
'urn:decentraland:amoy:collections-thirdparty:dcl-tests',
linked_contract_address: '0x02b6bD2420cCADC38726BD34BB7f5c52B3F4F3ff',
linked_contract_network: 'amoy',
third_party_id: 'urn:decentraland:amoy:collections-thirdparty:dcl-tests',
}

export const collectionFragmentMock: CollectionFragment = {
Expand Down
6 changes: 6 additions & 0 deletions src/Collection/Collection.schema.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { ContractNetwork } from '@dcl/schemas'
import { matchers } from '../common/matchers'

export const collectionSchema = Object.freeze({
Expand All @@ -24,6 +25,11 @@ export const collectionSchema = Object.freeze({
reviewed_at: { type: ['string', 'null'] },
created_at: { type: 'string' },
updated_at: { type: 'string' },
linked_contract_address: { type: ['string', 'null'] },
linked_contract_network: {
type: ['string', 'null'],
enum: [...Object.values(ContractNetwork), null],
},
},
additionalProperties: false,
required: [
Expand Down
8 changes: 6 additions & 2 deletions src/Collection/Collection.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,17 @@ export type CollectionAttributes = {
forum_id: number | null
lock: Date | null
reviewed_at: Date | null
linked_contract_address: string | null
linked_contract_network: string | null
created_at: Date
updated_at: Date
}

export type ThirdPartyCollectionAttributes = CollectionAttributes & {
third_party_id: string
urn_suffix: string
linked_contract_address: string
linked_contract_network: string
}

export type FullCollection = Omit<
Expand All @@ -46,7 +50,7 @@ export type PublishCollectionResponse<T> = {

export enum CollectionTypeFilter {
STANDARD = 'standard',
THIRD_PARTY = 'third_party'
THIRD_PARTY = 'third_party',
}

export enum CollectionSort {
Expand All @@ -56,5 +60,5 @@ export enum CollectionSort {
NAME_DESC = 'NAME_DESC',
NAME_ASC = 'NAME_ASC',
UPDATED_AT_DESC = 'UPDATED_AT_DESC',
UPDATED_AT_ASC = 'UPDATED_AT_ASC'
UPDATED_AT_ASC = 'UPDATED_AT_ASC',
}
15 changes: 14 additions & 1 deletion src/Item/Item.schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,20 @@ const baseItemSchema = Object.freeze({
},
utility: { type: ['string', 'null'], maxLength: 64 },
content_hash: { type: ['string', 'null'] },
mappings: { ...Mappings.schema, type: ['object', 'null'] },
mappings: {
...Mappings.schema,
type: ['object', 'null'],
properties: Object.fromEntries(
Object.entries(
Mappings.schema.properties
).map(([key, value]: [string, any]) => [
key,
{ ...value, maxProperties: 1 },
])
),
// Limit to one the number of linked networks
maxProperties: 1,
},
},
additionalProperties: false,
anyOf: [{ required: ['id'] }, { required: ['urn'] }],
Expand Down

0 comments on commit fe43e60

Please sign in to comment.