QDG Knowledge Base Read-only viewer QWebHub
overview

Overview

Version 2 · Expand overview beyond auth: add Story/Media/Lookup feature areas, three-database data layer, and cross-links to the new architecture/database/api/user-guide pages

QDG CMS API

A .NET 9 Web API that provides content management services for QDG and affiliated sites: story/article authoring, an image/video gallery backed by Wasabi (S3-compatible) storage, and reference-data lookups for editor dropdowns. Authentication is not owned locally — it is delegated to the centralized QDBAuth service, with this API managing only opaque session cookies.

Architecture

Clean/onion architecture with four projects in QDG-CMS-BE.sln:

  • QDG.CMS.API — ASP.NET Core entry point: controllers, Serilog bootstrap logging, Swagger/OpenAPI, API versioning (Asp.Versioning), CORS, and the custom session authentication handler.
  • QDG.CMS.Application — application layer: DTOs, service interfaces/implementations, lookup providers, settings (AuthSettings, WasabiSettings), mappings, and validation helpers.
  • QDG.CMS.Domain — domain entities (Story, Media) and enums (StoryAccessScope, MediaType).
  • QDG.CMS.Infrastructure — data access (Dapper repositories across three MySQL databases), health checks, and external service clients (auth, Wasabi storage).

See Architecture for the full request-flow and layering detail, Database for schema, API Reference for every endpoint, and User Guide for running and using the API.

Feature areas

  • Auth — session login via the centralized QDBAuth service (login + TOTP), opaque qdg_session cookie issued locally.
  • Stories — CRUD for tblcms (the CMS article table shared with the public Racing.CMS API), including parent/child story linking, site/news-type mapping sync, and restricted-content tag validation.
  • Media — CRUD for tblphotos (Image Gallery + Video Gallery, one table discriminated by type), with a two-phase presigned-URL upload flow against Wasabi.
  • Lookups — read-only reference data for editor dropdowns: CMS-side (sites, authors, contributors, news types) and racing reference data from the qdb database (horses, trainers, jockeys, courses, races).

Data & storage

Three separate MySQL databases, same server/credentials but distinct connection strings and DI marker interfaces (IDbConnectionFactory, IQdbConnectionFactory, IPhotoGalleryConnectionFactory), all backed by the same DbConnectionFactory/Dapper implementation:

  • cms — tblcms and related mapping/reference tables.
  • qdb — horse/trainer/jockey/course/race reference data.
  • photogallery — tblphotos (photo + video rows).

Wasabi (S3-compatible) object storage holds the actual media files; WasabiHealthCheck verifies connectivity alongside MySqlHealthCheck at /health.

Cross-cutting

  • Structured logging via Serilog (console sink, bootstrap + request logging).
  • /health endpoint returns a JSON report of tagged checks (db, ready, storage).
  • CORS locked to an AllowedOrigins allow-list, credentials enabled.
  • API versioning via Asp.Versioning, all routes under api/v{version}/....

Deployment

Manual workflow_dispatch GitHub Actions pipeline (.github/workflows/deploy.yml) builds the dev branch as a self-contained win-x64 publish and deploys to an on-prem IIS site (QdgCmsApi), with pre-deploy backup, post-deploy /health check, and automatic rollback to the latest backup on failure. Runs on a self-hosted Windows runner.

Updated by Claude on Sept. 2, 2026, 4:46 a.m. · Task: Refresh QDG CMS API overview to cover Story, Media, and Lookup features added since the initial auth-only draft