Skip to content

docs: 9 feature how-to guides plus exhaustive CLI and API reference - #446

Merged
thegdsks merged 1 commit into
mainfrom
docs/feature-guides-and-reference
Sep 14, 2026
Merged

docs: 9 feature how-to guides plus exhaustive CLI and API reference#446
thegdsks merged 1 commit into
mainfrom
docs/feature-guides-and-reference

Conversation

@thegdsks

@thegdsks thegdsks commented Sep 14, 2026

Copy link
Copy Markdown
Member

Summary

Documentation for what the platform actually provides at the page, feature, API, and CLI level, written by parallel agents and verified against real source (not guessed), per the docs/README.md Diataxis index protocol.

9 new how-to guides: deploying-apps, managing-databases, observability, multi-node, projects-and-organizations, identity-and-access, git-integrations, backups-and-storage, templates-and-registry. Each covers its feature domain holistically: what it does, the dashboard page(s), the real API endpoints, and the real CLI commands, in the same style as the existing feature-flags.md.

2 new reference docs: cli-reference.md (every CLI command's real usage syntax, extracted from source) and api-reference.md (all 290 registered routes with method/path/ability/handler).

Wired into docs/README.md's index and the VitePress sidebar nav.

Fixed along the way

  • A stale doc comment on handleDeleteApp claiming it doesn't stop the running container, contradicted by its own next lines.
  • Two ability-string typos (read_sensitiveread:sensitive, underscore vs. colon).
  • A missing --since alias in the nodes metrics usage line.
  • Several Markdown formatting bugs (multi-line inline-code spans wrapping a <placeholder>) that broke the VitePress build. Verified by actually running vitepress build clean, not just eyeballing the diff.
  • docs/feature-catalog.md's route count corrected from a stale 271 to the actual 290.

What this doesn't do

  • No request/response body documentation in api-reference.md (route table only; documenting every handler's body shape in depth is separate work).
  • No OpenAPI/Swagger spec generation.

Verification

  • npx vitepress build . — clean, no dead links.
  • go build ./... — clean (one Go doc-comment fix included).
  • Em-dash/en-dash sweep across all new/changed files — none found.

Summary by CodeRabbit

  • Documentation
    • Added comprehensive how-to guides for deploying apps, managing databases, observability, multi-node setups, projects, identity and access, Git integrations, backups, storage, templates, and registries.
    • Added new CLI and API reference documentation covering available commands, endpoints, permissions, and workflows.
    • Updated documentation navigation and indexes to make the new guides easier to discover.
    • Expanded the feature catalog with a link to the complete API route reference.

Written by parallel agents (9 feature-domain guides, 2 exhaustive
reference docs on a cheaper model for the mechanical extraction work),
every command/endpoint/flag verified against actual source rather than
guessed, then wired into docs/README.md's index and the VitePress
sidebar nav.

New how-to guides (Diataxis "how do I do X"):
- deploying-apps.md: the four ways to deploy, lifecycle actions, health
  checks, resource limits, exec, scheduled tasks
- managing-databases.md: engines, backups/restore/verification, TLS,
  public access, app attachment
- observability.md: metrics, logs, alerts, notification channels, the
  resource-usage dashboard ranking
- multi-node.md: enrollment, WireGuard mesh, cordon/drain, placement
- projects-and-organizations.md: grouping hierarchy, shared env
  layering, pause/resume, bulk restart, protected environments
- identity-and-access.md: auth, 2FA, tokens, roles vs IAM policies,
  invites, audit log
- git-integrations.md: GitHub/GitLab/Bitbucket Apps, webhooks, preview
  environments
- backups-and-storage.md: backup targets, registry credentials, app
  volume backups
- templates-and-registry.md: the service template catalog, static site
  detection

New reference docs:
- cli-reference.md: every command in every group, real usage syntax
  extracted from each command's own Usage string in source
- api-reference.md: every one of the 290 registered routes (not the
  271 docs/feature-catalog.md previously claimed, now corrected), with
  method/path/ability/handler

Fixed along the way:
- A stale doc comment on handleDeleteApp claiming it "does not itself
  stop the running container," contradicted by the very next lines of
  its own function (it calls teardownServiceContainers).
- Two ability-string typos in git-integrations.md (read_sensitive/
  write_sensitive with an underscore; the real constants use a colon).
- A missing --since alias in multi-node.md's nodes metrics usage line.
- Several multi-line inline-code spans wrapping a `<placeholder>` across
  a line break, which VitePress's Vue-based Markdown compiler parses as
  an unclosed HTML tag and fails the build on. Verified by actually
  running `vitepress build` clean before this commit, not just eyeballing
  the diff.

What this doesn't do: no request/response body documentation in
api-reference.md (route table only, verifying every handler's body
shape in depth is separate work); no OpenAPI/Swagger spec generation.
@thegdsks
thegdsks merged commit f367275 into main Sep 14, 2026
8 of 9 checks passed
@github-actions github-actions Bot added size/XXL area/api internal/api type/docs Documentation only labels Sep 14, 2026
@coderabbitai

coderabbitai Bot commented Sep 14, 2026

Copy link
Copy Markdown

Review Change StackReview Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: bc671b44-50e9-4e19-ae1a-7e87a61a67d2

📥 Commits

Reviewing files that changed from the base of the PR and between 0ca5899 and f155868.

📒 Files selected for processing (15)
  • docs/.vitepress/config.mts
  • docs/README.md
  • docs/api-reference.md
  • docs/backups-and-storage.md
  • docs/cli-reference.md
  • docs/deploying-apps.md
  • docs/feature-catalog.md
  • docs/git-integrations.md
  • docs/identity-and-access.md
  • docs/managing-databases.md
  • docs/multi-node.md
  • docs/observability.md
  • docs/projects-and-organizations.md
  • docs/templates-and-registry.md
  • internal/api/apps.go

📝 Walkthrough

Walkthrough

The pull request adds nine how-to guides, API and CLI references, navigation links, and expanded documentation for applications, databases, infrastructure, access control, integrations, observability, backups, and templates. It also updates the route count and one API handler comment.

Changes

Documentation navigation and references

Layer / File(s) Summary
Navigation and catalog links
docs/.vitepress/config.mts, docs/README.md, docs/feature-catalog.md
Adds sidebar and index entries for the new guides and references. Updates the documented route count from 271 to 290.
API and CLI references
docs/api-reference.md, docs/cli-reference.md
Adds a grouped inventory of 272 HTTP routes and documents CLI commands across the supported command groups.

Platform guides

Layer / File(s) Summary
Application delivery and integrations
docs/deploying-apps.md, docs/git-integrations.md, docs/templates-and-registry.md, internal/api/apps.go
Documents app lifecycle operations, Git provider flows, webhooks, previews, templates, static sites, and the updated handleDeleteApp comment.
Database and backup operations
docs/managing-databases.md, docs/backups-and-storage.md
Documents managed database lifecycle, database backups and restores, backup targets, registry credentials, scheduling, retention, and the built-in registry.
Infrastructure and observability
docs/multi-node.md, docs/observability.md
Documents node enrollment, health, placement, draining, telemetry, logs, alerts, notification channels, and current implementation gaps.
Access and organization
docs/identity-and-access.md, docs/projects-and-organizations.md
Documents authentication, authorization, IAM, audit logging, organizations, projects, environments, shared variables, and protected actions.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Other

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/feature-guides-and-reference

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@sonarqubecloud

Copy link
Copy Markdown

@greptile-apps

greptile-apps Bot commented Sep 14, 2026

Copy link
Copy Markdown

RetriggerConfidence Score: 2/5

The PR should not merge until the overprivileged IAM walkthrough and unsupported remote-node telemetry claims are corrected.

Findings

  1. P1 Security Token is globally privileged
  2. P1 Remote telemetry is unavailable
  3. P2 Magic variables are resolved
  4. P2 Re-enable rotates the password
  5. P2 App deletion comparison is false
  6. P2 Route total is stale
  7. P2 Commands are duplicated

Summary

  • Documents deployment, databases, observability, multi-node operation, identity, integrations, storage, projects, and templates.
  • Adds CLI and route inventories to the VitePress reference section.
  • Contains important inaccuracies around IAM-scoped deployment and remote-node telemetry, plus several lower-impact contradictions and generation artifacts.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  Index[docs/README and VitePress sidebar] --> Guides[Feature how-to guides]
  Index --> References[Reference documentation]
  Guides --> Deploy[Apps and databases]
  Guides --> Platform[Multi-node and observability]
  Guides --> Access[Identity and integrations]
  Guides --> Resources[Storage, projects, and templates]
  References --> CLI[CLI command inventory]
  References --> API[REST route inventory]
  Guides --> Source[Runtime source and handlers]
  References --> Source
Loading

Reviews (1) · Last reviewed commit: "docs: 9 feature how-to guides plus exhau..."

Comment on lines +273 to +288
3. **Scope a CI token down to one app** with an IAM policy, tighter than
any flat role could express:

```bash
levelrail-cli tokens create --name "ci-checkout" --abilities deploy
# → token tok_xyz, plaintext shown once

levelrail-cli iam policies create --name "checkout-only" \
--document '{"Statement":[{"Effect":"Allow","Action":["deploy"],"Resource":["app:checkout"]}]}'
# → policy pol_abc

levelrail-cli iam policies attach pol_abc --principal-type token --principal-id tok_xyz
```

That token can now deploy `checkout` even without a global `deploy`
ability, or be explicitly denied a resource a broader role would

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 security The walkthrough cannot produce an app-scoped deploy token. --abilities deploy grants the token global deploy access, and the deploy endpoint uses the global ability check rather than resource-scoped IAM evaluation. The token can therefore deploy every app, while the app:checkout Allow policy is redundant. Conversely, removing the global ability would make this endpoint reject the token rather than honor the policy. Following this example creates a substantially overprivileged CI credential.

How this was verified: The token stores deploy as a flat ability, while POST /api/v1/apps/{name}/deploys uses requireAbility(AbilityDeploy) instead of the resource-aware authorization wrapper.

Comment thread docs/observability.md
Comment on lines +19 to +29
This platform keeps metrics and logs where they are collected: each
node's own SQLite-backed telemetry store (the same `modernc.org/sqlite`
already used for the control plane's own state). The control plane
queries agents on demand instead of ingesting continuously. Right now
there is exactly one node (the control plane and the agent share a
process, see `internal/agent`'s in-memory transport), so "federated
query" fans out to a single source, but the query interface
(`TelemetryQuerier` in `internal/api/metrics.go`) is already the shape
Phase 3's real multi-node federation needs: nothing here changes when a
second node shows up, only how many sources `internal/telemetry`'s
querier has to ask.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 This describes remote-node telemetry as already stored per node and federated on demand, but production is wired only to NewLocalFederator(telemetryDB). Remote agents run no telemetry collectors or store, and the agent protocol has no remote telemetry query operation. Apps placed on remote nodes and remote node IDs therefore return empty metrics and logs instead of adding another query source, which can cause operators to incorrectly assume their multi-node fleet is monitored.

Comment on lines +47 to +54
Most templates use `$SERVICE_..._X` style tokens (for example
`$SERVICE_PASSWORD_DB`, `$SERVICE_HEX_64_ENCRYPTIONKEY`) in place of literal
secrets in their Compose environment blocks. These are the same magic-var
convention a large share of real-world Compose template datasets use; there
is no resolver for them yet (see "Not built yet" below), so as of today they
deploy as literal, unresolved strings unless you edit them out first. The
dashboard's preview step shows the full Compose body specifically so you can
edit these (and image tags, ports, or anything else) before deploying.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 This says Compose magic variables have no resolver and deploy as literal strings, but handleDeployCompose calls ResolveMagicVars. It persists supported generated values such as SERVICE_PASSWORD, SERVICE_HEX, and SERVICE_BASE64, resolves FQDN and default forms, and rejects variables that remain unresolved instead of deploying them literally. This advice makes users replace generated secrets by hand unnecessarily and contradicts the behavior documented in deploying-apps.md.

Suggested change
Most templates use `$SERVICE_..._X` style tokens (for example
`$SERVICE_PASSWORD_DB`, `$SERVICE_HEX_64_ENCRYPTIONKEY`) in place of literal
secrets in their Compose environment blocks. These are the same magic-var
convention a large share of real-world Compose template datasets use; there
is no resolver for them yet (see "Not built yet" below), so as of today they
deploy as literal, unresolved strings unless you edit them out first. The
dashboard's preview step shows the full Compose body specifically so you can
edit these (and image tags, ports, or anything else) before deploying.
Most templates use `$SERVICE_..._X` style tokens (for example
`$SERVICE_PASSWORD_DB`, `$SERVICE_HEX_64_ENCRYPTIONKEY`) in place of literal
secrets in their Compose environment blocks. These are resolved during
Compose deployment: supported generated values are persisted as secrets,
FQDN and default forms are expanded, and any variables that remain unresolved
cause the request to fail rather than being deployed literally. The
dashboard's preview step still shows the full Compose body so you can review
and edit image tags, ports, or anything else before deploying.

Comment on lines +158 to +164
means disabling and re-enabling to get a fresh one. Every later call
that doesn't need a fresh credential (toggling `host`, or re-enabling
after a disable that already cleared the old one) leaves whatever
credential currently exists untouched. `DELETE /api/v1/settings/registry`
disables the registry and clears its generated credentials via
`internal/secrets.Manager.DeleteAll`; it's idempotent, disabling an
already-disabled registry is not an error.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 The parenthetical says re-enabling after a disable preserves an existing registry credential, but DELETE /api/v1/settings/registry clears that credential and the next enable generates and returns a fresh password. This directly contradicts the preceding recovery instruction and leaves operators uncertain whether disable and re-enable rotates the credential.

Suggested change
means disabling and re-enabling to get a fresh one. Every later call
that doesn't need a fresh credential (toggling `host`, or re-enabling
after a disable that already cleared the old one) leaves whatever
credential currently exists untouched. `DELETE /api/v1/settings/registry`
disables the registry and clears its generated credentials via
`internal/secrets.Manager.DeleteAll`; it's idempotent, disabling an
already-disabled registry is not an error.
means disabling and re-enabling to get a fresh one. Later calls that only
toggle `host` preserve the existing credential. `DELETE
/api/v1/settings/registry` disables the registry and clears its generated
credentials via `internal/secrets.Manager.DeleteAll`; it's idempotent,
disabling an already-disabled registry is not an error. Re-enabling after
that generates and returns a fresh password.

Comment on lines +58 to +61
different and has a known gap worth knowing about: `DELETE
/api/v1/databases/{name}` removes the desired-state row but does not
itself stop or remove the running container, the same gap `DELETE
/api/v1/apps/{name}` has.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 The database-specific warning is correct, but the claim that app deletion has the same orphan-container gap is false. handleDeleteApp explicitly launches teardownServiceContainers after deleting desired state. This PR also updates that handler's comment to document the teardown, so the guide gives conflicting lifecycle expectations for app deletion. The same incorrect comparison appears again in the guide's “Not built yet” section.

Comment thread docs/api-reference.md
@@ -0,0 +1,412 @@
# REST API Reference

Exhaustive route inventory (272 routes total) for Levelrail's control plane HTTP API, organized by resource group matching `docs/feature-catalog.md`.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 The new API reference advertises 272 routes, but its table contains 290 route rows and the changed feature catalog correctly reports 290 registered routes. The documentation index repeats the stale 272 figure, undermining the reference's “exhaustive” claim and giving users conflicting inventory totals.

Suggested change
Exhaustive route inventory (272 routes total) for Levelrail's control plane HTTP API, organized by resource group matching `docs/feature-catalog.md`.
Exhaustive route inventory (290 routes total) for Levelrail's control plane HTTP API, organized by resource group matching `docs/feature-catalog.md`.

Comment thread docs/cli-reference.md
Comment on lines +72 to +79
```
levelrail apps deploys compare <name> --from ID [--to ID] [flags]
```

```
levelrail apps deploys compare <name> --from ID [--to ID] [flags]
```
diff two deploy attempts, or one against the current live state

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 The generated reference repeats many commands as separate adjacent entries, including apps deploys compare, apps environments create, and numerous list and create commands throughout the file. For an exhaustive reference, this makes command enumeration noisy and suggests duplicate commands exist. The usage and description records should be deduplicated before publication.

Suggested change
```
levelrail apps deploys compare <name> --from ID [--to ID] [flags]
```
```
levelrail apps deploys compare <name> --from ID [--to ID] [flags]
```
diff two deploy attempts, or one against the current live state

levelrail apps deploys compare --from ID [--to ID] [flags]

diff two deploy attempts, or one against the current live state

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/api internal/api size/XXL type/docs Documentation only

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant