Skip to main content

AI Website Construction & cockpitOS: Integration Concept

This document describes the target vision and implementation phases so that an AI session (e.g., Claude) can build websites and create or update content in cockpitOS — without users having to manually maintain everything in the dashboard. It applies to both Greenfield and Brownfield scenarios.

Guidelines: No data loss, no destructive schema steps; new interfaces only additively and with clear authentication. Existing APIs remain stable.


1. Problem & Target Vision

TodayGoal
AI generates UI quickly (v0, Claude, …), data is separatedOne session: Build + "for whom" + which content
Data is manually pulled into CockpitAI checks Cockpit (Is the center present? Is data there?) and writes missing data via secure APIs
Website shows demo dataPublic site reads the same data as Cockpit (Single Source of Truth)
Editorial needs IT for every changeEditorial creates drafts via voice — approval in Cockpit workflow

Identity: centerId consistently refers to the UUID ShoppingCenter.id in Cockpit (not Google Place ID). Slug → UUID can be resolved via public API (see Public API — Process for centerId).


2. Existing System Components

Do not reinvent these building blocks — build upon them:

ComponentPurposeDocumentation / Artifact
AgencyOS Magic Link + API-KeyTrust establishment, organization or user scopeAgencyOS Integration
Read/create/assign CenterGET/POST/PATCH under /api/agencyos/v1/centers/…See AgencyOS documentation
Context for AIExisting: Shops, Services, News, Events, Offers, Categories/Chains (slim), optional include=floors_summary without mapSvg bodyGET …/centers/{id}/context
Write content (Upsert)Shops, Events, News, Offers, Services; idempotency via metadataPOST …/content/push
Preview without DB writeDry-run before live pushPOST …/content/push/preview
Public read APIWebsite/SSR: Data from Cockpit without sessionPublic Center-Website API
MCP Server (Stdio + Remote)Claude Desktop / Remote: all public reads + AgencyOS Context/Preview/Push; including Center Plan (cockpit_public_wayfinding_floorsGET /api/wayfinding/floors, including Hybrid-SVG with mapSvg + optionally mapImage/shopViewBoxes)packages/mcp-cockpit-os, packages/mcp-cockpit-remote
Workflow & Approvals (UI)Review drafts, approve, rejectWorkflow & Approvals
Machine-readableOpenAPI AgencyOS (including context with floors_summary) and public wayfinding read/openapi/agencyos-integration.yaml, /openapi/public-wayfinding-read.yaml

3. Two Usage Paths

3.1 Greenfield (new center / new site)

  1. User specifies organization, center name, desired slug, needed content types.
  2. AI checks: Does the center exist? (GET Centers / possibly slug resolution via public API)
  3. If necessary: Create or assign the center (only with appropriate rights — AgencyOS/Cockpit flows).
  4. Content validated stepwise via Push-Preview, then Push — or directly Push with monitoring.
  5. Website template / v0: centerId or Slug hardwired; data reference only via public endpoints + getDashboardApiUrl() / contract.

3.2 Brownfield (existing center)

  1. User specifies the center (slug or UUID).
  2. AI loads context (context?include=…), sees existing entities and Push-IDs.
  3. Changes: again PreviewPush; no duplicates thanks to idempotency rules in the push documentation.
  4. Website remains linked to the same centerId — only the content version changes.

4. Architecture Sketch (Target)

  • Writing / sensitive context: via AgencyOS (or later user-scoped tokens — roadmap).
  • Drafts for approval: via submitToWorkflow path → land in Workflow & Approvals, not directly live.
  • Delivery to visitors: via Public API (no secret in the browser).

5. Specific Use Case: “Offer for all Deichmann Centers"

This use case has been analyzed as an end-to-end test of the entire AI editorial workflow. It is representative of all multi-center campaigns.

Desired Process:

Editor → Claude: "Create an offer for Deichmann in all centers where Deichmann exists"

Claude finds all centers with a Deichmann branch

Claude generates offer text
Editor provides image URL (or uploads image to Cockpit beforehand)

Claude creates draft in Cockpit — separately for each center

Drafts appear in Workflow & Approvals (all visible at once)

Approver approves (individually or in bulk) → goes live immediately on all websites

What Works Today — and What Doesn't

StepCurrent StatusNote
Retrieve all centerscockpit_list_centers
Filter Deichmann centers⚠️ Possible, but N+1 callsPer center: cockpit_center_context?include=chains — for 50 centers 51 API calls
Generate offer textNative to Claude
Provide image❌ Only as URLFile upload not possible; image must be hosted beforehand
Create offer as draft⚠️ Directly in DBcontent/push writes immediately, no workflow item
Draft in Workflow & Approvals❌ Not linkedAgencyOS push does not appear in the workflow queue
Approval in Dashboard⚠️ UI exists, backend partially mockedWorkflow system not yet fully implemented
Bulk approval of multiple centers❌ Planned, not implementedBulk actions in Workflow & Approvals are still missing

