# Projek Sarjana Muda (PSM) - Code Wiki

Welcome to the **Projek Sarjana Muda (PSM) Management System** developer wiki. This documentation provides a comprehensive overview of the project architecture, major modules, key classes, dependencies, and instructions for running the application.

---

## 🏗 Overall Project Architecture

The PSM Management System is a modern web application built with a decoupled frontend and backend architecture, utilizing a containerized environment for robust service management.

- **Backend**: Laravel 11.x (PHP 8.3) providing a RESTful API (`/api/v1`).
- **Frontend**: Nuxt.js 3 (Vue 3, TypeScript, Pinia, Tailwind CSS) providing a reactive single-page application (SPA) experience with SSR capabilities.
- **Database**: MySQL 8.0 for relational data storage.
- **Object Storage**: Minio (S3-compatible) for handling file uploads such as profile photos, PDFs, and system logos.
- **Caching & Queues**: Redis for high-performance caching and background job processing.
- **Email Delivery**: Mailpit for local email testing and debugging.
- **Containerization**: Docker & Docker Compose orchestrating the infrastructure.

---

## 🧩 Responsibilities of Major Modules

The application is structured around user roles and their specific workflows within the university ecosystem.

### Backend Modules (Laravel API)
1. **Authentication & Authorization** (`AuthController`, `Spatie/Laravel-Permission`): Manages user login, registration, JWT token generation (Sanctum), and Role-Based Access Control (RBAC).
2. **Proposal Management** (`ProposalController`): Handles the lifecycle of student project proposals (drafting, submission, versions, and objective tracking).
3. **Dissertation & Editor** (`DissertationController`, `CommentController`): Manages the writing process. Stores markdown/HTML content for dissertation sections, APA references, appendices, and handles supervisor/evaluator comments on specific chapters.
4. **Coordination & Approvals** (`CoordinatorController`, `AdminUserController`): Handles administrative workflows, such as approving students, verifying English applications, routing proposals to committees (AJK), and checking similarity.
5. **Evaluation & Grading** (`EvaluationWindowController`, `MarksController`): Manages grading windows and the submission of marks by appointed evaluators.
6. **Academic Setup** (`SesiController`, `ProgramDepartmentController`): Manages the core academic entities like Sessions, Faculties, Departments, and Programs.
7. **Session Lifecycle Management** (`SesiLifecycleController`, `SesiLifecycleService`): Manages the archival lifecycle of academic sessions (lock, archive, download, and recover).

### Frontend Modules (Nuxt 3)
1. **Role-Based Routing** (`pages/`): Distinct directory structures for each role (`student/`, `supervisor/`, `coordinator/`, `evaluator/`, `admin/`, `super_admin/`) to isolate domain logic and UI.
2. **State Management** (`stores/auth.ts`): Uses Pinia to securely store the user session, token, and role capabilities.
3. **API Integration** (`composables/useApi.ts`): Centralized wrapper around Nuxt's `ofetch` for making authenticated requests to the Laravel backend.
4. **Rich Text Editor**: Integrates Tiptap for a seamless dissertation writing experience (`@tiptap/vue-3`).

---

## 🔑 Key Classes and Functions

