feat: initial zeropost-engine structure
- AI service with Anthropic claude-sonnet-4-6 - Bull queue for async generation jobs - Routes: /api/generate, /api/channels, /api/posts - PostgreSQL schema: users, channels, posts, generation_jobs - Supports: post, article, topics generation types
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
const Queue = require('bull');
|
||||
const config = require('../config');
|
||||
const ai = require('../services/ai');
|
||||
const { query } = require('../config/db');
|
||||
|
||||
const generationQueue = new Queue('generation', {
|
||||
redis: config.redis,
|
||||
defaultJobOptions: {
|
||||
attempts: 3,
|
||||
backoff: { type: 'exponential', delay: 5000 },
|
||||
removeOnComplete: 100,
|
||||
removeOnFail: 200,
|
||||
},
|
||||
});
|
||||
|
||||
generationQueue.process(async (job) => {
|
||||
const { jobId, type, topic, tone, language, channelContext, keywords } = job.data;
|
||||
|
||||
await query(`UPDATE generation_jobs SET status='processing', updated_at=NOW() WHERE id=$1`, [jobId]);
|
||||
|
||||
try {
|
||||
let result;
|
||||
if (type === 'post') {
|
||||
result = await ai.generatePost({ topic, tone, language, channelContext });
|
||||
} else if (type === 'article') {
|
||||
result = await ai.generateArticle({ topic, language, keywords });
|
||||
} else if (type === 'topics') {
|
||||
const topics = await ai.generateTopics({ channelContext: topic, language });
|
||||
result = JSON.stringify(topics);
|
||||
} else {
|
||||
throw new Error(`Unknown job type: ${type}`);
|
||||
}
|
||||
|
||||
await query(
|
||||
`UPDATE generation_jobs SET status='done', result=$1, updated_at=NOW() WHERE id=$2`,
|
||||
[result, jobId]
|
||||
);
|
||||
|
||||
console.log(`[Worker] Job ${jobId} (${type}) done`);
|
||||
return { jobId, result };
|
||||
|
||||
} catch (err) {
|
||||
await query(
|
||||
`UPDATE generation_jobs SET status='failed', error=$1, updated_at=NOW() WHERE id=$2`,
|
||||
[err.message, jobId]
|
||||
);
|
||||
throw err;
|
||||
}
|
||||
});
|
||||
|
||||
generationQueue.on('failed', (job, err) => {
|
||||
console.error(`[Worker] Job ${job.data.jobId} failed:`, err.message);
|
||||
});
|
||||
|
||||
console.log('[Worker] Generation queue started');
|
||||
|
||||
module.exports = generationQueue;
|
||||
Reference in New Issue
Block a user