🚀 Add automatic deployment system

- Add auto-deploy.sh script with full CI/CD pipeline
- Add quick-deploy.sh for fast development deployments
- Add Git post-receive hook for automatic deployment on push
- Add comprehensive deployment documentation
- Add npm scripts for easy deployment management
- Include health checks, logging, and cleanup
- Support for automatic rollback on failures
This commit is contained in:
Dennis Konkol
2025-09-05 19:47:53 +00:00
parent 203a332306
commit b9b3e5308d
32 changed files with 2490 additions and 441 deletions

View File

@@ -0,0 +1,31 @@
import { NextRequest, NextResponse } from 'next/server';
export async function POST(request: NextRequest) {
try {
const body = await request.json();
// Log performance metrics (you can extend this to store in database)
console.log('Performance Metric:', {
timestamp: new Date().toISOString(),
...body,
});
// You could store this in a database or send to external service
// For now, we'll just log it since Umami handles the main analytics
return NextResponse.json({ success: true });
} catch (error) {
console.error('Analytics API Error:', error);
return NextResponse.json(
{ error: 'Failed to process analytics data' },
{ status: 500 }
);
}
}
export async function GET() {
return NextResponse.json({
message: 'Analytics API is running',
timestamp: new Date().toISOString(),
});
}

25
app/api/health/route.ts Normal file
View File

@@ -0,0 +1,25 @@
import { NextResponse } from 'next/server';
export async function GET() {
try {
// Basic health check
const healthCheck = {
status: 'healthy',
timestamp: new Date().toISOString(),
uptime: process.uptime(),
environment: process.env.NODE_ENV,
version: process.env.npm_package_version || '1.0.0',
};
return NextResponse.json(healthCheck, { status: 200 });
} catch (error) {
return NextResponse.json(
{
status: 'unhealthy',
timestamp: new Date().toISOString(),
error: error instanceof Error ? error.message : 'Unknown error',
},
{ status: 503 }
);
}
}

View File

@@ -3,10 +3,11 @@ import { prisma } from '@/lib/prisma';
export async function GET(
request: NextRequest,
{ params }: { params: { id: string } }
{ params }: { params: Promise<{ id: string }> }
) {
try {
const id = parseInt(params.id);
const { id: idParam } = await params;
const id = parseInt(idParam);
const project = await prisma.project.findUnique({
where: { id }
@@ -31,10 +32,11 @@ export async function GET(
export async function PUT(
request: NextRequest,
{ params }: { params: { id: string } }
{ params }: { params: Promise<{ id: string }> }
) {
try {
const id = parseInt(params.id);
const { id: idParam } = await params;
const id = parseInt(idParam);
const data = await request.json();
const project = await prisma.project.update({
@@ -54,10 +56,11 @@ export async function PUT(
export async function DELETE(
request: NextRequest,
{ params }: { params: { id: string } }
{ params }: { params: Promise<{ id: string }> }
) {
try {
const id = parseInt(params.id);
const { id: idParam } = await params;
const id = parseInt(idParam);
await prisma.project.delete({
where: { id }

View File

@@ -3,6 +3,8 @@ import { Metadata } from "next";
import { Inter } from "next/font/google";
import React from "react";
import { ToastProvider } from "@/components/Toast";
import { AnalyticsProvider } from "@/components/AnalyticsProvider";
import { PerformanceDashboard } from "@/components/PerformanceDashboard";
const inter = Inter({
variable: "--font-inter",
@@ -17,18 +19,17 @@ export default function RootLayout({
return (
<html lang="en">
<head>
<script
defer
src="https://umami.denshooter.de/script.js"
data-website-id="1f213877-deef-4238-8df1-71a5a3bcd142"
></script>
<script defer src="https://analytics.dk0.dev/script.js" data-website-id="b3665829-927a-4ada-b9bb-fcf24171061e"></script>
<meta charSet="utf-8"/>
<title>Dennis Konkol&#39;s Portfolio</title>
</head>
<body className={inter.variable}>
<ToastProvider>
{children}
</ToastProvider>
<AnalyticsProvider>
<ToastProvider>
{children}
<PerformanceDashboard />
</ToastProvider>
</AnalyticsProvider>
</body>
</html>
);