logicspike/docs

Blog Engine

Blog System — Developer Guide

Last Updated: 2026-05-06 Status: Active

The complete internal reference for the Vlozi blog system. Everything a developer needs — architecture, schema, deployment, editor internals, SDK — lives here or is one link away.


1. What Is This System?

The Vlozi blog system is a multi-tenant headless blog engine built across three codebases:

Codebase Location Role
blog-service apps/blog-service Cloudflare Worker — owns all blog data, enforces permissions, serves the API
seller-dashboard apps/seller-dashboard/src/modules/blog Next.js dashboard — where tenants write and manage posts
blog-sdk packages/blog-sdk Published as @vlozi/blog — what customers embed on their websites

Two doors in, one data store:

Seller Dashboard ──JWT──► Gateway ──service binding──► blog-service ──► Neon PostgreSQL
Customer Website ──API Key──► Gateway ──────────────────────────────────────────────────►
  • Admin door (/blog/admin/*): JWT-authenticated. Full CRUD for posts, categories, and tags.
  • Public door (/blog/public/*): API key-authenticated. Read-only, published posts only.

2. Start Here By Role

Role Reading Path
New to the project This doc → glossary.mdarchitecture.mduser-journey.md
Backend / blog-service work architecture.mddatabase.mdblog-service.mdpermissions.mddeployment.md
Frontend / dashboard work architecture.mdfrontend-spec.mdeditor.mdmarkdown-import.md
SDK integrator sdk-reference.mdsdk-security-model.mdai-integration-prompt.md
Need a curl example fast cookbook.md
Setting up locally or deploying deployment.md
Debugging a failing request blog-workflow.md

3. Doc Index

Core Reference

Doc What It Covers
glossary.md Every term used across these docs — tenant, JWT, slug, content_json, hydration, etc.
architecture.md System diagram, all services, request flows, header protocol, permission model, multi-tenant isolation
database.md All 4 tables — column reference, constraints, indexes with rationale, migrations
permissions.md Every permission string, what route it gates, role bundles, how to add a new scope
deployment.md Local dev setup, env vars for all 3 services, production deploy, health checks
blog-service.md Full API reference — every endpoint, request/response schemas, middleware pipeline
cookbook.md Runnable curl + fetch recipes for common admin and public operations
blog-workflow.md Step-by-step request traces, common failure modes and fixes, debug checklist
editor.md TipTap extension inventory, custom node views, slash commands, how to add extensions
markdown-import.md The 5-stage .md → draft pipeline: parse → resolve → convert → mirror images → create
frontend-spec.md Dashboard UI — pages, components, API hooks, Redux state, permission-gating
sdk-reference.md Complete @vlozi/blog API — all exports, hooks, components, types, defaults
sdk-security-model.md HTML sanitization, iframe allowlist, XSS prevention, CSP guidance
testing.md Test inventory, how to run, test patterns, coverage gaps

Context & Process

Doc What It Covers
user-journey.md 9 end-to-end user journeys for admin authoring and SDK consumption
sdk-backlog.md Active bug/improvement queue for @vlozi/blog
ai-integration-prompt.md Paste-ready AI prompt for SDK integration tasks

Vision (Forward-Looking)

These describe where the product is going — not the current implementation.

Doc What It Covers
vision/blog-engine-vision.md Product north star — full editor, management, and integration vision
vision/layouts-vision.md Pre-built blog layout presets
vision/hosted-blog-vision.md Hosted blog pages (no SDK needed)
vision/integration-friction-vision.md Reducing SDK integration friction
vision/books-vision.md Blog → series → book publishing ladder

4. Codebase Quick Map

apps/
├── blog-service/                     Cloudflare Worker · port 8791 (local)
│   ├── src/index.ts                  Entry point — middleware pipeline + route registration
│   ├── src/db/schema.ts              4 tables: blog_posts, blog_categories, blog_tags, blog_post_tags
│   ├── src/routes/admin/             posts.ts · categories.ts · tags.ts
│   ├── src/routes/public/            posts.ts · categories.ts · tags.ts
│   ├── src/middleware/               auth.middleware.ts · db.middleware.ts
│   └── src/utils/tiptap-renderer.ts  TipTap JSON → sanitized HTML

├── gateway/                          Cloudflare Worker · port 8788 (local)
│   └── src/routes/blog.proxy.ts      Admin + Public proxy handlers

└── seller-dashboard/                 Next.js · port 3000 (local)
    └── src/modules/blog/             ~54 files across pages, editor, components, store, import
 
packages/
└── blog-sdk/                         Published as @vlozi/blog@2.1.6
    └── src/                          client · react/ · server/ · next/

5. Three Things Every Dev Must Know

1. The gateway is the only trust boundary. blog-service validates x-gateway-key on every request. Requests missing or bearing an invalid key are rejected 403. There is no direct public access to blog-service. When something is 403 but shouldn't be, check that GATEWAY_SECRET matches in both services.

2. Content is TipTap JSON in the database, HTML on the public API. All content is stored as JSONB (content_json). The admin API returns raw TipTap JSON for the editor. The public API (/public/posts/:slug) runs it through tiptap-renderer.ts before responding — HTML is generated server-side per request, never persisted.

3. All database queries are scoped by tenant_id. There is one blog-service serving every tenant. Isolation is enforced at the query level, not by routing or separate databases. Every SELECT, INSERT, UPDATE, and DELETE includes a WHERE tenant_id = ? clause. The requireTenant middleware rejects any request where x-tenant-id is absent.

Blog Engine