platform69 ops

Platform API

Cross-cutting operations that don't fit a single domain.

Queries

QUERY

adminBlogPost

#

Single post by id, any status.

Arguments

  • tenantIdID
  • idID!
Returns
QUERY

adminBlogPostRevisions

#

Revision history for a post, newest first.

Arguments

  • tenantIdID
  • postIdID!
Returns[!]!
QUERY

adminBlogPosts

#

Admin listing of posts in one tenant with optional filters. All filters AND together. searchQuery matches title and slug case-insensitively (ILIKE).

Arguments

  • tenantIdID
  • status
  • authorIdID
  • categoryIdID
  • searchQueryString
  • pagination
Returns!
QUERY

adminBlogTags

#

Tags for the admin picker.

Arguments

  • tenantIdID
Returns[!]!
QUERY

canManageChangelog

#

Sanity check that the active session can author entries. Used by the admin drafting screens to render the "Save" button.

ReturnsBoolean!
QUERY

changelogEntries

#

All changelog entries (drafts + published + archived). Default order is most-recently-updated first.

Arguments

  • status
  • pagination
Returns!
QUERY

changelogEntry

#

Single entry by ID (any status).

Arguments

  • idID!
Returns
QUERY

changelogEntryRevisions

#

Revision history for one entry, newest first.

Arguments

  • entryIdID!
Returns[!]!
QUERY

dataSyncPlan

#

Build a MigrationPlan for a source — read-only projection of what runDataSyncSource would do given the current config. Surfaced before the "Run sync now" button so the operator can review the per-phase row + blob projections, missing required answers, and warnings.

Arguments

  • sourceId!
Returns!
QUERY

dataSyncRun

#

One run by id (with full coverage report when completed).

Arguments

  • id!
Returns
QUERY

dataSyncRuns

#

Recent runs for a source. Standard offset pagination via the kernel's PaginationInput; clients send limit + page (or an after cursor); response carries the standard pageInfo.

Arguments

  • sourceId!
  • pagination
Returns!
QUERY

dataSyncSource

#

One data-sync source by id (must belong to the calling tenant).

Arguments

  • id!
Returns
QUERY

dataSyncSources

#

Data-sync sources configured for the calling tenant. Standard offset pagination via the kernel's PaginationInput. Requires tenant_admin or higher.

Arguments

  • pagination
Returns!
QUERY

discoverDataSyncSource

#

Run discovery against a source — returns the open admin questions plus estimated row counts. Read-only on the source DB.

Arguments

  • sourceId!
Returns!
QUERY

health

#
ReturnsString!
QUERY

publicBlogTags

#

All tags for the system tenant.

Returns[!]!
QUERY

publishedBlogPostBySlug

#

Single published post by slug. Returns null for missing or non-public posts — drafts must never leak through this resolver.

Arguments

  • slugString!
Returns
QUERY

publishedBlogPosts

#

Reverse-chronological feed of published posts. Optional category filter (by slug). The website caches the response via Next.js ISR.

Arguments

  • categorySlugString
  • pagination
Returns!
QUERY

publishedChangelogEntries

#

Reverse-chronological feed of published entries. Optional product filter. The website caches the response via Next.js ISR (revalidate = 60).

Arguments

  • product
  • pagination
Returns!
QUERY

publishedChangelogEntryBySlug

#

Single published entry by slug. Returns null for missing or non-public entries — drafts must never leak through this resolver.

Arguments

  • slugString!
Returns
QUERY

recentGithubReleases

#

Recent releases for one source. Drafting screen calls this once the admin picks a source from the dropdown.

Arguments

  • sourceIdID!
  • limitInt!

    Default

    20
Returns[!]!
QUERY

releaseArtifact

#

Single artifact by key. Returns null if no artifact uses that key — UI surfaces "unknown artifact" rather than erroring.

Arguments

  • keyString!
Returns
QUERY

releaseArtifactInFlightDispatch

#

The single in-flight dispatch (pending or in_progress) for this artifact, if any. Returns null when the artifact has no active release. The UI uses this to disable the "Cut release" button while a release is queued.

Arguments

  • artifactKeyString!
Returns
QUERY

releaseArtifactRecentDispatches

#

Recent dispatches for a single artifact. Used by the per-artifact detail screen to show the last N releases.

Arguments

  • artifactKeyString!
  • firstInt
Returns[!]!
QUERY

releaseArtifacts

#

Every artifact known to Release Hub, in the order they appear in release_artifacts.toml. Cards on the dashboard are rendered directly from this list.

Returns[!]!
QUERY

releaseDispatch

#

