full upgrade to dev

This commit is contained in:
2026-01-07 14:30:00 +01:00
parent 4dc727fcd6
commit 26a8610aa7
34 changed files with 6890 additions and 920 deletions

127
prisma/migrations/README.md Normal file
View File

@@ -0,0 +1,127 @@
# Database Migrations
This directory contains SQL migration scripts for manual database updates.
## Running Migrations
### Method 1: Using psql (Recommended)
```bash
# Connect to your database
psql -d portfolio -f prisma/migrations/create_activity_status.sql
# Or with connection string
psql "postgresql://user:password@localhost:5432/portfolio" -f prisma/migrations/create_activity_status.sql
```
### Method 2: Using Docker
```bash
# If your database is in Docker
docker exec -i postgres_container psql -U username -d portfolio < prisma/migrations/create_activity_status.sql
```
### Method 3: Using pgAdmin or Database GUI
1. Open pgAdmin or your database GUI
2. Connect to your `portfolio` database
3. Open Query Tool
4. Copy and paste the contents of `create_activity_status.sql`
5. Execute the query
## Verifying Migration
After running the migration, verify it was successful:
```bash
# Check if table exists
psql -d portfolio -c "\dt activity_status"
# View table structure
psql -d portfolio -c "\d activity_status"
# Check if default row was inserted
psql -d portfolio -c "SELECT * FROM activity_status;"
```
Expected output:
```
id | activity_type | ... | updated_at
----+---------------+-----+---------------------------
1 | | ... | 2024-01-15 10:30:00+00
```
## Migration: create_activity_status.sql
**Purpose**: Creates the `activity_status` table for n8n activity feed integration.
**What it does**:
- Creates `activity_status` table with all necessary columns
- Inserts a default row with `id = 1`
- Sets up automatic `updated_at` timestamp trigger
- Adds table comment for documentation
**Required by**:
- `/api/n8n/status` endpoint
- `ActivityFeed` component
- n8n workflows for status updates
**Safe to run multiple times**: Yes (uses `IF NOT EXISTS` and `ON CONFLICT`)
## Troubleshooting
### "relation already exists"
Table already exists - migration is already applied. Safe to ignore.
### "permission denied"
Your database user needs CREATE TABLE permissions:
```sql
GRANT CREATE ON DATABASE portfolio TO your_user;
```
### "database does not exist"
Create the database first:
```bash
createdb portfolio
# Or
psql -c "CREATE DATABASE portfolio;"
```
### "connection refused"
Ensure PostgreSQL is running:
```bash
# Check status
pg_isready
# Start PostgreSQL (macOS)
brew services start postgresql
# Start PostgreSQL (Linux)
sudo systemctl start postgresql
```
## Rolling Back
To remove the activity_status table:
```sql
DROP TRIGGER IF EXISTS activity_status_updated_at ON activity_status;
DROP FUNCTION IF EXISTS update_activity_status_updated_at();
DROP TABLE IF EXISTS activity_status;
```
Save this as `rollback_activity_status.sql` and run if needed.
## Future Migrations
When adding new migrations:
1. Create a new `.sql` file with descriptive name
2. Use timestamps in filename: `YYYYMMDD_description.sql`
3. Document what it does in this README
4. Test on local database first
5. Mark as safe/unsafe for production
---
**Last Updated**: 2024-01-15
**Status**: Required for n8n integration

View File

