theming, date, time localisation, additional features, seeding initial cleanup
This commit is contained in:
@@ -0,0 +1,263 @@
|
||||
import Database from 'better-sqlite3';
|
||||
import { drizzle } from 'drizzle-orm/better-sqlite3';
|
||||
import * as schema from '../lib/db/schema';
|
||||
import { sql } from 'drizzle-orm';
|
||||
import { randomUUID } from 'crypto';
|
||||
import bcrypt from 'bcryptjs';
|
||||
|
||||
const sqlite = new Database('./sqlite.db');
|
||||
const db = drizzle(sqlite, { schema });
|
||||
|
||||
async function resetDatabase() {
|
||||
console.log('Resetting database...');
|
||||
|
||||
// Drop all tables
|
||||
const tables = [
|
||||
'activity_logs',
|
||||
'bookings',
|
||||
'announcements',
|
||||
'time_slots',
|
||||
'settings',
|
||||
'courts',
|
||||
'users',
|
||||
'__drizzle_migrations',
|
||||
'__old_push_courts',
|
||||
'__old_push_users',
|
||||
];
|
||||
|
||||
for (const table of tables) {
|
||||
try {
|
||||
await db.run(sql.raw(`DROP TABLE IF EXISTS ${table}`));
|
||||
console.log(`Dropped table: ${table}`);
|
||||
} catch (error) {
|
||||
console.log(`Table ${table} doesn't exist or error dropping:`, error);
|
||||
}
|
||||
}
|
||||
|
||||
// Create all tables with current schema
|
||||
console.log('Creating tables...');
|
||||
|
||||
// Users table
|
||||
await db.run(sql`
|
||||
CREATE TABLE users (
|
||||
id TEXT PRIMARY KEY,
|
||||
email TEXT NOT NULL UNIQUE,
|
||||
name TEXT NOT NULL,
|
||||
surname TEXT NOT NULL,
|
||||
password TEXT NOT NULL,
|
||||
role TEXT NOT NULL DEFAULT 'user' CHECK (role IN ('user', 'admin')),
|
||||
created_at INTEGER NOT NULL,
|
||||
updated_at INTEGER NOT NULL
|
||||
)
|
||||
`);
|
||||
|
||||
// Courts table
|
||||
await db.run(sql`
|
||||
CREATE TABLE courts (
|
||||
id TEXT PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
is_active INTEGER NOT NULL DEFAULT 1,
|
||||
created_at INTEGER NOT NULL,
|
||||
updated_at INTEGER NOT NULL
|
||||
)
|
||||
`);
|
||||
|
||||
// Settings table
|
||||
await db.run(sql`
|
||||
CREATE TABLE settings (
|
||||
id TEXT PRIMARY KEY,
|
||||
key TEXT NOT NULL UNIQUE,
|
||||
value TEXT NOT NULL,
|
||||
updated_at INTEGER NOT NULL
|
||||
)
|
||||
`);
|
||||
|
||||
// Time slots table
|
||||
await db.run(sql`
|
||||
CREATE TABLE time_slots (
|
||||
id TEXT PRIMARY KEY,
|
||||
day_of_week INTEGER NOT NULL,
|
||||
start_time TEXT NOT NULL,
|
||||
end_time TEXT NOT NULL,
|
||||
is_active INTEGER NOT NULL DEFAULT 1,
|
||||
created_at INTEGER NOT NULL,
|
||||
updated_at INTEGER NOT NULL
|
||||
)
|
||||
`);
|
||||
|
||||
// Bookings table
|
||||
await db.run(sql`
|
||||
CREATE TABLE bookings (
|
||||
id TEXT PRIMARY KEY,
|
||||
user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
court_id TEXT NOT NULL REFERENCES courts(id) ON DELETE CASCADE,
|
||||
date TEXT NOT NULL,
|
||||
start_time TEXT NOT NULL,
|
||||
end_time TEXT NOT NULL,
|
||||
status TEXT NOT NULL DEFAULT 'active' CHECK (status IN ('active', 'cancelled')),
|
||||
notes TEXT,
|
||||
created_at INTEGER NOT NULL,
|
||||
updated_at INTEGER NOT NULL
|
||||
)
|
||||
`);
|
||||
|
||||
// Announcements table with all required columns
|
||||
await db.run(sql`
|
||||
CREATE TABLE announcements (
|
||||
id TEXT PRIMARY KEY,
|
||||
title TEXT NOT NULL,
|
||||
content TEXT NOT NULL,
|
||||
is_active INTEGER NOT NULL DEFAULT 1,
|
||||
priority TEXT NOT NULL DEFAULT 'medium' CHECK (priority IN ('low', 'medium', 'high')),
|
||||
expires_at INTEGER,
|
||||
created_at INTEGER NOT NULL,
|
||||
updated_at INTEGER NOT NULL
|
||||
)
|
||||
`);
|
||||
|
||||
// Activity logs table
|
||||
await db.run(sql`
|
||||
CREATE TABLE activity_logs (
|
||||
id TEXT PRIMARY KEY,
|
||||
user_id TEXT REFERENCES users(id) ON DELETE SET NULL,
|
||||
action TEXT NOT NULL,
|
||||
entity_type TEXT NOT NULL,
|
||||
entity_id TEXT,
|
||||
details TEXT,
|
||||
ip_address TEXT,
|
||||
user_agent TEXT,
|
||||
created_at INTEGER NOT NULL
|
||||
)
|
||||
`);
|
||||
|
||||
console.log('All tables created successfully!');
|
||||
|
||||
// Insert seed data
|
||||
console.log('Inserting seed data...');
|
||||
|
||||
const now = Date.now();
|
||||
|
||||
// Create admin user
|
||||
const hashedPassword = await bcrypt.hash('admin123', 12);
|
||||
await db.insert(schema.users).values({
|
||||
id: randomUUID(),
|
||||
email: 'admin@ttbooking.com',
|
||||
name: 'Admin',
|
||||
surname: 'User',
|
||||
password: hashedPassword,
|
||||
role: 'admin',
|
||||
createdAt: new Date(now),
|
||||
updatedAt: new Date(now),
|
||||
});
|
||||
|
||||
// Create test user
|
||||
const testPassword = await bcrypt.hash('password123', 12);
|
||||
await db.insert(schema.users).values({
|
||||
id: randomUUID(),
|
||||
email: 'user@test.com',
|
||||
name: 'Test',
|
||||
surname: 'User',
|
||||
password: testPassword,
|
||||
role: 'user',
|
||||
createdAt: new Date(now),
|
||||
updatedAt: new Date(now),
|
||||
});
|
||||
|
||||
// Create courts
|
||||
const court1Id = randomUUID();
|
||||
const court2Id = randomUUID();
|
||||
|
||||
await db.insert(schema.courts).values([
|
||||
{
|
||||
id: court1Id,
|
||||
name: 'Court 1',
|
||||
isActive: true,
|
||||
createdAt: new Date(now),
|
||||
updatedAt: new Date(now),
|
||||
},
|
||||
{
|
||||
id: court2Id,
|
||||
name: 'Court 2',
|
||||
isActive: true,
|
||||
createdAt: new Date(now),
|
||||
updatedAt: new Date(now),
|
||||
},
|
||||
]);
|
||||
|
||||
// Insert default settings
|
||||
await db.insert(schema.settings).values([
|
||||
{
|
||||
id: randomUUID(),
|
||||
key: 'booking_window_days',
|
||||
value: '7',
|
||||
updatedAt: new Date(now),
|
||||
},
|
||||
{
|
||||
id: randomUUID(),
|
||||
key: 'max_booking_duration_hours',
|
||||
value: '2',
|
||||
updatedAt: new Date(now),
|
||||
},
|
||||
{
|
||||
id: randomUUID(),
|
||||
key: 'min_booking_duration_minutes',
|
||||
value: '30',
|
||||
updatedAt: new Date(now),
|
||||
},
|
||||
{
|
||||
id: randomUUID(),
|
||||
key: 'booking_start_time',
|
||||
value: '08:00',
|
||||
updatedAt: new Date(now),
|
||||
},
|
||||
{
|
||||
id: randomUUID(),
|
||||
key: 'booking_end_time',
|
||||
value: '22:00',
|
||||
updatedAt: new Date(now),
|
||||
},
|
||||
{
|
||||
id: randomUUID(),
|
||||
key: 'allow_weekend_bookings',
|
||||
value: 'true',
|
||||
updatedAt: new Date(now),
|
||||
},
|
||||
]);
|
||||
|
||||
// Create time slots for all days (8 AM to 10 PM)
|
||||
const timeSlotData = [];
|
||||
for (let day = 0; day < 7; day++) {
|
||||
for (let hour = 8; hour < 22; hour += 2) {
|
||||
timeSlotData.push({
|
||||
id: randomUUID(),
|
||||
dayOfWeek: day,
|
||||
startTime: `${hour.toString().padStart(2, '0')}:00`,
|
||||
endTime: `${(hour + 2).toString().padStart(2, '0')}:00`,
|
||||
isActive: true,
|
||||
createdAt: new Date(now),
|
||||
updatedAt: new Date(now),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
await db.insert(schema.timeSlots).values(timeSlotData);
|
||||
|
||||
// Create sample announcement
|
||||
await db.insert(schema.announcements).values({
|
||||
id: randomUUID(),
|
||||
title: 'Welcome to Table Tennis Booking System',
|
||||
content: 'Book your court times easily and manage your games efficiently.',
|
||||
isActive: true,
|
||||
priority: 'high',
|
||||
expiresAt: null,
|
||||
createdAt: new Date(now),
|
||||
updatedAt: new Date(now),
|
||||
});
|
||||
|
||||
console.log('Seed data inserted successfully!');
|
||||
console.log('Database reset complete!');
|
||||
|
||||
sqlite.close();
|
||||
}
|
||||
|
||||
resetDatabase().catch(console.error);
|
||||
Reference in New Issue
Block a user