Single dispatch by id. The dispatch detail / live status page polls this endpoint while a run is in progress.

Arguments

  • idID!
Returns
QUERY

releaseDispatches

#

Cross-artifact dispatch listing. Powers the global "Dispatch activity" tab on the admin shell.

Arguments

  • status
  • pagination
Returns!
QUERY

releaseDraftingPromptActive

#

Active drafting prompt revision (prompt_name = release_notes_drafting). Returns null when no admin has saved one yet — the use case falls back to the shipped default.

Returns
QUERY

releaseDraftingPromptRevisions

#

All revisions for the drafting prompt, newest first. Powers the revision history view in admin settings.

Returns[!]!
QUERY

releaseSources

#

All configured GitHub sources — populates the drafting picker and the settings list.

Returns[!]!
QUERY

serverInfo

#
Returns!
QUERY

tenantExportDestination

#

Single destination by id. Authorization: caller must satisfy resolve_target_tenant against the destination's tenant.

Arguments

  • id!
Returns
QUERY

tenantExportDestinations

#

List destinations for the caller's tenant (tenant-owner) or for the supplied tenant_id (PlatformAdmin only).

Arguments

  • tenantId
Returns[!]!
QUERY

tenantExportRun

#

Arguments

  • id!
Returns
QUERY

tenantExportRuns

#

Arguments

  • tenantId
  • limitInt!

    Default

    50
Returns[!]!

Mutations

MUTATION

activateReleaseDraftingPrompt

#

Arguments

  • idID!
ReturnsBoolean!
MUTATION

archiveBlogPost

#

Arguments

  • tenantIdID
  • idID!
Returns!
MUTATION

archiveChangelogEntry

#

Archive an entry — hidden from the public feed and the default admin list. Revisions stay intact.

Arguments

  • idID!
Returns!
MUTATION

cancelDataSyncRun

#

Mark a queued or running sync run as cancelled. The background task notices the status change between phase commits and bails out at the next checkpoint. Idempotent on already-terminal runs (returns the run as-is).

Arguments

  • runId!
Returns!
MUTATION

createDataSyncSource

#

Provision a new data-sync source for the calling tenant. Requires tenant_owner. Secrets are AES-GCM encrypted at rest; they're never returned over GraphQL afterwards.

Arguments

  • input!
Returns!
MUTATION

createTenantExportDestination

#

Create a destination. tenant_id in the input is honored only when the caller is PlatformAdmin.

Arguments

  • input!
Returns!
MUTATION

deleteDataSyncSource

#

Delete a source. Cascades to its data_sync_runs rows. When purgeMappings = true (default false), also wipes every data_sync_mappings row that this source's provider produced for the tenant — a clean disconnect that lets a re-imported source mint fresh UUIDs without bumping into the old mapping table. The BetterSuite rows themselves stay intact.

Arguments

  • id!
  • purgeMappingsBoolean!

    Default

    false
ReturnsBoolean!
MUTATION

deleteReleaseSource

#

Arguments

  • idID!
ReturnsBoolean!
MUTATION

deleteTenantExportDestination

#

Arguments

  • id!
ReturnsBoolean!
MUTATION

dispatchRelease

#