@@ -0,0 +1,49 @@
-- Create activity_status table for n8n integration
CREATE TABLE IF NOT EXISTS activity_status (
id INTEGER PRIMARY KEY DEFAULT 1,
activity_type VARCHAR(50),
activity_details VARCHAR(255),
activity_project VARCHAR(255),
activity_language VARCHAR(50),
activity_repo VARCHAR(500),
music_playing BOOLEAN DEFAULT FALSE,
music_track VARCHAR(255),
music_artist VARCHAR(255),
music_album VARCHAR(255),
music_platform VARCHAR(50),
music_progress INTEGER,
music_album_art VARCHAR(500),
watching_title VARCHAR(255),
watching_platform VARCHAR(50),
watching_type VARCHAR(50),
gaming_game VARCHAR(255),
gaming_platform VARCHAR(50),
gaming_status VARCHAR(50),
status_mood VARCHAR(50),
status_message VARCHAR(500),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- Insert default row
INSERT INTO activity_status (id, updated_at)
VALUES (1, NOW())
ON CONFLICT (id) DO NOTHING;
-- Create function to automatically update updated_at
CREATE OR REPLACE FUNCTION update_activity_status_updated_at()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
-- Create trigger for automatic timestamp updates
DROP TRIGGER IF EXISTS activity_status_updated_at ON activity_status;
CREATE TRIGGER activity_status_updated_at
BEFORE UPDATE ON activity_status
FOR EACH ROW
EXECUTE FUNCTION update_activity_status_updated_at();
-- Add helpful comment
COMMENT ON TABLE activity_status IS 'Stores real-time activity status from n8n workflows (coding, music, gaming, etc.)';

73
prisma/migrations/quick-fix.sh Executable file
View File

@@ -0,0 +1,73 @@
#!/bin/bash
# Quick Fix Script for Portfolio Database
# This script creates the activity_status table needed for n8n integration
set -e
echo "🔧 Portfolio Database Quick Fix"
echo "================================"
echo ""
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Check if .env.local exists
if [ ! -f .env.local ]; then
echo -e "${RED}❌ Error: .env.local not found${NC}"
echo "Please create .env.local with DATABASE_URL"
exit 1
fi
# Load DATABASE_URL from .env.local
export $(grep -v '^#' .env.local | xargs)
if [ -z "$DATABASE_URL" ]; then
echo -e "${RED}❌ Error: DATABASE_URL not found in .env.local${NC}"
exit 1
fi
echo -e "${GREEN}✓ Found DATABASE_URL${NC}"
echo ""
# Extract database name from DATABASE_URL
DB_NAME=$(echo $DATABASE_URL | sed -n 's/.*\/\([^?]*\).*/\1/p')
echo "📦 Database: $DB_NAME"
echo ""
# Run the migration
echo "🚀 Creating activity_status table..."
echo ""
psql "$DATABASE_URL" -f prisma/migrations/create_activity_status.sql
if [ $? -eq 0 ]; then
echo ""
echo -e "${GREEN}✅ SUCCESS! Migration completed${NC}"
echo ""
echo "Verifying table..."
psql "$DATABASE_URL" -c "\d activity_status" | head -20
echo ""
echo "Checking default row..."
psql "$DATABASE_URL" -c "SELECT id, updated_at FROM activity_status LIMIT 1;"
echo ""
echo -e "${GREEN}🎉 All done! Your database is ready.${NC}"
echo ""
echo "Next steps:"
echo " 1. Restart your Next.js dev server: npm run dev"
echo " 2. Visit http://localhost:3000"
echo " 3. The activity feed should now work without errors"
else
echo ""
echo -e "${RED}❌ Migration failed${NC}"
echo ""
echo "Troubleshooting:"
echo " 1. Ensure PostgreSQL is running: pg_isready"
echo " 2. Check your DATABASE_URL in .env.local"
echo " 3. Verify database exists: psql -l | grep $DB_NAME"
echo " 4. Try manual migration: psql $DB_NAME -f prisma/migrations/create_activity_status.sql"
exit 1
fi

View File

@@ -103,3 +103,30 @@ enum InteractionType {
BOOKMARK
COMMENT
}
model ActivityStatus {
id Int @id @default(1)
activityType String? @map("activity_type") @db.VarChar(50)
activityDetails String? @map("activity_details") @db.VarChar(255)
activityProject String? @map("activity_project") @db.VarChar(255)
activityLanguage String? @map("activity_language") @db.VarChar(50)
activityRepo String? @map("activity_repo") @db.VarChar(500)
musicPlaying Boolean @default(false) @map("music_playing")
musicTrack String? @map("music_track") @db.VarChar(255)
musicArtist String? @map("music_artist") @db.VarChar(255)
musicAlbum String? @map("music_album") @db.VarChar(255)
musicPlatform String? @map("music_platform") @db.VarChar(50)
musicProgress Int? @map("music_progress")
musicAlbumArt String? @map("music_album_art") @db.VarChar(500)
watchingTitle String? @map("watching_title") @db.VarChar(255)
watchingPlatform String? @map("watching_platform") @db.VarChar(50)
watchingType String? @map("watching_type") @db.VarChar(50)
gamingGame String? @map("gaming_game") @db.VarChar(255)
gamingPlatform String? @map("gaming_platform") @db.VarChar(50)
gamingStatus String? @map("gaming_status") @db.VarChar(50)
statusMood String? @map("status_mood") @db.VarChar(50)
statusMessage String? @map("status_message") @db.VarChar(500)
updatedAt DateTime @default(now()) @updatedAt @map("updated_at")
@@map("activity_status")
}

View File

@@ -1,296 +1,236 @@
import { PrismaClient } from '@prisma/client';
import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient();
async function main() {
console.log('🌱 Seeding database...');
console.log("🌱 Seeding database...");
// Clear existing data
await prisma.userInteraction.deleteMany();
await prisma.pageView.deleteMany();
await prisma.project.deleteMany();
// Create sample projects
// Create real projects
const projects = [
{
title: "Portfolio Website 2.0",
description: "A cutting-edge portfolio website showcasing modern web development techniques with advanced features and stunning design.",
content: `# Portfolio Website 2.0
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
This is my personal portfolio website built with cutting-edge web technologies. The site features a dark theme with glassmorphism effects, smooth animations, and advanced interactive elements.
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
- **Responsive Design**: Works perfectly on all devices
- **Dark Theme**: Modern dark mode with glassmorphism effects
- **Animations**: Smooth animations powered by Framer Motion
- **Markdown Support**: Projects are written in Markdown for easy editing
- **Performance**: Optimized for speed and SEO
- **Interactive Elements**: Advanced UI components and micro-interactions
- **Accessibility**: WCAG 2.1 AA compliant
- **Analytics**: Built-in performance and user analytics
- **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
- Next.js 15
- TypeScript
- Tailwind CSS
- Framer Motion
- React Markdown
- Advanced CSS (Grid, Flexbox, Custom Properties)
- Performance optimization techniques
- Flutter
- Dart
- AI Integration for text simplification
- OpenDyslexic Font
## 📈 Development Process
## 📱 Platform Support
The website was designed with a focus on user experience, performance, and accessibility. I used modern CSS techniques and best practices to create a responsive, fast, and beautiful layout.
- iOS
- Android
## 🔮 Future Improvements
## 💡 What I Learned
- AI-powered content suggestions
- Advanced project filtering and search
- Interactive project demos
- Real-time collaboration features
- Advanced analytics dashboard
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.
## 🔗 Links
## 🔮 Future Plans
- [Live Demo](https://dki.one)
- [GitHub Repository](https://github.com/Denshooter/portfolio)`,
tags: ["Next.js", "TypeScript", "Tailwind CSS", "Framer Motion", "Advanced CSS", "Performance"],
- 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: "Web Development",
date: "2024",
published: true,
difficulty: "ADVANCED",
timeToComplete: "3-4 weeks",
technologies: ["Next.js 15", "TypeScript", "Tailwind CSS", "Framer Motion", "React Markdown"],
challenges: ["Complex state management", "Performance optimization", "Responsive design across devices"],
lessonsLearned: ["Advanced CSS techniques", "Performance optimization", "User experience design"],
futureImprovements: ["AI integration", "Advanced analytics", "Real-time features"],
demoVideo: "",
screenshots: [],
colorScheme: "Dark with glassmorphism",
accessibility: true,
performance: {
lighthouse: 0,
bundleSize: "0KB",
loadTime: "0s"
},
analytics: {
views: 1250,
likes: 89,
shares: 23
}
},
{
title: "E-Commerce Platform",
description: "A full-stack e-commerce solution with advanced features like real-time inventory, payment processing, and admin dashboard.",
content: `# E-Commerce Platform
A comprehensive e-commerce solution built with modern web technologies, featuring a robust backend, secure payment processing, and an intuitive user interface.
## 🚀 Features
- **User Authentication**: Secure login and registration
- **Product Management**: Add, edit, and delete products
- **Shopping Cart**: Persistent cart with real-time updates
- **Payment Processing**: Stripe integration for secure payments
- **Order Management**: Complete order lifecycle tracking
- **Admin Dashboard**: Comprehensive admin interface
- **Inventory Management**: Real-time stock tracking
- **Responsive Design**: Mobile-first approach
## 🛠️ Technologies Used
- Frontend: React, TypeScript, Tailwind CSS
- Backend: Node.js, Express, Prisma
- Database: PostgreSQL
- Payment: Stripe API
- Authentication: JWT, bcrypt
- Deployment: Docker, AWS
## 📈 Development Process
Built with a focus on scalability and user experience. Implemented proper error handling, input validation, and security measures throughout the development process.
## 🔮 Future Improvements
- Multi-language support
- Advanced analytics dashboard
- AI-powered product recommendations
- Mobile app development
- Advanced search and filtering`,
tags: ["React", "Node.js", "PostgreSQL", "Stripe", "E-commerce", "Full-Stack"],
featured: true,
category: "Full-Stack",
date: "2024",
published: true,
difficulty: "EXPERT",
timeToComplete: "8-10 weeks",
technologies: ["React", "Node.js", "PostgreSQL", "Stripe", "Docker", "AWS"],
challenges: ["Payment integration", "Real-time updates", "Scalability", "Security"],
lessonsLearned: ["Payment processing", "Real-time systems", "Security best practices", "Scalable architecture"],
futureImprovements: ["AI recommendations", "Mobile app", "Multi-language", "Advanced analytics"],
demoVideo: "",
screenshots: [],
colorScheme: "Professional and clean",
accessibility: true,
performance: {
lighthouse: 0,
bundleSize: "0KB",
loadTime: "0s"
},
analytics: {
views: 890,
likes: 67,
shares: 18
}
},
{
title: "Task Management App",
description: "A collaborative task management application with real-time updates, team collaboration, and progress tracking.",
content: `# Task Management App
A collaborative task management application designed for teams to organize, track, and complete projects efficiently.
## 🚀 Features
- **Task Creation**: Easy task creation with descriptions and deadlines
- **Team Collaboration**: Assign tasks to team members
- **Real-time Updates**: Live updates across all connected clients
- **Progress Tracking**: Visual progress indicators and analytics
- **File Attachments**: Support for documents and images
- **Notifications**: Email and push notifications for updates
- **Mobile Responsive**: Works perfectly on all devices
- **Dark/Light Theme**: User preference support
## 🛠️ Technologies Used
- Frontend: React, TypeScript, Tailwind CSS
- Backend: Node.js, Express, Socket.io
- Database: MongoDB
- Real-time: WebSockets
- Authentication: JWT
- File Storage: AWS S3
- Deployment: Heroku
## 📈 Development Process
Focused on creating an intuitive user interface and seamless real-time collaboration. Implemented proper error handling and user feedback throughout the development.
## 🔮 Future Improvements
- Advanced reporting and analytics
- Integration with external tools
- Mobile app development
- AI-powered task suggestions
- Advanced automation features`,
tags: ["React", "Node.js", "MongoDB", "WebSockets", "Collaboration", "Real-time"],
featured: false,
category: "Web Application",
category: "Mobile Development",
date: "2024",
published: true,
difficulty: "INTERMEDIATE",
timeToComplete: "6-8 weeks",
technologies: ["React", "Node.js", "MongoDB", "Socket.io", "AWS S3", "Heroku"],
challenges: ["Real-time synchronization", "Team collaboration", "File management", "Mobile responsiveness"],
lessonsLearned: ["WebSocket implementation", "Real-time systems", "File upload handling", "Team collaboration features"],
futureImprovements: ["Advanced analytics", "Mobile app", "AI integration", "Automation"],
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: "Modern and clean",
accessibility: true,
performance: {
lighthouse: 88,
bundleSize: "65KB",
loadTime: "1.5s"
},
analytics: {
views: 567,
likes: 34,
shares: 12
}
},
{
title: "Weather Dashboard",
description: "A beautiful weather application with real-time data, forecasts, and interactive maps.",
content: `# Weather Dashboard
A beautiful and functional weather application that provides real-time weather data, forecasts, and interactive maps.
## 🚀 Features
- **Current Weather**: Real-time weather conditions
- **Forecast**: 7-day weather predictions
- **Interactive Maps**: Visual weather maps with overlays
- **Location Search**: Find weather for any location
- **Weather Alerts**: Severe weather notifications
- **Historical Data**: Past weather information
- **Responsive Design**: Works on all devices
- **Offline Support**: Basic functionality without internet
## 🛠️ Technologies Used
- Frontend: React, TypeScript, Tailwind CSS
- Maps: Mapbox GL JS
- Weather API: OpenWeatherMap
- State Management: Zustand
- Charts: Chart.js
- Icons: Weather Icons
- Deployment: Vercel
## 📈 Development Process
Built with a focus on user experience and visual appeal. Implemented proper error handling for API failures and created an intuitive interface for weather information.
## 🔮 Future Improvements
- Weather widgets for other websites
- Advanced forecasting algorithms
- Weather-based recommendations
- Social sharing features
- Weather photography integration`,
tags: ["React", "TypeScript", "Weather API", "Maps", "Real-time", "UI/UX"],
featured: false,
category: "Web Application",
date: "2024",
published: true,
difficulty: "BEGINNER",
timeToComplete: "3-4 weeks",
technologies: ["React", "TypeScript", "Tailwind CSS", "Mapbox", "OpenWeatherMap", "Chart.js"],
challenges: ["API integration", "Map implementation", "Responsive design", "Error handling"],
lessonsLearned: ["External API integration", "Map libraries", "Responsive design", "Error handling"],
futureImprovements: ["Advanced forecasting", "Weather widgets", "Social features", "Mobile app"],
demoVideo: "",
screenshots: [],
colorScheme: "Light and colorful",
colorScheme: "Clean and minimal with high contrast",
accessibility: true,
performance: {
lighthouse: 0,
bundleSize: "0KB",
loadTime: "0s"
loadTime: "0s",
},
analytics: {
views: 423,
likes: 28,
shares: 8
}
}
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',
}
difficulty: project.difficulty as
| "BEGINNER"
| "INTERMEDIATE"
| "ADVANCED"
| "EXPERT",
},
});
}
console.log(`✅ Created ${projects.length} sample projects`);
console.log(`✅ Created ${projects.length} projects`);
// Create some sample analytics data
for (let i = 1; i <= 4; i++) {
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({
@@ -298,9 +238,10 @@ Built with a focus on user experience and visual appeal. Implemented proper erro
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'
}
userAgent:
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
referrer: "https://google.com",
},
});
}
@@ -309,22 +250,23 @@ Built with a focus on user experience and visual appeal. Implemented proper erro
await prisma.userInteraction.create({
data: {
projectId: i,
type: Math.random() > 0.5 ? 'LIKE' : 'SHARE',
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'
}
userAgent:
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
},
});
}
}
console.log('✅ Created sample analytics data');
console.log("✅ Created sample analytics data");
console.log('🎉 Database seeding completed!');
console.log("🎉 Database seeding completed!");
}
main()
.catch((e) => {
console.error('❌ Error seeding database:', e);
console.error("❌ Error seeding database:", e);
process.exit(1);
})
.finally(async () => {