Files
portfolio/scripts/migrate-projects-to-directus.js
denshooter e431ff50fc 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.
2026-01-23 02:53:31 +01:00

226 lines
7.4 KiB
JavaScript

#!/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();