1import { Hono } from "https://esm.sh/hono@3.11.7";
2import { getCookie, setCookie, deleteCookie } from "https://esm.sh/hono@3.11.7/cookie";
3import { createSession, deleteSession } from "../database/sessions.ts";
4import { storeOAuthState, verifyOAuthState } from "../database/oauth_states.ts";
5import type { GitHubUser } from "../../shared/types.ts";
6
39 });
40
41 // Store state in database instead of cookie for better reliability
42 await storeOAuthState(state);
43
44 console.log('OAuth state stored in database:', state);
45
46 return new Response(null, {
98 }
99
100 // Verify state using database
101 const stateValid = await verifyOAuthState(state);
102 if (!stateValid) {
120โโโ backend/
121โ โโโ index.ts # Main Hono server with routes
122โ โโโ database/
123โ โ โโโ sessions.ts # Session management
124โ โโโ routes/
1import { Hono } from "https://esm.sh/hono@3.11.7";
2import { getCookie } from "https://esm.sh/hono@3.11.7/cookie";
3import { getSession } from "../database/sessions.ts";
4import type { GitHubUser, GitHubRepo, GitHubCommit, CommitExtractRequest } from "../../shared/types.ts";
5
1import { Hono } from "https://esm.sh/hono@3.11.7";
2import { readFile, serveFile } from "https://esm.town/v/std/utils@85-main/index.ts";
3import { runMigrations } from "./database/migrations.ts";
4import auth from "./routes/auth.ts";
5import transactions from "./routes/transactions.ts";
14});
15
16// Initialize database on startup
17let dbInitialized = false;
18async function initializeDatabase() {
19 if (!dbInitialized) {
20 await runMigrations();
35// Serve main app
36app.get("/", async c => {
37 await initializeDatabase();
38
39 let html = await readFile("/frontend/index.html", import.meta.url);
56 status: "healthy",
57 timestamp: new Date().toISOString(),
58 database: dbInitialized ? "initialized" : "pending"
59 });
60});
5 getMonthlyData,
6 getTotalBalance
7} from "../database/queries.ts";
8
9const analytics = new Hono();
17
18 const token = authHeader.substring(7);
19 const { getSessionByToken } = await import("../database/queries.ts");
20 const session = await getSessionByToken(token);
21 return session?.user_id || null;
5 getUserBudgets,
6 deleteBudget
7} from "../database/queries.ts";
8
9const budgets = new Hono();
17
18 const token = authHeader.substring(7);
19 const { getSessionByToken } = await import("../database/queries.ts");
20 const session = await getSessionByToken(token);
21 return session?.user_id || null;
7 updateTransaction,
8 deleteTransaction
9} from "../database/queries.ts";
10
11const transactions = new Hono();
19
20 const token = authHeader.substring(7);
21 const { getSessionByToken } = await import("../database/queries.ts");
22 const session = await getSessionByToken(token);
23 return session?.user_id || null;
7 deleteSession,
8 getSessionByToken
9} from "../database/queries.ts";
10
11const auth = new Hono();
177 }
178
179 const { getUserById } = await import("../database/queries.ts");
180 const user = await getUserById(session.user_id);
181
2
3export async function runMigrations() {
4 console.log("Running database migrations...");
5
6 // Users table
56 `);
57
58 console.log("Database migrations completed successfully!");
59}
17```
18โโโ backend/
19โ โโโ database/
20โ โ โโโ migrations.ts # Database schema setup
21โ โ โโโ queries.ts # Database query functions
22โ โโโ routes/
23โ โ โโโ auth.ts # Authentication routes
45- **Backend**: TypeScript with Hono framework
46- **Frontend**: React 18.2.0 with TypeScript
47- **Database**: SQLite
48- **Styling**: TailwindCSS
49- **Charts**: Chart.js
53
541. Set the backend trigger to HTTP
552. The app will automatically set up the database on first run
563. Access the app through the HTTP endpoint
574. Create an account and start tracking your budget!