Från GitHub till databas – hur jag fixade min bloggarkitektur
Nyligen stötte jag på ett irriterande problem: mina blogginlägg hade försvunnit. Eller, rättare sagt – de syntes inte längre på sidan. Det visade sig vara symptom på ett djupare arkitekturproblem som jag inte ens visste att jag hade.
Problemet
Appen var uppdelad i två separata flöden:
- Blogglistan (
/blog) hämtade metadata från databasen - Enskilda inlägg (
/blog/[slug]) hämtade innehåll från GitHub
Det innebar att ett inlägg behövde existera på två ställen för att fungera – i databasen och i GitHub-repot. Dessutom hade skapandet av nya inlägg ett skörönt webhookflöde: admin-sidan pushade till GitHub, anropade sedan en webhook mot sig självt för att spara metadata i databasen. Om webhooken misslyckades saknades inlägget i listan.
Den direkta orsaken till att inläggen försvann? Ett utgånget GitHub-token – men det avslöjade att arkitekturen aldrig var robust från början.
Lösningen
Vi bestämde oss för att göra databasen till enda källan till sanning (single source of truth).
1. Ny databaskolumn
Posttabellen saknade en content-kolumn – den lagrade bara metadata. Vi lade till den via en ny migration:
export const up = async (db: Kysely<any>) => {
await db.schema
.alterTable('posts')
.addColumn('content', 'text')
.execute();
};
2. Seeda från GitHub
För att migrera befintliga inlägg skrev vi ett seedskript som hämtar alla markdown-filer från GitHub-repot och sparar dem i databasen – inklusive innehållet:
npm run seed:posts
3. Konsekvent datahämtning
Båda sidorna läser nu från databasen:
// /blog/[slug]/page.tsx
const post = await db
.selectFrom('posts')
.selectAll()
.where('slug', '=', slug)
.executeTakeFirst();
4. Förenklat skrivflöde
createPost sparar nu direkt i databasen och pushar till GitHub som backup – utan webhook:
await db.insertInto('posts')
.values({ slug, title, excerpt, content, date, updatedAt: new Date() })
.onConflict((oc) => oc.column('slug').doUpdateSet({ ... }))
.execute();
// GitHub som backup (icke-fatal om det misslyckas)
try {
await pushPostToGitHub(slug, title, date, excerpt, content);
} catch (err) {
console.error('GitHub backup misslyckades:', err);
}
Bonus: Turbopack-cache
Under processen slutade plötsligt alla routes utom startsidan att fungera och returnerade 404. Orsaken visade sig vara en korrupt Turbopack-cache. Lösningen:
rm -rf .next
npm run dev
Lärdomar
- Dela aldrig upp samma data mellan två system utan en tydlig synkroniseringsstrategi
- Webhooks mot sig själv är sprödare än direkta databasanrop
- En utgången token kan avslöja arkitekturproblem som legat och slumrat
- Rensa
.nextnär Turbopack beter sig konstigt