mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-15 01:21:09 +02:00
Move inactive projects out of active workspace: - bauntown (community website) - maerchenzauber (AI story generation) - memoro (voice memo app) - news (news aggregation) - nutriphi (nutrition tracking) - reader (reading app) - uload (URL shortener) - wisekeep (AI wisdom extraction) Update CLAUDE.md documentation: - Add presi to active projects - Document archived projects section - Update workspace configuration Archived apps can be re-activated by moving back to apps/ 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
244 lines
6.7 KiB
JavaScript
Executable file
244 lines
6.7 KiB
JavaScript
Executable file
#!/usr/bin/env node
|
|
|
|
/**
|
|
* Seed Script for Local PocketBase Development
|
|
*
|
|
* This script creates test data for local development.
|
|
*
|
|
* Usage:
|
|
* 1. Make sure PocketBase is running locally (http://localhost:8090)
|
|
* 2. Run: node scripts/seed-local-db.js
|
|
*/
|
|
|
|
import PocketBase from 'pocketbase';
|
|
import { randomBytes } from 'crypto';
|
|
|
|
// Configuration
|
|
const POCKETBASE_URL = process.env.PUBLIC_POCKETBASE_URL || 'http://localhost:8090';
|
|
const ADMIN_EMAIL = process.env.POCKETBASE_ADMIN_EMAIL || 'admin@localhost';
|
|
const ADMIN_PASSWORD = process.env.POCKETBASE_ADMIN_PASSWORD || 'admin123456';
|
|
|
|
console.log('🌱 Seeding Local PocketBase Database');
|
|
console.log('=====================================\n');
|
|
console.log(`📍 PocketBase URL: ${POCKETBASE_URL}`);
|
|
|
|
const pb = new PocketBase(POCKETBASE_URL);
|
|
pb.autoCancellation(false);
|
|
|
|
// Test data
|
|
const testUsers = [
|
|
{
|
|
email: 'test@localhost',
|
|
password: 'test123456',
|
|
passwordConfirm: 'test123456',
|
|
username: 'testuser',
|
|
name: 'Test User',
|
|
emailVisibility: true,
|
|
},
|
|
{
|
|
email: 'demo@localhost',
|
|
password: 'demo123456',
|
|
passwordConfirm: 'demo123456',
|
|
username: 'demouser',
|
|
name: 'Demo User',
|
|
emailVisibility: true,
|
|
},
|
|
];
|
|
|
|
const testLinks = [
|
|
{
|
|
short_code: 'test1',
|
|
original_url: 'https://example.com',
|
|
title: 'Test Link 1',
|
|
description: 'This is a test link for development',
|
|
is_active: true,
|
|
click_limit: null,
|
|
expires_at: null,
|
|
password: null,
|
|
},
|
|
{
|
|
short_code: 'test2',
|
|
original_url: 'https://google.com',
|
|
title: 'Google Test',
|
|
description: 'Link to Google for testing',
|
|
is_active: true,
|
|
click_limit: 100,
|
|
expires_at: null,
|
|
password: null,
|
|
},
|
|
{
|
|
short_code: 'protected',
|
|
original_url: 'https://github.com',
|
|
title: 'Protected Link',
|
|
description: 'Password protected link',
|
|
is_active: true,
|
|
click_limit: null,
|
|
expires_at: null,
|
|
password: 'secret123',
|
|
},
|
|
{
|
|
short_code: 'expired',
|
|
original_url: 'https://stackoverflow.com',
|
|
title: 'Expired Link',
|
|
description: 'This link has expired',
|
|
is_active: true,
|
|
click_limit: null,
|
|
expires_at: new Date(Date.now() - 86400000).toISOString(), // Yesterday
|
|
password: null,
|
|
},
|
|
];
|
|
|
|
async function seedDatabase() {
|
|
try {
|
|
// Step 1: Try to authenticate as admin
|
|
console.log('🔐 Authenticating as admin...');
|
|
try {
|
|
await pb.admins.authWithPassword(ADMIN_EMAIL, ADMIN_PASSWORD);
|
|
console.log('✅ Admin authenticated\n');
|
|
} catch (error) {
|
|
console.log('⚠️ Admin auth failed. You may need to:');
|
|
console.log(' 1. Create admin account at http://localhost:8090/_/');
|
|
console.log(' 2. Update POCKETBASE_ADMIN_EMAIL and POCKETBASE_ADMIN_PASSWORD\n');
|
|
|
|
// Try to continue without admin auth (some operations might fail)
|
|
}
|
|
|
|
// Step 2: Create test users
|
|
console.log('👥 Creating test users...');
|
|
const createdUsers = [];
|
|
|
|
for (const userData of testUsers) {
|
|
try {
|
|
const user = await pb.collection('users').create(userData);
|
|
createdUsers.push(user);
|
|
console.log(` ✅ Created user: ${userData.email}`);
|
|
} catch (error) {
|
|
if (error.response?.data?.email?.message?.includes('already exists')) {
|
|
console.log(` ⚠️ User ${userData.email} already exists`);
|
|
// Try to get existing user
|
|
try {
|
|
const users = await pb.collection('users').getList(1, 1, {
|
|
filter: `email = "${userData.email}"`,
|
|
});
|
|
if (users.items.length > 0) {
|
|
createdUsers.push(users.items[0]);
|
|
}
|
|
} catch (e) {
|
|
console.log(` ❌ Could not fetch existing user: ${userData.email}`);
|
|
}
|
|
} else {
|
|
console.log(` ❌ Failed to create user ${userData.email}:`, error.message);
|
|
}
|
|
}
|
|
}
|
|
console.log('');
|
|
|
|
// Step 3: Create test links
|
|
console.log('🔗 Creating test links...');
|
|
|
|
// Use the first created user as the owner
|
|
const ownerId = createdUsers[0]?.id;
|
|
|
|
for (const linkData of testLinks) {
|
|
try {
|
|
// Add owner if we have one
|
|
if (ownerId) {
|
|
linkData.user_id = ownerId;
|
|
}
|
|
|
|
// Generate a random custom code if needed
|
|
if (!linkData.custom_code) {
|
|
linkData.custom_code = linkData.short_code;
|
|
}
|
|
|
|
const link = await pb.collection('links').create(linkData);
|
|
console.log(` ✅ Created link: ${linkData.short_code} -> ${linkData.original_url}`);
|
|
} catch (error) {
|
|
if (error.response?.data?.short_code?.message?.includes('already exists')) {
|
|
console.log(` ⚠️ Link ${linkData.short_code} already exists`);
|
|
} else {
|
|
console.log(` ❌ Failed to create link ${linkData.short_code}:`, error.message);
|
|
}
|
|
}
|
|
}
|
|
console.log('');
|
|
|
|
// Step 4: Create some test clicks
|
|
console.log('📊 Creating test click data...');
|
|
|
|
try {
|
|
// Get one of the links we created
|
|
const links = await pb.collection('links').getList(1, 1, {
|
|
filter: 'short_code = "test1"',
|
|
});
|
|
|
|
if (links.items.length > 0) {
|
|
const link = links.items[0];
|
|
|
|
// Create some fake clicks
|
|
const clickData = [
|
|
{
|
|
link_id: link.id,
|
|
ip_hash: '127.0.0.1',
|
|
user_agent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)',
|
|
browser: 'Chrome',
|
|
device_type: 'Desktop',
|
|
os: 'macOS',
|
|
country: 'Germany',
|
|
city: 'Munich',
|
|
clicked_at: new Date().toISOString(),
|
|
},
|
|
{
|
|
link_id: link.id,
|
|
ip_hash: '192.168.1.1',
|
|
user_agent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_0)',
|
|
browser: 'Safari',
|
|
device_type: 'Mobile',
|
|
os: 'iOS',
|
|
country: 'USA',
|
|
city: 'New York',
|
|
clicked_at: new Date(Date.now() - 3600000).toISOString(), // 1 hour ago
|
|
},
|
|
];
|
|
|
|
for (const click of clickData) {
|
|
try {
|
|
await pb.collection('clicks').create(click);
|
|
console.log(` ✅ Created test click from ${click.country}`);
|
|
} catch (error) {
|
|
console.log(` ❌ Failed to create click:`, error.message);
|
|
}
|
|
}
|
|
}
|
|
} catch (error) {
|
|
console.log(` ⚠️ Could not create click data:`, error.message);
|
|
}
|
|
console.log('');
|
|
|
|
// Summary
|
|
console.log('=====================================');
|
|
console.log('🎉 Database seeding complete!\n');
|
|
console.log('📝 Test Accounts:');
|
|
console.log(' Email: test@localhost');
|
|
console.log(' Password: test123456\n');
|
|
console.log('🔗 Test Links:');
|
|
console.log(' http://localhost:5173/test1 - Normal link');
|
|
console.log(' http://localhost:5173/test2 - Link with click limit');
|
|
console.log(' http://localhost:5173/protected - Password: secret123');
|
|
console.log(' http://localhost:5173/expired - Expired link\n');
|
|
console.log('👉 Next: Open http://localhost:5173 and test the app!');
|
|
} catch (error) {
|
|
console.error('❌ Seeding failed:', error);
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
// Run the seeding
|
|
seedDatabase()
|
|
.then(() => {
|
|
process.exit(0);
|
|
})
|
|
.catch((error) => {
|
|
console.error('Fatal error:', error);
|
|
process.exit(1);
|
|
});
|