CMS Database Schema
Database: cms_myeasyguideORM: Prisma 7.8 Purpose: Dedicated content management database, independent from the main API database.
Models
Post
The core content entity — replaces the API's Blog model. Supports blog posts, travel guides, and scheduled content.
| Field | Type | Notes |
|---|---|---|
id | String (cuid, PK) | |
title | String? | Post title |
slug | String (unique) | URL slug |
content | String | HTML/rich text content |
coverImage | String? | |
status | String | draft, published, scheduled, or trash |
scheduledAt | DateTime? | For scheduled publishing |
publishedAt | DateTime? | |
views | Int | Default 0 |
metaTitle | String? | SEO title |
metaDescription | String? | SEO description |
meta | Json? | Metadata (word count, reading time, focus keyphrase) |
jsonLdSchema | Json? | Structured data |
tags | String? | Comma-separated tag names |
canonicalUrl | String? | Canonical URL |
urlHistory | String[] | Previous URLs for redirects |
cityHandle | String? | City slug for geo-tagging |
Relations:
category→PostCategory(optional)subcategory→SubCategory(optional)author→Author(optional)city→City(optional)country→Country(optional)
PostCategory
Content categories (replaces API's BlogCategory).
| Field | Type | Notes |
|---|---|---|
id | String (cuid, PK) | |
name | String | Display name |
slug | String (unique) | URL slug |
SubCategory
Content subcategories — new model not present in the API schema.
| Field | Type | Notes |
|---|---|---|
id | String (cuid, PK) | |
name | String | Display name |
slug | String (unique) | URL slug |
Author
Blog authors. Note: This is a separate table from the API's Author model. Authors were migrated from the API database to the CMS database.
| Field | Type | Notes |
|---|---|---|
id | String (cuid, PK) | |
username | String (unique) | |
name | String? | |
email | String (unique) | Login email |
password | String | bcrypt-hashed |
bio | String? | |
image | String? | |
createdAt | DateTime | |
updatedAt | DateTime |
City
Cities for geo-tagging posts. Separate table from the API's City model.
| Field | Type | Notes |
|---|---|---|
id | String (cuid, PK) | |
cityName | String | |
cityHandle | String (unique) | URL-safe slug |
cityImage | String? |
Country
Countries for geo-tagging posts. New model not present in the API schema (the API had country as a string field on Blog).
| Field | Type | Notes |
|---|---|---|
id | String (cuid, PK) | |
countryName | String | |
countryCode | String (unique) | ISO country code |
countryHandle | String (unique) | URL-safe slug |
Tag
Blog tags. New model — the API stored tags as a comma-separated string.
| Field | Type | Notes |
|---|---|---|
id | String (cuid, PK) | |
name | String (unique) |
GenerationBatch
Tracks AI-generated blog post batches.
| Field | Type | Notes |
|---|---|---|
id | String (cuid, PK) | |
batchId | String (unique) | Claude batch API ID |
topics | String[] | Topics submitted for generation |
focus | String? | Writing focus/angle |
status | String | pending, processing, completed, or failed |
error | String? | Error message if failed |
Schema Comparison: API vs CMS
| API Model | CMS Equivalent | Notes |
|---|---|---|
Blog | Post | New fields: status (with trash support), scheduledAt, meta, jsonLdSchema, canonicalUrl, urlHistory |
BlogCategory | PostCategory | Simplified — no timestamps |
| — | SubCategory | New model, not in API |
Author | Author | Separate table in CMS database |
| — | Country | New model, API used a plain string |
| — | Tag | New model, API used comma-separated string |
BlogGenerationImport | GenerationBatch | Simplified — no import/row/job hierarchy |
BlogGenerationImportRow | — | Folded into GenerationBatch |
BlogGenerationJob | — | Folded into GenerationBatch |
BusinessLink | — | Feature removed |
City | City | Separate table in CMS database |