Skip to content

TidyFactor-Go Platform & Architecture Specifications

Complete technical specifications covering Content Models, Theme Manifests, Module Manifests, Config Formats, Storage Drivers, JSON Schemas, File Structures, Routing Rules, Template Specifications, Plugin APIs, and Media Specifications.


1. Content Model

The TidyFactor-Go Content Model represents all static and dynamic site content as a unified object structure.

Localized Text Pattern (LocalizedText)

All user-facing text fields follow the LocalizedText interface:

interface LocalizedText {
  en: string;
  ar: string;
}

Root Content Model (ManagedSiteContent)

interface ManagedSiteContent {
  version: number; // Must equal 1
  updatedAt: string; // ISO 8601 UTC timestamp
  header: HeaderSection;
  home: HomeSection;
  about: AboutSection;
  solutions: Solution[];
  caseStudies: CaseStudy[];
  pricing: PricingSection;
  contact: ContactSection;
  footer: FooterSection;
  seo: Record<SeoPageKey, LocalizedSeo>;
  contentEngine?: ContentEngineExportPayload; // Included in admin backup exports
}

2. Theme Manifest

Visual branding is controlled via the THEME manifest stored in the SQLite config table (key = 'theme').

{
  "name": "Default Blue",
  "preset": "default",
  "fontFamily": "Inter",
  "fontFamilyAr": "Cairo",
  "borderRadius": "8px",
  "colors": {
    "primary": "#0A2540",
    "primaryHover": "#081C30",
    "accent": "#D62828",
    "brandDepth": "#081C30",
    "bg": "#FFFFFF",
    "card": "#F8FAFC",
    "border": "#E2E8F0"
  }
}

