No description
This repository has been archived on 2026-02-16. You can view files and clone it, but you cannot make any changes to its state, such as pushing and creating new issues, pull requests or comments.
Find a file
2026-02-15 21:45:05 +07:00
prisma feat: migrate from NodeJS -> rust on client 2026-02-15 21:45:05 +07:00
src feat: migrate from NodeJS -> rust on client 2026-02-15 21:45:05 +07:00
.env.example feat: migrate from NodeJS -> rust on client 2026-02-15 21:45:05 +07:00
.gitignore Initial commit 2026-02-15 20:55:00 +07:00
Cargo.lock feat: migrate from NodeJS -> rust on client 2026-02-15 21:45:05 +07:00
Cargo.toml feat: migrate from NodeJS -> rust on client 2026-02-15 21:45:05 +07:00
README.md feat: migrate from NodeJS -> rust on client 2026-02-15 21:45:05 +07:00
sync_schema.sh Initial commit 2026-02-15 20:55:00 +07:00
sync_schema_helper.sh feat: migrate from NodeJS -> rust on client 2026-02-15 21:45:05 +07:00

Backend Rewrite - Rust Migration

This is the Rust rewrite of the YACPS backend, migrated from NestJS.

Key Changes

1. Bitwise Permission System

  • Migrated from array-based permissions to bitwise flags (like Discord)
  • Uses bitflags crate for efficient permission checks
  • Implements Allow/Inherit/Deny logic using dual bitfields (allow/deny)
  • Permission resolution follows hierarchy: Problem -> Category -> Global

2. Session-Based Authentication

  • Changed from JWT to session-based auth using database-backed sessions
  • Sessions stored in PostgreSQL with expiration
  • Session ID stored in HTTP-only cookies

3. Technology Stack

  • Framework: Axum (async, high-performance)
  • ORM: SeaORM (with Prisma for migrations)
  • Database: PostgreSQL
  • Auth: Session-based with cookie storage
  • Permissions: Bitwise flags with hierarchical resolution

Project Structure

src/
├── client/          # Client-facing API modules
│   ├── auth.rs
│   ├── users.rs
│   ├── problems.rs
│   ├── submissions.rs
│   ├── contests.rs
│   ├── categories.rs
│   ├── announcements.rs
│   ├── roles.rs
│   ├── sessions.rs
│   ├── types.rs
│   └── judge.rs
├── judge/           # Judge system modules
│   ├── submission_queue.rs
│   ├── judge_manager.rs
│   └── dmoj_bridge.rs
├── entities/        # SeaORM entities (auto-generated)
├── services/        # Business logic services
│   ├── permissions.rs
│   └── sessions.rs
├── middleware/      # Axum middleware
│   └── auth.rs
├── config.rs        # Configuration management
├── error.rs         # Error types and handling
├── permissions.rs   # Permission definitions and logic
└── main.rs         # Application entry point

Setup

  1. Copy .env.example to .env and configure:
cp .env.example .env
  1. Install dependencies:
cargo build
  1. Run Prisma migrations:
cd prisma
npx prisma migrate deploy
  1. Generate SeaORM entities:
./sync_schema.sh
  1. Run the server:
cargo run

Development

Running in development mode:

cargo watch -x run

Running tests:

cargo test

Permission System

The permission system uses bitwise operations for efficiency:

// Check single permission
let can_edit = permission_service.resolve_permission(
    Some(user_id),
    Permission::PROBLEM_EDIT,
    AidResourceType::Problem,
    problem_id
).await?;

// Get all permissions for context
let perms = permission_service.get_user_context_permissions(
    Some(user_id),
    AidResourceType::Problem,
    problem_id
).await?;

// Check if user can manage
let can_manage = permission_service.can_manage_problem(
    Some(user_id),
    problem_id,
    Some(Permission::PROBLEM_EDIT)
).await?;

Session Management

// Create session
let session = session_service.create_session(
    user_id,
    Some(ip_address),
    Some(user_agent)
).await?;

// Validate session
let (session, user) = session_service.get_session_with_user(&session_id).await?;

// Delete session (logout)
session_service.delete_session(&session_id).await?;

API Routes

All routes are prefixed with /client:

  • /client/auth - Authentication endpoints
  • /client/users - User management
  • /client/problems - Problem management
  • /client/submissions - Submission handling
  • /client/contests - Contest management
  • /client/categories - Category management
  • /client/announcements - Announcements
  • /client/roles - Role management
  • /client/sessions - Session management
  • /client/types - Type management
  • /client/judge - Judge system

Migration Notes

From NestJS to Rust:

  1. Controllers → Axum Handlers: NestJS controllers are now Axum handler functions
  2. Services → Services: Service layer structure remains similar
  3. Guards → Middleware: Auth guards are now Axum extractors
  4. DTOs → Structs: Request/response DTOs are now Rust structs with serde
  5. Decorators → Extractors: Parameter decorators are now Axum extractors

Permission Array → Bitwise:

Before (NestJS):

permissions: ['problem.edit', 'problem.delete']

After (Rust):

let perms = Permission::PROBLEM_EDIT | Permission::PROBLEM_DELETE;
// Stored as: 0x...0011000...

JWT → Sessions:

Before (NestJS):

const token = jwt.sign({ userId }, secret);
res.cookie('token', token);

After (Rust):

let session = session_service.create_session(user_id, ip, user_agent).await?;
// Session stored in DB, ID returned as cookie