# LMS Question Bank (Base Architecture)

This document outlines the core functionality, architectural design, and usage instructions for the **LMS Question Bank Base Module** developed in the `feat/admin-sub/lms-questions` (base) branch.

## Overview and Goals

The goal of this branch is to establish a **standalone, centralized repository** for all LMS questions. To keep the database clean and prevent an explosion of tables for different question types (e.g., Multi-Choice, Fill-in-the-Blank, Scenarios), this module employs a **Polymorphic JSON Plugin Architecture**.

**What this means:**
This base branch contains **zero hardcoded question types**. It provides the core table, listing, and modal scaffolding. Specific question types (like `multi_choice` or `scenario`) will be developed in independent **child branches** and merged into this base.

When you merge a child branch, its specific functionality will automatically plug into this base system without breaking existing features.

---

## What is Included in this Branch

1. **Unified Database Schema (`questions` table)**:
   - A single table handling all question types.
   - Flexible `content` column (JSON) to store specific configurations (like answer choices, hints, etc.).
   - A `parent_id` foreign key to support parent-child relationships (e.g., Scenario questions).
2. **Dynamic UI & Filtering**:
   - A standardized server-side AJAX table to list all questions.
   - Filter dropdowns that automatically populate based on the registered types.
   - A View Modal that dynamically resolves and injects specific Blade partials based on the question type.

3. **Registry Pattern (Config-driven)**:
   - The system reads from `config/question.php` to understand what question types are currently active in the system.

---

## File Paths & Core Structure

| Component           | File Path                                                          |
| :------------------ | :----------------------------------------------------------------- |
| **Migration**       | `database/migrations/2026_06_12_122830_create_questions_table.php` |
| **Model**           | `app/Models/Question.php`                                          |
| **Config Registry** | `config/question.php`                                              |
| **Controller**      | `app/Http/Controllers/Admin/Question/QuestionController.php`       |
| **Service (Logic)** | `app/Services/Admin/QuestionService.php`                           |
| **Views & Modal**   | `resources/views/pages/admin/question/*`                           |
| **JavaScript**      | `resources/js/admin/question.js`                                   |
| **Language**        | `lang/en/pages/admin/question.php`                                 |

---

## How to Build Child Branches (Question Types)

Because this base branch is type-agnostic, building a new question type (e.g., in branch `feat/admin-sub/lms-question-sub/multi-choice`) is extremely straightforward.

Follow these steps when creating a child branch:

### 1. Register the Type

Open `config/question.php` and append your new type to the array.

```php
'types' => [
    'multi_choice' => 'Multi Choice',
],
```

_Result: The main table's "Type" filter will instantly start showing "Multi Choice" as an option._

### 2. Create the View Modal Partial

The base modal automatically attempts to load a specific blade file when a user clicks the "View" icon.
Create your specific view layout here:
`resources/views/pages/admin/question/types/{your_type}/view.blade.php`

_(Example: `resources/views/pages/admin/question/types/multi_choice/view.blade.php`)_

Inside this file, you have access to the `$question` object, allowing you to parse its `$question->content` JSON array and render your checkboxes, inputs, or scenario text.

### 3. Setup Form Handlers (Create/Edit)

For future `create` and `edit` views, you will implement a similar pattern. The main `create.blade.php` page will have a dropdown to select the "Question Type". Using Alpine.js or Livewire, selecting a type will dynamically reveal the specific form inputs required for that JSON content.

---

## Summary of Usage

By keeping the foundation generic, the Question Bank can seamlessly integrate dozens of different question types over time. You do not need to modify the core `QuestionController` or database schema every time a new type is invented. Simply branch off this repository, register the type in the config, attach the specific view files, and merge it back!

The LMS Question Bank supports four core question types, each developed in its own isolated child branch. These child branches plug directly into the base architecture.

### Global Features & Validations (Applied to All Types)

- **Status Lifecycle:** Questions use "Save as Draft" and "Save as Publish" buttons, with conditional UI updates for required fields based on their status.
- **Input Validation:** Strict character limits (1-255 characters) are enforced on all text-based inputs, including options.
- **Rich Text Editor:** TinyMCE editors are used for question content, featuring focus-out validation with error messages displayed directly below the editor.
- **UI Enhancements:** The listing view includes "read more/less" functionality for long questions.

