chore: server-and-serverless template

This commit is contained in:
e2e
2026-06-26 15:01:11 +02:00
commit a5f832e9ed
202 changed files with 9060 additions and 0 deletions

8
db/annotations.gen.json Normal file
View File

@@ -0,0 +1,8 @@
{
"account": {},
"audit": {},
"message_state": {},
"session": {},
"user": {},
"verification": {}
}

16
db/annotations.ts Normal file
View File

@@ -0,0 +1,16 @@
import type { DbClassificationMap } from '/Users/yasser/git/pikku/fabric/templates/server-and-serverless/.pikku/db/classification-map.gen.d.ts'
export const classifications = {
"account": {
},
"audit": {
},
"message_state": {
},
"session": {
},
"user": {
},
"verification": {
},
} satisfies DbClassificationMap

3
db/sqlite-seed.sql Normal file
View File

@@ -0,0 +1,3 @@
INSERT INTO message_state (id, message)
VALUES (1, 'Hello from Starter')
ON CONFLICT (id) DO NOTHING;

10
db/sqlite-test-seed.sql Normal file
View File

@@ -0,0 +1,10 @@
-- Test-only seed: inserts a minimal user row so updateMessage's inner join
-- on (user.id = messageState.updatedByUserId) resolves. This file is only
-- used by the function-tests harness (never in the sandbox or production).
INSERT INTO "user" (id, name, email, email_verified, created_at, updated_at)
VALUES ('user-001', 'Test User', 'test@example.com', 1, datetime('now'), datetime('now'))
ON CONFLICT (id) DO NOTHING;
INSERT INTO message_state (id, message)
VALUES (1, 'Hello from Starter')
ON CONFLICT (id) DO NOTHING;

67
db/sqlite/0001-init.sql Normal file
View File

@@ -0,0 +1,67 @@
PRAGMA foreign_keys = ON;
-- Better Auth core schema. These four tables (user, session, account,
-- verification) are owned and written entirely by Better Auth — the app never
-- inserts into them directly; sign-up / sign-in / sessions all flow through the
-- generated `/api/auth/**` routes (see src/auth.ts).
--
-- The schema is generated by Better Auth's own migration generator
-- (`getMigrations(...).compileMigrations()`); the columns are spelled in
-- snake_case to match the rest of the app's DB convention. Better Auth is handed
-- the app's kysely (with CamelCasePlugin) in src/auth.ts, so its camelCase field
-- names (emailVerified, userId, createdAt, ...) compile to exactly these
-- snake_case columns at runtime. To change this schema (add a provider field, a
-- plugin table, ...), re-run the generator rather than hand-editing.
--
-- Email + password is the default sign-in method. The credential hash is stored
-- by Better Auth in account.password (provider_id = 'credential'), never on the
-- user row.
CREATE TABLE IF NOT EXISTS "user" (
"id" text not null primary key,
"name" text not null,
"email" text not null unique,
"email_verified" integer not null,
"image" text,
"created_at" date not null,
"updated_at" date not null
);
CREATE TABLE IF NOT EXISTS "session" (
"id" text not null primary key,
"expires_at" date not null,
"token" text not null unique,
"created_at" date not null,
"updated_at" date not null,
"ip_address" text,
"user_agent" text,
"user_id" text not null references "user" ("id") on delete cascade
);
CREATE TABLE IF NOT EXISTS "account" (
"id" text not null primary key,
"account_id" text not null,
"provider_id" text not null,
"user_id" text not null references "user" ("id") on delete cascade,
"access_token" text,
"refresh_token" text,
"id_token" text,
"access_token_expires_at" date,
"refresh_token_expires_at" date,
"scope" text,
"password" text,
"created_at" date not null,
"updated_at" date not null
);
CREATE TABLE IF NOT EXISTS "verification" (
"id" text not null primary key,
"identifier" text not null,
"value" text not null,
"expires_at" date not null,
"created_at" date not null,
"updated_at" date not null
);
CREATE INDEX IF NOT EXISTS "session_user_id_idx" ON "session" ("user_id");
CREATE INDEX IF NOT EXISTS "account_user_id_idx" ON "account" ("user_id");
CREATE INDEX IF NOT EXISTS "verification_identifier_idx" ON "verification" ("identifier");

View File

@@ -0,0 +1,12 @@
PRAGMA foreign_keys = ON;
-- Demo "hello world" persistence: a single editable message that shows the full
-- loop (sign in -> read from the DB -> write back -> see who last changed it).
-- Singleton row, always id = 1. Safe to delete this table and its functions
-- (get-message / update-message) once you start building your own thing.
CREATE TABLE IF NOT EXISTS message_state (
id INTEGER PRIMARY KEY,
message TEXT NOT NULL,
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
updated_by_user_id TEXT REFERENCES "user" ("id")
);

26
db/sqlite/0003-audit.sql Normal file
View File

@@ -0,0 +1,26 @@
-- Audit log. Fabric's audit service flushes events here via a per-stage
-- CF Queue. Add this table if you want audit capture; remove it (and skip
-- this migration) if your project has no audit requirements.
CREATE TABLE IF NOT EXISTS audit (
audit_id TEXT NOT NULL PRIMARY KEY DEFAULT (lower(hex(randomblob(16)))),
occurred_at TEXT NOT NULL DEFAULT (datetime('now')),
type TEXT NOT NULL,
source TEXT NOT NULL DEFAULT 'auto',
outcome TEXT,
function_id TEXT,
wire_type TEXT,
trace_id TEXT,
transaction_id TEXT,
query_id TEXT,
actor_user_id TEXT,
actor_org_id TEXT,
tables TEXT, -- JSON array of table names touched
changed_cols TEXT, -- JSON array of changed column names
event TEXT, -- custom event label
old TEXT, -- JSON: previous values
data TEXT -- JSON: new values / event payload
);
CREATE INDEX IF NOT EXISTS idx_audit_occurred_at ON audit (occurred_at);
CREATE INDEX IF NOT EXISTS idx_audit_actor ON audit (actor_user_id) WHERE actor_user_id IS NOT NULL;
CREATE INDEX IF NOT EXISTS idx_audit_function ON audit (function_id) WHERE function_id IS NOT NULL;