434 lines
13 KiB
JavaScript
434 lines
13 KiB
JavaScript
const express = require('express');
|
|
const router = express.Router();
|
|
const grammarController = require('../controllers/grammarController');
|
|
const { authenticateToken } = require('../middleware/auth');
|
|
|
|
/**
|
|
* @swagger
|
|
* tags:
|
|
* name: Grammar
|
|
* description: Grammar rule management system for sentence generation
|
|
*/
|
|
|
|
/**
|
|
* @swagger
|
|
* /api/grammar:
|
|
* post:
|
|
* summary: Create a new grammar rule
|
|
* tags: [Grammar]
|
|
* security:
|
|
* - bearerAuth: []
|
|
* requestBody:
|
|
* required: true
|
|
* content:
|
|
* application/json:
|
|
* schema:
|
|
* type: object
|
|
* required:
|
|
* - grammar_code
|
|
* - title
|
|
* - structure
|
|
* properties:
|
|
* grammar_code:
|
|
* type: string
|
|
* example: "gram-001-present-cont"
|
|
* title:
|
|
* type: string
|
|
* example: "Present Continuous"
|
|
* translation:
|
|
* type: string
|
|
* example: "Thì hiện tại tiếp diễn"
|
|
* structure:
|
|
* type: object
|
|
* required:
|
|
* - formula
|
|
* properties:
|
|
* formula:
|
|
* type: string
|
|
* example: "S + am/is/are + V-ing + (a/an) + O + Adv"
|
|
* pattern_logic:
|
|
* type: array
|
|
* items:
|
|
* type: object
|
|
* properties:
|
|
* slot_id:
|
|
* type: string
|
|
* role:
|
|
* type: string
|
|
* semantic_filter:
|
|
* type: array
|
|
* items:
|
|
* type: string
|
|
* use_form:
|
|
* type: string
|
|
* dependency:
|
|
* type: string
|
|
* is_optional:
|
|
* type: boolean
|
|
* position:
|
|
* type: string
|
|
* instructions:
|
|
* type: object
|
|
* properties:
|
|
* vi:
|
|
* type: string
|
|
* hint:
|
|
* type: string
|
|
* difficulty_score:
|
|
* type: integer
|
|
* minimum: 1
|
|
* maximum: 10
|
|
* category:
|
|
* type: string
|
|
* tags:
|
|
* type: array
|
|
* items:
|
|
* type: string
|
|
* mappings:
|
|
* type: array
|
|
* items:
|
|
* type: object
|
|
* properties:
|
|
* book_id:
|
|
* type: string
|
|
* grade:
|
|
* type: integer
|
|
* unit:
|
|
* type: integer
|
|
* lesson:
|
|
* type: integer
|
|
* context_note:
|
|
* type: string
|
|
* media_stories:
|
|
* type: array
|
|
* items:
|
|
* type: object
|
|
* properties:
|
|
* story_id:
|
|
* type: string
|
|
* title:
|
|
* type: string
|
|
* type:
|
|
* type: string
|
|
* enum: [story, video, animation, audio]
|
|
* url:
|
|
* type: string
|
|
* thumbnail:
|
|
* type: string
|
|
* description:
|
|
* type: string
|
|
* duration_seconds:
|
|
* type: integer
|
|
* min_grade:
|
|
* type: integer
|
|
* example:
|
|
* grammar_code: "gram-001-present-cont"
|
|
* title: "Present Continuous"
|
|
* translation: "Thì hiện tại tiếp diễn"
|
|
* structure:
|
|
* formula: "S + am/is/are + V-ing + (a/an) + O + Adv"
|
|
* pattern_logic:
|
|
* - slot_id: "S_01"
|
|
* role: "is_subject"
|
|
* semantic_filter: ["human", "animal"]
|
|
* - slot_id: "BE_01"
|
|
* role: "is_be"
|
|
* dependency: "S_01"
|
|
* - slot_id: "V_01"
|
|
* role: "is_verb"
|
|
* use_form: "v_ing"
|
|
* semantic_filter: ["action"]
|
|
* - slot_id: "ART_01"
|
|
* role: "is_article"
|
|
* dependency: "O_01"
|
|
* is_optional: true
|
|
* - slot_id: "O_01"
|
|
* role: "is_object"
|
|
* semantic_match: "V_01"
|
|
* - slot_id: "ADV_01"
|
|
* role: "is_adv"
|
|
* is_optional: true
|
|
* position: "end"
|
|
* instructions:
|
|
* vi: "Dùng để nói về hành động đang diễn ra."
|
|
* hint: "Cấu trúc: Be + V-ing"
|
|
* difficulty_score: 2
|
|
* category: "Tenses"
|
|
* tags: ["present", "continuous", "action"]
|
|
* mappings:
|
|
* - book_id: "global-success-2"
|
|
* grade: 2
|
|
* unit: 5
|
|
* lesson: 1
|
|
* media_stories:
|
|
* - story_id: "st-01"
|
|
* title: "The Greedy Cat"
|
|
* type: "story"
|
|
* url: "https://cdn.sena.tech/stories/the-greedy-cat-full.mp4"
|
|
* thumbnail: "https://cdn.sena.tech/thumbs/greedy-cat.jpg"
|
|
* description: "A story about a cat who loves eating everything."
|
|
* duration_seconds: 180
|
|
* min_grade: 2
|
|
* responses:
|
|
* 201:
|
|
* description: Grammar rule created successfully
|
|
* 400:
|
|
* description: Invalid input
|
|
* 500:
|
|
* description: Server error
|
|
*/
|
|
router.post('/', authenticateToken, grammarController.createGrammar);
|
|
|
|
/**
|
|
* @swagger
|
|
* /api/grammar:
|
|
* get:
|
|
* summary: Get all grammar rules with pagination and filters
|
|
* tags: [Grammar]
|
|
* security:
|
|
* - bearerAuth: []
|
|
* parameters:
|
|
* - in: query
|
|
* name: page
|
|
* schema:
|
|
* type: integer
|
|
* default: 1
|
|
* description: Page number
|
|
* - in: query
|
|
* name: limit
|
|
* schema:
|
|
* type: integer
|
|
* default: 20
|
|
* description: Items per page
|
|
* - in: query
|
|
* name: category
|
|
* schema:
|
|
* type: string
|
|
* description: Filter by category (e.g., "Tenses", "Modal Verbs")
|
|
* - in: query
|
|
* name: grade
|
|
* schema:
|
|
* type: integer
|
|
* description: Filter by grade level
|
|
* - in: query
|
|
* name: book_id
|
|
* schema:
|
|
* type: string
|
|
* description: Filter by book ID (e.g., "global-success-1")
|
|
* - in: query
|
|
* name: difficulty_min
|
|
* schema:
|
|
* type: integer
|
|
* description: Minimum difficulty score
|
|
* - in: query
|
|
* name: difficulty_max
|
|
* schema:
|
|
* type: integer
|
|
* description: Maximum difficulty score
|
|
* - in: query
|
|
* name: search
|
|
* schema:
|
|
* type: string
|
|
* description: Search in title, translation, or grammar_code
|
|
* - in: query
|
|
* name: include_media
|
|
* schema:
|
|
* type: string
|
|
* enum: ['true', 'false']
|
|
* default: 'false'
|
|
* description: Include media stories in response
|
|
* responses:
|
|
* 200:
|
|
* description: List of grammar rules
|
|
* 500:
|
|
* description: Server error
|
|
*/
|
|
router.get('/', authenticateToken, grammarController.getAllGrammars);
|
|
|
|
/**
|
|
* @swagger
|
|
* /api/grammar/curriculum:
|
|
* get:
|
|
* summary: Get grammar rules by curriculum mapping
|
|
* tags: [Grammar]
|
|
* security:
|
|
* - bearerAuth: []
|
|
* parameters:
|
|
* - in: query
|
|
* name: book_id
|
|
* required: false
|
|
* schema:
|
|
* type: string
|
|
* description: Book ID (e.g., "global-success-1")
|
|
* - in: query
|
|
* name: grade
|
|
* required: false
|
|
* schema:
|
|
* type: integer
|
|
* description: Grade level
|
|
* - in: query
|
|
* name: unit
|
|
* schema:
|
|
* type: integer
|
|
* description: Unit number
|
|
* - in: query
|
|
* name: lesson
|
|
* schema:
|
|
* type: integer
|
|
* description: Lesson number
|
|
* responses:
|
|
* 200:
|
|
* description: List of grammar rules for the specified curriculum
|
|
* 400:
|
|
* description: Invalid parameters
|
|
* 500:
|
|
* description: Server error
|
|
*/
|
|
router.get('/curriculum', authenticateToken, grammarController.getGrammarsByCurriculum);
|
|
|
|
/**
|
|
* @swagger
|
|
* /api/grammar/guide:
|
|
* get:
|
|
* summary: Get comprehensive guide for AI to create grammar rules
|
|
* tags: [Grammar]
|
|
* security:
|
|
* - bearerAuth: []
|
|
* responses:
|
|
* 200:
|
|
* description: Complete guide with rules, examples, and data structures
|
|
* content:
|
|
* application/json:
|
|
* schema:
|
|
* type: object
|
|
* properties:
|
|
* guide_version:
|
|
* type: string
|
|
* last_updated:
|
|
* type: string
|
|
* data_structure:
|
|
* type: object
|
|
* pattern_logic_roles:
|
|
* type: object
|
|
* semantic_filters:
|
|
* type: object
|
|
* form_keys_reference:
|
|
* type: object
|
|
* rules:
|
|
* type: object
|
|
* examples:
|
|
* type: object
|
|
* validation_checklist:
|
|
* type: array
|
|
* common_mistakes:
|
|
* type: array
|
|
* ai_tips:
|
|
* type: object
|
|
* 500:
|
|
* description: Server error
|
|
*/
|
|
router.get('/guide', authenticateToken, grammarController.getGrammarGuide);
|
|
|
|
/**
|
|
* @swagger
|
|
* /api/grammar/stats:
|
|
* get:
|
|
* summary: Get grammar statistics
|
|
* tags: [Grammar]
|
|
* security:
|
|
* - bearerAuth: []
|
|
* responses:
|
|
* 200:
|
|
* description: Grammar statistics
|
|
* 500:
|
|
* description: Server error
|
|
*/
|
|
router.get('/stats', authenticateToken, grammarController.getGrammarStats);
|
|
|
|
/**
|
|
* @swagger
|
|
* /api/grammar/{id}:
|
|
* get:
|
|
* summary: Get grammar rule by ID or code
|
|
* tags: [Grammar]
|
|
* security:
|
|
* - bearerAuth: []
|
|
* parameters:
|
|
* - in: path
|
|
* name: id
|
|
* required: true
|
|
* schema:
|
|
* type: string
|
|
* description: Grammar ID (numeric) or grammar_code (string)
|
|
* responses:
|
|
* 200:
|
|
* description: Grammar rule details
|
|
* 404:
|
|
* description: Grammar rule not found
|
|
* 500:
|
|
* description: Server error
|
|
*/
|
|
router.get('/:id', authenticateToken, grammarController.getGrammarById);
|
|
|
|
/**
|
|
* @swagger
|
|
* /api/grammar/{id}:
|
|
* put:
|
|
* summary: Update grammar rule
|
|
* tags: [Grammar]
|
|
* security:
|
|
* - bearerAuth: []
|
|
* parameters:
|
|
* - in: path
|
|
* name: id
|
|
* required: true
|
|
* schema:
|
|
* type: string
|
|
* description: Grammar ID (numeric) or grammar_code (string)
|
|
* requestBody:
|
|
* required: true
|
|
* content:
|
|
* application/json:
|
|
* schema:
|
|
* type: object
|
|
* example:
|
|
* translation: "Thì hiện tại tiếp diễn (cập nhật)"
|
|
* difficulty_score: 3
|
|
* tags: ["present", "continuous", "action", "updated"]
|
|
* responses:
|
|
* 200:
|
|
* description: Grammar rule updated successfully
|
|
* 404:
|
|
* description: Grammar rule not found
|
|
* 500:
|
|
* description: Server error
|
|
*/
|
|
router.put('/:id', authenticateToken, grammarController.updateGrammar);
|
|
|
|
/**
|
|
* @swagger
|
|
* /api/grammar/{id}:
|
|
* delete:
|
|
* summary: Delete grammar rule (soft delete)
|
|
* tags: [Grammar]
|
|
* security:
|
|
* - bearerAuth: []
|
|
* parameters:
|
|
* - in: path
|
|
* name: id
|
|
* required: true
|
|
* schema:
|
|
* type: string
|
|
* description: Grammar ID (numeric) or grammar_code (string)
|
|
* responses:
|
|
* 200:
|
|
* description: Grammar rule deleted successfully
|
|
* 404:
|
|
* description: Grammar rule not found
|
|
* 500:
|
|
* description: Server error
|
|
*/
|
|
router.delete('/:id', authenticateToken, grammarController.deleteGrammar);
|
|
|
|
module.exports = router;
|