2import { TODO_TABLE } from "./migrations.ts";
3
4// Convert database row to Todo object
5function rowToTodo(row: any) {
6 return {
4export const TODO_TABLE = 'todos_v1';
5
6export async function setupDatabase() {
7 // Create the todos table if it doesn't exist
8 await sqlite.execute(`
15 `);
16
17 console.log(`Database setup complete. Table: ${TODO_TABLE}`);
18}
12## Project Structure
13
14- `/backend` - Server-side code with Hono API and SQLite database
15- `/frontend` - Client-side HTML, CSS, and JavaScript
16- `/shared` - Shared types and utilities
20- TypeScript
21- Hono (API framework)
22- SQLite (database)
23- TailwindCSS (styling)
46 "slug": "codegen",
47 "link": "/blog/codegen",
48 "description": "Like Claude Artifacts, but with a backend and database",
49 "pubDate": "Thu, 22 Aug 2024 00:00:00 GMT",
50 "author": "JP Posma",
1---
2title: "Post-mortem: A Backward Incompatible Database Migration"
3description: Val runs failed due to a database migration that was not backward compatible
4pubDate: 2025-04-02T00:00:00.000Z
5author: Sophie Houser
6---
7
8Today at 10:11am we experienced a 12-minute outage, which caused HTTP vals to return 503 errors and other types of vals to fail. In the end, the root cause was a deployment timing issue where database migrations were deployed successfully, but our application code deployment hung for several minutes. The new database migrations were incompatible with the old application code and crashed the process.
9
10We aim to make all database migrations maintain backward compatibility, but in this case, we only discovered through the delayed deployment feedback that the new migrations were not compatible with previous versions.
11
12## Timeline
27## Next Steps
28
29Reliability is important to us and weβve taken steps to make sure this doesnβt happen again. Weβve added a test to ensure database migrations are backward compatible, which weβll run before we deploy any new code that includes database migrations.
1import { Hono } from "https://esm.sh/hono@3.11.7";
2import { OpenAI } from "https://esm.town/v/std/openai";
3import { getAllTools, getToolsByCategory, getToolById, searchTools } from "../database/queries";
4import { AITool, SearchRequest, ToolCategory } from "../../shared/types";
5
7
8// Create tables for the AI tools directory
9export async function setupDatabase() {
10 // Create tools table
11 await sqlite.execute(`
31 `);
32
33 // Check if we need to seed the database
34 const count = await sqlite.execute(`SELECT COUNT(*) as count FROM ${TOOLS_TABLE}`);
35 if (count.rows[0].count === 0) {
36 await seedDatabase();
37 }
38}
39
40// Seed the database with initial AI tools
41async function seedDatabase() {
42 // Sample tools data
43 const tools = [
17```
18βββ backend/
19β βββ database/
20β β βββ migrations.ts # Database schema setup
21β β βββ queries.ts # Database query functions
22β βββ routes/
23β β βββ api.ts # API routes for search and recommendations
47- Backend: Hono API framework
48- AI: OpenAI for query understanding and tool recommendations
49- Database: SQLite for tool information storage
4import { useAuth } from "../../hooks/useAuth";
5import { useExamService } from "../../hooks/useExamService";
6import { Exam, Attempt } from "../../../shared/database/schema";
7
8const AdminDashboard: React.FC = () => {
4import { useAuth } from "../../hooks/useAuth";
5import { useExamService } from "../../hooks/useExamService";
6import { Attempt, Exam, Question, Answer } from "../../../shared/database/schema";
7
8interface QuestionWithAnswer extends Question {