From 89d4cf235f4da34fb330c7a46230f8ee45bab6f3 Mon Sep 17 00:00:00 2001 From: Avinash Lingaloo Date: Mon, 11 Jan 2021 21:54:33 +0400 Subject: [PATCH] MM_30476 [v2] Section 'Team' of the Server schema (#5071) * MM_30476 : Added all isolated tables from the server schema * MM_30476 : Updated 'test' script in package.json * MM_30476 : ADDED team section of the server schema * MM_30476 : Apply suggestions from code review Co-authored-by: Miguel Alatzar * MM_30476 : Apply suggestions from code review Co-authored-by: Elias Nahum * MM_30476 : Updates to field name and description Co-authored-by: Elias Nahum Co-authored-by: Hossein * MM_30476 : Updated my_team and team_search_history description * MM_30476 : Prefixing boolean fields with 'is' * MM_30476 : Updated channel.d.ts Co-authored-by: Hossein Co-authored-by: Elias Nahum * MM_30476 : ADDED lazy queries to TeamMembership Two methods that will retrieve all users in a team and all the teams that a user is part of * MM_30476 : Updated descriptions for the associations * MM_30476 : Updated tests as server schema was updated * MM_30476 : Updated Team to have a 1:1 relationship with TeamChannelHistory * MM_30476 : Updated team_membership and user Co-authored-by: Miguel Alatzar Co-authored-by: Elias Nahum Co-authored-by: Hossein --- app/database/server/models/index.ts | 13 ++ app/database/server/models/my_team.ts | 41 +++++++ app/database/server/models/slash_command.ts | 53 ++++++++ app/database/server/models/team.ts | 104 ++++++++++++++++ .../server/models/team_channel_history.ts | 36 ++++++ app/database/server/models/team_membership.ts | 53 ++++++++ .../server/models/team_search_history.ts | 42 +++++++ app/database/server/schema/index.ts | 19 ++- .../server/schema/table_schemas/index.ts | 6 + .../server/schema/table_schemas/my_team.ts | 18 +++ .../schema/table_schemas/slash_command.ts | 22 ++++ .../server/schema/table_schemas/team.ts | 22 ++++ .../table_schemas/team_channel_history.ts | 16 +++ .../schema/table_schemas/team_membership.ts | 16 +++ .../table_schemas/team_search_history.ts | 18 +++ app/database/server/schema/test.ts | 113 +++++++++++++++++- types/database/channel.d.ts | 81 +++++++++++++ types/database/groups_in_team.d.ts | 37 ++++++ types/database/my_team.d.ts | 33 +++++ types/database/slash_command.d.ts | 45 +++++++ types/database/team.d.ts | 69 +++++++++++ types/database/team_channel_history.d.ts | 28 +++++ types/database/team_membership.d.ts | 40 +++++++ types/database/team_search_history.d.ts | 34 ++++++ types/database/user.d.ts | 112 +++++++++++++++++ 25 files changed, 1069 insertions(+), 2 deletions(-) create mode 100644 app/database/server/models/index.ts create mode 100644 app/database/server/models/my_team.ts create mode 100644 app/database/server/models/slash_command.ts create mode 100644 app/database/server/models/team.ts create mode 100644 app/database/server/models/team_channel_history.ts create mode 100644 app/database/server/models/team_membership.ts create mode 100644 app/database/server/models/team_search_history.ts create mode 100644 app/database/server/schema/table_schemas/my_team.ts create mode 100644 app/database/server/schema/table_schemas/slash_command.ts create mode 100644 app/database/server/schema/table_schemas/team.ts create mode 100644 app/database/server/schema/table_schemas/team_channel_history.ts create mode 100644 app/database/server/schema/table_schemas/team_membership.ts create mode 100644 app/database/server/schema/table_schemas/team_search_history.ts create mode 100644 types/database/channel.d.ts create mode 100644 types/database/groups_in_team.d.ts create mode 100644 types/database/my_team.d.ts create mode 100644 types/database/slash_command.d.ts create mode 100644 types/database/team.d.ts create mode 100644 types/database/team_channel_history.d.ts create mode 100644 types/database/team_membership.d.ts create mode 100644 types/database/team_search_history.d.ts create mode 100644 types/database/user.d.ts diff --git a/app/database/server/models/index.ts b/app/database/server/models/index.ts new file mode 100644 index 0000000000..c5c1ed4a23 --- /dev/null +++ b/app/database/server/models/index.ts @@ -0,0 +1,13 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +export {default as CustomEmoji} from './custom_emoji'; +export {default as MyTeam} from './my_team'; +export {default as Role} from './role'; +export {default as SlashCommand} from './slash_command'; +export {default as System} from './system'; +export {default as Team} from './team'; +export {default as TeamChannelHistory} from './team_channel_history'; +export {default as TeamMembership} from './team_membership'; +export {default as TeamSearchHistory} from './team_search_history'; +export {default as TermsOfService} from './terms_of_service'; diff --git a/app/database/server/models/my_team.ts b/app/database/server/models/my_team.ts new file mode 100644 index 0000000000..74e889c61c --- /dev/null +++ b/app/database/server/models/my_team.ts @@ -0,0 +1,41 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import {Relation} from '@nozbe/watermelondb'; +import Model, {Associations} from '@nozbe/watermelondb/Model'; +import {field, relation} from '@nozbe/watermelondb/decorators'; + +import {MM_TABLES} from '@constants/database'; +import Team from '@typings/database/team'; + +const {TEAM, MY_TEAM} = MM_TABLES.SERVER; + +/** + * MyTeam represents only the teams that the current user belongs to + */ +export default class MyTeam extends Model { + /** table (entity name) : MyTeam */ + static table = MY_TEAM; + + /** associations : Describes every relationship to this entity. */ + static associations: Associations = { + + /** TEAM and MY_TEAM have a 1:1 relationship. */ + [TEAM]: {type: 'belongs_to', key: 'team_id'}, + }; + + /** is_unread : Boolean flag for unread messages on team level */ + @field('is_unread') isUnread!: boolean; + + /** mentions_count : Count of posts in which the user has been mentioned */ + @field('mentions_count') mentionsCount!: number; + + /** roles : The different permissions that this user has in the team */ + @field('roles') roles!: string; + + /** team_id : The foreign key of the 'parent' Team entity */ + @field('team_id') teamId!: string; + + /** teams : The relation to the entity TEAM, that this user belongs to */ + @relation(MY_TEAM, 'team_id') team!: Relation +} diff --git a/app/database/server/models/slash_command.ts b/app/database/server/models/slash_command.ts new file mode 100644 index 0000000000..6eeea98d0b --- /dev/null +++ b/app/database/server/models/slash_command.ts @@ -0,0 +1,53 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import {Relation} from '@nozbe/watermelondb'; +import Model, {Associations} from '@nozbe/watermelondb/Model'; +import {field, immutableRelation} from '@nozbe/watermelondb/decorators'; + +import {MM_TABLES} from '@constants/database'; +import Team from '@typings/database/team'; + +const {SLASH_COMMAND, TEAM} = MM_TABLES.SERVER; + +/** + * The SlashCommand model describes the commands of the various commands available in each team. + */ +export default class SlashCommand extends Model { + /** table (entity name) : SlashCommand */ + static table = SLASH_COMMAND; + + /** associations : Describes every relationship to this entity. */ + static associations: Associations = { + + /** A TEAM can have multiple slash commands. (relationship is 1:N) */ + [TEAM]: {type: 'belongs_to', key: 'team_id'}, + }; + + /** is_auto_complete : Boolean flag for auto-completing slash commands */ + @field('is_auto_complete') isAutoComplete!: boolean; + + /** description : The description for the slash command */ + @field('description') description!: string; + + /** display_name : The name for the command */ + @field('display_name') displayName!: string; + + /** hint : A helpful text explaining the purpose of the command */ + @field('hint') hint!: string; + + /** method : HTTP API methods like get, put, post, patch, etc. */ + @field('method') method!: string; + + /** team_id : The foreign key of the parent Team */ + @field('team_id') teamId!: string; + + /** token : A key identifying this slash command */ + @field('token') token!: string; + + /** trigger : A pattern/text used to recognize when a slash command needs to launch */ + @field('trigger') trigger!: string; + + /** team : The related parent TEAM record */ + @immutableRelation(TEAM, 'team_id') team!: Relation; +} diff --git a/app/database/server/models/team.ts b/app/database/server/models/team.ts new file mode 100644 index 0000000000..0df3c8ca83 --- /dev/null +++ b/app/database/server/models/team.ts @@ -0,0 +1,104 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import {Q, Query} from '@nozbe/watermelondb'; +import Model, {Associations} from '@nozbe/watermelondb/Model'; +import {children, field, lazy} from '@nozbe/watermelondb/decorators'; + +import {MM_TABLES} from '@constants/database'; +import Channel from '@typings/database/channel'; +import GroupsInTeam from '@typings/database/groups_in_team'; +import MyTeam from '@typings/database/my_team'; +import SlashCommand from '@typings/database/slash_command'; +import TeamChannelHistory from '@typings/database/team_channel_history'; +import TeamMembership from '@typings/database/team_membership'; +import TeamSearchHistory from '@typings/database/team_search_history'; + +const { + CHANNEL, + GROUPS_IN_TEAM, + TEAM, + MY_TEAM, + SLASH_COMMAND, + TEAM_CHANNEL_HISTORY, + TEAM_MEMBERSHIP, + TEAM_SEARCH_HISTORY, +} = MM_TABLES.SERVER; + +/** + * A Team houses and enables communication to happen across channels and users. + */ +export default class Team extends Model { + /** table (entity name) : Team */ + static table = TEAM; + + /** associations : Describes every relationship to this entity. */ + static associations: Associations = { + + /** A TEAM has a 1:N relationship with CHANNEL. A TEAM can possess multiple channels */ + [CHANNEL]: {type: 'has_many', foreignKey: 'team_id'}, + + /** A TEAM has a 1:N relationship with GROUPS_IN_TEAM. A TEAM can possess multiple groups */ + [GROUPS_IN_TEAM]: {type: 'has_many', foreignKey: 'team_id'}, + + /** A TEAM has a 1:1 relationship with MY_TEAM. */ + [MY_TEAM]: {type: 'has_many', foreignKey: 'team_id'}, + + /** A TEAM has a 1:N relationship with SLASH_COMMAND. A TEAM can possess multiple slash commands */ + [SLASH_COMMAND]: {type: 'has_many', foreignKey: 'team_id'}, + + /** A TEAM has a 1:1 relationship with TEAM_CHANNEL_HISTORY.*/ + [TEAM_CHANNEL_HISTORY]: {type: 'has_many', foreignKey: 'team_id'}, + + /** A TEAM has a 1:N relationship with TEAM_MEMBERSHIP. A TEAM can regroup multiple users */ + [TEAM_MEMBERSHIP]: {type: 'has_many', foreignKey: 'team_id'}, + + /** A TEAM has a 1:N relationship with TEAM_SEARCH_HISTORY. A TEAM can possess multiple search histories*/ + [TEAM_SEARCH_HISTORY]: {type: 'has_many', foreignKey: 'team_id'}, + }; + + /** is_allow_open_invite : Boolean flag indicating if this team is open to the public */ + @field('is_allow_open_invite') isAllowOpenInvite!: boolean; + + /** description : The description for the team */ + @field('description') description!: string; + + /** display_name : The display name for the team */ + @field('display_name') displayName!: string; + + /** is_group_constrained : Boolean flag indicating if members are managed groups */ + @field('is_group_constrained') isGroupConstrained!: boolean; + + /** last_team_icon_updated_at : Timestamp for when this team's icon has been updated last */ + @field('last_team_icon_updated_at') lastTeamIconUpdatedAt!: number; + + /** name : The name for the team */ + @field('name') name!: string; + + /** type : The type of team ( e.g. open/private ) */ + @field('type') type!: string; + + /** allowed_domains : List of domains that can join this team */ + @field('allowed_domains') allowedDomains!: string; + + /** channels : All the channels associated with this team */ + @children(CHANNEL) channels!: Channel[]; + + /** groupsInTeam : All the groups associated with this team */ + @children(GROUPS_IN_TEAM) groupsInTeam!: GroupsInTeam[]; + + /** myTeam : Lazy query property returning only the team member that this user is part of */ + @lazy myTeam = this.collections.get(MY_TEAM).query(Q.on(TEAM, 'id', this.id)) as Query; + + /** slashCommands : All the slash commands associated with this team */ + @children(SLASH_COMMAND) slashCommands!: SlashCommand[]; + + /** teamChannelHistory : A history of the channels in this team that has been visited, ordered by the most recent and capped to the last 5 */ + @lazy teamChannelHistory = this.collections.get(TEAM_CHANNEL_HISTORY).query(Q.on(TEAM, 'id', this.id)) as Query; + + /** members : All the users associated with this team */ + @children(TEAM_MEMBERSHIP) members!: TeamMembership[]; + + /** teamSearchHistories : All the searches performed on this team */ + @children(TEAM_SEARCH_HISTORY) teamSearchHistories!: TeamSearchHistory[]; +} diff --git a/app/database/server/models/team_channel_history.ts b/app/database/server/models/team_channel_history.ts new file mode 100644 index 0000000000..f10bd32963 --- /dev/null +++ b/app/database/server/models/team_channel_history.ts @@ -0,0 +1,36 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import {Relation} from '@nozbe/watermelondb'; +import Model, {Associations} from '@nozbe/watermelondb/Model'; +import {field, immutableRelation, json} from '@nozbe/watermelondb/decorators'; + +import {MM_TABLES} from '@constants/database'; +import Team from '@typings/database/team'; + +const {TEAM, TEAM_CHANNEL_HISTORY} = MM_TABLES.SERVER; + +/** + * The TeamChannelHistory model helps keeping track of the last channel visited + * by the user. + */ +export default class TeamChannelHistory extends Model { + /** table (entity name) : TeamChannelHistory */ + static table = TEAM_CHANNEL_HISTORY; + + /** associations : Describes every relationship to this entity. */ + static associations: Associations = { + + /** A TEAM and TEAM_CHANNEL_HISTORY share a 1:1 relationship */ + [TEAM]: {type: 'belongs_to', key: 'team_id'}, + }; + + /** team_id : The foreign key to the related Team record */ + @field('team_id') teamId!: string; + + /** channelIds : An array containing the last 5 channels visited within this team order by recency */ + @json('channel_ids', (rawJson) => rawJson) channelIds!: string[]; + + /** team : The related record from the parent Team model */ + @immutableRelation(TEAM, 'team_id') team!: Relation; +} diff --git a/app/database/server/models/team_membership.ts b/app/database/server/models/team_membership.ts new file mode 100644 index 0000000000..aeddeab078 --- /dev/null +++ b/app/database/server/models/team_membership.ts @@ -0,0 +1,53 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import {Q, Query, Relation} from '@nozbe/watermelondb'; +import Model, {Associations} from '@nozbe/watermelondb/Model'; +import {field, immutableRelation, lazy} from '@nozbe/watermelondb/decorators'; + +import {MM_TABLES} from '@constants/database'; +import User from '@typings/database/user'; +import Team from '@typings/database/team'; + +const {TEAM, TEAM_MEMBERSHIP, USER} = MM_TABLES.SERVER; + +/** + * The TeamMembership model represents the 'association table' where many teams have users and many users are in + * teams (relationship type N:N) + */ +export default class TeamMembership extends Model { + /** table (entity name) : TeamMembership */ + static table = TEAM_MEMBERSHIP; + + /** associations : Describes every relationship to this entity. */ + static associations: Associations = { + + /** TEAM and TEAM_MEMBERSHIP share a 1:N relationship; USER can be part of multiple teams */ + [TEAM]: {type: 'belongs_to', key: 'team_id'}, + + /** USER and TEAM_MEMBERSHIP share a 1:N relationship; A TEAM can regroup multiple users */ + [USER]: {type: 'belongs_to', key: 'user_id'}, + }; + + /** team_id : The foreign key to the related Team record */ + @field('team_id') teamId!: string; + + /* user_id: The foreign key to the related User record*/ + @field('user_id') userId!: string; + + /** memberUser: The related user in the team */ + @immutableRelation(USER, 'user_id') memberUser!: Relation; + + /** memberTeam : The related team of users */ + @immutableRelation(TEAM, 'team_id') memberTeam!: Relation; + + /** + * getAllTeamsForUser - Retrieves all the teams that the user is part of + */ + @lazy getAllTeamsForUser = this.collections.get(TEAM).query(Q.on(USER, 'id', this.userId)) as Query + + /** + * getAllUsersInTeam - Retrieves all the users who are part of this team + */ + @lazy getAllUsersInTeam = this.collections.get(USER).query(Q.on(TEAM, 'id', this.teamId)) as Query +} diff --git a/app/database/server/models/team_search_history.ts b/app/database/server/models/team_search_history.ts new file mode 100644 index 0000000000..3ad29bf1fa --- /dev/null +++ b/app/database/server/models/team_search_history.ts @@ -0,0 +1,42 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import {Relation} from '@nozbe/watermelondb'; +import Model, {Associations} from '@nozbe/watermelondb/Model'; +import {field, immutableRelation, text} from '@nozbe/watermelondb/decorators'; + +import {MM_TABLES} from '@constants/database'; +import Team from '@typings/database/team'; + +const {TEAM, TEAM_SEARCH_HISTORY} = MM_TABLES.SERVER; + +/** + * The TeamSearchHistory model holds the term searched within a team. The searches are performed + * at team level in the app. + */ +export default class TeamSearchHistory extends Model { + /** table (entity name) : TeamSearchHistory */ + static table = TEAM_SEARCH_HISTORY; + + /** associations : Describes every relationship to this entity. */ + static associations: Associations = { + + /** A TEAM can have multiple search terms */ + [TEAM]: {type: 'belongs_to', key: 'team_id'}, + }; + + /** createdAt : The timestamp at which this search was performed */ + @field('created_at') createdAt!: number; + + /** teamId : The foreign key to the parent Team model */ + @field('team_id') teamId!: string; + + /** displayTerm : The term that we display to the user */ + @field('display_term') displayTerm!: string; + + /** term : The term that is sent to the server to perform the search */ + @text('term') term!: string; + + /** team : The related record to the parent team model */ + @immutableRelation(TEAM, 'team_id') team!: Relation; +} diff --git a/app/database/server/schema/index.ts b/app/database/server/schema/index.ts index 9957289e94..64b82a2ec9 100644 --- a/app/database/server/schema/index.ts +++ b/app/database/server/schema/index.ts @@ -3,14 +3,31 @@ import {AppSchema, appSchema} from '@nozbe/watermelondb'; -import {CustomEmojiSchema, RoleSchema, SystemSchema, TermsOfServiceSchema} from './table_schemas'; +import { + CustomEmojiSchema, + MyTeamSchema, + RoleSchema, + SlashCommandSchema, + SystemSchema, + TeamChannelHistorySchema, + TeamMembershipSchema, + TeamSchema, + TeamSearchHistorySchema, + TermsOfServiceSchema, +} from './table_schemas'; export const serverSchema: AppSchema = appSchema({ version: 1, tables: [ CustomEmojiSchema, + MyTeamSchema, RoleSchema, + SlashCommandSchema, SystemSchema, + TeamChannelHistorySchema, + TeamMembershipSchema, + TeamSchema, + TeamSearchHistorySchema, TermsOfServiceSchema, ], }); diff --git a/app/database/server/schema/table_schemas/index.ts b/app/database/server/schema/table_schemas/index.ts index f9982ee180..bd7e95c31b 100644 --- a/app/database/server/schema/table_schemas/index.ts +++ b/app/database/server/schema/table_schemas/index.ts @@ -2,6 +2,12 @@ // See LICENSE.txt for license information. export {default as CustomEmojiSchema} from './custom_emoji'; +export {default as MyTeamSchema} from './my_team'; export {default as RoleSchema} from './role'; +export {default as SlashCommandSchema} from './slash_command'; export {default as SystemSchema} from './system'; +export {default as TeamChannelHistorySchema} from './team_channel_history'; +export {default as TeamMembershipSchema} from './team_membership'; +export {default as TeamSchema} from './team'; +export {default as TeamSearchHistorySchema} from './team_search_history'; export {default as TermsOfServiceSchema} from './terms_of_service'; diff --git a/app/database/server/schema/table_schemas/my_team.ts b/app/database/server/schema/table_schemas/my_team.ts new file mode 100644 index 0000000000..b9faf8a73d --- /dev/null +++ b/app/database/server/schema/table_schemas/my_team.ts @@ -0,0 +1,18 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import {tableSchema} from '@nozbe/watermelondb'; + +import {MM_TABLES} from '@constants/database'; + +const {MY_TEAM} = MM_TABLES.SERVER; + +export default tableSchema({ + name: MY_TEAM, + columns: [ + {name: 'is_unread', type: 'boolean'}, + {name: 'mentions_count', type: 'number'}, + {name: 'roles', type: 'string'}, + {name: 'team_id', type: 'string', isIndexed: true}, + ], +}); diff --git a/app/database/server/schema/table_schemas/slash_command.ts b/app/database/server/schema/table_schemas/slash_command.ts new file mode 100644 index 0000000000..d4da717e35 --- /dev/null +++ b/app/database/server/schema/table_schemas/slash_command.ts @@ -0,0 +1,22 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import {tableSchema} from '@nozbe/watermelondb'; + +import {MM_TABLES} from '@constants/database'; + +const {SLASH_COMMAND} = MM_TABLES.SERVER; + +export default tableSchema({ + name: SLASH_COMMAND, + columns: [ + {name: 'is_auto_complete', type: 'boolean'}, + {name: 'description', type: 'string'}, + {name: 'display_name', type: 'string'}, + {name: 'hint', type: 'string'}, + {name: 'method', type: 'string'}, + {name: 'team_id', type: 'string', isIndexed: true}, + {name: 'token', type: 'string'}, + {name: 'trigger', type: 'string'}, + ], +}); diff --git a/app/database/server/schema/table_schemas/team.ts b/app/database/server/schema/table_schemas/team.ts new file mode 100644 index 0000000000..a08940658e --- /dev/null +++ b/app/database/server/schema/table_schemas/team.ts @@ -0,0 +1,22 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import {tableSchema} from '@nozbe/watermelondb'; + +import {MM_TABLES} from '@constants/database'; + +const {TEAM} = MM_TABLES.SERVER; + +export default tableSchema({ + name: TEAM, + columns: [ + {name: 'is_allow_open_invite', type: 'boolean'}, + {name: 'allowed_domains', type: 'string'}, + {name: 'description', type: 'string'}, + {name: 'display_name', type: 'string'}, + {name: 'is_group_constrained', type: 'boolean'}, + {name: 'last_team_icon_updated_at', type: 'number'}, + {name: 'name', type: 'string'}, + {name: 'type', type: 'string'}, + ], +}); diff --git a/app/database/server/schema/table_schemas/team_channel_history.ts b/app/database/server/schema/table_schemas/team_channel_history.ts new file mode 100644 index 0000000000..d47bb09191 --- /dev/null +++ b/app/database/server/schema/table_schemas/team_channel_history.ts @@ -0,0 +1,16 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import {tableSchema} from '@nozbe/watermelondb'; + +import {MM_TABLES} from '@constants/database'; + +const {TEAM_CHANNEL_HISTORY} = MM_TABLES.SERVER; + +export default tableSchema({ + name: TEAM_CHANNEL_HISTORY, + columns: [ + {name: 'channel_ids', type: 'string'}, + {name: 'team_id', type: 'string', isIndexed: true}, + ], +}); diff --git a/app/database/server/schema/table_schemas/team_membership.ts b/app/database/server/schema/table_schemas/team_membership.ts new file mode 100644 index 0000000000..0fdeed877d --- /dev/null +++ b/app/database/server/schema/table_schemas/team_membership.ts @@ -0,0 +1,16 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import {tableSchema} from '@nozbe/watermelondb'; + +import {MM_TABLES} from '@constants/database'; + +const {TEAM_MEMBERSHIP} = MM_TABLES.SERVER; + +export default tableSchema({ + name: TEAM_MEMBERSHIP, + columns: [ + {name: 'team_id', type: 'string', isIndexed: true}, + {name: 'user_id', type: 'string', isIndexed: true}, + ], +}); diff --git a/app/database/server/schema/table_schemas/team_search_history.ts b/app/database/server/schema/table_schemas/team_search_history.ts new file mode 100644 index 0000000000..6cd36e5824 --- /dev/null +++ b/app/database/server/schema/table_schemas/team_search_history.ts @@ -0,0 +1,18 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import {tableSchema} from '@nozbe/watermelondb'; + +import {MM_TABLES} from '@constants/database'; + +const {TEAM_SEARCH_HISTORY} = MM_TABLES.SERVER; + +export default tableSchema({ + name: TEAM_SEARCH_HISTORY, + columns: [ + {name: 'created_at', type: 'number'}, + {name: 'display_term', type: 'string'}, + {name: 'team_id', type: 'string', isIndexed: true}, + {name: 'term', type: 'string'}, + ], +}); diff --git a/app/database/server/schema/test.ts b/app/database/server/schema/test.ts index 949c459a4e..dcc7dbf818 100644 --- a/app/database/server/schema/test.ts +++ b/app/database/server/schema/test.ts @@ -4,7 +4,19 @@ import {MM_TABLES} from '@constants/database'; import {serverSchema} from './index'; -const {CUSTOM_EMOJI, ROLE, SYSTEM, TERMS_OF_SERVICE} = MM_TABLES.SERVER; + +const { + CUSTOM_EMOJI, + MY_TEAM, + ROLE, + SLASH_COMMAND, + SYSTEM, + TERMS_OF_SERVICE, + TEAM, + TEAM_CHANNEL_HISTORY, + TEAM_MEMBERSHIP, + TEAM_SEARCH_HISTORY, +} = MM_TABLES.SERVER; describe('*** Test schema for SERVER database ***', () => { it('=> The SERVER SCHEMA should strictly match', () => { @@ -20,6 +32,21 @@ describe('*** Test schema for SERVER database ***', () => { {name: 'name', type: 'string'}, ], }, + [MY_TEAM]: { + name: MY_TEAM, + columns: { + is_unread: {name: 'is_unread', type: 'boolean'}, + mentions_count: {name: 'mentions_count', type: 'number'}, + roles: {name: 'roles', type: 'string'}, + team_id: {name: 'team_id', type: 'string', isIndexed: true}, + }, + columnArray: [ + {name: 'is_unread', type: 'boolean'}, + {name: 'mentions_count', type: 'number'}, + {name: 'roles', type: 'string'}, + {name: 'team_id', type: 'string', isIndexed: true}, + ], + }, [ROLE]: { name: ROLE, columns: { @@ -31,6 +58,29 @@ describe('*** Test schema for SERVER database ***', () => { {name: 'permissions', type: 'string'}, ], }, + [SLASH_COMMAND]: { + name: SLASH_COMMAND, + columns: { + is_auto_complete: {name: 'is_auto_complete', type: 'boolean'}, + description: {name: 'description', type: 'string'}, + display_name: {name: 'display_name', type: 'string'}, + hint: {name: 'hint', type: 'string'}, + method: {name: 'method', type: 'string'}, + team_id: {name: 'team_id', type: 'string', isIndexed: true}, + token: {name: 'token', type: 'string'}, + trigger: {name: 'trigger', type: 'string'}, + }, + columnArray: [ + {name: 'is_auto_complete', type: 'boolean'}, + {name: 'description', type: 'string'}, + {name: 'display_name', type: 'string'}, + {name: 'hint', type: 'string'}, + {name: 'method', type: 'string'}, + {name: 'team_id', type: 'string', isIndexed: true}, + {name: 'token', type: 'string'}, + {name: 'trigger', type: 'string'}, + ], + }, [SYSTEM]: { name: SYSTEM, columns: { @@ -42,6 +92,67 @@ describe('*** Test schema for SERVER database ***', () => { {name: 'value', type: 'string'}, ], }, + [TEAM]: { + name: TEAM, + columns: { + is_allow_open_invite: {name: 'is_allow_open_invite', type: 'boolean'}, + allowed_domains: {name: 'allowed_domains', type: 'string'}, + description: {name: 'description', type: 'string'}, + display_name: {name: 'display_name', type: 'string'}, + is_group_constrained: {name: 'is_group_constrained', type: 'boolean'}, + last_team_icon_updated_at: {name: 'last_team_icon_updated_at', type: 'number'}, + name: {name: 'name', type: 'string'}, + type: {name: 'type', type: 'string'}, + }, + columnArray: [ + {name: 'is_allow_open_invite', type: 'boolean'}, + {name: 'allowed_domains', type: 'string'}, + {name: 'description', type: 'string'}, + {name: 'display_name', type: 'string'}, + {name: 'is_group_constrained', type: 'boolean'}, + {name: 'last_team_icon_updated_at', type: 'number'}, + {name: 'name', type: 'string'}, + {name: 'type', type: 'string'}, + ], + }, + [TEAM_CHANNEL_HISTORY]: { + name: TEAM_CHANNEL_HISTORY, + columns: { + channel_ids: {name: 'channel_ids', type: 'string'}, + team_id: {name: 'team_id', type: 'string', isIndexed: true}, + }, + columnArray: [ + {name: 'channel_ids', type: 'string'}, + {name: 'team_id', type: 'string', isIndexed: true}, + ], + }, + [TEAM_MEMBERSHIP]: { + name: TEAM_MEMBERSHIP, + columns: { + team_id: {name: 'team_id', type: 'string', isIndexed: true}, + user_id: {name: 'user_id', type: 'string', isIndexed: true}, + }, + columnArray: [ + {name: 'team_id', type: 'string', isIndexed: true}, + {name: 'user_id', type: 'string', isIndexed: true}, + ], + }, + [TEAM_SEARCH_HISTORY]: { + name: TEAM_SEARCH_HISTORY, + columns: { + created_at: {name: 'created_at', type: 'number'}, + display_term: {name: 'display_term', type: 'string'}, + team_id: {name: 'team_id', type: 'string', isIndexed: true}, + term: {name: 'term', type: 'string'}, + + }, + columnArray: [ + {name: 'created_at', type: 'number'}, + {name: 'display_term', type: 'string'}, + {name: 'team_id', type: 'string', isIndexed: true}, + {name: 'term', type: 'string'}, + ], + }, [TERMS_OF_SERVICE]: { name: TERMS_OF_SERVICE, columns: { diff --git a/types/database/channel.d.ts b/types/database/channel.d.ts new file mode 100644 index 0000000000..ad8a961514 --- /dev/null +++ b/types/database/channel.d.ts @@ -0,0 +1,81 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import {Query, Relation} from '@nozbe/watermelondb'; +import Model, {Associations} from '@nozbe/watermelondb/Model'; + +import ChannelInfo from '@typings/database/channel_info'; +import ChannelMembership from '@typings/database/channel_membership'; +import Draft from '@typings/database/draft'; +import GroupsInChannel from '@typings/database/groups_in_channel'; +import MyChannel from '@typings/database/my_channel'; +import MyChannelSettings from '@typings/database/my_channel_settings'; +import Post from '@typings/database/post'; +import PostsInChannel from '@typings/database/posts_in_channel'; +import Team from '@typings/database/team'; +import User from '@typings/database/user'; + +/** + * The Channel model represents a channel in the Mattermost app. + */ +export default class Channel extends Model { + /** table (entity name) : Channel */ + static table: string; + + /** associations : Describes every relationship to this entity. */ + static associations: Associations; + + /** create_at : The creation date for this channel */ + createAt: number; + + /** creator_id : The user who created this channel */ + creatorId: string; + + /** delete_at : The deletion/archived date of this channel */ + deleteAt: number; + + /** display_name : The channel display name (e.g. Town Square ) */ + displayName: string; + + /** is_group_constrained : If a channel is restricted to certain groups, this boolean will be true and only members of that group have access to this team. Hence indicating that the members of this channel are managed by groups. */ + isGroupConstrained: boolean; + + /** name : The name of the channel (e.g town-square) */ + name: string; + + /** team_id : The team to which this channel belongs. It can be empty for direct/group message. */ + teamId: string; + + /** type : The type of the channel ( e.g. G: group messages, D: direct messages, P: private channel and O: public channel) */ + type: string; + + /** members : Users belonging to this channel */ + members: ChannelMembership[]; + + /** draft : All drafts for this channel */ + drafts: Draft[]; + + /** groupsInChannel : Every group contained in this channel */ + groupsInChannel: GroupsInChannel[]; + + /** posts : all posts made in the channel */ + posts: Post[]; + + /** postsInChannel : a section of the posts for that channel bounded by a range */ + postsInChannel: PostsInChannel[]; + + /** team : The TEAM to which this CHANNEL belongs */ + team: Relation; + + /** creator : The USER who created this CHANNEL*/ + creator: Relation; + + /** info : Query returning extra information about this channel from entity CHANNEL_INFO */ + info: Query; + + /** membership : Query returning the membership data for the current user if it belongs to this channel */ + membership: Query; + + /** settings: User specific settings/preferences for this channel */ + settings: Query; +} diff --git a/types/database/groups_in_team.d.ts b/types/database/groups_in_team.d.ts new file mode 100644 index 0000000000..9b16de015d --- /dev/null +++ b/types/database/groups_in_team.d.ts @@ -0,0 +1,37 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import {Relation} from '@nozbe/watermelondb'; +import Model, {Associations} from '@nozbe/watermelondb/Model'; + +import Group from '@typings/database/group'; +import Team from '@typings/database/team'; + +/** + * The GroupsInTeam links the Team model with the Group model + */ +export default class GroupsInTeam extends Model { + /** table (entity name) : GroupsInTeam */ + static table: string; + + /** associations : Describes every relationship to this entity. */ + static associations: Associations; + + /** group_id : The foreign key to the related Group record */ + groupId: string; + + /** member_count : The number of users in the group */ + memberCount: number; + + /** team_id : The foreign key to the related Team record */ + teamId: string; + + /** timezone_count : The number of timezones */ + timezoneCount: number; + + /** team : The related record to the parent Team model */ + team: Relation; + + /** group : The related record to the parent Team model */ + group: Relation; +} diff --git a/types/database/my_team.d.ts b/types/database/my_team.d.ts new file mode 100644 index 0000000000..a84e608082 --- /dev/null +++ b/types/database/my_team.d.ts @@ -0,0 +1,33 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import {Relation} from '@nozbe/watermelondb'; +import Model, {Associations} from '@nozbe/watermelondb/Model'; + +import Team from '@typings/database/team'; + +/** + * MyTeam represents only the teams that the current user belongs to + */ +export default class MyTeam extends Model { + /** table (entity name) : MyTeam */ + static table: string; + + /** associations : Describes every relationship to this entity. */ + static associations: Associations; + + /** is_unread : Boolean flag for unread messages on team level */ + isUnread: boolean; + + /** mentions_count : Count of posts in which the user has been mentioned */ + mentionsCount: number; + + /** roles : The different permissions that this user has in the team */ + roles: string; + + /** team_id : The foreign key of the 'parent' Team entity */ + teamId: string; + + /** teams : The relation to the entity TEAM, that this user belongs to */ + team: Relation; +} diff --git a/types/database/slash_command.d.ts b/types/database/slash_command.d.ts new file mode 100644 index 0000000000..3e34ddf299 --- /dev/null +++ b/types/database/slash_command.d.ts @@ -0,0 +1,45 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import {Relation} from '@nozbe/watermelondb'; +import Model, {Associations} from '@nozbe/watermelondb/Model'; + +import Team from '@typings/database/team'; + +/** + * The SlashCommand model describes the commands of the various commands available in each team. + */ +export default class SlashCommand extends Model { + /** table (entity name) : SlashCommand */ + static table: string; + + /** associations : Describes every relationship to this entity. */ + static associations: Associations; + + /** is_auto_complete : Boolean flag for auto-completing slash commands */ + isAutoComplete: boolean; + + /** description : The description for the slash command */ + description: string; + + /** display_name : The name for the command */ + displayName: string; + + /** hint : A helpful text explaining the purpose of the command */ + hint: string; + + /** method : API methods like HTTP */ + method: string; + + /** team_id : The foreign key of the parent Team */ + teamId: string; + + /** token : A key identifying this slash command */ + token: string; + + /** trigger : A pattern/text used to recognize when a slash command needs to launch */ + trigger: string; + + /** team : The related parent TEAM record */ + team: Relation; +} diff --git a/types/database/team.d.ts b/types/database/team.d.ts new file mode 100644 index 0000000000..07cc971d23 --- /dev/null +++ b/types/database/team.d.ts @@ -0,0 +1,69 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import {Query} from '@nozbe/watermelondb'; +import Model, {Associations} from '@nozbe/watermelondb/Model'; + +import Channel from '@typings/database/channel'; +import GroupsInTeam from '@typings/database/groups_in_team'; +import MyTeam from '@typings/database/my_team'; +import SlashCommand from '@typings/database/slash_command'; +import TeamChannelHistory from '@typings/database/team_channel_history'; +import TeamMembership from '@typings/database/team_membership'; +import TeamSearchHistory from '@typings/database/team_search_history'; + +/** + * A Team houses and enables communication to happen across channels and users. + */ +export default class Team extends Model { + /** table (entity name) : Team */ + static table: string; + + /** associations : Describes every relationship to this entity. */ + static associations: Associations; + + /** is_allow_open_invite : Boolean flag indicating if this team is open to the public */ + isAllowOpenInvite: boolean; + + /** description : The description for the team */ + description: string; + + /** display_name : The display name for the team */ + displayName: string; + + /** is_group_constrained : Boolean flag indicating if members are managed groups */ + isGroupConstrained: boolean; + + /** last_team_icon_updated_at : Timestamp for when this team's icon has been updated last */ + lastTeamIconUpdatedAt: number; + + /** name : The name for the team */ + name: string; + + /** type : The type of team ( e.g. open/private ) */ + type: string; + + /** allowed_domains : List of domains that can join this team */ + allowedDomains: string; + + /** channels : All the channels associated with this team */ + channels: Channel[]; + + /** groupsInTeam : All the groups associated with this team */ + groupsInTeam: GroupsInTeam[]; + + /** myTeam : Lazy query property returning only the team member that this user is part of */ + myTeam: Query; + + /** slashCommands : All the slash commands associated with this team */ + slashCommands: SlashCommand[]; + + /** teamChannelHistory : A history of the channels in this team that has been visited, ordered by the most recent and capped to the last 5 */ + teamChannelHistory: Query; + + /** members : All the users associated with this team */ + members: TeamMembership[]; + + /** teamSearchHistories : All the searches performed on this team */ + teamSearchHistories: TeamSearchHistory[]; +} diff --git a/types/database/team_channel_history.d.ts b/types/database/team_channel_history.d.ts new file mode 100644 index 0000000000..35f5872111 --- /dev/null +++ b/types/database/team_channel_history.d.ts @@ -0,0 +1,28 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import {Relation} from '@nozbe/watermelondb'; +import Model, {Associations} from '@nozbe/watermelondb/Model'; + +import Team from '@typings/database/team'; + +/** + * The TeamChannelHistory model helps keeping track of the last channel visited + * by the user. + */ +export default class TeamChannelHistory extends Model { + /** table (entity name) : TeamChannelHistory */ + static table: string; + + /** associations : Describes every relationship to this entity. */ + static associations: Associations; + + /** team_id : The foreign key to the related Team record */ + teamId: string; + + /** channelIds : An array containing the last 5 channels visited within this team order by recency */ + channelIds: string[]; + + /** team : The related record from the parent Team model */ + team: Relation; +} diff --git a/types/database/team_membership.d.ts b/types/database/team_membership.d.ts new file mode 100644 index 0000000000..1a9ce24fa3 --- /dev/null +++ b/types/database/team_membership.d.ts @@ -0,0 +1,40 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. +import {Query, Relation} from '@nozbe/watermelondb'; +import Model, {Associations} from '@nozbe/watermelondb/Model'; +import User from '@typings/database/user'; +import Team from '@typings/database/team'; + +/** + * The TeamMembership model represents the 'association table' where many teams have users and many users are in + * teams (relationship type N:N) + */ +export default class TeamMembership extends Model { + /** table (entity name) : TeamMembership */ + static table: string; + + /** associations : Describes every relationship to this entity. */ + static associations: Associations; + + /** team_id : The foreign key to the related Team record */ + teamId: string; + + /* user_id: The foreign key to the related User record*/ + userId: string; + + /** memberUser: The related user in the team */ + memberUser: Relation; + + /** memberTeam : The related team of users */ + memberTeam: Relation; + + /** + * getAllTeamsForUser - Retrieves all the teams that the user is part of + */ + getAllTeamsForUser: Query; + + /** + * getAllUsersInTeam - Retrieves all the users who are part of this team + */ + getAllUsersInTeam: Query; +} diff --git a/types/database/team_search_history.d.ts b/types/database/team_search_history.d.ts new file mode 100644 index 0000000000..7d254e931f --- /dev/null +++ b/types/database/team_search_history.d.ts @@ -0,0 +1,34 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import {Relation} from '@nozbe/watermelondb'; +import Model, {Associations} from '@nozbe/watermelondb/Model'; + +import Team from '@typings/database/team'; + +/** + * The TeamSearchHistory model holds the term searched within a team. The searches are performed + * at team level in the app. + */ +export default class TeamSearchHistory extends Model { + /** table (entity name) : TeamSearchHistory */ + static table: string; + + /** associations : Describes every relationship to this entity. */ + static associations: Associations; + + /** createdAt : The timestamp at which this search was performed */ + createdAt: number; + + /** teamId : The foreign key to the parent Team model */ + teamId: string; + + /** displayTerm : The term that we display to the user */ + displayTerm: string; + + /** term : The term that is sent to the server to perform the search */ + term: string; + + /** team : The related record to the parent team model */ + team: Relation; +} diff --git a/types/database/user.d.ts b/types/database/user.d.ts new file mode 100644 index 0000000000..eff796cbfd --- /dev/null +++ b/types/database/user.d.ts @@ -0,0 +1,112 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import Model, {Associations} from '@nozbe/watermelondb/Model'; + +import Channel from '@typings/database/channel'; +import ChannelMembership from '@typings/database/channel_membership'; +import GroupMembership from '@typings/database/group_membership'; +import Post from '@typings/database/post'; +import Preference from '@typings/database/preference'; +import Reaction from '@typings/database/reaction'; +import TeamMembership from '@typings/database/team_membership'; + +/** + * The User model represents the 'USER' entity and its relationship to other + * shareholders in the app. + */ +export default class User extends Model { + /** table (entity name) : User */ + static table: string; + + /** associations : Describes every relationship to this entity. */ + static associations: Associations; + + /** auth_service : The type of authentication service registered to that user */ + authService: string; + + /** delete_at : The timestamp at which this user account has been archived/deleted */ + deleteAt: number; + + /** email : The email address for that user */ + email: string; + + /** first_name : The user's first name */ + firstName: string; + + /** is_bot : Boolean flag indicating if the user is a bot */ + isBot: boolean; + + /** is_guest : Boolean flag indicating if the user is a guest */ + isGuest: boolean; + + /** last_name : The user's last name */ + lastName: string; + + /** last_picture_update : The timestamp of the last time the profile picture has been updated */ + lastPictureUpdate: number; + + /** locale : The user's locale */ + locale: string; + + /** nickname : The user's nickname */ + nickname: string; + + /** position : The user's position in the company */ + position: string; + + /** roles : The associated roles that this user has */ + roles: string; + + /** status : The presence status for the user */ + status: string; + + /** username : The user's username */ + username: string; + + /** notify_props : Notification preferences/configurations */ + notifyProps: { + channel: true, + desktop: string, + desktop_sound: true, + email: true, + first_name: true + mention_keys: string, + push: string, + }; + + /** props : Custom objects ( e.g. custom status) can be stored in there. Its type definition is known as + * 'excess property check' in Typescript land. We keep using it till we build up the final shape of this object. + */ + props: { + [propName as string] : any + }; + + /** timezone : The timezone for this user */ + timezone: { + automaticTimezone: string + manualTimezone: string, + useAutomaticTimezone: true, + }; + + /** channelsCreated : All the channels that this user created */ + channelsCreated: Channel[]; + + /** channels : All the channels that this user is part of */ + channels: ChannelMembership[]; + + /** groups : All the groups that this user is part of */ + groups: GroupMembership[]; + + /** posts : All the posts that this user has written*/ + posts: Post[]; + + /** preferences : All user preferences */ + preferences: Preference[]; + + /** reactions : All the reactions to posts that this user had */ + reactions: Reaction[]; + + /** teams : All the team that this user is part of */ + teams: TeamMembership[]; +}