Presets

  • default (Primary Blue #0A2540)
  • ocean (Deep Sea #0284C7)
  • emerald (Forest Green #059669)
  • sunset (Warm Amber #D97706)
  • midnight (Dark Slate #0F172A)
  • rose (Crimson Rose #E11D48)

3. Module Manifest

Modules in TidyFactor-Go register navigation tabs, form workspaces, and API endpoints inside AdminPage.tsx:

interface AdminModuleManifest {
  id: string; // e.g. 'home', 'about', 'pricing', 'content-engine', 'theme', 'backups'
  label: LocalizedText;
  group: 'dashboard' | 'content' | 'design' | 'marketing' | 'system';
  icon: string; // Lucide icon identifier
  component: React.ComponentType;
}

4. Config Format

Global system options stored in backend/cms-api/storage/database.sqlite (table: config):

Key Type Description
BUSINESS_NAME string Brand identity title
BUSINESS_TYPE string Industry classification
BUSINESS_LOGO string Custom logo URL/path
BUSINESS_LANG string Default visitor language (en or ar)
BUSINESS_FAVICON string Custom favicon URL
UPLOAD_DIR string Absolute path to media uploads directory
SITE_URL string Public base URL for sitemap
GEMINI_API_KEY string Google Gemini AI Key
UNSPLASH_ACCESS_KEY string Unsplash API access key
BACKUP_ON_SAVE boolean Enable automatic snapshot creation (true)
BACKUP_MAX_COUNT integer Automatic snapshot retention limit (10)

5. Storage Drivers

TidyFactor-Go implements a decoupled Repository Pattern:

┌─────────────────────────────────────────────────────────┐
│               Storage Driver Architecture               │
└───────────────────────────┬─────────────────────────────┘
       ┌────────────────────┼────────────────────┐
       ▼                    ▼                    ▼
┌──────────────┐     ┌──────────────┐     ┌──────────────┐
│ SqliteContent│     │ SqliteEngine │     │ Baseline DB  │
│ Repository   │     │ Repository   │     │ Self-Healing │
│ (Active DB)  │     │ (Articles)   │     │ Fallback     │
└──────────────┘     └──────────────┘     └──────────────┘
  1. SqliteContentRepository: Reads/writes unified content table (id = 1).
  2. SqliteContentEngineRepository: Manages content_items, content_categories, content_types, and content_tags.
  3. database-baseline.sqlite Driver: Self-healing fallback that seeds a fresh database if missing.

6. Unified JSON Schema Contract

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "TidyFactorContentSchema",
  "type": "object",
  "required": [
    "version",
    "updatedAt",
    "home",
    "about",
    "solutions",
    "caseStudies",
    "pricing",
    "contact",
    "header",
    "footer",
    "seo"
  ],
  "properties": {
    "version": { "type": "integer", "const": 1 },
    "updatedAt": { "type": "string", "format": "date-time" }
  }
}

7. Project File Structure

TidyFactor-Go/
├── .agents/                    # AI Agent instructions, rules & skills
├── backend/
│   └── cms-api/
│       ├── public/index.php    # API gateway router & env parser
│       ├── src/                # PSR-4 App namespace
│       │   ├── Repository/     # SQLite database repositories
│       │   ├── Service/        # ContentService & validation
│       │   └── Support/        # AdminAuth, Config, Http helpers
│       ├── routes/             # FlightPHP domain routes
│       └── storage/            # database.sqlite
├── docs/                       # Docsify technical documentation
│   ├── index.html              # Docsify SPA entry point
│   ├── _sidebar.md             # Navigation tree
│   ├── api/                    # Endpoint references
│   └── guides/                 # Architecture, Security, DB, Setup guides
├── src/
│   ├── components/             # React UI widgets & shadcn components
│   ├── content/                # types.ts, defaultContent.ts, ContentProvider
│   ├── lib/                    # resolveApiUrl, usePageSeo, adminApi
│   ├── pages/                  # Route components & Admin dashboard
│   └── routes/                 # AppRouter.tsx
├── package.json
└── vite.config.ts

8. Routing Rules & Subfolder API Resolution

Client-Side SPA Routing

Bound to dynamic router basename (window.__router_basename__). Supported routes (/, /about, /solutions, /case-studies, /pricing, /content, /contact, /admin).

Server API Route Resolution (resolveApiUrl())

All frontend fetch requests resolve via resolveApiUrl('api/...'):

const url = resolveApiUrl('api/content/site');
// Output on domain root: /api/content/site
// Output in subfolder /demo/: /demo/api/content/site


9. Template Specification

Public pages follow a standardized component pattern:

export default function NewPage() {
  const { content, isLoading } = useContent();
  const { i18n } = useTranslation();

  if (isLoading) return <HomeSkeleton />;

  const pageData = content?.newPage;
  if (!isEnabled(pageData?.pageSettings)) return null;

  return (
    <div className="py-16 sm:py-24 bg-background">
      <h1 className="text-3xl font-bold text-foreground">
        {getLocalizedText(pageData?.title, i18n.language)}
      </h1>
    </div>
  );
}

10. Plugin API & Extensibility SDK

Extending TidyFactor-Go with custom section forms or API endpoints follows the 3-step plugin pattern:

  1. Form Input Binding (FieldRow):
    <FieldRow
      label="Section Title"
      valueEn={draft.title?.en}
      valueAr={draft.title?.ar}
      onChange={(en, ar) => setDraft({ ...draft, title: { en, ar } })}
    />
    
  2. Backend Route Handler:
    $app->route('GET /api/custom-endpoint', function() {
        Http::setCachePolicy('dynamic');
        Flight::json(['ok' => true]);
    });
    

11. Media Specification

  • Supported MIME Types: image/jpeg, image/png, image/webp, image/svg+xml, image/gif.
  • Max File Size: 20 MB (upload_max_filesize = 20M).
  • SVG Security Sanitization: Processed through enshrined/svg-sanitize to strip scripts and event handlers.
  • Unsplash Proxy Integration: Authenticated backend cURL proxy via GET /api/admin/unsplash/search.