Consequence: The workflow currently works with manual workarounds (upload image in advance, search for drafts manually in content list), but not as a seamless, secure editorial workflow for non-technical users.


6. Missing Components (Development Backlog)

The following features block or impair the idiot-proof AI editorial workflow. Prioritized by impact.


B1 — submitToWorkflow Mode in Content Push (Priority: High / Blocking)

Problem: POST /api/agencyos/v1/content/push writes directly to the database. Content goes live immediately (or as a draft without a queue entry). The Workflow & Approvals section does not see these items — editors and approvers cannot find them there.

Desired Behavior: A flag "submitToWorkflow": true in the push body (or a separate endpoint POST …/content/push/workflow-draft) should create a WorkflowItem record instead of a DB upsert:

  • source: "agencyos"
  • status: "pending"
  • All content fields (title, description, image, dates, …) as JSON in the WorkflowItem payload
  • centerId assigned
  • Optional: campaignId or campaignLabel (e.g., "Deichmann May Campaign") for bundled view
  • Upon approval: automatic conversion into a real content data record

Implementation (Proposal):

  • New optional body parameter submitToWorkflow: boolean in POST …/content/push
  • If true: no upsert logic, instead, create WorkflowItem with source: "agencyos", status: "pending"
  • Preview (/preview) remains as before (no DB write, no WorkflowItem)
  • MCP tool cockpit_content_push to include flag; alternatively, a new tool cockpit_submit_for_approval

Dependency: Requires B3 (Workflow system fully implemented).

Affected Files (Reference):

  • apps/dashboard/src/app/api/agencyos/v1/content/push/route.ts
  • apps/dashboard/src/lib/integration/process-center-entity-push.ts
  • packages/mcp-cockpit-os/src/register-cockpit-tools.ts

B2 — Filter Centers by Chain (Priority: Medium / Performance)

Problem: There is no endpoint to find all centers where a specific brand/chain is present. Today, Claude has to:

  1. Load all centers (GET /api/agencyos/v1/centers)
  2. Load context for each center with include=chains
  3. Manually filter

This amounts to N+1 API calls. For 50 centers: 51 requests, increased latency, more token usage, and greater error risk.

Desired Behavior:

GET /api/agencyos/v1/centers?chainSlug=deichmann
GET /api/agencyos/v1/centers?chainName=Deichmann

Or as a dedicated chain endpoint:

GET /api/agencyos/v1/chains?name=Deichmann
→ { id, name, slug, centers: [{ centerId, centerName, centerSlug }] }

Implementation (Proposal):

  • Optional chainSlug or chainName filter in GET /api/agencyos/v1/centers
  • Internally: Join ShoppingCenterShop/ShopLocationShopChain by name/slug
  • Same access check as existing center list (Org-Key vs. User-Key)
  • MCP tool cockpit_list_centers to extend with optional chainSlug/chainName parameters

Affected Files (Reference):

  • apps/dashboard/src/app/api/agencyos/v1/centers/route.ts
  • packages/mcp-cockpit-os/src/register-cockpit-tools.ts

B3 — Workflow & Approvals: Fully Implement Backend (Priority: High / Blocking)

Problem: According to the current documentation, several core functions of the workflow system are not yet production-ready:

FunctionStatus
Change Requests & Approval RequestsMock implementation, no real DB integration
User Session (who approved)Placeholder
Notifications / Audit TrailOnly logged, not persistent
Photo Upload in WorkflowIn progress
Bulk Actions (approve multiple items)Planned

What is needed:

  • WorkflowItem table with real database write operations
  • Fields: id, centerId, source (agencyos/ai-assistant/cms/manager-app), type (offer/news/event/job), status (pending/in_review/approved/rejected), payload (JSON, all content fields), campaignLabel (optional), submittedBy, approvedBy, approvedAt, rejectedReason, createdAt, updatedAt
  • Status transitions: pendingin_reviewapproved / rejected
  • Upon approved: automatic creation of the real content data record (Offer, News, Event, …) including image URL from payload
  • approvedBy with real user ID from NextAuth session
  • Bulk Approve: approve multiple items with one click — central for multi-center campaigns
  • Filter by campaignLabel — to allow approvers to see all items of a campaign at once
  • Email notification to the approver (or at least Dashboard notification for new items)

Especially important for multi-center campaigns: When Claude creates 8 offers for 8 Deichmann centers, these must be visible and approvable in bulk in the workflow.

Affected Files (Reference):

  • apps/dashboard/src/app/api/... (Workflow Route)
  • apps/dashboard/src/app/dashboard/workflow/... (UI)
  • Prisma Schema: new WorkflowItem table (additive, no DROP)

B4 — Image Upload via API / MCP (Priority: Medium)

Problem: The image field in offers, news, events expects a URL as string. Non-technical editors cannot provide Claude with an image — they would have to manually upload the image somewhere and copy the URL.

