A fork of mtelver's day10 project
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

day10-web: Status Dashboard Design#

Date: 2026-02-04 Status: Approved Author: Brainstorming session

Overview#

A web frontend for day10 that allows package maintainers to check their package status and operators to monitor system health. It runs as a separate service that reads day10's output directories.

Audience#

  1. Package maintainers - Want to see if their packages are building/documented correctly, investigate failures
  2. day10 operators/admins - Monitoring system health, viewing logs, managing runs

Not intended as a general documentation browser (that's what the generated HTML at /docs/ is for).

Architecture#

┌─────────────┐     writes      ┌──────────────────────────┐
│   day10     │ ───────────────►│  /data/                  │
│  (batch)    │                 │  ├── cache/logs/         │
└─────────────┘                 │  │   ├── runs/           │
                                │  │   │   └── summary.json│
                                │  │   └── latest          │
                                │  └── html/               │
┌─────────────┐     reads       │      └── p/{pkg}/{ver}/  │
│ day10-web   │ ◄───────────────┤                          │
│  (Dream)    │                 └──────────────────────────┘
└─────────────┘
       │
       ▼
   HTTP :8080

Key properties:

  • No database - all state derived from filesystem
  • Read-only access to day10's directories
  • Single configuration: paths to cache-dir and html-dir
  • Lightweight: day10-web --cache-dir /data/cache --html-dir /data/html

Pages and Routes#

Dashboard (/)#

  • Overview cards: total packages, build success rate, doc success rate
  • Latest run summary (timestamp, duration, pass/fail counts)
  • Link to full run history

Package List (/packages)#

  • Searchable/filterable table of all packages
  • Columns: package name, version, build status, doc status, last updated
  • Click through to package detail

Package Detail (/packages/{name}/{version})#

  • Build status with link to build log
  • Doc status with link to doc log and generated docs
  • Dependencies tab: what this package depends on (with their statuses)
  • Reverse dependencies tab: what depends on this package
  • Solver solution: OCaml version, full dependency list with versions

Run History (/runs)#

  • List of all batch runs (timestamp, duration, success/fail counts)
  • Click through to run detail

Run Detail (/runs/{run-id})#

  • Full summary.json data displayed nicely
  • List of failures with links to logs
  • Filterable list of all packages processed in that run

Data Sources#

All data is read from the filesystem:

Run data ({cache-dir}/logs/)#

Path Provides
runs/ directory listing Run history
runs/{id}/summary.json Run statistics, failure list
runs/{id}/build/*.log Build logs
runs/{id}/docs/*.log Doc generation logs
latest symlink Most recent run

Package data ({cache-dir}/{platform}/)#

Path Provides
solutions/ Cached solver results (deps, OCaml version)
build-*/layer.json Build metadata and status
doc-*/layer.json Doc generation metadata and status

Generated docs ({html-dir}/)#

Path Provides
p/{pkg}/{ver}/ existence Doc generation succeeded
Direct links Link to generated documentation

Dependency graph#

  • Built from solutions data
  • Forward deps: parse the solution for a package
  • Reverse deps: scan all solutions (indexed on startup)

UI Approach#

Rendering: Server-side HTML with minimal JS#

Dream renders HTML directly using its built-in HTML DSL or Tyxml. No heavy frontend framework:

  • HTML pages rendered on server
  • Small amount of vanilla JS for search/filtering
  • CSS styling (Pico CSS or simple custom styles)

Why this approach#

  • Simpler to build and maintain
  • No frontend build pipeline
  • Fast initial page loads
  • Works without JavaScript for core functionality
  • Fits "operational dashboard" use case

Visual style#

  • Clean, functional dashboard aesthetic
  • Status badges: green (success), red (failed), yellow (skipped)
  • Sortable tables for package lists
  • Collapsible sections for dependency trees
  • Syntax highlighting for logs (highlight.js)

Log viewer#

  • Display logs inline with scrolling
  • Link to raw log file for download
  • Client-side search within log

Project Structure#

/workspace/
├── day10.opam              # Existing - the batch runner
├── day10-web.opam          # New - the web frontend
├── bin/
│   └── main.ml             # Existing day10 CLI
├── lib/                    # Existing day10_lib
├── web/
│   ├── dune
│   ├── main.ml             # day10-web entry point
│   ├── server.ml           # Dream routes and handlers
│   ├── views/
│   │   ├── layout.ml       # Common HTML layout
│   │   ├── dashboard.ml    # Dashboard page
│   │   ├── packages.ml     # Package list and detail pages
│   │   └── runs.ml         # Run history and detail pages
│   ├── data/
│   │   ├── run_data.ml     # Read summary.json, logs
│   │   ├── package_data.ml # Read solutions, layer metadata
│   │   └── deps.ml         # Dependency graph builder
│   └── static/
│       ├── style.css
│       └── app.js          # Minimal JS for search/filter
└── dune-project            # Update to add day10-web package

Shared code: day10-web depends on day10_lib to reuse types (e.g., Run_log.summary).

CLI and Configuration#

day10-web [OPTIONS]

Required:
  --cache-dir DIR       Path to day10's cache directory
  --html-dir DIR        Path to generated documentation

Optional:
  --port PORT           HTTP port (default: 8080)
  --host HOST           Bind address (default: 127.0.0.1)
  --platform PLATFORM   Platform subdirectory (default: debian-12-x86_64)

Example usage#

# Development
day10-web --cache-dir /data/cache --html-dir /data/html

# Production (bind to all interfaces)
day10-web --cache-dir /data/cache --html-dir /data/html \
  --host 0.0.0.0 --port 80

Deployment with nginx#

server {
    listen 80;
    server_name docs.example.com;

    # Status dashboard
    location / {
        proxy_pass http://127.0.0.1:8080;
    }

    # Generated documentation
    location /docs/ {
        alias /data/html/;
        autoindex on;
    }
}

Error Handling#

Missing data#

Condition Behavior
No runs yet Dashboard shows "No runs recorded"
Package not found 404 with search suggestions
Run ID not found 404 with link to run history
Log file missing "Log not available" (may be GC'd)
Malformed JSON Log warning, show partial data

Large data sets#

Data Strategy
Package list Paginated (50/page) with search
Run history Paginated (20/page), most recent first
Dependency tree Depth-limited (2 levels), click to expand
Reverse deps Count with paginated list

Concurrent access#

  • Read-only filesystem access is safe
  • Atomic swaps mean readers see consistent state
  • No locking needed

Startup#

  • Validate cache-dir and html-dir exist
  • Build reverse dependency index
  • Log startup time and index size

Out of Scope (YAGNI)#

  • Real-time updates / WebSockets
  • Authentication / access control
  • Write operations (triggering builds)
  • REST API (just HTML pages for now)

Dependencies#

New opam dependencies for day10-web:

  • dream - Web framework
  • tyxml or Dream's HTML DSL - HTML generation

Implementation Plan#

  1. Set up project structure (dune-project, day10-web.opam, web/ directory)
  2. Implement data layer (run_data.ml, package_data.ml, deps.ml)
  3. Implement views (layout, dashboard, packages, runs)
  4. Wire up Dream routes in server.ml
  5. Add static assets (CSS, minimal JS)
  6. Add CLI with cmdliner
  7. Update admin guide with deployment instructions
  8. Write tests for data layer