Split embedded and standalone chart surfaces
This commit is contained in:
114
docs/embedding.md
Normal file
114
docs/embedding.md
Normal file
@@ -0,0 +1,114 @@
|
||||
# Embedding Chart
|
||||
|
||||
`chart` is intended to be embedded into another Go application that already obtains a Reanimator JSON snapshot.
|
||||
|
||||
The embedding application remains the source of truth for:
|
||||
|
||||
- where the JSON comes from
|
||||
- when the snapshot is collected
|
||||
- how routing, auth, and navigation work
|
||||
|
||||
`chart` only renders one snapshot as a read-only HTML view.
|
||||
|
||||
## Integration Modes
|
||||
|
||||
There are two supported integration styles:
|
||||
|
||||
1. Render HTML directly from bytes:
|
||||
|
||||
```go
|
||||
html, err := viewer.RenderHTML(snapshotBytes, "Hardware Snapshot")
|
||||
if err != nil {
|
||||
return fmt.Errorf("render chart html: %w", err)
|
||||
}
|
||||
```
|
||||
|
||||
2. Mount the embedded viewer HTTP handler:
|
||||
|
||||
```go
|
||||
mux.Handle("/chart/", http.StripPrefix("/chart", viewer.NewHandler(viewer.HandlerOptions{
|
||||
Title: "Hardware Snapshot",
|
||||
})))
|
||||
```
|
||||
|
||||
Use `viewer.NewHandler(...)` inside another application.
|
||||
|
||||
Use `viewer.NewStandaloneHandler(...)` only for the standalone `chart` binary or for a dedicated upload page where the viewer itself owns the first-screen file picker.
|
||||
|
||||
## Embedded Handler Behavior
|
||||
|
||||
`viewer.NewHandler(...)` is the embedded mode.
|
||||
|
||||
Routes:
|
||||
|
||||
- `GET /` renders the viewer shell with no upload controls
|
||||
- `POST /render` accepts one snapshot and returns rendered HTML
|
||||
- `GET /healthz` returns process health
|
||||
- `GET /static/...` serves embedded CSS assets
|
||||
|
||||
The embedded handler does not show a file-upload screen on `GET /`.
|
||||
|
||||
This is intentional: the host application decides how the snapshot is selected and passed in.
|
||||
|
||||
## Snapshot Submission
|
||||
|
||||
`POST /render` accepts:
|
||||
|
||||
- raw `application/json`
|
||||
- `multipart/form-data` with `snapshot_file`
|
||||
|
||||
Example with raw JSON:
|
||||
|
||||
```go
|
||||
req, err := http.NewRequest(http.MethodPost, "/chart/render", bytes.NewReader(snapshotBytes))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
```
|
||||
|
||||
Example with server-side render without an HTTP round-trip:
|
||||
|
||||
```go
|
||||
func chartPage(w http.ResponseWriter, r *http.Request) {
|
||||
snapshotBytes := loadSnapshotForRequest(r)
|
||||
|
||||
html, err := viewer.RenderHTML(snapshotBytes, "Hardware Snapshot")
|
||||
if err != nil {
|
||||
http.Error(w, "failed to render snapshot", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||
_, _ = w.Write(html)
|
||||
}
|
||||
```
|
||||
|
||||
## Recommended Host Responsibilities
|
||||
|
||||
When embedding `chart`, keep these responsibilities in the host application:
|
||||
|
||||
- authentication and authorization
|
||||
- selecting the target host or audit record
|
||||
- loading snapshot bytes from disk, database, object storage, or another service
|
||||
- page layout outside the chart surface
|
||||
- links back to the rest of the host application
|
||||
|
||||
## Constraints
|
||||
|
||||
- Input must be one Reanimator JSON snapshot.
|
||||
- `chart` is read-only.
|
||||
- `chart` preserves unknown fields where possible and does not compute new health summaries.
|
||||
- Presentation formatting is allowed, but payload semantics must not change.
|
||||
|
||||
## Standalone Binary
|
||||
|
||||
The standalone binary uses `viewer.NewStandaloneHandler(...)`.
|
||||
|
||||
That mode adds a first-screen upload form on `GET /` for local manual use.
|
||||
|
||||
Local run:
|
||||
|
||||
```bash
|
||||
make run
|
||||
```
|
||||
Reference in New Issue
Block a user