feat: add social features, leaderboard, auth enhancements, and admin fixes
continuous-integration/drone/push Build is passing

- Implement Social Features: Shared Tasks, Global Access, Privacy Settings (Leaderboard/Searchable).
- Add Leaderboard Page and API.
- Enhance Auth: Support Email/Username login, explicit duplicate registration errors.
- Fix: Admin login password hash regression.
- Refactor: Move to wouter for routing, add Admin Dashboard and User Management.
- Add Setup Wizard.
- Update UI with Sidebar and Gamification elements.
This commit is contained in:
2025-12-10 14:04:26 +01:00
parent d5b045158a
commit ccfb674318
52 changed files with 9206 additions and 1505 deletions
+14 -14
View File
@@ -5,12 +5,12 @@ import * as schema from '../shared/schema.js';
import { sql } from 'drizzle-orm';
let db: ReturnType<typeof drizzle> | null = null;
let pool: Pool | null = null;
export let pool: Pool | null = null;
export function getDatabase() {
if (!db) {
const databaseUrl = process.env.DATABASE_URL;
if (!databaseUrl) {
throw new Error('DATABASE_URL environment variable is not set');
}
@@ -19,7 +19,7 @@ export function getDatabase() {
// Values: 'true', 'false', or 'require'
// Default: false (no SSL)
let sslConfig: any = false;
if (process.env.DATABASE_SSL === 'true') {
sslConfig = { rejectUnauthorized: false }; // SSL with self-signed certs
} else if (process.env.DATABASE_SSL === 'require') {
@@ -41,14 +41,14 @@ export function getDatabase() {
export async function runMigrations() {
try {
const database = getDatabase();
// Push schema to database (creates/updates tables as needed)
// This is equivalent to running `drizzle-kit push`
console.log('Checking database schema...');
// Enable pgcrypto extension for gen_random_uuid()
await database.execute(sql`CREATE EXTENSION IF NOT EXISTS "pgcrypto"`);
// Create tables if they don't exist
await database.execute(sql`
CREATE TABLE IF NOT EXISTS users (
@@ -57,7 +57,7 @@ export async function runMigrations() {
password TEXT NOT NULL
)
`);
await database.execute(sql`
CREATE TABLE IF NOT EXISTS labels (
id VARCHAR PRIMARY KEY DEFAULT gen_random_uuid(),
@@ -65,7 +65,7 @@ export async function runMigrations() {
color TEXT NOT NULL
)
`);
await database.execute(sql`
CREATE TABLE IF NOT EXISTS tasks (
id VARCHAR PRIMARY KEY DEFAULT gen_random_uuid(),
@@ -81,7 +81,7 @@ export async function runMigrations() {
label_id VARCHAR REFERENCES labels(id)
)
`);
console.log('✓ Database schema is up to date');
} catch (error) {
console.error('Failed to run migrations:', error);
@@ -93,12 +93,12 @@ export async function initializeDatabase() {
try {
// Run migrations first
await runMigrations();
const database = getDatabase();
// Create default labels if they don't exist
const existingLabels = await database.select().from(schema.labels);
if (existingLabels.length === 0) {
const defaultLabels = [
{ name: "Work", color: "#3B82F6" },
@@ -106,11 +106,11 @@ export async function initializeDatabase() {
{ name: "Urgent", color: "#EF4444" },
{ name: "Study", color: "#8B5CF6" },
];
await database.insert(schema.labels).values(defaultLabels);
console.log('✓ Created default labels');
}
console.log('✓ Database initialized successfully');
} catch (error) {
console.error('Failed to initialize database:', error);