base on Monorepo for Revolt backend services. <div align="center">
<h1>
Revolt Backend
[](https://github.com/revoltchat/backend/stargazers)
[](https://github.com/revoltchat/backend/network/members)
[](https://github.com/revoltchat/backend/pulls)
[](https://github.com/revoltchat/backend/issues)
[](https://github.com/revoltchat/backend/graphs/contributors)
[](https://github.com/revoltchat/backend/blob/main/LICENSE)
</h1>
The services and libraries that power the Revolt service.<br/>
<br/>
| Crate | Path | Description | |
| ------------------ | -------------------------------------------------- | ---------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `core/config` | [crates/core/config](crates/core/config) | Core: Configuration |     |
| `core/database` | [crates/core/database](crates/core/database) | Core: Database Implementation |     |
| `core/files` | [crates/core/files](crates/core/files) | Core: S3 and encryption subroutines |     |
| `core/models` | [crates/core/models](crates/core/models) | Core: API Models |     |
| `core/permissions` | [crates/core/permissions](crates/core/permissions) | Core: Permission Logic |     |
| `core/presence` | [crates/core/presence](crates/core/presence) | Core: User Presence |     |
| `core/result` | [crates/core/result](crates/core/result) | Core: Result and Error types |     |
| `delta` | [crates/delta](crates/delta) | REST API server |  |
| `bonfire` | [crates/bonfire](crates/bonfire) | WebSocket events server |  |
| `services/january` | [crates/services/january](crates/services/january) | Proxy server |  |
| `services/autumn` | [crates/services/autumn](crates/services/autumn) | File server |  |
| `bindings/node` | [crates/bindings/node](crates/bindings/node) | Node.js bindings for the Revolt software |  |
| `daemons/crond` | [crates/daemons/crond](crates/daemons/crond) | Timed data clean up daemon server |  |
| `daemons/pushd` | [crates/daemons/pushd](crates/daemons/pushd) | Push notification daemon server |  |
</div>
<br/>
## Minimum Supported Rust Version
Rust 1.76 or higher.
> [!CAUTION]
> The events server has a significant performance regression between Rust 1.77.2 and 1.78.0 onwards, see [issue #341](https://github.com/revoltchat/backend/issues/341).
## Development Guide
Before contributing, make yourself familiar with [our contribution guidelines](https://developers.revolt.chat/contrib.html) and the [technical documentation for this project](https://revoltchat.github.io/backend/).
Before getting started, you'll want to install:
- Rust toolchain (rustup recommended)
- Docker
- Git
- mold (optional, faster compilation)
> A **default.nix** is available for Nix users!
> Just run `nix-shell` and continue.
As a heads-up, the development environment uses the following ports:
| Service | Port |
| ------------------------- | :------------: |
| MongoDB | 27017 |
| Redis | 6379 |
| MinIO | 14009 |
| Maildev | 14025<br>14080 |
| Revolt Web App | 14701 |
| RabbitMQ | 5672<br>15672 |
| `crates/delta` | 14702 |
| `crates/bonfire` | 14703 |
| `crates/services/autumn` | 14704 |
| `crates/services/january` | 14705 |
Now you can clone and build the project:
```bash
git clone https://github.com/revoltchat/backend revolt-backend
cd revolt-backend
cargo build
```
A default configuration `Revolt.toml` is present in this project that is suited for development.
If you'd like to change anything, create a `Revolt.overrides.toml` file and specify relevant variables.
> [!TIP]
> Use Sentry to catch unexpected service errors:
>
> ```toml
> # Revolt.overrides.toml
> [sentry]
> api = "https://
[email protected]/1"
> events = "https://
[email protected]/1"
> files = "https://
[email protected]/1"
> proxy = "https://
[email protected]/1"
> ```
> [!TIP]
> If you have port conflicts on common services, you can try the following:
>
> ```yaml
> # compose.override.yml
> services:
> redis:
> ports: !override
> - "14079:6379"
>
> database:
> ports: !override
> - "14017:27017"
>
> rabbit:
> ports: !override
> - "14072:5672"
> - "14672:15672"
> ```
>
> And corresponding Revolt configuration:
>
> ```toml
> # Revolt.overrides.toml
> [database]
> mongodb = "mongodb://127.0.0.1:14017"
> redis = "redis://127.0.0.1:14079/"
>
> [rabbit]
> port = 14072
> ```
Then continue:
```bash
# start other necessary services
docker compose up -d
# run everything together
./scripts/start.sh
# .. or individually
# run the API server
cargo run --bin revolt-delta
# run the events server
cargo run --bin revolt-bonfire
# run the file server
cargo run --bin revolt-autumn
# run the proxy server
cargo run --bin revolt-january
# run the push daemon (not usually needed in regular development)
cargo run --bin revolt-pushd
# hint:
# mold -run <cargo build, cargo run, etc...>
# mold -run ./scripts/start.sh
```
You can start a web client by doing the following:
```bash
# if you do not have yarn yet and have a modern Node.js:
corepack enable
# clone the web client and run it:
git clone --recursive https://github.com/revoltchat/revite
cd revite
yarn
yarn build:deps
echo "VITE_API_URL=http://local.revolt.chat:14702" > .env.local
yarn dev --port 14701
```
Then go to http://local.revolt.chat:14701 to create an account/login.
When signing up, go to http://localhost:14080 to find confirmation/password reset emails.
## Deployment Guide
### Cutting new crate releases
Begin by bumping crate versions:
```bash
just patch # 0.0.X
just minor # 0.X.0
just major # X.0.0
```
Then commit the changes to package files.
Proceed to publish all the new crates:
```bash
just publish
```
### Cutting new binary releases
Tag and push a new release by running:
```bash
just release
```
If you have bumped the crate versions, proceed to [GitHub releases](https://github.com/revoltchat/backend/releases/new) to create a changelog.
## Testing
First, start the required services:
```sh
docker compose -f docker-compose.db.yml up -d
```
Now run tests for whichever database:
```sh
TEST_DB=REFERENCE cargo nextest run
TEST_DB=MONGODB cargo nextest run
```
## License
The Revolt backend is generally licensed under the [GNU Affero General Public License v3.0](https://github.com/revoltchat/backend/blob/master/LICENSE).
**Individual crates may supply their own licenses!**
", Assign "at most 3 tags" to the expected json: {"id":"11940","tags":[]} "only from the tags list I provide: [{"id":77,"name":"3d"},{"id":89,"name":"agent"},{"id":17,"name":"ai"},{"id":54,"name":"algorithm"},{"id":24,"name":"api"},{"id":44,"name":"authentication"},{"id":3,"name":"aws"},{"id":27,"name":"backend"},{"id":60,"name":"benchmark"},{"id":72,"name":"best-practices"},{"id":39,"name":"bitcoin"},{"id":37,"name":"blockchain"},{"id":1,"name":"blog"},{"id":45,"name":"bundler"},{"id":58,"name":"cache"},{"id":21,"name":"chat"},{"id":49,"name":"cicd"},{"id":4,"name":"cli"},{"id":64,"name":"cloud-native"},{"id":48,"name":"cms"},{"id":61,"name":"compiler"},{"id":68,"name":"containerization"},{"id":92,"name":"crm"},{"id":34,"name":"data"},{"id":47,"name":"database"},{"id":8,"name":"declarative-gui "},{"id":9,"name":"deploy-tool"},{"id":53,"name":"desktop-app"},{"id":6,"name":"dev-exp-lib"},{"id":59,"name":"dev-tool"},{"id":13,"name":"ecommerce"},{"id":26,"name":"editor"},{"id":66,"name":"emulator"},{"id":62,"name":"filesystem"},{"id":80,"name":"finance"},{"id":15,"name":"firmware"},{"id":73,"name":"for-fun"},{"id":2,"name":"framework"},{"id":11,"name":"frontend"},{"id":22,"name":"game"},{"id":81,"name":"game-engine "},{"id":23,"name":"graphql"},{"id":84,"name":"gui"},{"id":91,"name":"http"},{"id":5,"name":"http-client"},{"id":51,"name":"iac"},{"id":30,"name":"ide"},{"id":78,"name":"iot"},{"id":40,"name":"json"},{"id":83,"name":"julian"},{"id":38,"name":"k8s"},{"id":31,"name":"language"},{"id":10,"name":"learning-resource"},{"id":33,"name":"lib"},{"id":41,"name":"linter"},{"id":28,"name":"lms"},{"id":16,"name":"logging"},{"id":76,"name":"low-code"},{"id":90,"name":"message-queue"},{"id":42,"name":"mobile-app"},{"id":18,"name":"monitoring"},{"id":36,"name":"networking"},{"id":7,"name":"node-version"},{"id":55,"name":"nosql"},{"id":57,"name":"observability"},{"id":46,"name":"orm"},{"id":52,"name":"os"},{"id":14,"name":"parser"},{"id":74,"name":"react"},{"id":82,"name":"real-time"},{"id":56,"name":"robot"},{"id":65,"name":"runtime"},{"id":32,"name":"sdk"},{"id":71,"name":"search"},{"id":63,"name":"secrets"},{"id":25,"name":"security"},{"id":85,"name":"server"},{"id":86,"name":"serverless"},{"id":70,"name":"storage"},{"id":75,"name":"system-design"},{"id":79,"name":"terminal"},{"id":29,"name":"testing"},{"id":12,"name":"ui"},{"id":50,"name":"ux"},{"id":88,"name":"video"},{"id":20,"name":"web-app"},{"id":35,"name":"web-server"},{"id":43,"name":"webassembly"},{"id":69,"name":"workflow"},{"id":87,"name":"yaml"}]" returns me the "expected json"