125 lines
4.4 KiB
SQL
125 lines
4.4 KiB
SQL
-- CreateTable
|
|
CREATE TABLE "BlogPost" (
|
|
"id" TEXT NOT NULL,
|
|
"title" TEXT NOT NULL,
|
|
"slug" TEXT NOT NULL,
|
|
"excerpt" TEXT NOT NULL,
|
|
"coverImageUrl" TEXT,
|
|
"content" TEXT NOT NULL,
|
|
"isPublished" BOOLEAN NOT NULL DEFAULT true,
|
|
"views" INTEGER NOT NULL DEFAULT 0,
|
|
"publishedAt" TIMESTAMP(3),
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
|
|
CONSTRAINT "BlogPost_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "BlogPost_slug_key" ON "BlogPost"("slug");
|
|
|
|
-- Seed starter posts
|
|
INSERT INTO "BlogPost" ("id", "title", "slug", "excerpt", "coverImageUrl", "content", "isPublished", "views", "publishedAt", "createdAt", "updatedAt")
|
|
VALUES
|
|
(
|
|
'blog_bootstrapping_luna',
|
|
'Bootstrapping Luna on Home Infra',
|
|
'bootstrapping-luna-on-home-infra',
|
|
'How I wired a local-first assistant onto my own infrastructure without making the whole stack brittle.',
|
|
NULL,
|
|
$$# Bootstrapping Luna on Home Infra
|
|
|
|
Running an assistant from your own box sounds fun until the first reboot eats half the state and the other half lives in five unrelated scripts.
|
|
|
|
## The actual goal
|
|
|
|
I wanted a setup that stayed **local-first**, reacted quickly, and did not fall apart the second a service restarted. That meant a few rules:
|
|
|
|
- keep the state in places I control
|
|
- make tools callable without browser hacks
|
|
- prefer plain files and tiny APIs over magic
|
|
|
|
## What worked
|
|
|
|
The best decision was treating memory as part of the product instead of an afterthought. Notes, small docs, and project context live close to the runtime, so the assistant does not have to guess everything from chat history.
|
|
|
|
## What still sucks
|
|
|
|
The annoying bits are always the same: auth edges, stale sessions, and making sure background jobs stay visible instead of silently drifting.
|
|
|
|
## The payoff
|
|
|
|
Once the boring plumbing was stable, the fun part happened: the assistant could actually help with real work instead of just answering one-off questions.
|
|
$$,
|
|
true,
|
|
182,
|
|
TIMESTAMP '2026-07-12 18:30:00',
|
|
CURRENT_TIMESTAMP,
|
|
CURRENT_TIMESTAMP
|
|
),
|
|
(
|
|
'blog_prisma_content_systems',
|
|
'What Prisma Gets Right for Small Content Systems',
|
|
'what-prisma-gets-right-for-small-content-systems',
|
|
'Why a tiny Prisma-backed CMS is often cleaner than bolting markdown files onto a growing product.',
|
|
NULL,
|
|
$$# What Prisma Gets Right for Small Content Systems
|
|
|
|
When a site starts growing beyond a landing page, content sneaks in everywhere. Suddenly there are projects, changelogs, notes, announcements, and blog posts.
|
|
|
|
## Why I keep reaching for Prisma
|
|
|
|
Prisma gives me a couple things I care about:
|
|
|
|
1. typed data access
|
|
2. migrations I can inspect
|
|
3. one place to validate how content actually looks
|
|
|
|
That matters because the problem is rarely “where do I put the text?” The problem is keeping **editing**, **rendering**, and **publishing** from drifting apart.
|
|
|
|
## Markdown still wins
|
|
|
|
I still like markdown for the authoring format. It is fast, portable, and not weird to diff. The database just becomes the durable source of truth around that markdown.
|
|
|
|
## The tradeoff
|
|
|
|
You do lose some git-native niceness compared to file-based content. But once non-technical editing or richer admin flows matter, the database route gets way less annoying.
|
|
$$,
|
|
true,
|
|
141,
|
|
TIMESTAMP '2026-07-09 16:45:00',
|
|
CURRENT_TIMESTAMP,
|
|
CURRENT_TIMESTAMP
|
|
),
|
|
(
|
|
'blog_shipping_small_tools',
|
|
'Shipping Small Tools Without Making a Mess',
|
|
'shipping-small-tools-without-making-a-mess',
|
|
'A few rules I use to keep side tools useful, maintainable, and not instantly cursed.',
|
|
NULL,
|
|
$$# Shipping Small Tools Without Making a Mess
|
|
|
|
Tiny tools are dangerous because they feel too small to design properly. That is how you end up with “temporary” scripts haunting production six months later.
|
|
|
|
## My rule set
|
|
|
|
- name things like they will still exist next month
|
|
- write down the weird assumptions
|
|
- keep input and output dead simple
|
|
- make deletion easier than expansion
|
|
|
|
## The hidden trick
|
|
|
|
A good small tool usually does **less** than you first wanted. The moment a script starts collecting flags, modes, and special cases, it is begging to become a real service.
|
|
|
|
## Final thought
|
|
|
|
Shipping fast is good. Shipping something you can still understand later is better.
|
|
$$,
|
|
true,
|
|
96,
|
|
TIMESTAMP '2026-07-05 10:20:00',
|
|
CURRENT_TIMESTAMP,
|
|
CURRENT_TIMESTAMP
|
|
);
|