From 55b07757ff04d083f99c76651590d7adbcfaf254 Mon Sep 17 00:00:00 2001 From: rotorsoft Date: Thu, 3 Oct 2024 14:16:50 -0400 Subject: [PATCH 1/2] add xp tables --- libs/model/src/models/associations.ts | 5 +- libs/model/src/models/factories.ts | 2 + libs/model/src/models/user.ts | 1 + libs/model/src/models/xp_log.ts | 23 ++++++++++ libs/schemas/src/entities/user.schemas.ts | 8 ++++ .../20241003134700-add-xp-tables.js | 46 +++++++++++++++++++ 6 files changed, 82 insertions(+), 3 deletions(-) create mode 100644 libs/model/src/models/xp_log.ts create mode 100644 packages/commonwealth/server/migrations/20241003134700-add-xp-tables.js diff --git a/libs/model/src/models/associations.ts b/libs/model/src/models/associations.ts index 84363e4fa7e..24b9a77758c 100644 --- a/libs/model/src/models/associations.ts +++ b/libs/model/src/models/associations.ts @@ -11,9 +11,8 @@ export const buildAssociations = (db: DB) => { onDelete: 'CASCADE', }) .withMany(db.Wallets) - .withOne(db.ApiKey, { - onDelete: 'CASCADE', - }); + .withMany(db.XpLog, { onDelete: 'CASCADE' }) + .withOne(db.ApiKey, { onDelete: 'CASCADE' }); db.Address.withMany(db.Thread, { asOne: 'Address', diff --git a/libs/model/src/models/factories.ts b/libs/model/src/models/factories.ts index f724355655d..b92197182b1 100644 --- a/libs/model/src/models/factories.ts +++ b/libs/model/src/models/factories.ts @@ -43,6 +43,7 @@ import User from './user'; import Vote from './vote'; import Wallets from './wallets'; import Webhook from './webhook'; +import XpLog from './xp_log'; export const Factories = { Address, @@ -87,6 +88,7 @@ export const Factories = { Vote, Webhook, Wallets, + XpLog, }; export type DB = { diff --git a/libs/model/src/models/user.ts b/libs/model/src/models/user.ts index 284ffeb02b5..1267d8c6799 100644 --- a/libs/model/src/models/user.ts +++ b/libs/model/src/models/user.ts @@ -72,6 +72,7 @@ export default (sequelize: Sequelize.Sequelize): UserModelStatic => }, selected_community_id: { type: Sequelize.STRING, allowNull: true }, profile: { type: Sequelize.JSONB, allowNull: false }, + xp_points: { type: Sequelize.INTEGER, defaultValue: 0, allowNull: true }, }, { timestamps: true, diff --git a/libs/model/src/models/xp_log.ts b/libs/model/src/models/xp_log.ts new file mode 100644 index 00000000000..cf57200b7c8 --- /dev/null +++ b/libs/model/src/models/xp_log.ts @@ -0,0 +1,23 @@ +import { XpLog } from '@hicommonwealth/schemas'; +import Sequelize from 'sequelize'; +import { z } from 'zod'; +import type { ModelInstance } from './types'; + +export type XpLogInstance = ModelInstance>; +export type XpLogModelStatic = Sequelize.ModelStatic; + +export default (sequelize: Sequelize.Sequelize) => + sequelize.define( + 'XpLog', + { + user_id: { type: Sequelize.INTEGER, primaryKey: true }, + created_at: { type: Sequelize.DATE, primaryKey: true }, + event_name: { type: Sequelize.STRING, primaryKey: true }, + xp_points: { type: Sequelize.INTEGER, allowNull: false }, + }, + { + timestamps: false, + tableName: 'XpLogs', + underscored: true, + }, + ); diff --git a/libs/schemas/src/entities/user.schemas.ts b/libs/schemas/src/entities/user.schemas.ts index a5732327f7c..4956cb905df 100644 --- a/libs/schemas/src/entities/user.schemas.ts +++ b/libs/schemas/src/entities/user.schemas.ts @@ -49,6 +49,7 @@ export const User = z.object({ is_welcome_onboard_flow_complete: z.boolean().default(false).optional(), profile: UserProfile, + xp_points: PG_INT.default(0).nullish(), ProfileTags: z.array(ProfileTags).optional(), @@ -105,3 +106,10 @@ export const CommunityMember = z.object({ group_ids: z.array(PG_INT), last_active: z.any().nullish().describe('string or date'), }); + +export const XpLog = z.object({ + user_id: PG_INT, + created_at: z.coerce.date(), + event_name: z.string(), + xp_points: PG_INT, +}); diff --git a/packages/commonwealth/server/migrations/20241003134700-add-xp-tables.js b/packages/commonwealth/server/migrations/20241003134700-add-xp-tables.js new file mode 100644 index 00000000000..f82853b8ff4 --- /dev/null +++ b/packages/commonwealth/server/migrations/20241003134700-add-xp-tables.js @@ -0,0 +1,46 @@ +'use strict'; + +/** @type {import('sequelize-cli').Migration} */ +module.exports = { + async up(queryInterface, Sequelize) { + await queryInterface.sequelize.transaction(async (transaction) => { + await queryInterface.createTable( + 'XpLogs', + { + user_id: { + primaryKey: true, + type: Sequelize.INTEGER, + references: { + model: 'Users', + key: 'id', + }, + onDelete: 'CASCADE', + }, + created_at: { type: Sequelize.DATE, primaryKey: true }, + event_name: { type: Sequelize.STRING, primaryKey: true }, + xp_points: { type: Sequelize.INTEGER, allowNull: false }, + }, + { transaction }, + ); + await queryInterface.addColumn( + 'Users', + 'xp_points', + { + type: Sequelize.INTEGER, + defaultValue: 0, + allowNull: true, + }, + { transaction }, + ); + }); + }, + + async down(queryInterface) { + await queryInterface.sequelize.transaction(async (transaction) => { + await queryInterface.dropTable('XpLogs', { transaction }); + await queryInterface.removeColumn('Users', 'xp_points', { + transaction, + }); + }); + }, +}; From d20f97d328394d6c7c637392c823f746bbae8035 Mon Sep 17 00:00:00 2001 From: rotorsoft Date: Thu, 3 Oct 2024 16:09:35 -0400 Subject: [PATCH 2/2] set sequelize autodates --- libs/model/src/models/xp_log.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libs/model/src/models/xp_log.ts b/libs/model/src/models/xp_log.ts index cf57200b7c8..a8650a619d0 100644 --- a/libs/model/src/models/xp_log.ts +++ b/libs/model/src/models/xp_log.ts @@ -16,7 +16,9 @@ export default (sequelize: Sequelize.Sequelize) => xp_points: { type: Sequelize.INTEGER, allowNull: false }, }, { - timestamps: false, + timestamps: true, + createdAt: 'created_at', + updatedAt: false, tableName: 'XpLogs', underscored: true, },