This project is a web platform designed to help students and faculty showcase their final year projects easily. It lets users submit their project details and files, explore recent and top-voted projects, vote for favorites, and leave comments to share feedback. The system also includes an admin dashboard for managing projects and users, and supports separate login for students and admins.
Find a file
sarah 6d18d3fe72
All checks were successful
/ check_lfs (push) Successful in 2s
very small text changes for consistency
2025-11-23 16:53:36 +00:00
.devcontainer More CI/CD Fixes 2025-11-23 10:08:06 +00:00
.forgejo/workflows CI WORKING 2025-11-23 16:33:54 +00:00
backend CI WORKING 2025-11-23 16:33:54 +00:00
doc Organizing Monorepo 2025-11-22 11:16:49 +00:00
frontend very small text changes for consistency 2025-11-23 16:53:36 +00:00
fyp_portal Minor Docker Changes 2025-11-23 08:06:55 +00:00
.gitattributes Initial commit 2025-11-22 10:18:01 +00:00
.gitignore Added CI Fixes 2025-11-23 08:17:53 +00:00
.mailmap Initial commit 2025-11-22 10:18:01 +00:00
docker-compose.yaml Fixed sqlx, adapting to new db 2025-11-23 14:32:06 +00:00
LICENSE Initial commit 2025-11-22 10:18:01 +00:00
package-lock.json Further fixes 2025-11-22 17:46:48 +00:00
README.md Organizing Monorepo 2025-11-22 11:16:49 +00:00

FYP Showcase Portal

Monorepo for the Final Year Project Showcase platform.

This system uses a type-sharing contract (via ts-rs) to ensure the React frontend and Rust backend stay in sync, maintaining type safety across the entire application boundary.


Architecture & Technical Strategy

The backend employs the Unified State Pattern and Clean Architecture to maintain strict separation of concerns, ensuring high testability and a hardened security posture.

  • Language & Stack: Rust (Axum + Tokio + Tower).
  • Core Pattern: Unified State (AppState holds immutable AppConfig and thread-safe Repositories/Storage).
  • Security: Defense-in-Depth enforced by modular routing (Public, Authenticated, Admin) and a strict AuthUser extractor for JWT validation and RBAC.
  • Observability: Production-ready tracing layer with Request Correlation (unique x-request-id header) and Structured JSON Logging.
  • Storage Strategy: Hybrid—MinIO for local development, Supabase Storage (S3 compatible) for production.

Directory Structure

We use a specific folder structure to ensure the build pipelines work correctly. Please keep files within their designated directories.

fyp-portal/
├── backend/                # [Source of Truth] Rust API logic and Core Business Layer
│   ├── src/                # Handlers, models, and repository implementations
│   ├── Dockerfile          # Multi-stage build for production (no hardcoded APP_ENV)
│   └── ...
├── frontend/               # [Consumer] React UI
│   ├── types/              # [READ-ONLY] Generated TypeScript interfaces (Source: backend/models.rs)
│   └── ...
├── db/                     # [Reference] SQL schemas and migrations
├── .forgejo/               # [CI] Skynet CI/CD workflows (Runs all Unit/Integration tests)
├── scripts/                # Utility scripts (e.g., Smoke Testing)
├── docker-compose.yml      # Local development orchestration (MinIO + Postgres)
└── .devcontainer/          # VS Code environment config

Configuration & Secrets

We utilize a fail-fast configuration approach in the backend to prevent runtime errors and ensure production security.

1. Backend Secrets (.env) The backend requires a .env file in the backend/ directory to connect to the database and retrieve the JWT secret (SUPABASE_JWT_SECRET).

  • Action: Ask the team for the current .env template.
  • Warning: In the production environment (APP_ENV=production), missing secrets (e.g., S3_ACCESS_KEY) will panic at startup.

2. Frontend Secrets Public API keys for Supabase (if needed) are stored in frontend/.env.local.


Quickstart

We use a Dev Container to ensure everyone has the same tools (Node, Cargo, Postgres) installed automatically.

  1. Install Docker Desktop and VS Code.
  2. Install the "Dev Containers" extension in VS Code.
  3. Open this folder.
  4. Click "Reopen in Container" when prompted.

Development Workflows

1. The ts-rs Type Contract

The ts-rs crate is used to automatically generate TypeScript interface definitions from our core Rust structs in backend/src/models.rs.

  • Goal: Eliminate manual syncing errors. If a field is changed from String to Option<String> in Rust, the corresponding TypeScript interface is updated automatically.
  • Source of Truth: All structs marked with #[derive(TS)] in backend/src/models.rs.
  • Destination: The generated files are placed in the frontend/types/ directory for the React application to import.

2. Running the Full Stack

To spin up the Backend, local Database (Postgres), and local S3 mirror (MinIO) simultaneously:

docker compose up
Component Endpoint Purpose
API http://localhost:3000 Rust backend web service.
Swagger Docs http://localhost:3000/swagger-ui Auto-generated API contract and documentation.
Rust Docs http://localhost:3000/docs HTML documentation for the Rust source code.
Local DB localhost:5432 Vanilla Postgres container for development.

Note on Documentation: The Swagger UI generated by Utoipa provides the primary contract reference. The Rust Docs (cargo doc) provide deep insight into the internal architecture, traits, and handler logic.

3. Frontend Development

You can run the frontend independently for faster reloading.

cd frontend
npm install
npm run dev

4. Syncing Types (The Contract)

If the backend data models (models.rs) change, we need to update the frontend types to maintain type safety.

  1. Open a terminal in the backend/ folder.
  2. Run: cargo test
  3. This automatically regenerates the files in frontend/types/.

Warning: The files in frontend/types/ are generated automatically. Manual edits will be overwritten and discarded.

5. Viewing Rust Documentation

To view the internal, deeply commented documentation for the Rust code:

  1. Open a terminal in the backend/ folder.
  2. Run: cargo doc --open

This command generates the HTML docs and automatically opens them in your browser. This is essential for understanding the Repository Abstraction, State Management, and the security reasoning behind the Auth Extractor.