Mirror of https://github.com/roostorg/coop github.com/roostorg/coop
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 163 lines 4.7 kB view raw
1import _ from 'lodash'; 2import sequelize, { 3 type BelongsToGetAssociationMixin, 4 type HasManyAddAssociationsMixin, 5 type HasManyGetAssociationsMixin, 6 type HasManySetAssociationsMixin, 7 type InferAttributes, 8 type InferCreationAttributes, 9 type Sequelize, 10} from 'sequelize'; 11 12import { 13 PolicyType, 14 UserPenaltySeverity, 15} from '../services/moderationConfigService/index.js'; 16import { type DataTypes } from './index.js'; 17import { type Rule } from './rules/RuleModel.js'; 18 19const { groupBy, mapValues } = _; 20const { Model } = sequelize; 21 22export type Policy = InstanceType<ReturnType<typeof makePolicy>>; 23 24/** 25 * Data Model for Policies. These policies can represent overall 26 * policy areas (crime, safety) or more granular policy areas (e.g. 27 * selling dangerous goods, child safety). Policies are constructed as 28 * a tree - or rather, a set of trees, all of which can be thought of 29 * as child trees under an abstract root node. 30 * 31 * ROOT 32 * | | | 33 * Crime Safety Hate 34 * | | | | | | 35 * Weapons Drugs Children Self-harm Dehumanization Threats 36 * 37 * Each node (except the root) is a policy. 38 */ 39const makePolicy = (sequelize: Sequelize, DataTypes: DataTypes) => { 40 class Policy extends Model< 41 InferAttributes<Policy>, 42 InferCreationAttributes<Policy> 43 > { 44 public declare id: string; 45 public declare name: string; 46 public declare policyText?: string | undefined; 47 48 public declare orgId: string; 49 50 public declare parentId: string | undefined; 51 public declare parent?: Policy; 52 public declare getParent: BelongsToGetAssociationMixin<Policy>; 53 54 public declare getChildren: HasManyGetAssociationsMixin<Policy>; 55 public declare addChildren: HasManyAddAssociationsMixin<Policy, string>; 56 public declare setChildren: HasManySetAssociationsMixin<Policy, string>; 57 58 public declare penalty: UserPenaltySeverity; 59 public declare userStrikeCount: number; 60 public declare applyUserStrikeCountConfigToChildren: boolean; 61 public declare semanticVersion: number; 62 public declare policyType: PolicyType | undefined; 63 64 public declare rules?: Rule[]; 65 66 // eslint-disable-next-line @typescript-eslint/no-explicit-any 67 static associate(models: { [key: string]: any }) { 68 Policy.belongsTo(models.Org, { as: 'org' }); 69 Policy.hasMany(models.Policy, { 70 as: 'children', 71 foreignKey: 'parentId', 72 }); 73 Policy.belongsTo(models.Policy, { 74 as: 'parent', 75 foreignKey: 'parentId', 76 }); 77 Policy.belongsToMany(models.Rule, { 78 through: 'rules_and_policies', 79 as: 'rules', 80 }); 81 } 82 83 static async getPoliciesForRuleIds(ruleIds: readonly string[]) { 84 const results = await Policy.findAll({ 85 where: { '$rules.id$': ruleIds }, 86 include: [{ association: 'rules', attributes: ['id'] }], 87 }); 88 89 const ruleIdPolicyPairs = results.flatMap((policy) => 90 policy.rules!.map((rule) => [rule.id, policy] as const), 91 ); 92 93 return mapValues( 94 groupBy(ruleIdPolicyPairs, ([ruleId]) => ruleId), 95 (pairs) => pairs.map(([, policy]) => policy), 96 ) as { [ruleId: string]: Policy[] | undefined }; 97 } 98 } 99 100 /* Fields */ 101 Policy.init( 102 { 103 id: { 104 type: DataTypes.STRING, 105 primaryKey: true, 106 }, 107 orgId: { 108 type: DataTypes.STRING, 109 allowNull: false, 110 }, 111 name: { 112 type: DataTypes.STRING, 113 allowNull: true, 114 }, 115 policyText: { 116 type: DataTypes.STRING, 117 allowNull: true, 118 }, 119 parentId: { 120 allowNull: true, 121 type: DataTypes.STRING, 122 }, 123 policyType: { 124 type: DataTypes.ENUM(...Object.values(PolicyType)), 125 allowNull: true, 126 }, 127 penalty: { 128 type: DataTypes.STRING, 129 defaultValue: UserPenaltySeverity.NONE, 130 allowNull: false, 131 validate: { 132 notNull: true, 133 isIn: [Object.values(UserPenaltySeverity)], 134 }, 135 }, 136 userStrikeCount: { 137 allowNull: false, 138 type: DataTypes.INTEGER, 139 defaultValue: 1, 140 }, 141 applyUserStrikeCountConfigToChildren: { 142 allowNull: false, 143 type: DataTypes.BOOLEAN, 144 defaultValue: false, 145 }, 146 semanticVersion: { 147 allowNull: false, 148 type: DataTypes.INTEGER, 149 defaultValue: 1, 150 }, 151 }, 152 { 153 sequelize, 154 modelName: 'policy', 155 underscored: true, 156 tableName: 'policies', 157 }, 158 ); 159 160 return Policy; 161}; 162 163export default makePolicy;