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

173 lines
7.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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`.