Cut a release for the given artifact. Persists a dispatch row (which acquires the artifact's in-flight slot via a DB unique index), POSTs workflow_dispatch to GitHub Actions, writes a ReleaseDispatched audit row. The returned ReleaseDispatch starts in status pending; the reconciler worker updates it to in_progress once GitHub surfaces the run id, then to a terminal status. Errors: * ArtifactNotFound — unknown artifactKey * InvalidDispatchInputs — typed-confirm mismatch, unknown input name, missing required input, invalid choice * DispatchInFlight — another dispatch for this artifact is still pending or in_progress * RateLimited — recent successful dispatch is inside the cooldown window (5 min by default) * GithubApiworkflow_dispatch POST failed upstream

Arguments

  • input!
Returns!
MUTATION

draftChangelogEntry

#

Arguments

  • input!
Returns!
MUTATION

fetchDataSyncSourceRemoteEnvFile

#

Read a .env-shaped file from the legacy backend host via the source's already-saved SSH tunnel credentials. The raw contents are returned to the client, which parses them with the same routine the "paste .env" textarea uses. Requires connection_mode = ssh_tunnel and saved SSH secrets.

Arguments

  • sourceId!
  • remotePathString!
ReturnsString!
MUTATION

publishBlogPost

#

Arguments

  • tenantIdID
  • idID!
Returns!
MUTATION

publishChangelogEntry

#

Promote a draft to published (or republish an archived entry). Idempotent.

Arguments

  • idID!
Returns!
MUTATION

queueTenantExportRun

#

Queue an export run. v1 only the planning phase (dry_run = true) produces real output; non-dry runs land on the run row as failed with a "not implemented yet" message until the COPY+SSH pipeline is wired.

Arguments

  • input!
Returns!
MUTATION

refineChangelogEntry

#

Arguments

  • input!
Returns!
MUTATION

retryDataSyncRun

#

Re-trigger a sync against the source of a previous (typically failed) run. Mints a fresh run row — the original is left intact for audit. Convenience over runDataSyncSource(sourceId) so the UI's Retry button doesn't have to look up the source id client-side.

Arguments

  • runId!
Returns!
MUTATION

runDataSyncSource

#

Trigger a sync run. Mutation returns immediately with a SyncRun in queued status; the worker picks it up and transitions through runningcompleted / failed. Clients poll (or subscribe via the realtime service) for progress.

Arguments

  • sourceId!
  • dryRunBoolean!

    Default

    false
Returns!
MUTATION

saveBlogPost

#

Arguments

  • input!
Returns!
MUTATION

saveBlogTag

#

Arguments

  • input!
Returns!
MUTATION

saveChangelogEntry

#

Create-or-update a changelog entry. New entries are inserted as drafts; promote with publishChangelogEntry. Every call appends a new revision row.

Arguments

  • input!
Returns!
MUTATION

saveReleaseDraftingPrompt

#

Arguments

  • input!
Returns!
MUTATION

scheduleBlogPost

#

Arguments

  • tenantIdID
  • idID!
  • publishAt!
Returns!
MUTATION

setDataSyncSourceLegacyEnv

#

Persist the parsed .env of the legacy app on the source row. Server parses the raw blob (so the canonical key set stays defined in Rust), stores it under data_sync_sources.legacy_env_import. The provider config resolves layered against this — operator answers win, otherwise env-derived defaults flow through, otherwise compiled defaults. Re-importing replaces the column without touching config, so explicit operator overrides survive.

Arguments

  • sourceId!
  • envContentsString!
Returns!
MUTATION

tenantExportRunDownloadUrl

#

Mint a short-lived download URL for a successful tarball-mode run's artifact. The URL points at the platform's /api/tenant-export/runs/:id/artifact route, which validates the embedded token and streams the .tar.gz. Re-minting rotates the token; any previous URL stops working. ttl_seconds is bounded between 60s and 7 days; default is download_token_default_ttl from AppState (24h out of the box).

Arguments

  • runId!
  • ttlSecondsInt
Returns!
MUTATION

testDataSyncSourceConnection

#

Validate a source's connection without saving anything. The admin can hit this from the Configure page before committing credentials. Read-only on the source DB; nothing is written to the target.

Arguments

  • input!
Returns!
MUTATION

testDataSyncSourceSshTunnel

#

Validate just the SSH layer — open the bastion session, capture the host-key fingerprint, disconnect. No MySQL connection is attempted. Returns success + the discovered fingerprint so the operator can sanity-check the bastion auth before saving credentials or running a full discovery.

Arguments

  • input!
Returns!
MUTATION

testTenantExportDestination

#

Dial the destination without queueing a run. Returns { ok, message, capturedSshFingerprint? }. For database destinations we open the SSH bastion tunnel (if configured) and run SELECT 1 against the target. For tarball destinations we touch the exports directory to confirm it's writable. When the SSH bastion's host key is captured for the first time, the fingerprint is BOTH persisted into the destination's config (so subsequent runs validate it) AND returned in the response so the UI can show it to the operator for explicit confirmation.

Arguments

  • id!
Returns!
MUTATION

unpublishBlogPost

#

Arguments

  • tenantIdID
  • idID!
Returns!
MUTATION

unpublishChangelogEntry

#

Flip a published entry back to draft. The original published_at is preserved so republishing keeps the same feed position.

Arguments

  • idID!
Returns!
MUTATION

updateDataSyncSource

#

Update a source's config and (optionally) its stored secrets. Requires tenant_owner.

Arguments

  • input!
Returns!
MUTATION

updateTenantExportDestination

#

Sparse update. The destination's tenant_id is fixed and not editable; transferring ownership isn't supported.

Arguments

  • input!
Returns!
MUTATION

upsertReleaseSource

#

Arguments

  • input!
Returns!

Subscriptions

SUBSCRIPTION

adminEvents

#

Subscribe to admin events Receive ALL real-time events across the platform for monitoring purposes. **Requirements:** - Must be authenticated - Must have admin role (PlatformAdmin, TenantAdmin, or PartnerAdmin)

Returns!