Skip to content

feat: documentation site served at /docs (co-located in web/docs) - #88

Merged
fclairamb merged 84 commits into
mainfrom
batch/2026-06-20
Jun 22, 2026
Merged

fclairamb merged 84 commits into
mainfrom
batch/2026-06-20

Conversation

@fclairamb

Copy link
Copy Markdown
Owner

Co-locates the docs in this repo (web/docs/, Docusaurus) and serves them from the binary at the /docs path on every host (like /dash0, /status0), so solidping.io/docs works with no extra infra. docs.solidping.io redirects into /docs (server.docs_host).

Highlights

  • web/docs/: Docusaurus 3.10.1; API reference generated at build from server/internal/app/openapi/openapi.yaml (can't drift).
  • Go: //go:embed all:docsres + /docs routes + docs-host redirect; Swagger explorer moved /docs → /openapi.
  • Makefile / CI / Dockerfile: docs build + embed wiring.
  • Rename internal wiki docs/ → wiki/ (ends the docs/ vs web/docs/ collision).
  • deploy/docs-ingress.yaml: optional ingress template for the docs.solidping.io subdomain.

Marketing site moved to the solidping-website repo (PRs #2, #3 there). Implements specs/done/2026/06/2026-06-22-01-docs-site-from-code-repo.md.

🤖 Generated with Claude Code

fclairamb and others added 30 commits June 20, 2026 02:01
Specs for the genuine feature gaps surfaced by docs/competitors/maintenant.md,
grounded in the current code:

- todos/2026-06-20-01 SSL graduated expiry (warning/critical tiers) +
  whole-chain nearest-expiry & chain reporting
- todos/2026-06-20-02 Docker restart-loop (crash-loop) detection
- todos/2026-06-20-03 OAuth 2.1 authorization for the MCP endpoint
- todos/2026-06-20-04 first-class StatusWarning (degraded-but-up) status —
  enabler that 01 and 02 depend on
- ideas/2026-06-20-config-as-code declarative checks + Docker-label discovery

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Code-verified every claim in 2026-06-20-04 against the tree and folded in
corrections:

- checkerdef.Status has no Created (starts Running=2)
- new finding: aggregation rollup tie-break (calculateDominantStatus) ranks by
  raw status number, so Warning=7 would mask outages — add Severity() helper +
  severity-aware tie-break (Decision D)
- frontend wire string is split between "warning" and "degraded"; standardise on
  "degraded" + one shared statusStyle() util (Decision C); per-file table, plus
  two previously-missed components (status-timeline, check-summary-cards)
- incident classifier early-returns before the visible-status update; warning
  needs a third path modelled on the display-only CheckStatusValidating
- slack statusIntToString currently maps warning to "unknown"

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…odel

Spec 04 reshaped per user answers to the open questions:

- two statuses: Warning (live, value 8, "up but something to report") +
  Degraded (aggregated, value 7); aggregation promotes raw Warning -> rolled-up
  Degraded
- availability: warning counts as up; incidents: warning neutral
- constraint: amend 001 in place, widen results.status to (0..8) incl. the
  previously-missing 6 (error)
- frontend: one shared statusStyle() util mapping both "warning" and "degraded"
- record follow-on sub-decisions (values 7/8, rollup promotion rule, role of
  CheckStatusDegraded) and the five status->string sites found in review

Specs 01 (SSL) and 02 (restart-loop) realigned: a live warning shows current
status Warning; Degraded appears only in rolled-up history.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Resolve open questions in the 2026-06-20 todos and align ideas with the
new Warning/Degraded status model.

- ssl (-01): warningDays defaults to criticalDays (30); criticalDays stays
  30 (docs recommend 7); checkdomain tiering is a follow-up.
- docker (-02): Approach A heuristic MVP; loop => StatusWarning;
  minRestarts=3/window=120s; firm dependency on -04.
- mcp-oauth (-03): embedded AS + DCR in scope (Phase 3); 4 unrecommended
  forks kept as explicit open questions with leanings.
- ideas: flag stale enum/warn_days in check-interface as superseded; note
  Warning is incident-neutral in notification-channels & telegram specs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
fclairamb and others added 24 commits June 20, 2026 04:36
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…in gating

- Reconcile/plan engine (create/update/delete/unmanaged/rename) scoped by the
  reserved solidping.io/managed=<manifest> label
- ApplyChecks service: dryRun (plan only), prune+managed-label+deletion-cap
  delete-by-absence, never touches unmanaged checks
- Secret references ${env:NAME}/${param:KEY} resolved server-side; missing ref
  is a hard error; plaintext-fallback emits a warning
- POST /checks/apply endpoint accepting JSON and YAML bodies
- Admin-gate apply, and retro-gate /checks/export + /checks/import to admin-only
- sp apply [-f] <manifest> [--dry-run] [--prune] [--force] [--yes]: computes a
  dry-run plan first, prints it, prompts before mutating unless --yes
- sp checks export [--file] and sp checks import <file> [--dry-run] wrappers
- client methods ApplyChecks/ExportChecks/ImportChecks (raw HTTP; apply sends
  the manifest bytes with a YAML/JSON content-type)
Reframe the config-as-code idea around what SolidPing already ships
(export schema, idempotent upsert-by-slug import, sp CLI, secret
envelope + parameters table, check labels). The gap narrows to the
reconcile loop: delete-by-absence within a managed-label scope,
dry-run/diff, secret references (${env}/${param}), an sp apply verb,
and admin-gating. Resolves the five open questions against the code and
phases the work; demotes Docker-label discovery to an optional suggest
source.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Move specs/ideas/2026-06-20-config-as-code.md to
specs/todos/2026-06-20-05-config-as-code.md (NN=05, next free for the
day). Update the banner from "idea" to active spec and fix the sibling
links to the ideas/ folder that the move would otherwise break.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds table-driven coverage for the apply reconcile engine and resolves
pre-existing lint findings in the apply/CLI/client code from the prior
implementation commits.

Tests:
- plan computation (create/update/delete/unmanaged), dryRun mutates nothing
- delete-by-absence only with prune+managed-label+within-cap; cap refuses
  oversized prune (force overrides); unmanaged checks never touched
- secret-ref resolution (${env}/${param}, missing -> error, plaintext
  fallback -> warning); rename via previousSlug
- JSON and YAML bodies parse to the same plan (internal + HTTP)
- export->apply round-trip idempotence (apply of an export is no-op/update)
- admin-only gating on apply AND export/import (non-admin -> 403)

Lint: queryTrue/colSlug constants, checked json marshals, dropped unused
nolint directives and the unused rawRequestBytes status return.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The new "header stacks the action toolbar" test asserted no horizontal
overflow on the whole document (documentElement.scrollWidth), which is
tripped by unrelated page content (a chart that sizes differently in
headless CI) rather than the header it is testing — failing all 3 CI
attempts though it passes locally. Add a data-testid to the header
container and scope the overflow check to that element. The header
(flex-col title row + flex-wrap toolbar + truncating h1) cannot overflow
its own width, and this still catches a real header regression.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…research

Re-research Maintenant against primary sources (official site, docs, GitHub, IT-Connect, LinuxFr) and correct the earlier single-source writeup: ~17 MB RAM, no built-in auth, Community/Pro/Enterprise open-core, container-observability focus. Sync the comparison.md analogue line to match.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Container discovery enumerates containers on configured Docker-compatible endpoints and suggests checks through the existing discovered_hosts/promote flow; kubernetes discovery builds on it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Move the Docusaurus docs out of solidping-website into web/docs/, embed and serve from the Go binary like dash0/status0, and generate the API reference from the canonical openapi.yaml. Marketing site stays on www.solidping.io.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…nary

Implements specs/todos/2026-06-22-01-docs-site-from-code-repo.md.

- web/docs/: Docusaurus 3.10.1 docs site moved from solidping-website, docs-only
  at the host root. API reference generated at build time from
  server/internal/app/openapi/openapi.yaml (no drift). webpack pinned to 5.104.1.
- server: //go:embed all:docsres + Host-routed serving (serveDocsFile, MPA path
  resolution) for server.docs_host (default docs.solidping.io / SP_DOCS_HOST).
- Makefile: build-docs/copy-docs/dev-docs + build chain + sync-brand-assets.
- CI + Dockerfile: docs build stage, docsres placeholder + artifact wiring.
- Rename internal wiki docs/ -> wiki/ to end the docs/ vs web/docs/ collision.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Switch from host-root serving to the /docs path (baseUrl /docs/), consistent with /dash0 and /status0, so docs serve on the existing domain (solidping.io/docs) with no new DNS/ingress. docs.solidping.io now redirects its root into /docs (server.docs_host). The interactive OpenAPI (Swagger) explorer moved from /docs to /openapi.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Optional — docs already serve at solidping.io/docs. Apply only to enable the docs.solidping.io subdomain (fill the cluster-specific TODOs first).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
TestHTTPChecker_Execute_ExpectedStatusCodes hits a local httptest server; under heavy parallel CI load a transient dial error was occasionally read as a status mismatch (status=down, want up). Retry the call a few times — the server always responds, and a genuinely wrong status stays wrong across attempts and still fails. Root-caused (passes 30x locally), not re-run.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@fclairamb
fclairamb merged commit 27d9ccd into main Jun 22, 2026
11 checks passed
@fclairamb
fclairamb deleted the batch/2026-06-20 branch June 22, 2026 23:27
@fclairamb fclairamb mentioned this pull request Jun 21, 2026
fclairamb added a commit that referenced this pull request Jun 23, 2026
🤖 I have created a release *beep* *boop*
---


##
[0.1.0](v0.0.0...v0.1.0)
(2026-06-22)


### Features

* add check type registry, sample configs, notification senders, and
observability integrations
([eea049e](eea049e))
* batch — Warning/Degraded statuses, SSL/Docker check upgrades, MCP
OAuth 2.1, config-as-code
([#85](#85))
([936d830](936d830))
* batch spec implementations (dashboard UI, jobs, notifications, SaaS,
perf) ([#78](#78))
([fe003e4](fe003e4))
* bulk feature integration (discovery, web push, badges, webhooks, and
more) ([#73](#73))
([a976856](a976856))
* custom user-agent, refresh checks, vite plugin switch, CI updates
([#1](#1))
([cc00858](cc00858))
* documentation site served at /docs (co-located in web/docs)
([#88](#88))
([27d9ccd](27d9ccd))
* email check frontend (spec 03)
([#30](#30))
([aebd106](aebd106))
* email inbox foundation via JMAP (spec 01)
([#24](#24))
([0f3b0c1](0f3b0c1))
* email passive checks (spec 02)
([#27](#27))
([ba5536f](ba5536f))
* **entitlements:** trim to MaxSSOUsers + MaxChecksPerMinute + status
page history fixes
([#50](#50))
([a007de0](a007de0))
* **entitlements:** trim to MaxSSOUsers + MaxChecksPerMinute, enforce
both ([#49](#49))
([d25cc5f](d25cc5f))
* group incident correlation (spec 04 backend v1)
([#31](#31))
([1883986](1883986))
* **observability:** instrument hot path + add bench harness
([#60](#60))
([c6604cc](c6604cc))
* **oncall:** searchable timezone dropdown + sidebar logo polish
([#46](#46))
([4396898](4396898))
* per-IP HTTP rate limiting and concurrency limiting
([#59](#59))
([f9cc273](f9cc273))
* soften HTTP rate limits with bounded queues + request timeout
([#63](#63))
([025501b](025501b))
* SolidPing — distributed uptime monitoring platform
([eef4383](eef4383))
* **statuspages:** drag-and-drop resource reordering + dash conventions
([#41](#41))
([cf910d4](cf910d4))


### Bug Fixes

* **deps:** update dependency i18next to v26
([#26](#26))
([d5d1b7e](d5d1b7e))
* **deps:** update dependency lucide-react to v1
([#28](#28))
([cdc8e8c](cdc8e8c))
* **deps:** update dependency react-i18next to v17
([#29](#29))
([13135d8](13135d8))
* **deps:** update dependency recharts to v3.8.1
([#14](#14))
([5d95a3b](5d95a3b))
* **deps:** update go dependencies (non-major)
([#16](#16))
([2450f13](2450f13))
* **deps:** update go dependencies (non-major)
([#19](#19))
([f842310](f842310))
* **deps:** update go dependencies (non-major)
([#37](#37))
([c020eca](c020eca))
* **deps:** update go dependencies (non-major)
([#44](#44))
([ff0bcd0](ff0bcd0))
* **deps:** update go dependencies (non-major)
([#52](#52))
([2e3bc28](2e3bc28))
* **deps:** update go dependencies (non-major)
([#69](#69))
([a65ed4c](a65ed4c))
* **deps:** update go dependencies (non-major)
([#77](#77))
([a0920ff](a0920ff))
* **deps:** update go dependencies (non-major) to v1.4.2
([#86](#86))
([1eb7504](1eb7504))
* **deps:** update module github.com/aws/aws-sdk-go-v2/config to
v1.32.18 ([#72](#72))
([6406537](6406537))
* **deps:** update module github.com/aws/aws-sdk-go-v2/service/s3 to
v1.101.0 ([#39](#39))
([f9c9563](f9c9563))
* **deps:** update module github.com/go-webauthn/webauthn to v0.17.3
([#45](#45))
([593931a](593931a))
* **deps:** update module github.com/go-webauthn/webauthn to v0.17.4
([#70](#70))
([fca1c97](fca1c97))
* **deps:** update module github.com/ibm/sarama to v1.48.1
([#47](#47))
([93ccf3a](93ccf3a))
* **deps:** update module github.com/ibm/sarama to v1.48.2
([#54](#54))
([e84d868](e84d868))
* **deps:** update module github.com/ibm/sarama to v1.49.0
([#64](#64))
([fd61bd7](fd61bd7))
* **deps:** update module github.com/oapi-codegen/runtime to v1.4.1
([#65](#65))
([a3a3e9f](a3a3e9f))
* **deps:** update module github.com/prometheus/common to v0.67.5
([#61](#61))
([095dd6f](095dd6f))
* **deps:** update module github.com/slack-go/slack to v0.24.0
([#75](#75))
([6e86d5b](6e86d5b))
* **deps:** update module golang.org/x/sys to v0.44.0
([#42](#42))
([a245730](a245730))
* **deps:** update module golang.org/x/sys to v0.45.0
([#67](#67))
([49c3d90](49c3d90))
* **deps:** update module golang.org/x/term to v0.43.0
([#43](#43))
([4a934f1](4a934f1))
* **deps:** update module google.golang.org/grpc to v1.81.0
([#36](#36))
([1be183a](1be183a))
* **deps:** update module google.golang.org/grpc to v1.81.1
([#55](#55))
([6bfac2d](6bfac2d))
* status lifecycle improvements and created/running result handling
([#5](#5))
([fc64c7d](fc64c7d))
* **status0:** white page header and de-duplicated footer
([#48](#48))
([77506a7](77506a7))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).
This was referenced Sep 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant