From 9940f48efa2bec89af4e6b29244af618e378a1fa Mon Sep 17 00:00:00 2001 From: Tom Moor Date: Sat, 14 Mar 2026 20:17:03 -0400 Subject: [PATCH] Add flags to Team model to match User (#11758) --- .../20260314000000-add-team-flags.js | 14 +++++ server/models/Team.ts | 60 +++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 server/migrations/20260314000000-add-team-flags.js diff --git a/server/migrations/20260314000000-add-team-flags.js b/server/migrations/20260314000000-add-team-flags.js new file mode 100644 index 0000000000..6dddf3c0c0 --- /dev/null +++ b/server/migrations/20260314000000-add-team-flags.js @@ -0,0 +1,14 @@ +"use strict"; + +module.exports = { + up: async (queryInterface, Sequelize) => { + return queryInterface.addColumn("teams", "flags", { + type: Sequelize.JSONB, + allowNull: true, + }); + }, + + down: async (queryInterface) => { + return queryInterface.removeColumn("teams", "flags"); + }, +}; diff --git a/server/models/Team.ts b/server/models/Team.ts index 4d9e7e6708..9b18711b18 100644 --- a/server/models/Team.ts +++ b/server/models/Team.ts @@ -50,6 +50,13 @@ import Length from "./validators/Length"; import NotContainsUrl from "./validators/NotContainsUrl"; import { SkipChangeset } from "./decorators/Changeset"; +/** + * Flags that are available for setting on the team. + */ +export enum TeamFlag { + MarkedSafe = "markedSafe", +} + @Scopes(() => ({ withDomains: { include: [{ model: TeamDomain }], @@ -188,6 +195,9 @@ class Team extends ParanoidModel< @Column suspendedAt: Date | null; + @Column(DataType.JSONB) + flags: { [key in TeamFlag]?: number } | null; + @IsDate @Column @SkipChangeset @@ -282,6 +292,56 @@ class Team extends ParanoidModel< TeamPreferenceDefaults[preference] ?? false; + /** + * Team flags are for storing information on a team record that is not visible + * to the team members. + * + * @param flag The flag to set + * @param value Set the flag to true/false + * @returns The current team flags + */ + public setFlag = (flag: TeamFlag, value = true) => { + if (!this.flags) { + this.flags = {}; + } + const binary = value ? 1 : 0; + if (this.flags[flag] !== binary) { + this.flags = { + ...this.flags, + [flag]: binary, + }; + } + + return this.flags; + }; + + /** + * Returns the content of the given team flag. + * + * @param flag The flag to retrieve + * @returns The flag value + */ + public getFlag = (flag: TeamFlag) => this.flags?.[flag] ?? 0; + + /** + * Team flags are for storing information on a team record that is not visible + * to the team members. + * + * @param flag The flag to set + * @param value The amount to increment by, defaults to 1 + * @returns The current team flags + */ + public incrementFlag = (flag: TeamFlag, value = 1) => { + if (!this.flags) { + this.flags = {}; + } + this.flags = { + ...this.flags, + [flag]: (this.flags[flag] ?? 0) + value, + }; + return this.flags; + }; + /** * Updates the lastActiveAt timestamp to the current time. *