انتقل إلى المحتوى

Content Engine Architecture & API Guide

Detailed technical documentation covering the database schema, FlightPHP REST endpoints, markdown rendering pipeline, backup synchronization, and frontend integration for the TidyFactor-Go Content Engine.


1. System Architecture & Overview

The Content Engine is a core module in TidyFactor-Go designed to manage digital publications, blog posts, news articles, technical documentation, and multimedia press releases.

┌──────────────────────────────────────────────────────────────────┐
│                   React 19 Frontend Components                    │
│   (ContentHubPage.tsx, ContentDetailPage.tsx, ContentManager)    │
└─────────────────────────────────┬────────────────────────────────┘
                                  │ API Requests via resolveApiUrl()
┌─────────────────────────────────▼────────────────────────────────┐
│               FlightPHP REST API Gateway                         │
│             (routes/content_engine.php & Http)                   │
└─────────────────────────────────┬────────────────────────────────┘
                                  │ Prepared Statements & PDO
┌─────────────────────────────────▼────────────────────────────────┐
│            SqliteContentEngineRepository Data Layer              │
│       (content_items, content_categories, content_types)        │
└──────────────────────────────────────────────────────────────────┘

2. Database Schema Reference

The Content Engine persists data across four normalized tables in backend/cms-api/storage/database.sqlite.

A. content_items Table

Stores published and draft publication records.

Column Type Constraints Description
id INTEGER PRIMARY KEY AUTOINCREMENT Unique integer record ID
slug TEXT NOT NULL UNIQUE URL-safe article slug (e.g. ai-vision-2026)
type TEXT DEFAULT 'article' Article type (article, guide, news, video)
title TEXT NOT NULL Article headline
summary TEXT NULLABLE Short article excerpt
body TEXT NOT NULL Markdown formatted body content
cover_image TEXT NULLABLE Hero image URL or path
video_url TEXT NULLABLE Embedded video URL
gallery_images TEXT NULLABLE JSON array string of image gallery URLs
takeaways TEXT NULLABLE Key takeaways list
category TEXT DEFAULT 'general' Category slug reference
author_name TEXT DEFAULT 'Editorial Team' Author display name
author_avatar TEXT NULLABLE Author avatar image URL
author_role TEXT NULLABLE Author title/role
author_bio TEXT NULLABLE Author short biography
is_featured INTEGER DEFAULT 0 1 = Featured item, 0 = Standard
is_sticky INTEGER DEFAULT 0 1 = Pinned to top of feed, 0 = Standard
status TEXT DEFAULT 'published' Status (published, draft, archived)
reading_time_min INTEGER DEFAULT 1 Estimated reading duration in minutes
published_at TEXT NOT NULL ISO 8601 UTC timestamp (2026-08-02T10:00:00Z)
created_at TEXT DEFAULT CURRENT_TIMESTAMP Record creation timestamp
updated_at TEXT DEFAULT CURRENT_TIMESTAMP Last update timestamp

B. content_categories Table

Column Type Constraints Description
slug TEXT PRIMARY KEY Category key (engineering, product)
name_en TEXT NOT NULL English category title
name_ar TEXT NOT NULL Arabic category title
description TEXT NULLABLE Category description

C. content_types Table

Column Type Constraints Description
slug TEXT PRIMARY KEY Type key (article, guide, case-study)
name_en TEXT NOT NULL English type title
name_ar TEXT NOT NULL Arabic type title
description TEXT NULLABLE Content type description

D. content_tags Table

Column Type Constraints Description
item_id INTEGER NOT NULL Foreign key referencing content_items.id
tag TEXT NOT NULL Tag keyword string

3. FlightPHP REST API Specification

Public Endpoints

GET /api/content/items

Retrieves published content items with dynamic filtering and pagination.

Query Parameters - type (optional): Filter by type slug (article, guide). Pass all to ignore filter. - category (optional): Filter by category slug. Pass all to ignore filter. - tag (optional): Filter by tag keyword. - featured (optional): 1 for featured only. - sticky (optional): 1 for sticky only. - search (optional): Search query string matching title or summary. - page (optional): Page number (Default: 1). - limit (optional): Items per page (Default: 10, Max: 100).

Response Example

{
  "items": [
    {
      "id": 1,
      "slug": "welcome-to-tidyfactor",
      "type": "article",
      "title": "Welcome to TidyFactor-Go",
      "summary": "Platform announcement and feature overview.",
      "body": "# Welcome...",
      "coverImage": "/uploads/welcome.jpg",
      "category": "news",
      "authorName": "Editorial Team",
      "isFeatured": 1,
      "isSticky": 1,
      "status": "published",
      "readingTimeMin": 3,
      "publishedAt": "2026-08-02T10:00:00Z",
      "tags": ["announcement", "platform"]
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 10,
    "totalItems": 1,
    "totalPages": 1
  }
}

GET /api/content/item/@slug

Fetches a single published publication by its unique slug.

Response (200 OK): Single article JSON object.
Errors (404 Not Found): {"error": "Content item not found"}.

GET /api/content/categories

Returns array of registered category objects.

GET /api/content/types

Returns array of registered content type objects.

GET /api/content/tags

Returns list of unique tags with published item counts.


Admin Endpoints (Session Authenticated)

GET /api/admin/content/items

Lists all items regardless of status (includes draft, scheduled, archived).

POST /api/admin/content/items

Creates a new content item.

Request Body

{
  "title": "New Research Guide",
  "slug": "new-research-guide",
  "type": "guide",
  "category": "engineering",
  "summary": "Technical research summary.",
  "body": "## Executive Summary\n\nContent details...",
  "coverImage": "/uploads/guide.jpg",
  "authorName": "Engineering Lead",
  "isFeatured": 0,
  "isSticky": 0,
  "status": "published",
  "tags": ["engineering", "research"]
}

PUT /api/admin/content/items/@id

Updates an existing content item matching @id.

DELETE /api/admin/content/items/@id

Deletes a content item matching @id and prunes associated tags.


4. Performance & Core Architectural Guards

  1. Payload Un-bloating: GET /api/content/site excludes full article bodies from the main site configuration payload, ensuring instant homepage load times.
  2. Double Storage Bloat Elimination: ContentService::updateContent() unsets contentEngine before writing to the single-row content table, preventing redundant article duplication between content and content_items.
  3. ISO 8601 UTC Standardization: All timestamp properties (publishedAt, createdAt, updatedAt) are formatted with standard ISO 8601 'T' delimiters to guarantee cross-browser compatibility across Safari, Chrome, and Mobile WebKit.
  4. Subfolder API Path Resolution: All frontend requests wrap relative paths using resolveApiUrl('api/content/...') from src/lib/apiUrl.ts.