Short-term Workaround (Option A):

  • Editor uploads image to Cockpit media library or a linked CDN
  • Copies the public URL
  • Provides the URL to Claude as text: “Image: https://cdn.cockpit-os.de/…”
  • Claude sets the URL in the push body

This option should be documented as a Step-0 Process and incorporated into the editorial workflow as a mandatory step until Option B is fully implemented.

Long-term Solution (Option B):

New endpoint:

POST /api/agencyos/v1/media/upload
Content-Type: multipart/form-data
Authorization: Bearer <apiKey>

→ { "success": true, "data": { "url": "https://cdn.cockpit-os.de/media/…" } }
  • Register MCP tool cockpit_upload_media in the package
  • Claude can call this endpoint when the editor uploads an image in the chat (Base64 or file reference via Filesystem-MCP)

Affected Files (Reference):

  • New endpoint: apps/dashboard/src/app/api/agencyos/v1/media/upload/route.ts
  • packages/mcp-cockpit-os/src/register-cockpit-tools.ts

B5 — Batch Context for Multiple Centers (Priority: Low / Convenience)

Problem: For multi-center campaigns (e.g., "check all Deichmann offers"), Claude has to make a separate cockpit_center_context call for each center today. This burdens the context window and increases latency.

Desired Behavior:

POST /api/agencyos/v1/centers/batch-context
Body: { "centerIds": ["uuid-1", "uuid-2"], "include": "offers,chains" }
→ { "success": true, "data": { "uuid-1": { ... }, "uuid-2": { ... } } }

Or as MCP tool:

cockpit_multi_center_context({ centerIds: [...], include: "offers,chains" })

Affected Files (Reference):

  • New endpoint: apps/dashboard/src/app/api/agencyos/v1/centers/batch-context/route.ts
  • packages/mcp-cockpit-os/src/register-cockpit-tools.ts

7. Phased Roadmap (Updated)

PhaseContentBlocked byRisk
0 — completedConcept + Capabilities JSON + MCP Phase 1 (public reads + AgencyOS Context/Preview/Push)Documentation only
1 — next stepComplete the Workflow backend (B3): WorkflowItem table, status transitions, user session, bulk approve, campaignLabel filterDB migration additive; no schema drop
2submitToWorkflow flag in content push (B1) + MCP tool extensionB3 (Phase 1)No breaking changes; new optional parameter
3Chain filter endpoint (B2) + MCP updateOnly READ; no write risk
4Image upload Option A: document Cockpit media library URL workflow (B4)Only documentation + UI check
5Image upload Option B: POST …/media/upload + MCP tool (B4)New endpoint; additive
6Batch context endpoint + MCP (B5)Only READ; convenience
7Personal access tokens (User-Scope) parallel to Org-KeysDesign + migration soft

Prohibited in all phases: DROP statements, destructive migrations, changes to existing push semantics without versioning.


8. Target Workflow After Completing Backlog Items

When phases 1–4 are complete, the secure editorial workflow will look like this:

1. [Editor — optional, Step 0]
Upload image to Cockpit media library → copy URL

2. [Claude Chat]
"Create an offer for Deichmann, 20% off shoes,
valid May 1–14, image: https://cdn.cockpit-os.de/…
Please for all centers where Deichmann exists."

3. [Claude — automatically]
cockpit_list_centers → load all centers
Filter: Centers with chainSlug=deichmann (Phase 3 / B2)
Generate offer text
cockpit_content_push with submitToWorkflow: true
+ campaignLabel: "Deichmann May Campaign"
separately for each center — idempotency via agencyosPushId

4. [Cockpit Dashboard — Approver]
Workflow & Approvals → Filter "Deichmann May Campaign"
See all 8 drafts at once, image preview
Bulk approve with one click
→ Immediately live on all center websites

Security Properties of this Workflow:

  • No content goes live without human approval
  • Audit trail: who submitted what, when, who approved
  • Idempotency: duplicate push overwrites, does not create a duplicate
  • Rollback: rejected items remain as rejected, no data loss
  • No force mode; no direct DB access for editors
  • COCKPIT_ALLOW_CONTENT_PUSH remains as a safety switch for direct push (without workflow)

9. Checklist for Implementers

  • centerId = UUID from Cockpit; resolve slug via GET /api/centers/by-slug/{slug}.
  • Writing: always Preview (/push/preview) before direct push; in the editorial workflow submitToWorkflow: true.
  • Idempotency: agencyosPushId / externalId / Cockpit UUID according to AgencyOS documentation.
  • Website: only public URLs from Public API; no dashboard session in the client.
  • WorkflowItem upon approval: create a real content data record with source: "agencyos" and set WorkflowItem to approved.
  • Bulk Approve: all items of a campaign (same campaignLabel) should be approvable together.
  • After API extension: include cockpit-api-capabilities.json and possibly OpenAPI.

Nutzungsstatistik: Seitenaufrufe werden anonymisiert erfasst. Im Umami-Dashboard nach diesem Pfad filtern: /en/developer-guide/ki-website-builder-cockpit-sync-konzept