Add database configuration
This commit is contained in:
@@ -0,0 +1,85 @@
|
|||||||
|
const knex = require('knex');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
const db = knex({
|
||||||
|
client: 'sqlite3',
|
||||||
|
connection: {
|
||||||
|
filename: path.join(__dirname, '../../data/photo_sharing.db')
|
||||||
|
},
|
||||||
|
useNullAsDefault: true
|
||||||
|
});
|
||||||
|
|
||||||
|
async function initializeDatabase() {
|
||||||
|
// Events table
|
||||||
|
await db.schema.createTableIfNotExists('events', (table) => {
|
||||||
|
table.increments('id').primary();
|
||||||
|
table.string('slug').unique().notNullable();
|
||||||
|
table.string('event_type').notNullable();
|
||||||
|
table.string('event_name').notNullable();
|
||||||
|
table.date('event_date').notNullable();
|
||||||
|
table.string('host_email').notNullable();
|
||||||
|
table.string('admin_email').notNullable();
|
||||||
|
table.string('password_hash').notNullable();
|
||||||
|
table.text('welcome_message');
|
||||||
|
table.string('color_theme');
|
||||||
|
table.string('share_link').unique().notNullable();
|
||||||
|
table.datetime('created_at').defaultTo(db.fn.now());
|
||||||
|
table.datetime('expires_at').notNullable();
|
||||||
|
table.boolean('is_active').defaultTo(true);
|
||||||
|
table.boolean('is_archived').defaultTo(false);
|
||||||
|
table.string('archive_path');
|
||||||
|
table.datetime('archived_at');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Photo metadata table
|
||||||
|
await db.schema.createTableIfNotExists('photos', (table) => {
|
||||||
|
table.increments('id').primary();
|
||||||
|
table.integer('event_id').references('id').inTable('events').onDelete('CASCADE');
|
||||||
|
table.string('filename').notNullable();
|
||||||
|
table.string('path').notNullable();
|
||||||
|
table.string('thumbnail_path');
|
||||||
|
table.string('type').notNullable(); // 'collage' or 'individual'
|
||||||
|
table.integer('size_bytes');
|
||||||
|
table.datetime('uploaded_at').defaultTo(db.fn.now());
|
||||||
|
table.integer('view_count').defaultTo(0);
|
||||||
|
table.integer('download_count').defaultTo(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Access logs table
|
||||||
|
await db.schema.createTableIfNotExists('access_logs', (table) => {
|
||||||
|
table.increments('id').primary();
|
||||||
|
table.integer('event_id').references('id').inTable('events');
|
||||||
|
table.string('ip_address');
|
||||||
|
table.string('user_agent');
|
||||||
|
table.string('action'); // 'view', 'download', 'login_success', 'login_fail'
|
||||||
|
table.string('photo_id');
|
||||||
|
table.datetime('timestamp').defaultTo(db.fn.now());
|
||||||
|
});
|
||||||
|
|
||||||
|
// Email queue table
|
||||||
|
await db.schema.createTableIfNotExists('email_queue', (table) => {
|
||||||
|
table.increments('id').primary();
|
||||||
|
table.integer('event_id').references('id').inTable('events');
|
||||||
|
table.string('recipient_email').notNullable();
|
||||||
|
table.string('email_type').notNullable(); // 'creation', 'warning', 'expiration', 'archive_complete'
|
||||||
|
table.json('email_data');
|
||||||
|
table.string('status').defaultTo('pending'); // 'pending', 'sent', 'failed'
|
||||||
|
table.datetime('scheduled_at').defaultTo(db.fn.now());
|
||||||
|
table.datetime('sent_at');
|
||||||
|
table.text('error_message');
|
||||||
|
table.integer('retry_count').defaultTo(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Admin users table
|
||||||
|
await db.schema.createTableIfNotExists('admin_users', (table) => {
|
||||||
|
table.increments('id').primary();
|
||||||
|
table.string('username').unique().notNullable();
|
||||||
|
table.string('email').unique().notNullable();
|
||||||
|
table.string('password_hash').notNullable();
|
||||||
|
table.boolean('is_active').defaultTo(true);
|
||||||
|
table.datetime('created_at').defaultTo(db.fn.now());
|
||||||
|
table.datetime('last_login');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { db, initializeDatabase };
|
||||||
Reference in New Issue
Block a user