feat: Add Directus setup scripts for collections, fields, and relations
- Created setup-directus-collections.js to automate the creation of tech stack collections, fields, and relations in Directus. - Created setup-directus-hobbies.js for setting up hobbies collection with translations. - Created setup-directus-projects.js for establishing projects collection with comprehensive fields and translations. - Added setup-tech-stack-directus.js to populate tech_stack_items with predefined data.
This commit is contained in:
225
scripts/migrate-projects-to-directus.js
Normal file
225
scripts/migrate-projects-to-directus.js
Normal file
@@ -0,0 +1,225 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Migrate Projects from PostgreSQL to Directus
|
||||
*
|
||||
* Migriert ALLE bestehenden Projects aus deiner PostgreSQL Datenbank nach Directus
|
||||
* inklusive aller Felder und Translations.
|
||||
*
|
||||
* Usage:
|
||||
* node scripts/migrate-projects-to-directus.js
|
||||
*/
|
||||
|
||||
const fetch = require('node-fetch');
|
||||
const { PrismaClient } = require('@prisma/client');
|
||||
require('dotenv').config();
|
||||
|
||||
const DIRECTUS_URL = process.env.DIRECTUS_URL || 'https://cms.dk0.dev';
|
||||
const DIRECTUS_TOKEN = process.env.DIRECTUS_STATIC_TOKEN;
|
||||
|
||||
if (!DIRECTUS_TOKEN) {
|
||||
console.error('❌ Error: DIRECTUS_STATIC_TOKEN not found in .env');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
async function directusRequest(endpoint, method = 'GET', body = null) {
|
||||
const url = `${DIRECTUS_URL}/${endpoint}`;
|
||||
const options = {
|
||||
method,
|
||||
headers: {
|
||||
'Authorization': `Bearer ${DIRECTUS_TOKEN}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
};
|
||||
|
||||
if (body) {
|
||||
options.body = JSON.stringify(body);
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(url, options);
|
||||
if (!response.ok) {
|
||||
const text = await response.text();
|
||||
throw new Error(`HTTP ${response.status}: ${text}`);
|
||||
}
|
||||
return await response.json();
|
||||
} catch (error) {
|
||||
console.error(`Error calling ${method} ${endpoint}:`, error.message);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async function migrateProjects() {
|
||||
console.log('\n📦 Migrating Projects from PostgreSQL to Directus...\n');
|
||||
|
||||
// Load all published projects from PostgreSQL
|
||||
const projects = await prisma.project.findMany({
|
||||
where: { published: true },
|
||||
include: {
|
||||
translations: true
|
||||
},
|
||||
orderBy: { createdAt: 'desc' }
|
||||
});
|
||||
|
||||
console.log(`Found ${projects.length} published projects in PostgreSQL\n`);
|
||||
|
||||
let successCount = 0;
|
||||
let errorCount = 0;
|
||||
|
||||
for (const project of projects) {
|
||||
console.log(`\n📁 Migrating: ${project.title}`);
|
||||
|
||||
try {
|
||||
// 1. Create project in Directus
|
||||
console.log(' Creating project...');
|
||||
const projectData = {
|
||||
slug: project.slug,
|
||||
status: 'published',
|
||||
featured: project.featured,
|
||||
category: project.category,
|
||||
difficulty: project.difficulty,
|
||||
date: project.date,
|
||||
time_to_complete: project.timeToComplete,
|
||||
github: project.github,
|
||||
live: project.live,
|
||||
image_url: project.imageUrl,
|
||||
demo_video: project.demoVideo,
|
||||
color_scheme: project.colorScheme,
|
||||
accessibility: project.accessibility,
|
||||
tags: project.tags,
|
||||
technologies: project.technologies,
|
||||
challenges: project.challenges,
|
||||
lessons_learned: project.lessonsLearned,
|
||||
future_improvements: project.futureImprovements,
|
||||
screenshots: project.screenshots,
|
||||
performance: project.performance
|
||||
};
|
||||
|
||||
const { data: createdProject } = await directusRequest(
|
||||
'items/projects',
|
||||
'POST',
|
||||
projectData
|
||||
);
|
||||
|
||||
console.log(` ✅ Project created with ID: ${createdProject.id}`);
|
||||
|
||||
// 2. Create Translations
|
||||
console.log(' Creating translations...');
|
||||
|
||||
// Default locale translation (from main project fields)
|
||||
await directusRequest(
|
||||
'items/projects_translations',
|
||||
'POST',
|
||||
{
|
||||
projects_id: createdProject.id,
|
||||
languages_code: project.defaultLocale === 'en' ? 'en-US' : 'de-DE',
|
||||
title: project.title,
|
||||
description: project.description,
|
||||
content: project.content,
|
||||
meta_description: project.metaDescription,
|
||||
keywords: project.keywords
|
||||
}
|
||||
);
|
||||
|
||||
// Additional translations from ProjectTranslation table
|
||||
for (const translation of project.translations) {
|
||||
// Skip if it's the same as default locale (already created above)
|
||||
if (translation.locale === project.defaultLocale) {
|
||||
continue;
|
||||
}
|
||||
|
||||
await directusRequest(
|
||||
'items/projects_translations',
|
||||
'POST',
|
||||
{
|
||||
projects_id: createdProject.id,
|
||||
languages_code: translation.locale === 'en' ? 'en-US' : 'de-DE',
|
||||
title: translation.title,
|
||||
description: translation.description,
|
||||
content: translation.content ? JSON.stringify(translation.content) : null,
|
||||
meta_description: translation.metaDescription,
|
||||
keywords: translation.keywords
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
console.log(` ✅ Translations created (${project.translations.length + 1} locales)`);
|
||||
successCount++;
|
||||
|
||||
} catch (error) {
|
||||
console.error(` ❌ Error migrating ${project.title}:`, error.message);
|
||||
errorCount++;
|
||||
}
|
||||
}
|
||||
|
||||
console.log('\n╔════════════════════════════════════════╗');
|
||||
console.log(`║ Migration Complete! ║`);
|
||||
console.log('╚════════════════════════════════════════╝\n');
|
||||
console.log(`✅ Successfully migrated: ${successCount} projects`);
|
||||
console.log(`❌ Failed: ${errorCount} projects\n`);
|
||||
|
||||
if (successCount > 0) {
|
||||
console.log('🎉 Projects are now in Directus!\n');
|
||||
console.log('Next steps:');
|
||||
console.log(' 1. Visit: https://cms.dk0.dev/admin/content/projects');
|
||||
console.log(' 2. Verify all projects are visible');
|
||||
console.log(' 3. Update lib/directus.ts with getProjects() function');
|
||||
console.log(' 4. Update components to use Directus API\n');
|
||||
}
|
||||
}
|
||||
|
||||
async function verifyMigration() {
|
||||
console.log('\n🔍 Verifying Migration...\n');
|
||||
|
||||
try {
|
||||
const { data: projects } = await directusRequest(
|
||||
'items/projects?fields=slug,status,translations.title,translations.languages_code'
|
||||
);
|
||||
|
||||
console.log(`✅ Found ${projects.length} projects in Directus:`);
|
||||
projects.slice(0, 5).forEach(p => {
|
||||
const enTitle = p.translations?.find(t => t.languages_code === 'en-US')?.title;
|
||||
console.log(` - ${p.slug}: "${enTitle || 'No title'}"`);
|
||||
});
|
||||
|
||||
if (projects.length > 5) {
|
||||
console.log(` ... and ${projects.length - 5} more`);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Verification failed:', error.message);
|
||||
}
|
||||
}
|
||||
|
||||
async function main() {
|
||||
console.log('\n╔════════════════════════════════════════╗');
|
||||
console.log('║ Project Migration: PostgreSQL → Directus ║');
|
||||
console.log('╚════════════════════════════════════════╝\n');
|
||||
|
||||
try {
|
||||
// Test database connection first
|
||||
console.log('🔍 Testing database connection...');
|
||||
await prisma.$connect();
|
||||
console.log('✅ Database connected\n');
|
||||
|
||||
await migrateProjects();
|
||||
await verifyMigration();
|
||||
} catch (error) {
|
||||
if (error.message?.includes("Can't reach database")) {
|
||||
console.error('\n❌ PostgreSQL ist nicht erreichbar!');
|
||||
console.error('\n💡 Lösungen:');
|
||||
console.error(' 1. Starte PostgreSQL: npm run dev');
|
||||
console.error(' 2. Oder nutze Docker: docker-compose up -d postgres');
|
||||
console.error(' 3. Oder skip diesen Schritt - Projects Collection existiert bereits in Directus\n');
|
||||
console.error('Du kannst Projects später manuell in Directus erstellen oder die Migration erneut ausführen.\n');
|
||||
process.exit(0); // Graceful exit
|
||||
}
|
||||
console.error('\n❌ Migration failed:', error);
|
||||
process.exit(1);
|
||||
} finally {
|
||||
await prisma.$disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
Reference in New Issue
Block a user