Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 91 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,92 @@
# xContest API
# xContest REST API
![Build Action Workflow Status](https://img.shields.io/github/actions/workflow/status/xcontest/api/docker_build.yml)
![Test Action Workflow Status](https://img.shields.io/github/actions/workflow/status/xcontest/api/api_testing.yml?label=tests)
![GitHub commit activity](https://img.shields.io/github/commit-activity/w/xcontest/api)
![GitHub Repo stars](https://img.shields.io/github/stars/xcontest/api?style=flat)
![GitHub License](https://img.shields.io/github/license/xcontest/api)

The API component for the xContest application. Allows for hosting events of different types.
---
## Project Overview
The xContest REST API is designed to provide a standardized interface for accessing and manipulating data related to the xContest project.
It is used by various other components like the xContest web application and the xContest CLI.
The API is built using Node.JS and AdonisJS framework.
It also contains a set of custom tools like OpenAPI documentation generator and builtin UI for the generated spec.

---
## Features
This component is still under active development and does not yet contain all the features planned for the final project.
At this moment we focus heavily on the hackathon functionality, but it is planned to include other features
for algorithmic competitions with automated evaluation and CTFs as well.

At the moment features supported by the API are:
- User authentication and authorization via email and password or OAuth2,
- Creation and management of events,
- Creation and management of hackathon-related tasks,
- Creation and management participant teams,
- Submission and evaluation of hackathon tasks,

More features will be added in the future.

---
## Running the API
Recommended, and the easiest way to run the API is using Docker.
You can use the provided `docker-compose.yml` file to set up the necessary services, including the database and the API itself.

Before running the API, you will need to create a `.env` file in the project root directory and fill it with the necessary environment variables.
The `.env.example` file contains all the necessary variables and their example values.
Please replace the values with your own.

To run the API this way you will need to have [Docker](https://www.docker.com/get-started/) installed on your machine.
After that, running the project is as simple as executing the following command in the project root directory:
```shell
docker compose --profile <profile> up -d
```
Where `<profile>` is the name of the profile you want to run. Currently available profiles are:
- `prod` - for production environment.
- `dev` - for development environment (with HMR),
- `base` - starts only required services (database, object storage, redis)

Production and development profiles will run everything needed to run the API.

To stop the API and all related services, you can use the following command:
```shell
docker compose --profile <profile> down
```
Stopping the API this way will preserve the data stored in the database and object storage,
so you can safely stop and start the API without losing any data.

If, however, you want to shut everything down and start over, you can add the `-v` flag to the end of `down` command.
This will permanently remove all the data stored in the database and object storage.

For more details on deployment, please refer to the [deployment guide](docs/DEPLOYMENT.md).

---
# License
This project is licensed under [AGPLv3.0](/LICENSE.md).
For more information, please refer to <https://www.gnu.org/licenses/agpl-3.0.html>.

---
## Maintainers & Contact

The core team responsible for the strategic direction and maintenance of the project.

| [<img src="https://github.com/InfoX1337.png?size=100" width="100px;"/><br /><sub><b>@InfoX1337</b></sub>](https://github.com/InfoX1337)<br />Developer | [<img src="https://github.com/olix3001.png?size=100" width="100px;"/><br /><sub><b>@olix3001</b></sub>](https://github.com/olix3001)<br />Developer | [<img src="https://github.com/InfoTCube.png?size=100" width="100px;"/><br /><sub><b>@InfoTCube</b></sub>](https://github.com/InfoTCube)<br />Developer |
|:------------------------------------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------------------------:|

If you find any issues or have any questions, please feel free to reach out to us on [GitHub](https://github.com/xcontest/api/issues).
We are always happy to help!

If you are interested in using our project for your events and
need some help setting it up, please reach out to us privately (contact info will be provided in the near future).

---
## Contributors
Thank you to all the contributors who have helped make this project possible!
We greatly appreciate your help! :heart:
If you would like to contribute to this project, please see our [contributing guidelines](docs/CONTRIBUTING.md).

<a href="https://github.com/xcontest/api/graphs/contributors">
<img src="https://contrib.rocks/image?repo=xcontest/api" />
</a>

Made with [contrib.rocks](https://contrib.rocks).
138 changes: 138 additions & 0 deletions docs/CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
# Contributing to xContest

Thank you for your interest in contributing! To maintain a high standard of code quality and a clean project history, we enforce the following guidelines.

---
## Development Environment

This project requires **pnpm** for package management.

To set up your development environment, first clone the repository:
```shell
git clone https://github.com/xcontest/api
```
Then, navigate to the project directory and install dependencies:
```shell
pnpm install
```
And finally, create `.env` file based on `.env.example`.
Just copy the content of `.env.example` and paste it into `.env` file.
This will provide you with a mostly working configuration.
Although, features like mailer and oauth2 will require providing your own credentials.

> [!IMPORTANT]
> Before continuing any further, please ensure you have [Docker](https://docs.docker.com/get-docker/) installed on your machine.

There are two main ways of developing the project, depending on your needs and preferences:
### Full Docker setup:
Our app supports HMR inside a docker container for development.
To run everything inside the container, all you need to do is run the following command in the project root directory:
```shell
docker compose --profile dev up -d
```
Provided you have followed all steps correctly,
you should be able to access the app at `http://localhost:3333`.

### Docker for services only:
If you prefer running the app manually, you can use docker to run only the services required for development.
Those services include: PostgreSQL, SeaweedFS, and Redis.
To do so, run the following command:
```shell
docker compose --profile base up -d
```
This will start all required services in the background, and you can run the app manually using `pnpm dev` command.
This setup is also useful for running tests, as it will only require using `node ace test` command.

---
# Guidelines

Here are some guidelines to follow when contributing to the project.
Those help us maintain a consistent code base and ensure a smooth development process.
Please note that code not following these guidelines will be rejected.

### Code Style
We enforce a consistent code style using our custom ESLint configuration.
Those rules are defined in [`eslint.config.js`](/eslint.config.js) file.
Please make sure your code follows these guidelines before submitting a Pull Request:
* Run `pnpm lint` for standard ESLint checks.
* Run `pnpm check` for full validation (ESLint + Semgrep).
*Note: You must have [Semgrep](https://semgrep.dev/) installed manually on your machine.*

Currently semgrep only checks for known common mistakes we have identified, like
using `bouncer.allows(...)` instead of `bouncer.authorize(...)`, which is a security risk.

### Testing
We use [Jest](https://jestjs.io/) for testing our application.
If contributing to the project, ensure all tests pass before submitting a Pull Request.
If tests fail, your PR will automatically be blocked from merging.

* Execute the test suite via `pnpm test` or `node ace test`.

As all our tests are e2e, you need to have all required services running in the background while running the tests.
For instructions on how to set up the required services,
please refer to the [Docker services setup](#docker-for-services-only) section above.

### Ensure production build works
Ensure that the production build of the app works correctly.
This can be done by either running `pnpm build` or `docker build -t xcontest-rest .`.

---

## Git Workflow & History Policy

We strictly enforce a **Linear Git History**. This makes the project history easier to follow, bisect, and audit.
Other rules related to this policy include:

### Preferred Rebasing
We prefer using full rebasing over squashing or merging.
This makes the history more readable and easier to follow.

Rebasing means putting all your commits on top of the latest `main` branch.
This ensures more granular commits and a clean history.
It also makes it easier to resolve conflicts.

To rebase your branch, use the following command:
```bash
git checkout your-branch
git fetch origin
git rebase origin/main`
```

If there are no conflicts, this will be a fast-forward merge, and your branch will be up to date with the latest `main`.
If, however, there are conflicts, you will be prompted to resolve them locally for every commit.
After resolving the conflicts, you can continue the rebase process by using:
```bash
git rebase --continue
```

If you have any issues with rebasing, please reach out to us via the PR comment.

### Mandatory Signed Commits
> [!IMPORTANT]
> We require all commits to be signed.
This ensures that the committer is the author of the change,
and that the commit is properly attributed to the author.

For more information on how to set up commit signing, please refer to the [Github Documentation](https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits).

---

## Submission Requirements

All pull requests must meet the following requirements before they can be merged:

- **Review:** All code must be reviewed and approved by at least one maintainer.
- **Green CI:** All automated checks must pass, including:
- * Code quality (Linting/Semgrep).
- * Functional tests.
- * Successful Docker build.
- **Linear History:** The branch must be a clean, linear set of commits on top of the current `main`.
- **Signed Commits:** All commits must be signed.

---

## Code of Conduct

By participating in this project, you agree to maintain a professional and respectful environment for all contributors.

**Thank you for helping us build something great!**
73 changes: 73 additions & 0 deletions docs/DEPLOYMENT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Deployment of xContest app
This guideline is intended to provide a comprehensive overview of the deployment process for the xContest platform.
It covers full deployment including required infrastructure, api, frontend, and other components.

There are multiple ways to deploy the xContest platform:
- [Deploying on Docker](#deploying-on-docker)
- [Deploying on Docker Swarm](#deploying-on-docker-swarm) (not ready yet)
- [Deploying on Kubernetes](#deploying-on-kubernetes) (not ready yet)
- [Deploying Manually](#deploying-manually)

---
# Deploying on Docker
This is the easiest and recommended way to deploy the xContest platform.
It requires minimal manual intervention and provides a seamless deployment process.

Although easily enough for small-scale events and local development,
it is not recommended for huge events with thousands of participants, as it does not provide the necessary scalability and reliability.
For such events, we recommend using Kubernetes or Docker Swarm.

To deploy the xContest platform on Docker, set up some server or VPS with Docker installed, and run the following command in the project root directory:
```shell
# TODO: Update once we have global docker compose profiles with frontend, etc...
docker compose --profile prod up -d
```
As this will run the entire stack, it is recommended your server has sufficient resources to handle more than just the base platform load.

For guide on how to set up Docker, please refer to the official [Docker documentation](https://docs.docker.com/get-started/).

If you do not want to compile the project yourself, pre-built images are available on our [Github Actions](https://github.com/xcontest/api/actions/workflows/docker_build.yml).

---
# Deploying on Docker Swarm
This method is more complex than standard Docker,
it provides better scalability and reliability, making it suitable for larger events with more participants.
This method requires multiple machines to be set up,
and it is not recommended for local development.

**Not ready yet:** Docker Swarm does not allow profiles and locally built images are not available.
Due to this, we do not support Docker Swarm deployment at the moment.
It will be available in the future, once xContest reaches a stable version.

---
# Deploying on Kubernetes
This method is way more complex than those above,
as it requires setting up a whole Kubernetes cluster.
It is only recommended for huge-scale deployments that will require
handling multiple huge events at the same time.

**Not ready yet:** We will probably provide a helm chart for this in the future,
but at the moment Kubernetes deployment is not officially supported.
You can still use it, but you will need to create all the necessary manifests yourself.
It will be available in the future, once xContest reaches a stable version.

---
# Deploying Manually
Manual deployment is not recommended for most users,
as it requires a lot of manual work.

Due to required manual work and knowledge, this guide only
provides a brief overview of the deployment process and required services.

xContest requires the following third-party services:
- [PostgreSQL](https://www.postgresql.org/)
- [Redis](https://redis.io/)
- [SeaweedFS](https://seaweedfs.com/)
- [RabbitMQ](https://www.rabbitmq.com/)
- Some SMTP server (for email notifications)

And the following xContest services:
- [xContest REST API](https://github.com/xcontest/api)
- [xContest Realtime API](https://github.com/xcontest/realtime-api) (for live updates and notifications on the website)
- [xContest Frontend](https://github.com/xcontest/web)
- [xContest Workers](https://www.rabbitmq.com/worker) (multiple, required only for algorithmic and CTF events)