main: vibe coded app to feel like paper
Signed-off-by: nfel <nfilsaraee@gmail.com>
This commit is contained in:
+265
@@ -0,0 +1,265 @@
|
||||
const Database = require('better-sqlite3');
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
|
||||
// Demo albums data
|
||||
const albums = [
|
||||
{
|
||||
id: "echoes-of-time",
|
||||
title: "Echoes of Time",
|
||||
coverImage: "/albums/echoes-of-time.jpg",
|
||||
year: 2024,
|
||||
genre: "Progressive Rock",
|
||||
price: 350000,
|
||||
tag: "Album",
|
||||
format: "flac",
|
||||
bitrate: "lossless",
|
||||
description: "An epic journey through time and space, featuring complex polyrhythms, atmospheric keyboards, and powerful guitar solos. This concept album tells the story of humanity's relationship with time.",
|
||||
songs: [
|
||||
{
|
||||
id: "echoes-1",
|
||||
title: "Temporal Flux",
|
||||
duration: "8:45",
|
||||
previewUrl: "/audio/preview-1.mp3",
|
||||
fullUrl: "/audio/echoes-1-full.mp3"
|
||||
},
|
||||
{
|
||||
id: "echoes-2",
|
||||
title: "Clockwork Dreams",
|
||||
duration: "6:23",
|
||||
previewUrl: "/audio/preview-1.mp3",
|
||||
fullUrl: "/audio/echoes-2-full.mp3"
|
||||
},
|
||||
{
|
||||
id: "echoes-3",
|
||||
title: "The Eternal Now",
|
||||
duration: "12:17",
|
||||
previewUrl: "/audio/preview-1.mp3",
|
||||
fullUrl: "/audio/echoes-3-full.mp3"
|
||||
},
|
||||
{
|
||||
id: "echoes-4",
|
||||
title: "Yesterday's Tomorrow",
|
||||
duration: "7:56",
|
||||
previewUrl: "/audio/preview-1.mp3",
|
||||
fullUrl: "/audio/echoes-4-full.mp3"
|
||||
},
|
||||
{
|
||||
id: "echoes-5",
|
||||
title: "Echoes Fade",
|
||||
duration: "15:32",
|
||||
previewUrl: "/audio/preview-1.mp3",
|
||||
fullUrl: "/audio/echoes-5-full.mp3"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "crimson-horizons",
|
||||
title: "Crimson Horizons",
|
||||
coverImage: "/albums/crimson-horizons.jpg",
|
||||
year: 2023,
|
||||
genre: "Progressive Rock",
|
||||
price: 10.99,
|
||||
tag: "Deluxe",
|
||||
format: "mp3",
|
||||
bitrate: "320kbps",
|
||||
description: "A darker, heavier exploration of prog rock with crushing riffs and intricate instrumental passages. Features extended improvisational sections and powerful vocals.",
|
||||
songs: [
|
||||
{
|
||||
id: "crimson-1",
|
||||
title: "Red Dawn",
|
||||
duration: "9:12",
|
||||
previewUrl: "/audio/preview-1.mp3",
|
||||
fullUrl: "/audio/crimson-1-full.mp3"
|
||||
},
|
||||
{
|
||||
id: "crimson-2",
|
||||
title: "Horizon's Edge",
|
||||
duration: "7:45",
|
||||
previewUrl: "/audio/preview-1.mp3",
|
||||
fullUrl: "/audio/crimson-2-full.mp3"
|
||||
},
|
||||
{
|
||||
id: "crimson-3",
|
||||
title: "Scarlet Skies",
|
||||
duration: "11:03",
|
||||
previewUrl: "/audio/preview-1.mp3",
|
||||
fullUrl: "/audio/crimson-3-full.mp3"
|
||||
},
|
||||
{
|
||||
id: "crimson-4",
|
||||
title: "Blood Moon Rising",
|
||||
duration: "8:34",
|
||||
previewUrl: "/audio/preview-1.mp3",
|
||||
fullUrl: "/audio/crimson-4-full.mp3"
|
||||
},
|
||||
{
|
||||
id: "crimson-5",
|
||||
title: "Into the Void",
|
||||
duration: "13:21",
|
||||
previewUrl: "/audio/preview-1.mp3",
|
||||
fullUrl: "/audio/crimson-5-full.mp3"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "cosmic-resonance",
|
||||
title: "Cosmic Resonance",
|
||||
coverImage: "/albums/cosmic-resonance.jpg",
|
||||
year: 2022,
|
||||
genre: "Space Rock",
|
||||
price: 11.99,
|
||||
tag: "EP",
|
||||
format: "wav",
|
||||
bitrate: "lossless",
|
||||
description: "A space-themed odyssey combining ambient soundscapes with progressive rock energy. Synthesizers and guitars intertwine to create an otherworldly sonic experience.",
|
||||
songs: [
|
||||
{
|
||||
id: "cosmic-1",
|
||||
title: "Stellar Winds",
|
||||
duration: "10:24",
|
||||
previewUrl: "/audio/preview-1.mp3",
|
||||
fullUrl: "/audio/cosmic-1-full.mp3"
|
||||
},
|
||||
{
|
||||
id: "cosmic-2",
|
||||
title: "Nebula Dreams",
|
||||
duration: "8:17",
|
||||
previewUrl: "/audio/preview-1.mp3",
|
||||
fullUrl: "/audio/cosmic-2-full.mp3"
|
||||
},
|
||||
{
|
||||
id: "cosmic-3",
|
||||
title: "Gravity Wells",
|
||||
duration: "9:45",
|
||||
previewUrl: "/audio/preview-1.mp3",
|
||||
fullUrl: "/audio/cosmic-3-full.mp3"
|
||||
},
|
||||
{
|
||||
id: "cosmic-4",
|
||||
title: "Cosmic Dance",
|
||||
duration: "11:56",
|
||||
previewUrl: "/audio/preview-1.mp3",
|
||||
fullUrl: "/audio/cosmic-4-full.mp3"
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
function seedDatabase() {
|
||||
try {
|
||||
// Database path
|
||||
const dbPath = path.join(process.cwd(), 'data', 'parsa.db');
|
||||
|
||||
// Create data directory if it doesn't exist
|
||||
const dataDir = path.join(process.cwd(), 'data');
|
||||
if (!fs.existsSync(dataDir)) {
|
||||
fs.mkdirSync(dataDir, { recursive: true });
|
||||
console.log('✓ Created data directory');
|
||||
}
|
||||
|
||||
// Initialize database
|
||||
const db = new Database(dbPath);
|
||||
db.pragma('journal_mode = WAL');
|
||||
console.log('✓ Connected to database');
|
||||
|
||||
// Create albums table
|
||||
db.exec(`
|
||||
CREATE TABLE IF NOT EXISTS albums (
|
||||
id TEXT PRIMARY KEY,
|
||||
title TEXT NOT NULL,
|
||||
coverImage TEXT NOT NULL,
|
||||
year INTEGER NOT NULL,
|
||||
genre TEXT NOT NULL,
|
||||
description TEXT NOT NULL,
|
||||
price REAL NOT NULL,
|
||||
tag TEXT NOT NULL DEFAULT 'Album',
|
||||
format TEXT NOT NULL DEFAULT 'mp3',
|
||||
bitrate TEXT NOT NULL DEFAULT '320kbps',
|
||||
songs TEXT NOT NULL,
|
||||
createdAt INTEGER DEFAULT (strftime('%s', 'now')),
|
||||
updatedAt INTEGER DEFAULT (strftime('%s', 'now'))
|
||||
)
|
||||
`);
|
||||
console.log('✓ Created albums table');
|
||||
|
||||
// Create purchases table
|
||||
db.exec(`
|
||||
CREATE TABLE IF NOT EXISTS purchases (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
albumId TEXT NOT NULL,
|
||||
transactionId TEXT NOT NULL UNIQUE,
|
||||
customerName TEXT,
|
||||
email TEXT,
|
||||
phoneNumber TEXT,
|
||||
txReceipt TEXT,
|
||||
purchaseDate INTEGER NOT NULL,
|
||||
createdAt INTEGER DEFAULT (strftime('%s', 'now')),
|
||||
FOREIGN KEY (albumId) REFERENCES albums(id) ON DELETE CASCADE
|
||||
)
|
||||
`);
|
||||
console.log('✓ Created purchases table');
|
||||
|
||||
// Create indexes
|
||||
db.exec(`
|
||||
CREATE INDEX IF NOT EXISTS idx_purchases_albumId ON purchases(albumId);
|
||||
CREATE INDEX IF NOT EXISTS idx_purchases_transactionId ON purchases(transactionId);
|
||||
`);
|
||||
console.log('✓ Created indexes');
|
||||
|
||||
// Clear existing albums
|
||||
db.exec('DELETE FROM albums');
|
||||
console.log('✓ Cleared existing albums');
|
||||
|
||||
// Insert demo albums
|
||||
const insert = db.prepare(`
|
||||
INSERT INTO albums (id, title, coverImage, year, genre, description, price, tag, format, bitrate, songs)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
`);
|
||||
|
||||
const insertMany = db.transaction((albums) => {
|
||||
for (const album of albums) {
|
||||
insert.run(
|
||||
album.id,
|
||||
album.title,
|
||||
album.coverImage,
|
||||
album.year,
|
||||
album.genre,
|
||||
album.description,
|
||||
album.price,
|
||||
album.tag,
|
||||
album.format,
|
||||
album.bitrate,
|
||||
JSON.stringify(album.songs)
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
insertMany(albums);
|
||||
console.log(`✓ Inserted ${albums.length} demo albums`);
|
||||
|
||||
// Verify
|
||||
const count = db.prepare('SELECT COUNT(*) as count FROM albums').get();
|
||||
console.log(`✓ Database now contains ${count.count} albums`);
|
||||
|
||||
db.close();
|
||||
console.log('\n✅ Database seeded successfully!');
|
||||
console.log('\nYou can now run: pnpm dev');
|
||||
|
||||
} catch (error) {
|
||||
console.error('\n❌ Error seeding database:', error.message);
|
||||
console.error('\nTrying to rebuild better-sqlite3...');
|
||||
|
||||
const { execSync } = require('child_process');
|
||||
try {
|
||||
execSync('npm rebuild better-sqlite3', { stdio: 'inherit' });
|
||||
console.log('\n✓ Rebuilt better-sqlite3, please run the seed script again: pnpm seed');
|
||||
} catch (rebuildError) {
|
||||
console.error('❌ Failed to rebuild better-sqlite3');
|
||||
console.error('Please try manually: npm rebuild better-sqlite3');
|
||||
}
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
seedDatabase();
|
||||
+252
@@ -0,0 +1,252 @@
|
||||
import { Database } from 'bun:sqlite';
|
||||
import path from 'path';
|
||||
import { existsSync, mkdirSync } from 'fs';
|
||||
|
||||
// Demo albums data
|
||||
const albums = [
|
||||
{
|
||||
id: "echoes-of-time",
|
||||
title: "Echoes of Time",
|
||||
coverImage: "/albums/echoes-of-time.jpg",
|
||||
year: 2024,
|
||||
genre: "Progressive Rock",
|
||||
price: 350000, // Toman
|
||||
tag: "Album",
|
||||
format: "flac",
|
||||
bitrate: "lossless",
|
||||
description: "An epic journey through time and space, featuring complex polyrhythms, atmospheric keyboards, and powerful guitar solos. This concept album tells the story of humanity's relationship with time.",
|
||||
songs: [
|
||||
{
|
||||
id: "echoes-1",
|
||||
title: "Temporal Flux",
|
||||
duration: "8:45",
|
||||
previewUrl: "/audio/preview-1.mp3",
|
||||
fullUrl: "/audio/echoes-1-full.mp3"
|
||||
},
|
||||
{
|
||||
id: "echoes-2",
|
||||
title: "Clockwork Dreams",
|
||||
duration: "6:23",
|
||||
previewUrl: "/audio/preview-1.mp3",
|
||||
fullUrl: "/audio/echoes-2-full.mp3"
|
||||
},
|
||||
{
|
||||
id: "echoes-3",
|
||||
title: "The Eternal Now",
|
||||
duration: "12:17",
|
||||
previewUrl: "/audio/preview-1.mp3",
|
||||
fullUrl: "/audio/echoes-3-full.mp3"
|
||||
},
|
||||
{
|
||||
id: "echoes-4",
|
||||
title: "Yesterday's Tomorrow",
|
||||
duration: "7:56",
|
||||
previewUrl: "/audio/preview-1.mp3",
|
||||
fullUrl: "/audio/echoes-4-full.mp3"
|
||||
},
|
||||
{
|
||||
id: "echoes-5",
|
||||
title: "Echoes Fade",
|
||||
duration: "15:32",
|
||||
previewUrl: "/audio/preview-1.mp3",
|
||||
fullUrl: "/audio/echoes-5-full.mp3"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "crimson-horizons",
|
||||
title: "Crimson Horizons",
|
||||
coverImage: "/albums/crimson-horizons.jpg",
|
||||
year: 2023,
|
||||
genre: "Progressive Rock",
|
||||
price: 450000, // Toman
|
||||
tag: "Deluxe",
|
||||
format: "mp3",
|
||||
bitrate: "320kbps",
|
||||
description: "A darker, heavier exploration of prog rock with crushing riffs and intricate instrumental passages. Features extended improvisational sections and powerful vocals.",
|
||||
songs: [
|
||||
{
|
||||
id: "crimson-1",
|
||||
title: "Red Dawn",
|
||||
duration: "9:12",
|
||||
previewUrl: "/audio/preview-1.mp3",
|
||||
fullUrl: "/audio/crimson-1-full.mp3"
|
||||
},
|
||||
{
|
||||
id: "crimson-2",
|
||||
title: "Horizon's Edge",
|
||||
duration: "7:45",
|
||||
previewUrl: "/audio/preview-1.mp3",
|
||||
fullUrl: "/audio/crimson-2-full.mp3"
|
||||
},
|
||||
{
|
||||
id: "crimson-3",
|
||||
title: "Scarlet Skies",
|
||||
duration: "11:03",
|
||||
previewUrl: "/audio/preview-1.mp3",
|
||||
fullUrl: "/audio/crimson-3-full.mp3"
|
||||
},
|
||||
{
|
||||
id: "crimson-4",
|
||||
title: "Blood Moon Rising",
|
||||
duration: "8:34",
|
||||
previewUrl: "/audio/preview-1.mp3",
|
||||
fullUrl: "/audio/crimson-4-full.mp3"
|
||||
},
|
||||
{
|
||||
id: "crimson-5",
|
||||
title: "Into the Void",
|
||||
duration: "13:21",
|
||||
previewUrl: "/audio/preview-1.mp3",
|
||||
fullUrl: "/audio/crimson-5-full.mp3"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "cosmic-resonance",
|
||||
title: "Cosmic Resonance",
|
||||
coverImage: "/albums/cosmic-resonance.jpg",
|
||||
year: 2022,
|
||||
genre: "Space Rock",
|
||||
price: 150000, // Toman
|
||||
tag: "EP",
|
||||
format: "wav",
|
||||
bitrate: "lossless",
|
||||
description: "A space-themed odyssey combining ambient soundscapes with progressive rock energy. Synthesizers and guitars intertwine to create an otherworldly sonic experience.",
|
||||
songs: [
|
||||
{
|
||||
id: "cosmic-1",
|
||||
title: "Stellar Winds",
|
||||
duration: "10:24",
|
||||
previewUrl: "/audio/preview-1.mp3",
|
||||
fullUrl: "/audio/cosmic-1-full.mp3"
|
||||
},
|
||||
{
|
||||
id: "cosmic-2",
|
||||
title: "Nebula Dreams",
|
||||
duration: "8:17",
|
||||
previewUrl: "/audio/preview-1.mp3",
|
||||
fullUrl: "/audio/cosmic-2-full.mp3"
|
||||
},
|
||||
{
|
||||
id: "cosmic-3",
|
||||
title: "Gravity Wells",
|
||||
duration: "9:45",
|
||||
previewUrl: "/audio/preview-1.mp3",
|
||||
fullUrl: "/audio/cosmic-3-full.mp3"
|
||||
},
|
||||
{
|
||||
id: "cosmic-4",
|
||||
title: "Cosmic Dance",
|
||||
duration: "11:56",
|
||||
previewUrl: "/audio/preview-1.mp3",
|
||||
fullUrl: "/audio/cosmic-4-full.mp3"
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
function seedDatabase() {
|
||||
try {
|
||||
// Database path
|
||||
const dbPath = path.join(process.cwd(), 'data', 'parsa.db');
|
||||
|
||||
// Create data directory if it doesn't exist
|
||||
const dataDir = path.join(process.cwd(), 'data');
|
||||
if (!existsSync(dataDir)) {
|
||||
mkdirSync(dataDir, { recursive: true });
|
||||
console.log('✓ Created data directory');
|
||||
}
|
||||
|
||||
// Initialize database
|
||||
const db = new Database(dbPath, { create: true });
|
||||
db.exec('PRAGMA journal_mode = WAL');
|
||||
console.log('✓ Connected to database');
|
||||
|
||||
// Create albums table
|
||||
db.exec(`
|
||||
CREATE TABLE IF NOT EXISTS albums (
|
||||
id TEXT PRIMARY KEY,
|
||||
title TEXT NOT NULL,
|
||||
coverImage TEXT NOT NULL,
|
||||
year INTEGER NOT NULL,
|
||||
genre TEXT NOT NULL,
|
||||
description TEXT NOT NULL,
|
||||
price REAL NOT NULL,
|
||||
tag TEXT NOT NULL DEFAULT 'Album',
|
||||
format TEXT NOT NULL DEFAULT 'mp3',
|
||||
bitrate TEXT NOT NULL DEFAULT '320kbps',
|
||||
songs TEXT NOT NULL,
|
||||
createdAt INTEGER DEFAULT (strftime('%s', 'now')),
|
||||
updatedAt INTEGER DEFAULT (strftime('%s', 'now'))
|
||||
)
|
||||
`);
|
||||
console.log('✓ Created albums table');
|
||||
|
||||
// Create purchases table
|
||||
db.exec(`
|
||||
CREATE TABLE IF NOT EXISTS purchases (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
albumId TEXT NOT NULL,
|
||||
transactionId TEXT NOT NULL UNIQUE,
|
||||
customerName TEXT,
|
||||
email TEXT,
|
||||
phoneNumber TEXT,
|
||||
txReceipt TEXT,
|
||||
purchaseDate INTEGER NOT NULL,
|
||||
createdAt INTEGER DEFAULT (strftime('%s', 'now')),
|
||||
FOREIGN KEY (albumId) REFERENCES albums(id) ON DELETE CASCADE
|
||||
)
|
||||
`);
|
||||
console.log('✓ Created purchases table');
|
||||
|
||||
// Create indexes
|
||||
db.exec(`
|
||||
CREATE INDEX IF NOT EXISTS idx_purchases_albumId ON purchases(albumId);
|
||||
CREATE INDEX IF NOT EXISTS idx_purchases_transactionId ON purchases(transactionId);
|
||||
`);
|
||||
console.log('✓ Created indexes');
|
||||
|
||||
// Clear existing albums
|
||||
db.exec('DELETE FROM albums');
|
||||
console.log('✓ Cleared existing albums');
|
||||
|
||||
// Insert demo albums
|
||||
const insert = db.prepare(`
|
||||
INSERT INTO albums (id, title, coverImage, year, genre, description, price, tag, format, bitrate, songs)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
`);
|
||||
|
||||
for (const album of albums) {
|
||||
insert.run(
|
||||
album.id,
|
||||
album.title,
|
||||
album.coverImage,
|
||||
album.year,
|
||||
album.genre,
|
||||
album.description,
|
||||
album.price,
|
||||
album.tag,
|
||||
album.format,
|
||||
album.bitrate,
|
||||
JSON.stringify(album.songs)
|
||||
);
|
||||
}
|
||||
|
||||
console.log(`✓ Inserted ${albums.length} demo albums`);
|
||||
|
||||
// Verify
|
||||
const count = db.prepare('SELECT COUNT(*) as count FROM albums').get() as { count: number };
|
||||
console.log(`✓ Database now contains ${count.count} albums`);
|
||||
|
||||
db.close();
|
||||
console.log('\n✅ Database seeded successfully!');
|
||||
console.log('\nYou can now run: bun dev');
|
||||
|
||||
} catch (error) {
|
||||
console.error('\n❌ Error seeding database:', error);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
seedDatabase();
|
||||
Reference in New Issue
Block a user