### Backend Models (`app/Models/`)
- **[User](file:///d:/projek%20psm/psm-disertasi/backend/app/Models/User.php)**: The core authentication model. Relates to `UserProfile` (for students) and `StaffProfile` (for staff). Traits include `HasApiTokens` and `HasRoles`.
- **[Proposal](file:///d:/projek%20psm/psm-disertasi/backend/app/Models/Proposal.php)**: The central entity for a student's project. Tracks the title, abstract, status, supervisor (`sv_main_id`), and associated academic session (`sesi_id`).
- **[DissertationSection](file:///d:/projek%20psm/psm-disertasi/backend/app/Models/DissertationSection.php)**: Represents individual chapters or sections of the student's thesis.
- **[Sesi](file:///d:/projek%20psm/psm-disertasi/backend/app/Models/Sesi.php)**: Represents the academic session/semester (e.g., Sesi 2025/2026 Sem 1).
- **[EvaluationWindow](file:///d:/projek%20psm/psm-disertasi/backend/app/Models/EvaluationWindow.php)** & **[Mark](file:///d:/projek%20psm/psm-disertasi/backend/app/Models/Mark.php)**: Define the periods during which evaluators can submit grades, and the actual grades themselves.

### Backend Controllers (`app/Http/Controllers/Api/V1/`)
- **`AuthController@login`**: Authenticates users and returns a Sanctum token.
- **`ProposalController@store` / `@submit`**: Handles saving draft proposals and formally submitting them for review.
- **`CoordinatorController@acceptProposal` / `@sendToAjk`**: Workflow actions for coordinators to route proposals.
- **`DissertationController@saveSection`**: Persists rich text editor content from the frontend into the database.

### Frontend Composables & Stores
- **`useAuthStore`** ([auth.ts](file:///d:/projek%20psm/psm-disertasi/frontend/stores/auth.ts)): Manages login state, roles (`hasRole`, `hasAnyRole`), and handles auto-fetching the user profile on load.
- **`useApi`** ([useApi.ts](file:///d:/projek%20psm/psm-disertasi/frontend/composables/useApi.ts)): A composable that injects the authorization header and handles base URL configuration for all API calls.

---

## 🔗 Dependency Relationships

1. **Frontend $\rightarrow$ Backend**: 
   - The Nuxt frontend communicates exclusively with the Laravel backend via RESTful JSON APIs prefixed with `/api/v1`.
   - Cross-Origin Resource Sharing (CORS) and proxying are configured in `nuxt.config.ts` (`vite.server.proxy` and `nitro.routeRules`).
2. **Backend $\rightarrow$ Database (MySQL)**: 
   - Managed via Laravel Eloquent ORM. Migrations and Seeders dictate the schema.
3. **Backend $\rightarrow$ Redis**: 
   - Used for caching system settings, active sessions, and managing background queues (e.g., email notifications, PDF generation).
4. **Backend $\rightarrow$ Minio (S3)**: 
   - The Laravel `filesystems.php` is configured to use the S3 driver pointing to the local Minio container for storing student appendices, PDFs, and profile images.

---

## 🚀 Running the Project Locally

The project includes a `Makefile` to drastically simplify local development. Ensure you have Docker, Docker Compose, PHP, Composer, Node.js, and npm installed on your machine.

### 1. Initial Setup
Run the setup command to install dependencies for both frontend and backend, generate the application key, and migrate the database:
```bash
make setup
```

### 2. Start Infrastructure Services
Boot up the Docker containers (MySQL, Minio, Redis, Mailpit):
```bash
make up
```

### 3. Run the Backend API
Start the Laravel development server (runs on port `8000`):
```bash
make serve-backend
```

### 4. Start the Queue Worker (Optional but recommended)
To process background jobs like emails or document generation:
```bash
make queue
```

### 5. Run the Frontend
Start the Nuxt 3 development server (runs on port `3000`):
```bash
make serve-frontend
```

### Useful Commands
- **Stop Services**: `make down`
- **Reset Database**: `make migrate-fresh`
- **Run Backend Tests**: `make test-backend`
- **Run Frontend Tests**: `make test-frontend`

---

## 🔄 Session Lifecycle Management (Kitaran Hayat Sesi)

The system supports a full archival lifecycle for academic sessions to keep the active database lean and to free up server storage.

### Lifecycle States

```
ACTIVE ──lock──▶ LOCKED ──archive──▶ ARCHIVED ──download──▶ External Storage
   ▲                │                    │
   └────unlock──────┘                    └──recover──▶ LOCKED (read-only)
```

| State | Meaning | Effect |
| :--- | :--- | :--- |
| **ACTIVE** | Session is running | Full read/write access |
| **LOCKED** | Process complete, data frozen | Read-only; write operations rejected (HTTP 423) |
| **ARCHIVED** | Data packaged into a ZIP archive | Data removed from active DB; archive stored in MinIO |

### API Endpoints

| Method | Endpoint | Description | Access |
| :--- | :--- | :--- | :--- |
| POST | `/api/v1/admin/sesis/{id}/lock` | Lock a session | ADMIN / SUPER_ADMIN |
| POST | `/api/v1/admin/sesis/{id}/unlock` | Reopen a locked session | ADMIN / SUPER_ADMIN |
| POST | `/api/v1/admin/sesis/{id}/archive` | Archive a locked session | ADMIN / SUPER_ADMIN |
| GET | `/api/v1/admin/sesis/{id}/download` | Download the archive ZIP | ADMIN / SUPER_ADMIN |
| POST | `/api/v1/admin/sesis/{id}/recover` | Recover from an uploaded archive | ADMIN / SUPER_ADMIN |

### Archive Structure

Each archive is a single ZIP file containing:
- `manifest.json` — metadata (version, session ID, checksum)
- `data.json` — all database records for the session
- `files/` — actual files (appendices, images, PDFs) from MinIO

### Key Classes

- **`SesiLifecycleService`** — Core business logic for lock/unlock/archive/download/recover.
- **`SesiLifecycleController`** — API endpoints for the lifecycle operations.
- **`SesiPolicy`** — RBAC enforcement (only `ADMIN` role, including `SUPER_ADMIN`).
- **`EnsureSesiActive`** middleware — Rejects write operations on locked/archived sessions.
- **`RecoverSesiRequest`** — Form Request validation for archive upload (ZIP, max 500MB).

### Database Fields (on `sesis` table)

| Field | Type | Description |
| :--- | :--- | :--- |
| `lifecycle_status` | string | `ACTIVE`, `LOCKED`, or `ARCHIVED` |
| `locked_at` | timestamp | When the session was locked |
| `archived_at` | timestamp | When the session was archived |
| `archive_path` | string | MinIO path of the archive ZIP |
| `archive_checksum` | string | SHA-256 checksum for integrity verification |
