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

332 lines
9.1 KiB
Markdown

# RethinkDB 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
* `State` account state: normal (ok), suspended, soft-deleted
* `StateAt` timestamp when the state was last updated or NULL
* `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` state of the user: normal, disabled, 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` multi-index (indexed array)
* `DeletedAt` index
* `DeviceIds` multi-index of push notification tokens
Sample:
```js
{
"Access": {
"Anon": 0 ,
"Auth": 47
} ,
"CreatedAt": Mon Jul 24 2017 11:16:38 GMT+00:00 ,
"State": 0,
"StateAt": null ,
"Devices": null ,
"Id": "7yUCHniegrM" ,
"LastSeen": Mon Jan 01 1 00:00:00 GMT+00:00 ,
"Public": {
"fn": "Alice Johnson" ,
"photo": {
"data": <binary, 6.5KB, "ff d8 ff e0 00 10..."> ,
"type": "jpg"
}
} ,
"State": 1 ,
"Tags": [
"email:alice@example.com" ,
"tel:17025550001"
] ,
"UpdatedAt": Mon Jul 24 2017 11:16:38 GMT+00:00 ,
"UserAgent": "TinodeWeb/0.13 (MacIntel) tinodejs/0.13"
}
```
### Table `auth`
Stores authentication secrets
Fields:
* `userid` ID of the user who owns the record
* `unique` unique string which identifies this record, primary key; defined as "_authentication scheme_':'_some unique value per scheme_"
* `secret` shared secret, for instance bcrypt of password
* `authLvl` authentication level
* `expires` timestamp when the records expires
Indexes:
* `unique` primary key
* `userid` index
Sample:
```js
{
"authLvl": 20 ,
"expires": Mon Jan 01 1 00:00:00 GMT+00:00 ,
"secret": <binary, 60 bytes, "24 32 61 24 31 30..."> ,
"unique": "basic:alice" ,
"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
* `State` topic state: normal (ok), suspended, soft-deleted
* `StateAt` timestamp when the state was last updated or NULL
* `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` state of the topic: normal, disabled, deleted
* `SeqId` sequential ID of the last message
* `DelId` topic-sequential ID of the deletion operation
* `UseBt` indicator that channel functionality is enabled in the topic
Indexes:
* `Id` primary key
* `Owner` index
Sample:
```js
{
"Access": {
"Anon": 64 ,
"Auth": 64
} ,
"DelId": 0,
"CreatedAt": Thu Oct 15 2015 04:06:51 GMT+00:00 ,
"State": 0 ,
"StateAt": null ,
"LastMessageAt": Sat Oct 17 2015 13:51:56 GMT+00:00 ,
"Id": "p2pavVGHLCBbKrvJQIeeJ6Csw" ,
"Owner": "v2JyG4OLSoA" ,
"Public": {
"fn": "Travel, travel, travel" ,
"photo": {
"data": <binary, 6.2KB, "ff d8 ff e0 00 10..."> ,
"type": "jpg"
}
} ,
"SeqId": 14,
"State": 0 ,
"UpdatedAt": Thu Oct 15 2015 04:06:51 GMT+00:00 ,
"UseBt": false
}
```
### Table `subscriptions`
The table stores relationships between users and topics.
Fields:
* `Id` used for object retrieval
* `CreatedAt` timestamp when the subscription was created
* `UpdatedAt` timestamp when the subscription was updated
* `DeletedAt` timestamp when the subscription was deleted
* `ReadSeqId` id of the message last read by the user
* `RecvSeqId` id of the message last received by any 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:
```js
{
"ClearId": 0 ,
"CreatedAt": Tue Jul 25 2017 15:34:39 GMT+00:00 ,
"DeletedAt": null ,
"Id": "grpjajVKrHn0PU:v2JyG4OLSoA" ,
"ModeGiven": 47 ,
"ModeWant": 47 ,
"Private": "Kirgudu" ,
"ReadSeqId": 0 ,
"RecvSeqId": 0 ,
"State": 0 ,
"Topic": "grpjajVKrHn0PU" ,
"UpdatedAt": Tue Jul 25 2017 15:34:39 GMT+00:00 ,
"User": "v2JyG4OLSoA"
}
```
### 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
* `Topic_SeqId` compound index `["Topic", "SeqId"]`
* `Topic_DelId` compound index `["Topic", "DelId"]`
* `Topic_DeletedFor` compound multi-index `["Topic", "DeletedFor"("User"), "DeletedFor"("DelId")]`
Sample:
```js
{
"Content": {
"fmt": [
{
"len": 6 ,
"tp": "ST"
}
] ,
"txt": "Hello!"
} ,
"CreatedAt": Sun Dec 24 2017 05:16:23 GMT+00:00 ,
"From": "wTI0jO9rEqY" ,
"Head": {
"mime": "text/x-drafty"
} ,
"DeletedFor": [
{
"DelId": 1 ,
"User": "wTI0jO9rEqY"
}
] ,
"Id": "LLXKEe9W4Bs" ,
"SeqId": 3 ,
"Topic": "p2pJhbJnya8z5PBMjSM72sSpg" ,
"UpdatedAt": Sun Dec 24 2017 05:16:23 GMT+00:00
}
```
### 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:
```js
{
"Id": "9LfrjW349Rc",
"CreatedAt": Tue Dec 05 2017 01:51:38 GMT+00:00,
"DelId": 18,
"DeletedFor": "xY-YHx09-WI" ,
"SeqIdRanges": [
{
"Low": 20,
"Hi": 25,
}
] ,
"Topic": "grpGx7fpjQwVC0" ,
"UpdatedAt": Tue Dec 05 2017 01:51:38 GMT+00:00
}
```
### 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
* `Closed` unvalidated credential is no longer being validated. Only one credential is not Closed for each user/method.
Indexes:
* `Id` Primary key composed either as `User`:`Method`:`Value` for unconfirmed credentials or as `Method`:`Value` for confirmed.
* `User` Index
Sample:
```js
{
"Id": "tel:+17025550001",
"CreatedAt": Sun Jun 10 2018 16:37:27 GMT+00:00 ,
"UpdatedAt": Sun Jun 10 2018 16:37:28 GMT+00:00 ,
"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` primary key
* `UseCount` index
Sample:
```js
{
"CreatedAt": Sun Jun 10 2018 16:38:45 GMT+00:00 ,
"Id": "sFmjlQ_kA6A" ,
"Location": "uploads/sFmjlQ_kA6A" ,
"MimeType": "image/jpeg" ,
"Size": 54961090 ,
"UseCount": 3,
"Status": 1,
"UpdatedAt": Sun Jun 10 2018 16:38:45 GMT+00:00 ,
"User": "7j-RR1V7O3Y"
}
```