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

@@ -4,6 +4,7 @@ import { apiCache } from '@/lib/cache';
import { requireSessionAuth, checkRateLimit, getRateLimitHeaders, getClientIp } from '@/lib/auth';
import { PrismaClientKnownRequestError } from '@prisma/client/runtime/library';
import { generateUniqueSlug } from '@/lib/slug';
import { getProjects as getDirectusProjects } from '@/lib/directus';
export async function GET(request: NextRequest) {
try {
@@ -43,6 +44,47 @@ export async function GET(request: NextRequest) {
const published = searchParams.get('published');
const difficulty = searchParams.get('difficulty');
const search = searchParams.get('search');
const locale = searchParams.get('locale') || 'en';
// Try Directus FIRST (Primary Source)
try {
const directusProjects = await getDirectusProjects(locale, {
featured: featured === 'true' ? true : featured === 'false' ? false : undefined,
published: published === 'true' ? true : published === 'false' ? false : undefined,
category: category || undefined,
difficulty: difficulty || undefined,
search: search || undefined,
limit
});
if (directusProjects && directusProjects.length > 0) {
return NextResponse.json({
projects: directusProjects,
total: directusProjects.length,
page: 1,
limit: directusProjects.length,
source: 'directus'
});
}
} catch (directusError) {
console.log('Directus not available, trying PostgreSQL fallback');
}
// Fallback 1: Try PostgreSQL
try {
await prisma.$queryRaw`SELECT 1`;
} catch (dbError) {
console.log('PostgreSQL also not available, using empty fallback');
// Fallback 2: Return empty (components should have hardcoded fallback)
return NextResponse.json({
projects: [],
total: 0,
page: 1,
limit,
source: 'fallback'
});
}
// Create cache parameters object
const cacheParams = {
@@ -93,7 +135,8 @@ export async function GET(request: NextRequest) {
projects,
total,
pages: Math.ceil(total / limit),
currentPage: page
currentPage: page,
source: 'postgresql'
};
// Cache the result (only for non-search queries)
@@ -105,7 +148,7 @@ export async function GET(request: NextRequest) {
} catch (error) {
// Handle missing database table gracefully
if (error instanceof PrismaClientKnownRequestError && error.code === 'P2021') {
if (process.env.NODE_ENV === 'development') {
if (process.env.NOD-fallbackE_ENV === 'development') {
console.warn('Project table does not exist. Returning empty result.');
}
return NextResponse.json({