@@ -12,6 +12,48 @@ let dbInstance: unknown | null = null;
1212let cloudflareDbInstance : ReturnType < typeof drizzleProxy > | null = null ;
1313let sqliteInstance : import ( 'better-sqlite3' ) . Database | null = null ;
1414
15+ function ensureSqliteSchema ( db : import ( 'better-sqlite3' ) . Database ) : void {
16+ db . exec ( `
17+ CREATE TABLE IF NOT EXISTS stats_requests (
18+ id INTEGER PRIMARY KEY AUTOINCREMENT,
19+ username TEXT NOT NULL,
20+ url TEXT NOT NULL,
21+ created_at INTEGER
22+ );
23+
24+ CREATE UNIQUE INDEX IF NOT EXISTS uq_stats_request_url
25+ ON stats_requests (url);
26+
27+ CREATE TABLE IF NOT EXISTS visitor_logs (
28+ id INTEGER PRIMARY KEY AUTOINCREMENT,
29+ username TEXT NOT NULL,
30+ ip_hash TEXT NOT NULL,
31+ visit_date TEXT NOT NULL,
32+ created_at INTEGER
33+ );
34+
35+ CREATE UNIQUE INDEX IF NOT EXISTS uq_visitor_log
36+ ON visitor_logs (username, ip_hash, visit_date);
37+
38+ CREATE TABLE IF NOT EXISTS badges (
39+ username TEXT PRIMARY KEY,
40+ visitors INTEGER NOT NULL DEFAULT 0,
41+ repositories INTEGER,
42+ organization INTEGER,
43+ languages INTEGER,
44+ followers INTEGER,
45+ total_stars INTEGER,
46+ total_contributors INTEGER,
47+ total_commits INTEGER,
48+ total_code_reviews INTEGER,
49+ total_issues INTEGER,
50+ total_pull_requests INTEGER,
51+ total_joined_years INTEGER,
52+ updated_at INTEGER
53+ );
54+ ` ) ;
55+ }
56+
1557function getRequiredCloudflareConfig ( ) {
1658 const env = getEnv ( ) ;
1759 const accountId = env . CLOUDFLARE_ACCOUNT_ID ;
@@ -142,11 +184,11 @@ export function initializeDatabase() {
142184
143185 return cloudflareDbInstance ;
144186 }
145-
187+
146188 if ( ! sqliteInstance ) {
147189 throw new Error ( 'SQLite initialization must use initializeDatabaseAsync()' ) ;
148190 }
149-
191+
150192 return dbInstance ;
151193}
152194
@@ -171,19 +213,20 @@ export async function initializeDatabaseAsync() {
171213
172214 const Database = sqliteModule . default ;
173215 sqliteInstance = new Database ( env . DATABASE_URL ) ;
174-
216+
175217 // Enable WAL mode for better concurrent access
176218 sqliteInstance . pragma ( 'journal_mode = WAL' ) ;
177-
219+ ensureSqliteSchema ( sqliteInstance ) ;
220+
178221 // Initialize Drizzle ORM
179222 dbInstance = drizzle ( sqliteInstance , { schema } ) ;
180223
181224 // Populate the shared db proxy so service imports work on the Node.js path
182225 setDb ( dbInstance as any ) ;
183-
226+
184227 console . log ( `✅ Database connected: ${ env . DATABASE_URL } ` ) ;
185228 }
186-
229+
187230 return dbInstance ;
188231}
189232
0 commit comments