---

## 1. Multi Choice (`feat/admin-sub/lms-questions-sub/multi-choice`)

Allows multiple correct answers from a list of options.

### Scoring Logic

- Awards partial marks per correct option (1/N, where N is the total number of correct options).

---

## 1. Multi Choice

Allows multiple correct answers.

### Example

Question: Which of the following are PHP frameworks?

Content:

```json
[
  {
    "text": "Laravel",
    "is_correct": true
  },
  {
    "text": "Symfony",
    "is_correct": true
  },
  {
    "text": "React",
    "is_correct": false
  }
]
```

---

## 2. Single Choice

Allows only one correct answer.

### Example

Question: Which company develops Laravel?

Content:

```json
[
  {
    "text": "Microsoft",
    "is_correct": false
  },
  {
    "text": "Laravel LLC",
    "is_correct": true
  },
  {
    "text": "Google",
    "is_correct": false
  }
]
```

---

## 3. Fill in the Blank

Allows users to enter a text-based answer.

### Example

Question: Laravel is built on the **\_** framework.

Content:

```json
{
  "answer": "Symfony",
  "hint": "Popular PHP framework"
}
```

---

## 4. Scenario

A scenario acts as a parent container for one or more child questions.

Scenario questions do not store answer data.

### Example

Question: Read the following case study and answer the questions below.

Content:

```json
null
```

Child questions reference the scenario using:

```
parent_id = scenario_question_id
```

Example Structure:

```
Scenario Question
├── Child Question 1
├── Child Question 2
└── Child Question 3
```

# Content Structure Rules

## Multi Choice (`feat/admin-sub/lms-questions-sub/multi-choice`)

```json
[
  {
    "text": "Option",
    "is_correct": true
  }
]
```

### Validation & UI Rules:

- Minimum 2 options.
- Multiple correct answers allowed, but at least one correct answer required.
- Cannot select ALL checkboxes simultaneously (prevents user from checking every single option).
- Delete icons are dynamically removed when only two options remain to enforce the minimum requirement.
- Character limit (1-255) for each option input.

---

## 2. Single Choice (`feat/admin-sub/lms-questions-sub/single-choice`)

Allows only one correct answer from a list of options.

### Scoring Logic

- Awards 1 mark for the correct answer, otherwise 0.

### Content Structure

```json
[
  {
    "text": "Option",
    "is_correct": true
  }
]
```

### Validation & UI Rules:

- Minimum 2 options.
- Exactly one correct answer required.
- Character limit (1-255) for each option input.

---

## 3. Fill in the Blank (`feat/admin-sub/lms-questions-sub/fill-in-blanks`)

Allows users to enter a text-based answer.

### Scoring Logic

- Awards 1 mark for any attempt, 0 otherwise.

### Content Structure

```json
{
  "answer": "Answer Text",
  "hint": "Optional Hint"
}
```

### Validation Rules:

- Answer is required (1-255 character limit).
- Hint is optional (1-255 character limit).

---

## 4. Scenario (`feat/admin-sub/lms-questions-sub/scenario`)

A scenario acts as a parent container for one or more child questions. Scenario questions do not store answer data themselves but group related questions together under a single case study or reading passage.

### Scoring Logic

- Distributes 1 mark evenly across its child questions. For example, if there are 3 child questions, each is worth 1/3 of a mark. Multi-choice child questions further divide their fractional score among their correct options.

### Content Structure

```json
null
```

Child questions reference the scenario using `parent_id = scenario_question_id`.

Example Structure:

```
Scenario Question
├── Child Question 1 (Single Choice)
├── Child Question 2 (Multi Choice)
```

### Validation & Rules:

- Content must be null.
- Scenario can have child questions, managed via an integrated, dynamic UI.
- Child questions may be any supported question type (Multi Choice, Single Choice) except another scenario.
- Updates securely handle existing child questions without deleting and recreating them.
