268 lines
8.3 KiB
Markdown
268 lines
8.3 KiB
Markdown
# Test Templates System - Implementation Summary
|
|
|
|
## Overview
|
|
|
|
This document describes the implementation of a comprehensive **Test Template System** for OpenCCB, allowing instructors to create and reuse test/quiz templates based on:
|
|
|
|
1. **Course Level**: `beginner`, `beginner_1`, `beginner_2`, `intermediate`, `advanced`, etc.
|
|
2. **Course Type**: `intensive` or `regular`
|
|
3. **Assessment Type**: `CA`, `MWT`, `MOT`, `FOT`, `FWT`
|
|
|
|
## Database Changes
|
|
|
|
### New Enums
|
|
|
|
```sql
|
|
-- Course levels
|
|
CREATE TYPE course_level AS ENUM (
|
|
'beginner', 'beginner_1', 'beginner_2',
|
|
'intermediate', 'intermediate_1', 'intermediate_2',
|
|
'advanced', 'advanced_1', 'advanced_2'
|
|
);
|
|
|
|
-- Course types
|
|
CREATE TYPE course_type AS ENUM ('intensive', 'regular');
|
|
|
|
-- Test types (assessment types)
|
|
CREATE TYPE test_type AS ENUM ('CA', 'MWT', 'MOT', 'FOT', 'FWT');
|
|
```
|
|
|
|
### New Tables
|
|
|
|
#### `test_templates`
|
|
Main table for storing test templates with metadata:
|
|
- `id`: UUID primary key
|
|
- `organization_id`: Multi-tenancy support
|
|
- `name`, `description`: Template identification
|
|
- `level`, `course_type`, `test_type`: Classification enums
|
|
- `duration_minutes`, `passing_score`, `total_points`: Configuration
|
|
- `instructions`: General test instructions
|
|
- `template_data`: JSONB with complete test structure
|
|
- `tags`: Text array for categorization
|
|
- `usage_count`: Tracks template popularity
|
|
- `is_active`: Soft delete support
|
|
|
|
#### `test_template_sections`
|
|
Optional sections within a test (e.g., "Reading", "Grammar", "Listening"):
|
|
- `template_id`: Foreign key to `test_templates`
|
|
- `section_order`: Ordering within template
|
|
- `points`, `instructions`: Section-specific config
|
|
- `section_data`: JSONB for advanced configuration
|
|
|
|
#### `test_template_questions`
|
|
Individual questions for each template:
|
|
- `template_id`, `section_id`: Foreign keys
|
|
- `question_order`: Ordering
|
|
- `question_type`: "multiple-choice", "true-false", "short-answer", "essay", "matching", "ordering"
|
|
- `question_text`, `options`, `correct_answer`, `explanation`: Question content
|
|
- `points`, `metadata`: Scoring and additional data
|
|
|
|
### Database Functions
|
|
|
|
- `get_test_templates_by_filters()`: Filter templates by level, type, test type, and search
|
|
- `increment_template_usage()`: Track template usage statistics
|
|
|
|
### Course Model Updates
|
|
|
|
Added optional fields to `courses` table:
|
|
- `level`: Course level enum
|
|
- `course_type`: Course type enum
|
|
|
|
## Backend Implementation
|
|
|
|
### Models (`shared/common/src/models.rs`)
|
|
|
|
New Rust structs:
|
|
- `CourseLevel`, `CourseType`, `TestType`: Enum types
|
|
- `TestTemplate`, `TestTemplateSection`, `TestTemplateQuestion`: Main models
|
|
- `CreateTestTemplatePayload`, `UpdateTestTemplatePayload`: Request/Response DTOs
|
|
- `TestTemplateWithQuestions`: Composite response type
|
|
|
|
### API Handlers (`services/cms-service/src/handlers_test_templates.rs`)
|
|
|
|
RESTful endpoints:
|
|
|
|
| Method | Endpoint | Description |
|
|
|--------|----------|-------------|
|
|
| GET | `/test-templates` | List templates with filters |
|
|
| POST | `/test-templates` | Create new template |
|
|
| GET | `/test-templates/{id}` | Get template with questions |
|
|
| PUT | `/test-templates/{id}` | Update template |
|
|
| DELETE | `/test-templates/{id}` | Delete template |
|
|
| POST | `/test-templates/{id}/questions` | Add question |
|
|
| DELETE | `/test-templates/{id}/questions/{qid}` | Delete question |
|
|
| POST | `/test-templates/{id}/sections` | Add section |
|
|
| DELETE | `/test-templates/{id}/sections/{sid}` | Delete section |
|
|
| POST | `/test-templates/{id}/apply` | Apply template to lesson |
|
|
|
|
### Routes (`services/cms-service/src/main.rs`)
|
|
|
|
All routes are protected and require organization context.
|
|
|
|
## Frontend Implementation
|
|
|
|
### TypeScript Types (`web/studio/src/lib/api.ts`)
|
|
|
|
```typescript
|
|
type CourseLevel = 'beginner' | 'beginner_1' | ... | 'advanced_2';
|
|
type CourseType = 'intensive' | 'regular';
|
|
type TestType = 'CA' | 'MWT' | 'MOT' | 'FOT' | 'FWT';
|
|
type QuestionType = 'multiple-choice' | 'true-false' | ...;
|
|
|
|
interface TestTemplate { ... }
|
|
interface TestTemplateSection { ... }
|
|
interface TestTemplateQuestion { ... }
|
|
interface CreateTestTemplatePayload { ... }
|
|
```
|
|
|
|
### API Functions (`cmsApi` object)
|
|
|
|
- `listTestTemplates(filters)`
|
|
- `getTestTemplate(templateId)`
|
|
- `createTestTemplate(payload)`
|
|
- `updateTestTemplate(templateId, payload)`
|
|
- `deleteTestTemplate(templateId)`
|
|
- `createTemplateQuestion(templateId, payload)`
|
|
- `deleteTemplateQuestion(templateId, questionId)`
|
|
- `createTemplateSection(templateId, payload)`
|
|
- `deleteTemplateSection(templateId, sectionId)`
|
|
- `applyTemplateToLesson(templateId, lessonId, gradingCategoryId)`
|
|
|
|
### UI Components
|
|
|
|
#### `TestTemplateManager` (`web/studio/src/components/TestTemplates/TestTemplateManager.tsx`)
|
|
|
|
Main management interface with:
|
|
- Grid view of templates
|
|
- Search functionality
|
|
- Advanced filters (level, course type, test type)
|
|
- Template cards showing:
|
|
- Name, description
|
|
- Level, type badges with color coding
|
|
- Duration, passing score, total points
|
|
- Tags
|
|
- Usage statistics
|
|
- Action buttons (view, edit, delete, apply)
|
|
|
|
#### `TestTemplateForm` (`web/studio/src/components/TestTemplates/TestTemplateForm.tsx`)
|
|
|
|
Modal form for creating/editing templates with:
|
|
- Basic info (name, description)
|
|
- Classification (level, course type, test type)
|
|
- Configuration (duration, passing score, total points)
|
|
- Instructions
|
|
- Tag management
|
|
|
|
#### Page (`web/studio/src/app/test-templates/page.tsx`)
|
|
|
|
Dedicated page at `/test-templates` route.
|
|
|
|
## Usage Examples
|
|
|
|
### Creating a Template via API
|
|
|
|
```bash
|
|
curl -X POST http://localhost:3001/test-templates \
|
|
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
|
|
-H "X-Organization-Id: YOUR_ORG_ID" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"name": "Final Exam - Beginner 1",
|
|
"description": "Comprehensive final exam for beginner level",
|
|
"level": "beginner_1",
|
|
"course_type": "regular",
|
|
"test_type": "FWT",
|
|
"duration_minutes": 90,
|
|
"passing_score": 70,
|
|
"total_points": 100,
|
|
"instructions": "Answer all questions. You have 90 minutes.",
|
|
"tags": ["final", "beginner", "written"]
|
|
}'
|
|
```
|
|
|
|
### Filtering Templates
|
|
|
|
```bash
|
|
# Get all FOT templates for beginner intensive courses
|
|
curl "http://localhost:3001/test-templates?level=beginner_1&course_type=intensive&test_type=FOT" \
|
|
-H "Authorization: Bearer YOUR_JWT_TOKEN"
|
|
```
|
|
|
|
### Applying Template to a Lesson
|
|
|
|
```bash
|
|
curl -X POST http://localhost:3001/test-templates/TEMPLATE_ID/apply \
|
|
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
|
|
-H "X-Organization-Id: YOUR_ORG_ID" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"lesson_id": "LESSON_ID",
|
|
"grading_category_id": "CATEGORY_ID"
|
|
}'
|
|
```
|
|
|
|
## Migration
|
|
|
|
Run the migration to set up the database schema:
|
|
|
|
```bash
|
|
cd services/cms-service
|
|
sqlx migrate run --source migrations
|
|
```
|
|
|
|
The migration file is: `20260316000000_test_templates.sql`
|
|
|
|
## Future Enhancements
|
|
|
|
1. **Template Cloning**: Allow duplicating existing templates
|
|
2. **Question Bank**: Centralized repository of questions that can be mixed and matched
|
|
3. **Template Sharing**: Share templates across organizations
|
|
4. **Analytics**: Track template effectiveness and student performance
|
|
5. **AI Generation**: Auto-generate templates based on course content
|
|
6. **Version Control**: Track template revisions
|
|
7. **Bulk Operations**: Apply templates to multiple lessons at once
|
|
8. **Preview Mode**: Preview template before applying
|
|
|
|
## File Structure
|
|
|
|
```
|
|
openccb/
|
|
├── shared/common/src/models.rs # Rust models
|
|
├── services/cms-service/
|
|
│ ├── migrations/20260316000000_test_templates.sql
|
|
│ ├── src/handlers_test_templates.rs # API handlers
|
|
│ └── src/main.rs # Routes
|
|
└── web/studio/
|
|
├── src/lib/api.ts # TypeScript types & API functions
|
|
├── src/components/TestTemplates/
|
|
│ ├── TestTemplateManager.tsx
|
|
│ ├── TestTemplateForm.tsx
|
|
│ └── index.ts
|
|
└── src/app/test-templates/
|
|
└── page.tsx
|
|
```
|
|
|
|
## Testing
|
|
|
|
### Backend Tests
|
|
|
|
```bash
|
|
cargo test -p common
|
|
cargo test -p cms-service
|
|
```
|
|
|
|
### Frontend Type Check
|
|
|
|
```bash
|
|
cd web/studio
|
|
npm run type-check
|
|
```
|
|
|
|
## Notes
|
|
|
|
- All templates are organization-scoped for multi-tenancy
|
|
- Soft delete via `is_active` flag preserves historical data
|
|
- Usage count helps identify popular templates
|
|
- JSONB fields provide flexibility for evolving question types
|
|
- The system integrates with existing grading categories via `tipo_nota` catalog
|