Files
core/bible-local/architecture/api-surface.md
Michael Chus c5d253a9df Add shared bible submodule, rename local bible to bible-local
- Add bible.git as submodule at bible/
- Rename bible/ → bible-local/ (project-specific architecture)
- Update CLAUDE.md to reference both bible/ and bible-local/
- Add AGENTS.md for Codex with same structure

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 16:37:10 +03:00

7.8 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}

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}.

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"

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.