Files
core/bible-local/architecture/api-surface.md
Mikhail Chusavitin aac3a69526 Add platform config ingest, storage, API, and UI tab
Auditors can now send BIOS/Redfish platform settings via
POST /ingest/hardware as hardware.platform_config (map[string]any).
Stored as latest-snapshot per machine with per-key change history.
Exposed via GET /api/assets/{id}/platform-config and .../history.
Asset page gets a third tab "Platform Config" with inline history expand.
Contract bumped to v2.9, migration 0024 adds two new tables.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 15:07:21 +03:00

8.5 KiB
Raw Blame History

API Surface

Health

  • GET /health

Registry

  • GET /assets
  • POST /assets
  • GET /registry/assets/{id}
  • PUT /registry/assets/{id}
  • DELETE /registry/assets/{id}
  • GET /components
  • POST /components
  • GET /registry/components/{id}
  • PUT /registry/components/{id}

Registry invariants:

  • Assets do not carry project_id in request/response contracts.
  • Registry PUT mutations are history-backed (event + snapshot + projection update), not direct projection writes.

Ingest

  • POST /ingest/hardware
  • POST /ingest/manual/csv
  • GET /ingest/manual/csv/jobs/{id}
  • GET /api/assets/{asset_id}/logs
    • returns deduplicated asset event logs (host, bmc, redfish) with filters by source, severity, activity state, and date range

Manual CSV ingest contract:

  • POST /ingest/manual/csv is asynchronous and returns 202 Accepted with job_id.
  • Final result is read from GET /ingest/manual/csv/jobs/{id}.

Hardware ingest notes:

  • POST /ingest/hardware may accept optional event_logs inside the snapshot payload.
  • event_logs are persisted into dedicated asset log storage and are not mapped to history/timeline events.

Timeline

  • GET /assets/{id}/timeline
  • GET /components/{id}/timeline
  • These routes now return the same structured timeline cards contract as history timeline endpoints (breaking change accepted).

History API

  • POST /api/history/admin/backfill/current-from-observations
    • idempotent operational backfill: copies component_type and open installation.slot_name from historical observations.details into history-first projections (parts, installations)
  • POST /api/history/admin/repair/all
    • best-effort admin repair flow (single action) that can restore missing timeline slots from observations and enqueue recompute jobs for affected entities
  • POST /api/history/admin/cleanup-orphaned-projections/preview
    • lightweight count preview for orphan cleanup candidates
  • POST /api/history/admin/cleanup-orphaned-projections
    • destructive cleanup of registry/projection/raw rows for assets/components that no longer have active history (is_deleted = FALSE)
  • POST /api/history/admin/cancel-by-source/preview
    • previews soft-delete of history events by source_type (ingest_json, ingest_csv, user, system) and optional date/source_ref filters
  • POST /api/history/admin/cancel-by-source
    • soft-deletes matched history events and queues recompute jobs for affected assets/components
  • GET /api/history/jobs/{id}
  • GET /api/history/components/{id}/events
  • GET /api/history/assets/{id}/events
  • POST /api/history/components/{id}/apply
  • POST /api/history/assets/{id}/apply
  • GET /api/history/components/{id}/timeline
  • GET /api/history/assets/{id}/timeline
  • GET /api/history/components/{id}/timeline/cards/{card_id}/events
  • GET /api/history/assets/{id}/timeline/cards/{card_id}/events
  • GET /api/history/components/{id}/events/{timeline_event_id}/detail
  • GET /api/history/assets/{id}/events/{timeline_event_id}/detail
  • DELETE /api/history/components/{id}/events/{event_id}
  • DELETE /api/history/assets/{id}/events/{event_id}
  • POST /api/history/components/{id}/rollback
  • POST /api/history/assets/{id}/rollback

Asset Page Component Management API (Current Components)

  • GET /api/assets/{asset_id}/current-components
    • returns enriched current component rows for asset page table (status, type, slot, vendor/model, firmware) and filter options
  • POST /api/assets/{asset_id}/components/add/check
    • duplicate preflight by vendor_serial and vendor_serial + model
  • POST /api/assets/{asset_id}/components/actions/add
    • mode = create_and_attach | attach_existing
    • supports force=true for moving an existing component from another asset to current asset
  • POST /api/assets/{asset_id}/components/actions/edit
    • bulk edit selected components on current asset (history-backed)
    • multi-select rejects unique fields (vendor_serial, slot)
  • POST /api/assets/{asset_id}/components/actions/remove
    • remove is de-assert only
    • requires deassert_status = working | not_working | unknown
  • GET /api/components/search-lite
    • lightweight component search for Add modal (vendor_serial, vendor/model, current installation, status)

