Skip to content

Core Concepts

Understanding these key concepts will help you get the most out of DCS.

Sites

A site is a website managed through DCS. Each site has:

  • A unique slug (e.g., my-company-website)
  • An associated GitHub repository containing the source code
  • Azure Static Web Apps resources for hosting (development and production)
  • Text overrides for editing text through the portal, no developer needed
  • SEO metadata for search optimization

Site Types

DCS supports different site architectures:

TypeDescriptionExample
VitePressDocumentation-style sites with markdownCompany blogs, docs
Vue SPASingle-page applicationsWeb apps, dashboards
StaticPre-rendered HTML sitesMarketing sites

Companies

Sites belong to companies in DCS. A company represents an organization that owns one or more sites.

Site Permission Levels

Access to each site is granted per user at one of four permission levels:

PermissionCapabilities
ownerFull control of the site, including managing other users' access
adminSite management, development requests, and content
editorContent and text editing
viewerRead-only access

A separate platform-level global admin role exists for DCS operators and is independent of per-site permissions.

Text Keys

Text keys are identifiers for editable text regions on your site. They follow a hierarchical naming convention:

{page}.{section}.{element}

Examples:

  • home.hero.title — The main heading on the home page
  • about.team.description — Team description on the about page
  • footer.copyright — Copyright text in the footer

Text Overrides

When you edit text in the portal, you create a text override. In the default commit mode, overrides are committed to the site's .dcs/content.yaml and baked in at build time, so your edits go live with the site's next deployment. Sites can instead opt into runtime override mode, where the site fetches overrides from the API and applies them without a rebuild.

Default Text (in code) → Text Override → Displayed Text

Change Lifecycle

DCS separates two kinds of change:

  • Text and SEO edits are stored as overrides. In the default commit mode they are committed to the site repository and go live on the next deployment; the opt-in runtime mode applies them on the site's next fetch instead, with no rebuild. (See Text Overrides above.)
  • Code changes — anything a text override can't express — flow through the development request lifecycle below, are committed to a release branch, and are reviewed in a preview before deploying to production.

Text changes can also be attached to a development request so they commit and deploy together with the related code.

Development Requests

When changes require code modifications, you create a development request. An AI-assisted pipeline analyzes each request to determine the best approach.

Request Lifecycle

A request moves through these states:

submitted → triage → in-progress → in-review → completed

Two off-ramps can end a request early: rejected (declined) and archived (closed out of the active list).

StatusDescription
submittedReceived, awaiting analysis
triageAnalyzed and classified; automation potential determined
in-progressBeing implemented by the pipeline
in-reviewDeployed to a preview, awaiting your review
completedApproved and deployed to production
rejectedDeclined — will not be implemented
archivedClosed out of the active request list

Automation Flow

Request → Intent Analysis → GitHub Issue → AI coding agent → PR → Review → Deploy

Requests are processed one at a time per site so that changes serialize cleanly.

Release Branches

DCS uses release branches to manage deployments:

master (production)
  └── release/1.2.0 (in-flight version)
        └── feature branch (automated work)
  • master — Production code, always stable
  • release/X.Y.Z — The in-flight version being worked on
  • feature branches — Created by the automation to implement a request, then merged back via pull request

Semantic Versioning

Sites follow semantic versioning:

  • MAJOR (1.0.0) — Breaking changes
  • MINOR (1.1.0) — New features
  • PATCH (1.1.1) — Bug fixes, text changes

Deployment Environments

Each site is hosted on Azure Static Web Apps with two environments, selected by the branch that was pushed:

EnvironmentBranchPurpose
ProductionmasterThe live site
Previewrelease/**Review changes before they go to production

Pushing a release/** branch deploys to the Preview environment; pushing master deploys to Production.

Deployment Flow

Code Change → Build → Deploy to Preview → Review → Approve → Deploy to Production

APIs

DCS exposes a small set of public, read-only runtime APIs. The site is resolved server-side from the request Host (or a dedicated Container App's DCS_SITE_SLUG), so the site slug never appears in the path.

Text Content API

Fetch text overrides for a page:

http
GET /api/v1/pages/{pageSlug}/text

See the Text Content API reference for the full contract.

Content API

Fetch page configuration and blog content for runtime hydration:

http
GET /api/v1/content/pages
GET /api/v1/content/pages/{pageSlug}
GET /api/v1/content/posts
GET /api/v1/content/posts/{postSlug}

SEO

SEO metadata is not a runtime API. It is driven by the site's .dcs/seo.yaml and applied at build time through the useSEO composable in @duffcloudservices/cms. Edit SEO in the portal and it is committed to seo.yaml.

Integration Points

The useTextContent Composable

For Vue/VitePress sites, this composable provides text override functionality:

ts
const { t, isLoading } = useTextContent()

// t(key, defaultValue) returns the override or default
const title = t('page.title', 'Default Title')

GitHub Webhooks

DCS listens for GitHub events to:

  • Track PR status for development requests
  • Trigger deployments on branch updates
  • Update request status when PRs merge

Azure Integration

DCS integrates with Azure for:

  • Static Web Apps hosting
  • Blob storage for assets
  • Table storage for data
  • Entra ID for the platform's own identity against Azure resources (user sign-in is separate: Google always, GitHub or Microsoft where enabled, or a passkey — see Sign-in & Accounts)

Next Steps

Now that you understand the concepts: