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:
2026-01-23 02:53:31 +01:00
parent 7604e00e0f
commit e431ff50fc
28 changed files with 5253 additions and 23 deletions

View File

@@ -0,0 +1,106 @@
#!/usr/bin/env node
/**
* Add German translations for projects in Directus (if missing).
* - Reads projects from Directus REST
* - If no de-DE translation exists, creates one using provided fallback strings
*/
const fetch = require('node-fetch');
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('❌ DIRECTUS_STATIC_TOKEN missing');
process.exit(1);
}
const deFallback = {
'kernel-panic-404-interactive-terminal': {
title: 'Kernel Panic 404 Interaktives Terminal',
description: 'Ein spielerisches 404-Erlebnis als interaktives Terminal mit Retro-Feeling.',
},
'machine-learning-model-api': {
title: 'Machine-Learning-Modell API',
description: 'Produktionsreife API für ML-Modelle mit klarer Dokumentation und Monitoring.',
},
'weather-forecast-app': {
title: 'Wettervorhersage App',
description: 'Schnelle Wetter-UI mit klaren Prognosen und responsivem Design.',
},
'task-management-dashboard': {
title: 'Task-Management Dashboard',
description: 'Kanban-Board mit Kollaboration, Filtern und Realtime-Updates.',
},
'real-time-chat-application': {
title: 'Echtzeit Chat App',
description: 'Websocket-basierter Chat mit Typing-Status, Presence und Uploads.',
},
'e-commerce-platform-api': {
title: 'E-Commerce Plattform API',
description: 'Headless Commerce API mit Checkout, Inventory und Webhooks.',
},
'portfolio-website-modern-developer-showcase': {
title: 'Portfolio Website Moderner Entwicklerauftritt',
description: 'Schnelle, übersichtliche Portfolio-Seite mit Projekten und Aktivitäten.',
},
clarity: {
title: 'Clarity Dyslexie-Unterstützung',
description: 'Mobile App mit OpenDyslexic Schrift und AI-Textvereinfachung.',
},
};
async function directus(path, options = {}) {
const res = await fetch(`${DIRECTUS_URL}/${path}`, {
...options,
headers: {
Authorization: `Bearer ${DIRECTUS_TOKEN}`,
'Content-Type': 'application/json',
...(options.headers || {}),
},
});
if (!res.ok) {
const text = await res.text();
throw new Error(`HTTP ${res.status} ${path}: ${text}`);
}
return res.json();
}
async function main() {
console.log('🔍 Fetching projects from Directus...');
const { data: projects } = await directus(
'items/projects?fields=id,slug,translations.languages_code,translations.title,translations.description'
);
let created = 0;
for (const proj of projects) {
const hasDe = (proj.translations || []).some((t) => t.languages_code === 'de-DE');
if (hasDe) continue;
const fallback = deFallback[proj.slug] || {};
const en = (proj.translations || [])[0] || {};
const payload = {
projects_id: proj.id,
languages_code: 'de-DE',
title: fallback.title || en.title || proj.slug,
description: fallback.description || en.description || en.title || proj.slug,
content: en.content || null,
meta_description: null,
keywords: null,
};
await directus('items/projects_translations', {
method: 'POST',
body: JSON.stringify(payload),
});
created += 1;
console.log(` Added de-DE translation for ${proj.slug}`);
}
console.log(`✅ Done. Added ${created} de-DE translations.`);
}
main().catch((err) => {
console.error('❌ Failed:', err.message);
process.exit(1);
});