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;