275 lines
8.0 KiB
TypeScript
275 lines
8.0 KiB
TypeScript
import { PrismaClient } from "@prisma/client";
|
||
|
||
const prisma = new PrismaClient();
|
||
|
||
async function main() {
|
||
console.log("🌱 Seeding database...");
|
||
|
||
// Clear existing data
|
||
await prisma.userInteraction.deleteMany();
|
||
await prisma.pageView.deleteMany();
|
||
await prisma.project.deleteMany();
|
||
|
||
// Create real projects
|
||
const projects = [
|
||
{
|
||
title: "Clarity",
|
||
description:
|
||
"A Flutter mobile app supporting people with dyslexia by displaying text in OpenDyslexic font and simplifying content using AI.",
|
||
content: `# Clarity - Dyslexia Support App
|
||
|
||
Clarity is a mobile application built with Flutter to help people with dyslexia read and understand text more easily.
|
||
|
||
## 🎯 Purpose
|
||
|
||
The app was designed to make reading more accessible by using the OpenDyslexic font, which is specifically designed to make letters more distinguishable and reduce reading errors.
|
||
|
||
## 🚀 Features
|
||
|
||
- **OpenDyslexic Font**: All text is displayed in the OpenDyslexic typeface
|
||
- **AI Text Simplification**: Complex texts are simplified using AI integration
|
||
- **Clean Interface**: Simple, distraction-free reading experience
|
||
- **Mobile-First**: Optimized for smartphones and tablets
|
||
- **Accessibility**: Built with accessibility in mind from the ground up
|
||
|
||
## 🛠️ Technologies Used
|
||
|
||
- Flutter
|
||
- Dart
|
||
- AI Integration for text simplification
|
||
- OpenDyslexic Font
|
||
|
||
## 📱 Platform Support
|
||
|
||
- iOS
|
||
- Android
|
||
|
||
## 💡 What I Learned
|
||
|
||
Building Clarity taught me a lot about accessibility, mobile UI/UX design, and how to integrate AI services into mobile applications. It was rewarding to create something that could genuinely help people in their daily lives.
|
||
|
||
## 🔮 Future Plans
|
||
|
||
- Add more font options
|
||
- Implement text-to-speech
|
||
- Support for more languages
|
||
- PDF and document scanning`,
|
||
tags: ["Flutter", "Mobile", "AI", "Accessibility", "Dart"],
|
||
featured: true,
|
||
category: "Mobile Development",
|
||
date: "2024",
|
||
published: true,
|
||
difficulty: "INTERMEDIATE",
|
||
timeToComplete: "4-6 weeks",
|
||
technologies: ["Flutter", "Dart", "AI Integration", "OpenDyslexic Font"],
|
||
challenges: [
|
||
"Implementing AI text simplification",
|
||
"Font rendering optimization",
|
||
"Mobile accessibility standards",
|
||
],
|
||
lessonsLearned: [
|
||
"Mobile development with Flutter",
|
||
"Accessibility best practices",
|
||
"AI API integration",
|
||
],
|
||
futureImprovements: [
|
||
"Text-to-speech",
|
||
"Multi-language support",
|
||
"Document scanning",
|
||
],
|
||
demoVideo: "",
|
||
screenshots: [],
|
||
colorScheme: "Clean and minimal with high contrast",
|
||
accessibility: true,
|
||
performance: {
|
||
lighthouse: 0,
|
||
bundleSize: "0KB",
|
||
loadTime: "0s",
|
||
},
|
||
analytics: {
|
||
views: 850,
|
||
likes: 67,
|
||
shares: 34,
|
||
},
|
||
},
|
||
{
|
||
title: "Self-Hosted Infrastructure & Portfolio",
|
||
description:
|
||
"A complete DevOps setup running in Docker Swarm. My Next.js projects are deployed via automated CI/CD pipelines with custom runners.",
|
||
content: `# Self-Hosted Infrastructure & Portfolio
|
||
|
||
Not just a website – this is a complete self-hosted infrastructure project showcasing my DevOps skills and passion for self-hosting.
|
||
|
||
## 🏗️ Architecture
|
||
|
||
All my projects run on a Docker Swarm cluster hosted on IONOS and OVHcloud servers. Everything is self-managed, from the networking layer to the application deployments.
|
||
|
||
## 🚀 Features
|
||
|
||
- **Docker Swarm Cluster**: Multi-node orchestration for high availability
|
||
- **Traefik Reverse Proxy**: Automatic SSL certificates and routing
|
||
- **Automated CI/CD**: Custom GitLab/Gitea runners for continuous deployment
|
||
- **Zero-Downtime Deployments**: Rolling updates without service interruption
|
||
- **Redis Caching**: Performance optimization with Redis
|
||
- **Nginx Proxy Manager**: Additional layer for complex routing scenarios
|
||
|
||
## 🛠️ Tech Stack
|
||
|
||
- **Frontend**: Next.js, Tailwind CSS
|
||
- **Infrastructure**: Docker Swarm, Traefik, Nginx Proxy Manager
|
||
- **CI/CD**: Custom Git runners with automated pipelines
|
||
- **Monitoring**: Self-hosted monitoring stack
|
||
- **Security**: CrowdSec, Suricata, Mailcow
|
||
- **Caching**: Redis
|
||
|
||
## 🔐 Security
|
||
|
||
Security is a top priority. I use CrowdSec for intrusion prevention, Suricata for network monitoring, and Mailcow for secure email communications.
|
||
|
||
## 📈 DevOps Process
|
||
|
||
1. Code push triggers CI/CD pipeline
|
||
2. Automated tests run on custom runners
|
||
3. Docker images are built and tagged
|
||
4. Rolling deployment to Swarm cluster
|
||
5. Traefik automatically routes traffic
|
||
6. Zero downtime for users
|
||
|
||
## 💡 What I Learned
|
||
|
||
This project taught me everything about production-grade DevOps, from container orchestration to security hardening. Managing my own infrastructure has given me deep insights into networking, load balancing, and system administration.
|
||
|
||
## 🎯 Other Projects
|
||
|
||
Besides this portfolio, I host:
|
||
- Interactive photo galleries
|
||
- Quiz applications
|
||
- Game servers
|
||
- n8n automation workflows
|
||
- Various experimental Next.js apps
|
||
|
||
## 🔮 Future Improvements
|
||
|
||
- Kubernetes migration for more advanced orchestration
|
||
- Automated backup and disaster recovery
|
||
- Advanced monitoring with Prometheus and Grafana
|
||
- Multi-region deployment`,
|
||
tags: [
|
||
"Docker",
|
||
"Swarm",
|
||
"DevOps",
|
||
"CI/CD",
|
||
"Next.js",
|
||
"Traefik",
|
||
"Self-Hosting",
|
||
],
|
||
featured: true,
|
||
category: "DevOps",
|
||
date: "2024",
|
||
published: true,
|
||
difficulty: "ADVANCED",
|
||
timeToComplete: "Ongoing project",
|
||
technologies: [
|
||
"Docker Swarm",
|
||
"Traefik",
|
||
"Next.js",
|
||
"Redis",
|
||
"CI/CD",
|
||
"Nginx",
|
||
"CrowdSec",
|
||
"Suricata",
|
||
],
|
||
challenges: [
|
||
"Zero-downtime deployments",
|
||
"Network configuration",
|
||
"Security hardening",
|
||
"Performance optimization",
|
||
],
|
||
lessonsLearned: [
|
||
"Container orchestration",
|
||
"DevOps practices",
|
||
"Infrastructure as Code",
|
||
"Security best practices",
|
||
],
|
||
futureImprovements: [
|
||
"Kubernetes migration",
|
||
"Multi-region setup",
|
||
"Advanced monitoring",
|
||
"Automated backups",
|
||
],
|
||
demoVideo: "",
|
||
screenshots: [],
|
||
colorScheme: "Modern and professional",
|
||
accessibility: true,
|
||
performance: {
|
||
lighthouse: 0,
|
||
bundleSize: "0KB",
|
||
loadTime: "0s",
|
||
},
|
||
analytics: {
|
||
views: 1420,
|
||
likes: 112,
|
||
shares: 45,
|
||
},
|
||
},
|
||
];
|
||
|
||
for (const project of projects) {
|
||
await prisma.project.create({
|
||
data: {
|
||
...project,
|
||
difficulty: project.difficulty as
|
||
| "BEGINNER"
|
||
| "INTERMEDIATE"
|
||
| "ADVANCED"
|
||
| "EXPERT",
|
||
},
|
||
});
|
||
}
|
||
|
||
console.log(`✅ Created ${projects.length} projects`);
|
||
|
||
// Create some sample analytics data
|
||
for (let i = 1; i <= projects.length; i++) {
|
||
// Create page views
|
||
for (let j = 0; j < Math.floor(Math.random() * 100) + 50; j++) {
|
||
await prisma.pageView.create({
|
||
data: {
|
||
projectId: i,
|
||
page: `/projects/${i}`,
|
||
ip: `192.168.1.${Math.floor(Math.random() * 255)}`,
|
||
userAgent:
|
||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
|
||
referrer: "https://google.com",
|
||
},
|
||
});
|
||
}
|
||
|
||
// Create user interactions
|
||
for (let j = 0; j < Math.floor(Math.random() * 20) + 10; j++) {
|
||
await prisma.userInteraction.create({
|
||
data: {
|
||
projectId: i,
|
||
type: Math.random() > 0.5 ? "LIKE" : "SHARE",
|
||
ip: `192.168.1.${Math.floor(Math.random() * 255)}`,
|
||
userAgent:
|
||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
|
||
},
|
||
});
|
||
}
|
||
}
|
||
|
||
console.log("✅ Created sample analytics data");
|
||
|
||
console.log("🎉 Database seeding completed!");
|
||
}
|
||
|
||
main()
|
||
.catch((e) => {
|
||
console.error("❌ Error seeding database:", e);
|
||
process.exit(1);
|
||
})
|
||
.finally(async () => {
|
||
await prisma.$disconnect();
|
||
});
|