diff --git a/docs/postman/Organization API.postman_collection.json b/docs/postman/Organization API.postman_collection.json index 52797d7e..4b677d64 100644 --- a/docs/postman/Organization API.postman_collection.json +++ b/docs/postman/Organization API.postman_collection.json @@ -341,6 +341,44 @@ } }, "response": [] + }, + { + "name": "add_metadata", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "formdata", + "formdata": [ + { + "key": "hello", + "value": "world", + "type": "text" + } + ] + }, + "url": { + "raw": "http://localhost:31310/v1/organizations/metadata", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "31310", + "path": [ + "v1", + "organizations", + "metadata" + ], + "query": [ + { + "key": "test", + "value": "hello world", + "disabled": true + } + ] + } + }, + "response": [] } ] } \ No newline at end of file diff --git a/src/controllers/organization.controller.js b/src/controllers/organization.controller.js index effc6238..2900897a 100644 --- a/src/controllers/organization.controller.js +++ b/src/controllers/organization.controller.js @@ -324,6 +324,27 @@ export const resyncOrganization = async (req, res) => { } }; +export const addMetadata = async (req, res) => { + try { + await assertIfReadOnlyMode(); + await assertWalletIsSynced(); + await assertHomeOrgExists(); + + Organization.addMetadata(req.body); + + return res.json({ + message: 'Home org currently being updated, will be completed soon.', + }); + } catch (error) { + console.trace(error); + res.status(400).json({ + message: 'Error adding metadata to your organization', + error: error.message, + }); + } +}; + + export const addMirror = async (req, res) => { try { await assertIfReadOnlyMode(); diff --git a/src/database/migrations/20220831023546-add-org-metadata.js b/src/database/migrations/20220831023546-add-org-metadata.js new file mode 100644 index 00000000..0484afb6 --- /dev/null +++ b/src/database/migrations/20220831023546-add-org-metadata.js @@ -0,0 +1,23 @@ +'use strict'; + +export default { + async up(queryInterface, Sequelize) { + await Promise.all( + ['organizations'].map((table) => { + queryInterface.addColumn(table, 'metadata', { + type: Sequelize.String, + allowNull: true, + defaultValue: false, + }); + }), + ); + }, + + async down(queryInterface) { + await Promise.all( + [].map((table) => { + queryInterface.removeColumn(table, 'metadata'); + }), + ); + }, +}; \ No newline at end of file diff --git a/src/database/migrations/index.js b/src/database/migrations/index.js index d71f8df4..38371f65 100644 --- a/src/database/migrations/index.js +++ b/src/database/migrations/index.js @@ -29,6 +29,7 @@ import AddFiltStoreSubscribedColumnToProject from './20220809182156-AddFileStore import PopulateUnitsFTS from './20220808192709-populate-units-fts'; import ResetDBForNewSingletons from './20220816155101-reset-db-for-new-singletons'; import AddIsTransferColumn from './20220825124702-add-isTransfer-column'; +import AddOrgMetadata from './20220831023546-add-org-metadata'; export const migrations = [ { @@ -159,4 +160,8 @@ export const migrations = [ migration: AddIsTransferColumn, name: '20220825124702-add-isTransfer-column', }, + { + migration: AddOrgMetadata, + name: '20220831023546-add-org-metadata', + }, ]; diff --git a/src/models/organizations/organizations.model.js b/src/models/organizations/organizations.model.js index 4dcdca7f..0ae156bd 100644 --- a/src/models/organizations/organizations.model.js +++ b/src/models/organizations/organizations.model.js @@ -1,11 +1,13 @@ 'use strict'; import Sequelize from 'sequelize'; +import _ from 'lodash'; + const { Model } = Sequelize; + import { sequelize } from '../../database'; import datalayer from '../../datalayer'; - import { logger } from '../../config/logger.cjs'; import { getDefaultOrganizationList } from '../../utils/data-loaders'; @@ -302,16 +304,23 @@ class Organization extends Model { await Promise.all( allSubscribedOrganizations.map((organization) => { const onResult = (data) => { - const updateData = data.reduce((update, current) => { - // TODO: this needs to pull the v1 record - if (current.key !== 'registryId') { + const updateData = data + .filter(({ dataEntry }) => current.key !== 'registryId' || !dataEntry.key.includes('meta_')) + .reduce((update, current) => { + update[current.key] = current.value; + return update; + }, {}); + + // will return metadata fields. i.e.: { meta_key1: 'value1', meta_key2: 'value2' } + const metadata = data + .filter(({ dataEntry }) => dataEntry.key.includes('meta_')) + .reduce((update, current) => { update[current.key] = current.value; - } - return update; - }, {}); + return update; + }, {}); Organization.update( - { ...updateData }, + { ...updateData, metadata }, { where: { orgUid: organization.orgUid }, }, @@ -386,6 +395,15 @@ class Organization extends Model { await datalayer.upsertDataLayer(myOrganization.orgUid, payload); }; + static addMetadata = async (payload) => { + const myOrganization = await Organization.getHomeOrg(); + + // Prefix keys with "meta_" + const metadata = _.mapKeys(payload, (_value, key) => `meta_${key}`); + + await datalayer.upsertDataLayer(myOrganization.orgUid, metadata); + }; + static removeMirror = async (storeId, coinId) => { datalayer.removeMirror(storeId, coinId); }; diff --git a/src/routes/v1/resources/organization.js b/src/routes/v1/resources/organization.js index a68283e8..9de09ba4 100644 --- a/src/routes/v1/resources/organization.js +++ b/src/routes/v1/resources/organization.js @@ -102,4 +102,11 @@ OrganizationRouter.post( }, ); +OrganizationRouter.post( + '/metadata', + (req, res) => { + return OrganizationController.addMetadata(req, res); + }, +); + export { OrganizationRouter };