mattermost-mobile-upstream/docs/database/server/server.md
cursor[bot] 0869dc8eab
[MM-62038] Fix urgent mention badge colors (#10119)
* [MM-62038] Fix urgent mention badge colors

Persist urgent mention counts and use them to render channel list badges with the urgent color treatment.

Co-authored-by: mattermost-code <matty-code@mattermost.com>

* Address CodeRabbit feedback on urgent mention count persistence

Skip unread updates when fetchMyChannel fails so persisted urgent
counts are not cleared, and preserve urgentMentionCount on partial
MyChannel transformer updates.

Co-authored-by: mattermost-code <matty-code@mattermost.com>

* Use should... names for urgent mention transformer tests

CodeRabbit requested the parameterized transformMyChannelRecord cases
start with should, matching the repo test-name guideline.

Co-authored-by: mattermost-code <matty-code@mattermost.com>

* Address PR feedback: 1 answered, 1 resolved, 0 declined

Persist urgent mention counts on the native killed-app push path
so in-app channel list badges stay urgent-colored after a cold start.

Co-authored-by: mattermost-code <matty-code@mattermost.com>

* Persist computed is_unread on iOS MyChannel update path

CodeRabbit flagged isUnreadCol <- isUnreadCol, which is a no-op.
Write the computed isUnread value so native push updates store
recalculated unread state, matching the insert path and Android.

Co-authored-by: mattermost-code <matty-code@mattermost.com>

* Address PR feedback: 2 answered, 1 resolved, 0 declined

Use the active theme's buttonColor for urgent mention badge text
instead of hardcoded Denim.

Co-authored-by: mattermost-code <matty-code@mattermost.com>

* Address PR feedback: 1 answered, 1 resolved, 0 declined

Treat omitted urgent_mention_count as 0 in transformMyChannelRecord.

Co-authored-by: mattermost-code <matty-code@mattermost.com>

---------

Co-authored-by: Matty Code <mattycode@mattycode-3.com>
Co-authored-by: mattermost-code <matty-code@mattermost.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-09-14 14:03:53 -04:00

506 lines
11 KiB
Markdown

# Server Database - Schema Version 21
# Please bump the version by 1, any time the schema changes.
# Also, include the migration plan under app/database/migration/server,
# update all models, relationships and types.
# Lastly, export all PNGs, SVGs, etc under the source project (./docs/database)
# If you have any question/queries that you would like to clarify, please reach out to the Mobile Platform Team.
Category
-
id PK string # server-generated
collapsed bool
display_name string
muted bool
sort_order number
sorting string # alpha, recent, manual
team_id string INDEX FK >- Team.id
type string # 'channels' | 'direct_messages' | 'favorites' | 'custom'
CategoryChannel
-
id PK string # composition ID Team.id_Channel.id
category_id string INDEX FK >- Category.id
channel_id string INDEX
sort_order number
Channel
-
id PK string FK - CategoryChannel.channel_id # server-generated
create_at string
creator_id string INDEX FK >- User.id
delete_at number
display_name string
is_group_constrained bool
name string INDEX
shared bool
team_id string INDEX FK >- Team.id
type string
update_at number
banner_info string
abac_policy_enforced boolean
autotranslation boolean
ChannelInfo
-
id PK string FK - Channel.id# same value as Channel.id
guest_count number
header string
member_count number
pinned_post_count number
files_count number
purpose string
ChannelMembership
-
id PK string # composition ID Channel.id-User.id
channel_id string INDEX FK >- Channel.id
user_id string INDEX FK >- User.id
scheme_admin bool
CustomEmoji
-
id PK string # auto-generated
name string
CustomProfileField
-
id PK string # server-generated
group_id string
name string
type string
target_id string
target_type string
create_at number
update_at number
delete_at number
attrs string NULL # stringified JSON
CustomProfileAttribute
-
id PK string # composition ID User.id-CustomProfileField.id
field_id string INDEX FK >- CustomProfileField.id
user_id string INDEX FK >- User.id
value string
Draft
-
id PK string # auto-generated
channel_id string INDEX FK >- Channel.id
files string #stringify (array)
message string
root_id string INDEX NULL FK >- Post.id
type string NULL
ScheduledPost
-
id PK string # auto-generated
channel_id string INDEX FK >- Channel.id
files string #stringify (array)
message string
root_id string INDEX NULL FK >- Post.id
metadata string NULL
create_at number
update_at number
scheduled_at number
processed_at number NULL
error_code string
type string NULL
File
-
id PK string # server-generated
extension string
height number
image_thumbnail string #base64 data string or filepath for video thumbnails
local_path string NULL
mime_type string
name string
post_id string INDEX FK >- Post.id
size number
width number
is_blocked bool #Determines if a file has been blocked and cannot be opened anymore
Group
-
id PK string # server-generated
name string INDEX
display_name string
description string
remote_id string INDEX
source string
created_at number
updated_at number
deleted_at number
GroupChannel
-
id PK string # composition ID Group.id-Channel.id
group_id string INDEX FK >- Group.id
channel_id string INDEX FK >- Channel.id
created_at number
updated_at number
deleted_at number
GroupMembership
-
id PK string # composition ID Group.id-User.id
group_id string INDEX FK >- Group.id
user_id string INDEX FK >- User.id
created_at number
updated_at number
deleted_at number
GroupTeam
-
id PK string # composition ID Group.id-Team.id
group_id string INDEX FK >- Group.id
team_id string INDEX FK >- Team.id
created_at number
updated_at number
deleted_at number
MyChannel
-
id PK string FK - Channel.id # same as Channel.id
is_unread boolean
last_post_at number
last_viewed_at number
manually_unread boolean
mentions_count number
urgent_mention_count number
message_count number
roles string
viewed_at number
autotranslation_disabled boolean
MyChannelSettings
-
id PK string FK - MyChannel.id # same as Channel.id
notify_props string
MyTeam
-
id PK string FK - Team.id # same as Team.id
roles string
PlaybookRun
-
id PK string # server-generated
playbook_id string
name string
description string
is_active boolean
active_stage number
active_stage_title string
participant_ids string # stringified array of user IDs
summary string
current_status string # (valid values InProgres, Finished)
owner_user_id string INDEX FK >- User.id
team_id string INDEX FK >- Team.id
channel_id string INDEX FK >- Channel.id
post_id string INDEX FK >- Post.id
create_at number
end_at number
delete_at number
last_status_update_at number
retrospective_enabled boolean
retrospective string
retrospective_published_at number
synced string NULL INDEX # optional field for sync status
last_sync_at number NULL # optional field for last sync timestamp
PlaybookChecklist
-
id PK string # server-generated
run_id string INDEX FK >- PlaybookRun.id
title string
sort_order number
synced string NULL INDEX # optional field for sync status
last_sync_at number NULL # optional field for last sync timestamp
PlaybookChecklistItem
-
id PK string # server-generated
checklist_id string INDEX FK >- PlaybookChecklist.id
title string
description string
state string # e.g., 'open', 'closed'
state_modified number
assignee_id string INDEX FK >- User.id
assignee_modified number
command string
command_last_run number
due_date number
task_actions string # stringified array of TaskAction
condition_action string # condition action for the checklist item (values should be '' or 'hidden')
condition_reason string # condition reason for the checklist item (default empty string meaning there is no condition affecting)
order number
completed_at number
synced string NULL INDEX # optional field for sync status
last_sync_at number NULL # optional field for last sync timestamp
PlaybookRunAttribute
-
id PK string # server-generated
group_id string
name string
type string
target_id string
target_type string
create_at number
update_at number
delete_at number
attrs string NULL # stringified JSON
PlaybookRunAttributeValue
-
id PK string # composition ID PlaybookRun.id-PlaybookRunAttribute.id
attribute_id string INDEX FK >- PlaybookRunAttribute.id
run_id string INDEX FK >- PlaybookRun.id
value string
Post
-
id PK string # server generated
channel_id string INDEX FK >- Channel.id
create_at number
delete_at number
edit_at number
is_pinned boolean
message string
metadata string NULL
original_id string
pending_post_id string INDEX
previous_post_id string
props string
root_id string
type string INDEX
update_at number
user_id string INDEX FK >- User.id
PostsInChannel
-
id PK string # auto-generated
channel_id string INDEX FK >- Channel.id
earliest number
latest number
PostsInThread
-
id PK string # auto-generated
earliest number
latest number
root_id string FK >- Post.id
Preference
-
id string PK # server-generated
category string INDEX
name string
user_id string INDEX FK >- User.id
value string
Reaction
-
id PK string # server-generated
create_at number
emoji_name string
post_id string INDEX FK >- Post.id
user_id string INDEX FK >- User.id
Role
-
id PK string # server-generated
name string
permissions string #stringify array
System
-
id PK string # SYSTEM_IDENTIFIERS
value string
Team
-
id PK string # server-generated
allowed_domains string
description string
display_name string
is_allow_open_invite boolean
is_group_constrained boolean
last_team_icon_updated_at number
name string
type string
update_at number
TeamChannelHistory
-
id PK string FK - Team.id # same as Team.id
channel_ids string # stringified JSON array; FIFO
TeamMembership
-
id PK string # auto-generated
team_id string INDEX FK >- Team.id
user_id string INDEX FK >- User.id
scheme_admin bool
TeamSearchHistory
-
id PK string # auto-generated
created_at number
display_term string
team_id string FK >- Team.id
term string
Thread
-
id PK string FK - Post.id # similar to Post.id but for root post only
is_following boolean
last_reply_at number
last_viewed_at number
reply_count number
unread_mentions number
unread_replies number
viewed_at number
ThreadsInTeam
-
id PK string # auto-generated
loaded_in_global_threads boolean
team_id string INDEX FK >- Team.id
thread_id string INDEX FK >- Thread.id
ThreadParticipant # who is participating in this conversation
-
id PK string # auto-generated
thread_id string INDEX FK >- Thread.id
user_id string INDEX FK >- User.id
User
-
id PK string # server generated
auth_service string
delete_at number
email string
first_name string
is_bot boolean
is_guest boolean
last_name string
last_picture_update number
locale string
nickname string
notify_props string
position string
props string
remote_id string NULL
roles string
status string
timezone string
update_at number
username string
AiBot
-
id PK string
display_name string
username string
last_icon_update number
dm_channel_id string INDEX
channel_access_level number
channel_ids string
user_access_level number
user_ids string
team_ids string
AiThread
-
id PK string
message string
title string
channel_id string INDEX FK >- Channel.id
reply_count number
update_at number INDEX
BoardView
-
# WatermelonDB table name is BoardView; the domain model class is BoardViewModel.
# "BoardView" avoids collision with SQL's reserved VIEW keyword (and with React Native's View) and encodes the boards semantics.
id PK string # server-generated
channel_id string INDEX FK >- Channel.id
type string # 'kanban'
creator_id string FK >- User.id
title string
description string
sort_order number
props string # JSON
create_at number
update_at number INDEX
delete_at number # soft-delete, 0 when active
PropertyField
-
# Definition of a card (or other object) property. Shared infrastructure reused by future property-based features.
id PK string # server-generated
group_id string # opaque; resolved server-side
name string
type string # 'text' | 'select' | 'multiselect' | ...
attrs string # JSON (options, sort_order, ...)
object_type string # 'card' | 'post' | 'user'
target_id string INDEX # scope target (channel/team id, empty for system)
target_type string # 'system' | 'team' | 'channel'
protected boolean
permission_field string
permission_values string # JSON
permission_options string # JSON
create_at number
update_at number INDEX
delete_at number # soft-delete, 0 when active
created_by string FK >- User.id
updated_by string FK >- User.id
PropertyValue
-
# Single object's value for a single PropertyField.
# target_id is polymorphic (keyed by target_type); no typed WatermelonDB relation is declared for it.
id PK string # server-generated
field_id string INDEX FK >- PropertyField.id
target_id string INDEX # polymorphic target
target_type string # 'post' | 'user' | ...
group_id string
value string # JSON (shape depends on field type)
create_at number
update_at number
delete_at number # soft-delete, 0 when active
created_by string FK >- User.id
updated_by string FK >- User.id