Compare commits
1 Commits
94ce012837
...
v2-rawaj
| Author | SHA1 | Date | |
|---|---|---|---|
| af91dba268 |
@@ -673,6 +673,111 @@ app.get('/api/health', async (req, res) => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// ─── MIGRATIONS ─────────────────────────────────────────────────
|
||||||
|
|
||||||
|
// One-time migration: convert Translations with post_id → Artefacts (copy type)
|
||||||
|
// Safe to run multiple times — skips posts that already have copy Artefacts.
|
||||||
|
app.post('/api/admin/migrate-translations-to-artefacts', requireAuth, async (req, res) => {
|
||||||
|
if (req.session.userRole !== 'superadmin') return res.status(403).json({ error: 'Superadmin only' });
|
||||||
|
const dryRun = req.body.dry_run !== false; // default true for safety
|
||||||
|
const report = { dry_run: dryRun, skipped: [], migrated: [], errors: [] };
|
||||||
|
|
||||||
|
try {
|
||||||
|
// All translations linked to a post (caption or body copy)
|
||||||
|
const translations = await nocodb.list('Translations', {
|
||||||
|
where: `(post_id,gt,0)`, limit: 2000,
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const t of translations) {
|
||||||
|
if (!t.post_id) continue;
|
||||||
|
const copyType = t.copy_type || 'body';
|
||||||
|
|
||||||
|
// Skip if an Artefact for this post+copy_type already exists
|
||||||
|
const existing = await nocodb.list('Artefacts', {
|
||||||
|
where: `(post_id,eq,${t.post_id})~and(type,eq,copy)~and(copy_type,eq,${copyType})`,
|
||||||
|
limit: 1,
|
||||||
|
});
|
||||||
|
if (existing.length > 0) {
|
||||||
|
report.skipped.push({ translation_id: t.Id, post_id: t.post_id, copy_type: copyType, reason: 'artefact already exists' });
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dryRun) {
|
||||||
|
report.migrated.push({ translation_id: t.Id, post_id: t.post_id, copy_type: copyType, title: t.title, dry_run: true });
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 1. Create Artefact
|
||||||
|
const artefact = await nocodb.create('Artefacts', {
|
||||||
|
title: t.title || (copyType === 'caption' ? 'Caption' : 'Body Copy'),
|
||||||
|
type: 'copy',
|
||||||
|
copy_type: copyType,
|
||||||
|
status: t.status || 'draft',
|
||||||
|
post_id: t.post_id,
|
||||||
|
brand_id: t.brand_id || null,
|
||||||
|
approver_ids: t.approver_ids || null,
|
||||||
|
approval_token: t.approval_token || null,
|
||||||
|
approved_by_name: t.approved_by_name || null,
|
||||||
|
approved_at: t.approved_at || null,
|
||||||
|
feedback: t.feedback || null,
|
||||||
|
created_by_user_id: t.created_by_user_id || null,
|
||||||
|
});
|
||||||
|
|
||||||
|
// 2. Create first ArtefactVersion
|
||||||
|
const version = await nocodb.create('ArtefactVersions', {
|
||||||
|
artefact_id: artefact.Id,
|
||||||
|
version_number: 1,
|
||||||
|
status: t.status || 'draft',
|
||||||
|
created_by_user_id: t.created_by_user_id || null,
|
||||||
|
});
|
||||||
|
|
||||||
|
// 3. Migrate source content as a version text entry
|
||||||
|
const textsToCreate = [];
|
||||||
|
if (t.source_content && t.source_language) {
|
||||||
|
textsToCreate.push({
|
||||||
|
version_id: version.Id,
|
||||||
|
language_code: t.source_language,
|
||||||
|
language_label: t.source_language,
|
||||||
|
content: t.source_content,
|
||||||
|
status: 'draft',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Migrate TranslationTexts as additional language entries
|
||||||
|
const translationTexts = await nocodb.list('TranslationTexts', {
|
||||||
|
where: `(translation_id,eq,${t.Id})`, limit: 50,
|
||||||
|
});
|
||||||
|
for (const tt of translationTexts) {
|
||||||
|
if (tt.language_code === t.source_language) continue; // already added above
|
||||||
|
textsToCreate.push({
|
||||||
|
version_id: version.Id,
|
||||||
|
language_code: tt.language_code,
|
||||||
|
language_label: tt.language_label || tt.language_code,
|
||||||
|
content: tt.content || '',
|
||||||
|
status: tt.status || 'draft',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (textsToCreate.length > 0) {
|
||||||
|
await nocodb.bulkCreate('ArtefactVersionTexts', textsToCreate);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. Set current_version on Artefact
|
||||||
|
await nocodb.update('Artefacts', artefact.Id, { current_version: 1 });
|
||||||
|
|
||||||
|
report.migrated.push({ translation_id: t.Id, artefact_id: artefact.Id, post_id: t.post_id, copy_type: copyType, title: artefact.title, texts: textsToCreate.length });
|
||||||
|
} catch (err) {
|
||||||
|
report.errors.push({ translation_id: t.Id, post_id: t.post_id, error: err.message });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
res.json({ ...report, summary: { total: translations.length, migrated: report.migrated.length, skipped: report.skipped.length, errors: report.errors.length } });
|
||||||
|
} catch (err) {
|
||||||
|
res.status(500).json({ error: err.message });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// ─── EMAIL TEST ─────────────────────────────────────────────────
|
// ─── EMAIL TEST ─────────────────────────────────────────────────
|
||||||
|
|
||||||
app.post('/api/admin/test-email', requireAuth, async (req, res) => {
|
app.post('/api/admin/test-email', requireAuth, async (req, res) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user