History API invariants:

  • POST /api/history/*/apply uses semantic dedupe (no-op changes do not create events/snapshots/timeline rows).
  • Delete/rollback/hard-restore are asynchronous and return 202 Accepted with job_id.
  • Timeline endpoints are grouped by day by default (UTC, optional tz override).
  • Timeline endpoints return cards (single/dedup/bulk), not raw rows.
  • Timeline supports server-side filters via query parameters: date_from, date_to, action, source, device, slot, part_number (mapped to model), serial.
  • Card drilldown endpoint (.../timeline/cards/{card_id}/events) accepts tz and must use the same timezone as the timeline cards response used to render the card.
  • DELETE .../events/{event_id} is soft-delete + recompute enqueue (not physical delete).
  • POST .../rollback supports compensating and hard_restore modes.
  • Asset page component mutating actions (add/edit/remove) are history-backed and must not bypass history transaction flows.

Failures

  • GET /failures
  • POST /failures

POST /failures (manual UI registration) request:

  • component_serial (required, exact component serial)
  • server_serial (optional, used for validation/binding; submit without component serial is rejected)
  • failure_date (required, YYYY-MM-DD)
  • description (optional)

POST /failures behavior:

  • resolves component by serial
  • records component failure status via history (COMPONENT_STATUS_SET -> FAILED)
  • writes/updates failure_events projection row with source manual_ui
  • returns resolved component/server summary and created IDs

UI Routes

  • GET /ui
  • GET /ui/search
  • GET /ui/asset
  • GET /ui/asset/{vendor}
  • GET /ui/asset/{vendor}/{model}
  • GET /ui/asset/{vendor}/{model}/{vendor_serial}
  • GET /ui/component
  • GET /ui/component/{vendor}
  • GET /ui/component/models
  • GET /ui/component/{vendor}/{model} (model statistics page)
  • GET /ui/component/{vendor}/{model}/{vendor_serial}
  • GET /ui/failure
  • GET /ui/failure/{failure_id} (failure detail page)
  • GET /ui/failures
  • GET /ui/failures/{failure_id} (compatibility alias to failure detail page)
  • GET /ui/ingest
  • GET /ui/ingest/manual-template.csv
  • GET /ui/history-admin

UI/admin notes:

  • Destructive registry action DELETE /registry/assets/{id} ("Asset -> Delete with details") is operated from the Data Admin UI, not from the regular asset page.
  • UI routes are semantic-first and singular (/ui/asset, /ui/component, /ui/failure); legacy plural/ID-based UI fallback routes are intentionally removed.
  • Failure detail page supports both singular and plural ID routes for compatibility (/ui/failure/{id} primary, /ui/failures/{id} alias).

CSV Export Contract

Route: GET /ui/ingest/manual-template.csv

Rules:

  • Encoding: UTF-8.
  • UTF-8 BOM is included at file start for Excel compatibility.
  • Delimiter: ;.
  • Line endings: \r\n.
  • Escaping: RFC4180-compatible (fields with ;, ", \n, \r are quoted; inner " is doubled).
  • Header row is always present.
  • Stable column order (deterministic, no map-driven order).
  • Exported header order:
    • дата_осмотра
    • серийный_номер_сервера
    • вендор
    • p/n_устройства
    • s/n_устройства
    • локейшн_в_сервере
    • версия_прошивки
    • состояние_оборудования
  • Identifier-like columns are exported with Excel-safe text protection (to preserve leading zeros/codes).
  • Empty values are exported as empty cells (no null/undefined).
  • HTTP headers:
    • Content-Type: text/csv; charset=utf-8
    • Content-Disposition: attachment; filename="manual-import-template.csv"

Platform Config API

GET /api/assets/{asset_id}/platform-config
  Response: { asset_id, collected_at, items: [{ key, value, change_count }] }
  404 if not yet collected

GET /api/assets/{asset_id}/platform-config/{key}/history
  Response: { asset_id, key, items: [{ collected_at, value, source }] }

Routing Notes

  • API router is registered in internal/api/server.go.
  • Registry, ingest, failures, asset/component pages, and UI routes are attached to http.ServeMux.
  • History API routes and background history worker are also wired from internal/api/server.go.