208```
209βββ backend/
210β βββ database/
211β β βββ migrations.ts # Schema definitions
212β β βββ queries.ts # DB query functions
270- Handle API calls properly with proper error catching
271
272### Database Patterns
273- Run migrations on startup or comment out for performance
274- Change table names when modifying schemas rather than altering
308 const url = new URL(request.url);
309
310 // Comprehensive database setup
311 await sqlite.execute(`
312 CREATE TABLE IF NOT EXISTS ${KEY}_posts (
308 const url = new URL(request.url);
309
310 // Comprehensive database setup
311 await sqlite.execute(`
312 CREATE TABLE IF NOT EXISTS ${KEY}_posts (
308 const url = new URL(request.url);
309
310 // Comprehensive database setup
311 await sqlite.execute(`
312 CREATE TABLE IF NOT EXISTS ${KEY}_posts (
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.
2
3/**
4 * Retrieves all memories from the database
5 * @param includeDate Whether to include date-specific memories or not
6 * @param startDate Optional start date to filter memories from (ISO format)
1// Script to set up the telegram_chats table in SQLite
2// Run this script manually to create the database table
3
4export default async function setupTelegramChatDb() {
25 `);
26
27 return "Telegram chat database table created successfully.";
28 } catch (error) {
29 console.error("Error setting up telegram_chats table:", error);
13## Technical Architecture
14
15**β οΈ important caveat: the admin dashboard doesn't have auth! currently it just relies on security by obscurity of people not knowing the url to a private val. this is not very secure. if you fork this project and put sensitive data in a database you should think carefully about how to secure it.**
16
17Stevens has been designed with the utmost simplicity and extensibility, much like a well-organized household. At the heart of his operation lies a single "memories" table - a digital equivalent of a butler's meticulous records. This table serves as the foundation for all of Stevens' operations.
45- `dashboard`: the admin view for showing the memories notebook + visualizing imports
46- `dailyBriefing`: stuff related to sending a daily update via telegram
47- `dbUtils`: little one-off scripts for database stuff
48
49## Hiring your own Stevens
57- For the Google Calendar integration you'll need `GOOGLE_CALENDAR_ACCOUNT_ID` and `GOOGLE_CALENDAR_CALENDAR_ID`. See [these instuctions](https://www.val.town/v/stevekrouse/pipedream) for details.
58
59**important caveat: the admin dashboard doesn't have auth! currently it just relies on security by obscurity of people not knowing the url to a private val. this is not very secure, if you put sensitive data in a database you should think carefully about how to secure it.**
60
61Overall it's a simple enough project that I encourage you to just copy the ideas and run in your own direction rather than try to use it as-is.
4
5* `index.ts` - this is the **entrypoint** for this whole project
6* `database/` - this contains the code for interfacing with the app's SQLite database table
7
8## Hono
26## CRUD API Routes
27
28This app has two CRUD API routes: for reading and inserting into the messages table. They both speak JSON, which is standard. They import their functions from `/backend/database/queries.ts`. These routes are called from the React app to refresh and update data.
29
30## Errors