264 lines
6.1 KiB
TypeScript
264 lines
6.1 KiB
TypeScript
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);
|