update context API
All checks were successful
Deploy to Production / deploy (push) Successful in 19s
All checks were successful
Deploy to Production / deploy (push) Successful in 19s
This commit is contained in:
@@ -1,20 +1,67 @@
|
||||
const { Context } = require('../models');
|
||||
|
||||
/**
|
||||
* Context Controller
|
||||
* Context Controller - Workflow-based status management
|
||||
* Status flow: 0 (Draft) -> 1 (Enriched) -> 2 (Prompt Ready) -> 3 (Generating) -> 4 (Image Ready) -> 5 (Approved)
|
||||
*/
|
||||
class ContextController {
|
||||
/**
|
||||
* Get all contexts with pagination and filters
|
||||
* Create new context - Status 0 (Draft)
|
||||
* Required fields: title, desc, grade
|
||||
*/
|
||||
async getAllContexts(req, res, next) {
|
||||
async createContext(req, res, next) {
|
||||
try {
|
||||
const { page = 1, limit = 50, type, title } = req.query;
|
||||
const { title, desc, grade, type } = req.body;
|
||||
|
||||
// Validate required fields
|
||||
if (!title || !desc || !grade) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: 'Title, desc, and grade are required'
|
||||
});
|
||||
}
|
||||
|
||||
// Validate grade format (gradeX100 + unitX10 + lesson)
|
||||
const gradeNum = parseInt(grade);
|
||||
if (isNaN(gradeNum) || gradeNum < 100) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: 'Grade must be in format: gradeX100 + unitX10 + lesson (e.g., 123 for Grade 1 Unit 2 Lesson 3)'
|
||||
});
|
||||
}
|
||||
|
||||
const context = await Context.create({
|
||||
title,
|
||||
desc,
|
||||
grade: gradeNum,
|
||||
type: type || 'general',
|
||||
status: 0, // Draft
|
||||
context: '',
|
||||
knowledge: ''
|
||||
});
|
||||
|
||||
res.status(201).json({
|
||||
success: true,
|
||||
message: 'Context created successfully',
|
||||
data: context
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get contexts by status
|
||||
*/
|
||||
async getContextsByStatus(req, res, next) {
|
||||
try {
|
||||
const { status } = req.params;
|
||||
const { page = 1, limit = 50, type, grade } = req.query;
|
||||
const offset = (page - 1) * limit;
|
||||
|
||||
const where = {};
|
||||
const where = { status: parseInt(status) };
|
||||
if (type) where.type = type;
|
||||
if (title) where.title = title;
|
||||
if (grade) where.grade = parseInt(grade);
|
||||
|
||||
const { count, rows } = await Context.findAndCountAll({
|
||||
where,
|
||||
@@ -41,7 +88,219 @@ class ContextController {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get context by UUID
|
||||
* Update knowledge - Status 0 -> 1 (Enriched)
|
||||
*/
|
||||
async enrichContext(req, res, next) {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const { knowledge } = req.body;
|
||||
|
||||
if (!knowledge) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: 'Knowledge is required'
|
||||
});
|
||||
}
|
||||
|
||||
const context = await Context.findByPk(id);
|
||||
if (!context) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: 'Context not found'
|
||||
});
|
||||
}
|
||||
|
||||
if (context.status !== 0) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: 'Context must be in Draft status (0) to enrich'
|
||||
});
|
||||
}
|
||||
|
||||
await context.update({
|
||||
knowledge,
|
||||
status: 1
|
||||
});
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
message: 'Context enriched successfully',
|
||||
data: context
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update context and img_prompt - Status 1 -> 2 (Prompt Ready)
|
||||
*/
|
||||
async preparePrompt(req, res, next) {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const { context, img_prompt } = req.body;
|
||||
|
||||
if (!context || !img_prompt) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: 'Context and img_prompt are required'
|
||||
});
|
||||
}
|
||||
|
||||
const contextRecord = await Context.findByPk(id);
|
||||
if (!contextRecord) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: 'Context not found'
|
||||
});
|
||||
}
|
||||
|
||||
if (contextRecord.status !== 1) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: 'Context must be in Enriched status (1) to prepare prompt'
|
||||
});
|
||||
}
|
||||
|
||||
await contextRecord.update({
|
||||
context,
|
||||
img_prompt,
|
||||
status: 2
|
||||
});
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
message: 'Prompt prepared successfully',
|
||||
data: contextRecord
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update status to 3 (Generating) or back to 1 (Enriched)
|
||||
*/
|
||||
async updateStatusFromPromptReady(req, res, next) {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const { status } = req.body;
|
||||
|
||||
if (![1, 3].includes(parseInt(status))) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: 'Status must be 1 (Enriched) or 3 (Generating)'
|
||||
});
|
||||
}
|
||||
|
||||
const context = await Context.findByPk(id);
|
||||
if (!context) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: 'Context not found'
|
||||
});
|
||||
}
|
||||
|
||||
if (context.status !== 2) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: 'Context must be in Prompt Ready status (2) to update'
|
||||
});
|
||||
}
|
||||
|
||||
await context.update({ status: parseInt(status) });
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
message: `Status updated to ${status}`,
|
||||
data: context
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add images - Status 3 -> 4 (Image Ready)
|
||||
*/
|
||||
async addImages(req, res, next) {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const { image } = req.body;
|
||||
|
||||
if (!image || !Array.isArray(image) || image.length === 0) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: 'Image must be a non-empty array of URLs'
|
||||
});
|
||||
}
|
||||
|
||||
const context = await Context.findByPk(id);
|
||||
if (!context) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: 'Context not found'
|
||||
});
|
||||
}
|
||||
|
||||
if (context.status !== 3) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: 'Context must be in Generating status (3) to add images'
|
||||
});
|
||||
}
|
||||
|
||||
await context.update({
|
||||
image,
|
||||
status: 4
|
||||
});
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
message: 'Images added successfully',
|
||||
data: context
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Approve context - Status 4 -> 5 (Approved)
|
||||
*/
|
||||
async approveContext(req, res, next) {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
|
||||
const context = await Context.findByPk(id);
|
||||
if (!context) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: 'Context not found'
|
||||
});
|
||||
}
|
||||
|
||||
if (context.status !== 4) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: 'Context must be in Image Ready status (4) to approve'
|
||||
});
|
||||
}
|
||||
|
||||
await context.update({ status: 5 });
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
message: 'Context approved successfully',
|
||||
data: context
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get context by UUID (for viewing details)
|
||||
*/
|
||||
async getContextById(req, res, next) {
|
||||
try {
|
||||
@@ -65,16 +324,36 @@ class ContextController {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new context
|
||||
* Get all contexts with pagination and filters
|
||||
*/
|
||||
async createContext(req, res, next) {
|
||||
async getAllContexts(req, res, next) {
|
||||
try {
|
||||
const context = await Context.create(req.body);
|
||||
const { page = 1, limit = 50, type, grade, status } = req.query;
|
||||
const offset = (page - 1) * limit;
|
||||
|
||||
res.status(201).json({
|
||||
const where = {};
|
||||
if (type) where.type = type;
|
||||
if (grade) where.grade = parseInt(grade);
|
||||
if (status !== undefined) where.status = parseInt(status);
|
||||
|
||||
const { count, rows } = await Context.findAndCountAll({
|
||||
where,
|
||||
limit: parseInt(limit),
|
||||
offset: parseInt(offset),
|
||||
order: [['created_at', 'DESC']]
|
||||
});
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
message: 'Context created successfully',
|
||||
data: context
|
||||
data: {
|
||||
contexts: rows,
|
||||
pagination: {
|
||||
total: count,
|
||||
page: parseInt(page),
|
||||
limit: parseInt(limit),
|
||||
totalPages: Math.ceil(count / limit)
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
@@ -82,7 +361,7 @@ class ContextController {
|
||||
}
|
||||
|
||||
/**
|
||||
* Update context
|
||||
* Update context (general update - use with caution)
|
||||
*/
|
||||
async updateContext(req, res, next) {
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user