Files
im_server/server/db/mongodb/schema.md
T
2026-08-11 15:59:57 +08:00

323 lines
8.4 KiB
Markdown

# MongoDB Database Schema
## Database `tinode`
### Table `users`
Stores user accounts
Fields:
* `_id` user id, primary key
* `createdat` timestamp when the user was created
* `updatedat` timestamp when user metadata was updated
* `access` user's default access level for peer-to-peer topics
* `auth`, `anon` default permissions for authenticated and anonymous users
* `public` application-defined data
* `state` account state: normal (ok), suspended, soft-deleted
* `stateat` timestamp when the state was last updated or NULL
* `lastseen` timestamp when the user was last online
* `useragent` client User-Agent used when last online
* `tags` unique strings for user discovery
* `devices` client devices for push notifications
* `deviceid` device registration ID
* `platform` device platform string (iOS, Android, Web)
* `lastseen` last logged in
* `lang` device language, ISO code
Indexes:
* `_id` primary key
* `tags` multikey-index (indexed array)
* `deletedat` index
* `deviceids` multikey-index of push notification tokens
Sample:
```json
{
"access": {
"anon": 0 ,
"auth": 47
} ,
"createdat": "2019-10-11T12:13:14.522Z" ,
"state": 0,
"stateat": null ,
"devices": null ,
"_id": "7yUCHniegrM" ,
"lastseen": "2019-10-11T12:13:14.522Z" ,
"public": {
"fn": "Alice Johnson" ,
"photo": {
"data": Binary('/9j/4AAQSkZJRgAB...'),
"type": "jpg"
}
} ,
"state": 1 ,
"tags": [
"email:alice@example.com" ,
"tel:17025550001"
] ,
"updatedat": "2019-10-11T12:13:14.522Z",
"useragent": "TinodeWeb/0.13 (MacIntel) tinodejs/0.13"
}
```
### Table `auth`
Stores authentication secrets
Fields:
* `_id` unique string which identifies this record, primary key; defined as "_authentication scheme_':'_some unique value per scheme_"
* `userid` ID of the user who owns the record
* `secret` shared secret, for instance bcrypt of password
* `authLvl` authentication level
* `expires` timestamp when the records expires
Indexes:
* `_id` primary key
* `userid` index
Sample:
```json
{
"_id": "basic:alice" ,
"authLvl": 20 ,
"expires": "2019-10-11T12:13:14.522Z" ,
"secret": Binary('/9j/RgAB...'),
"userid": "7yUCHniegrM"
}
```
### Table `topics`
The table stores topics.
Fields:
* `_id` name of the topic, primary key
* `createdat` topic creation time
* `updatedat` timestamp of the last change to topic metadata
* `access` stores topic's default access permissions
* `auth`, `anon` permissions for authenticated and anonymous users respectively
* `owner` ID of the user who owns the topic
* `public` application-defined data
* `state` topic state: normal (ok), suspended, soft-deleted
* `stateat` timestamp when the state was last updated or NULL
* `seqid` sequential ID of the last message
* `delid` topic-sequential ID of the deletion operation
* `usebt` currently unused
Indexes:
* `_id` primary key
* `owner` index
* `tags` multikey index
Sample:
```json
{
"access": {
"anon": 64 ,
"auth": 64
} ,
"delid": 0,
"createdat": "2019-10-11T12:13:14.522Z",
"lastmessageat": "2019-10-11T12:13:14.522Z" ,
"id": "p2pavVGHLCBbKrvJQIeeJ6Csw" ,
"owner": "v2JyG4OLSoA" ,
"public": {
"fn": "Travel, travel, travel" ,
"photo": {
"data": Binary('/9j/RgAB...') ,
"type": "jpg"
}
} ,
"seqid": 14,
"state": 0,
"stateat": null,
"updatedat": "2019-10-11T12:13:14.522Z" ,
"usebt": false
}
```
### Table `subscriptions`
The table stores relationships between users and topics.
Fields:
* `_id` used for object retrieval
* `createdat` timestamp when the user was created
* `updatedat` timestamp when user metadata was updated
* `deletedat` currently unused
* `readseqid` id of the message last read by the user
* `recvseqid` id of the message last received by user device
* `delid` topic-sequential ID of the soft-deletion operation
* `topic` name of the topic subscribed to
* `user` subscriber's user ID
* `modewant` access mode that user wants when accessing the topic
* `modegiven` access mode granted to user by the topic
* `private` application-defined data, accessible by the user only
Indexes:
* `_id` primary key composed as "_topic name_':'_user ID_"
* `user` index
* `topic` index
Sample:
```json
{
"_id": "grpjajVKrHn0PU:v2JyG4OLSoA" ,
"createdat": "2019-10-11T12:13:14.522Z" ,
"updatedat": "2019-10-11T12:13:14.522Z" ,
"deletedat": null ,
"user": "v2JyG4OLSoA",
"topic": "grpjajVKrHn0PU" ,
"recvseqid": 0 ,
"readseqid": 0 ,
"modewant": 47 ,
"modegiven": 47 ,
"private": "Kirgudu" ,
"state": 0
}
```
### Table `messages`
The table stores `{data}` messages
Fields:
* `_id` currently unused, primary key
* `createdat` timestamp when the message was created
* `updatedat` initially equal to CreatedAt, for deleted messages equal to DeletedAt
* `deletedfor` array of user IDs which soft-deleted the message
* `delid` topic-sequential ID of the soft-deletion operation
* `user` ID of the user who soft-deleted the message
* `from` ID of the user who generated this message
* `topic` which received this message
* `seqid` messages ID - sequential number of the message in the topic
* `head` message headers
* `attachments` denormalized IDs of files attached to the message
* `content` application-defined message payload
Indexes:
* `_id` primary key
Sample:
```json
{
"_id": "LLXKEe9W4Bs" ,
"createdat": "2019-10-11T12:13:14.522Z" ,
"updatedat": "2019-10-11T12:13:14.522Z",
"deletedfor": [
{
"delid": 1 ,
"user": "wTI0jO9rEqY"
}
] ,
"seqid": 3 ,
"topic": "p2pJhbJnya8z5PBMjSM72sSpg",
"from": "wTI0jO9rEqY" ,
"head": {
"mime": "text/x-drafty"
} ,
"content": {
"fmt": [
{
"len": 6 ,
"tp": "ST"
}
] ,
"txt": "Hello!"
}
}
```
### Table `dellog`
The table stores records of message deletions
Fields:
* `_id` currently unused, primary key
* `createdat` timestamp when the record was created
* `updatedat` timestamp equal to CreatedAt
* `delid` topic-sequential ID of the deletion operation.
* `deletedfor` ID of the user for soft-deletions, blank string for hard-deletions
* `topic` affected topic
* `seqidranges` array of ranges of deleted message IDs (see `messages.seqid`)
Indexes:
* `_id` primary key
* `topic_delid` compound index `["Topic", "DelId"]`
Sample:
```json
{
"_id": "9LfrjW349Rc",
"createdat": "2019-10-11T12:13:14.522Z",
"updatedat": "2019-10-11T12:13:14.522Z",
"topic": "grpGx7fpjQwVC0",
"delid": 18,
"deletedfor": "xY-YHx09-WI",
"seqidranges": [
{
"low": 20,
"hi": 25
}
]
}
```
### Table `credentials`
The tables stores user credentials used for validation.
* `_id` credential, primary key
* `createdat` timestamp when the record was created
* `updatedat` timestamp when the last validation attempt was performed (successful or not).
* `method` validation method
* `done` indicator if the credential is validated
* `resp` expected validation response
* `retries` number of failed attempts at validation
* `user` id of the user who owns this credential
* `value` value of the credential
Indexes:
* `_id` Primary key composed either as `user`:`method`:`value` for unconfirmed credentials or as `method`:`value` for confirmed.
* `user` Index
Sample:
```json
{
"Id": "tel:+17025550001",
"CreatedAt": "2019-10-11T12:13:14.522Z",
"UpdatedAt": "2019-10-11T12:13:14.522Z",
"Method": "tel" ,
"Done": true ,
"Resp": "123456" ,
"Retries": 0 ,
"User": "k3srBRk9RYw" ,
"Value": "+17025550001"
}
```
### Table `fileuploads`
The table stores records of uploaded files. The files themselves are stored outside of the database.
* `_id` unique user-visible file name, primary key
* `createdat` timestamp when the record was created
* `updatedat` timestamp of when th upload has cmpleted or failed
* `user` id of the user who uploaded this file.
* `location` actual location of the file on the server.
* `mimetype` file content type as a [Mime](https://en.wikipedia.org/wiki/MIME) string.
* `size` size of the file in bytes. Could be 0 if upload has not completed yet.
* `usecount` count of messages referencing this file.
* `status` upload status: 0 pending, 1 completed, -1 failed.
Indexes:
* `_id` file name, primary key
* `user` index
* `usecount` index
Sample:
```json
{
"_id": "sFmjlQ_kA6A" ,
"createdat": "2019-10-11T12:13:14.522Z" ,
"updatedat": "2019-10-11T12:13:14.522Z" ,
"location": "uploads/sFmjlQ_kA6A" ,
"mimetype": "image/jpeg" ,
"size": 54961090 ,
"usecount": 3,
"status": 1 ,
"user": "7j-RR1V7O3Y"
}
```