|
|
||
|---|---|---|
| .devcontainer | ||
| .forgejo/workflows | ||
| backend | ||
| doc | ||
| frontend | ||
| fyp_portal | ||
| .gitattributes | ||
| .gitignore | ||
| .mailmap | ||
| docker-compose.yaml | ||
| LICENSE | ||
| package-lock.json | ||
| README.md | ||
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
AuthUserextractor for JWT validation and RBAC. - Observability: Production-ready tracing layer with Request Correlation (unique
x-request-idheader) 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
.envtemplate. - 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.
- Install Docker Desktop and VS Code.
- Install the "Dev Containers" extension in VS Code.
- Open this folder.
- 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
StringtoOption<String>in Rust, the corresponding TypeScript interface is updated automatically. - Source of Truth: All structs marked with
#[derive(TS)]inbackend/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.
- Open a terminal in the
backend/folder. - Run:
cargo test - 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:
- Open a terminal in the
backend/folder. - 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.