Tetra · Documentation

← Back to Main

This page documents the key concepts, data shapes, API endpoints, and admin notes for the Tetra platform's semantic search and recommendation features.

High-level view

Tetra is a small platform that turns historical tickets into a semantic search and recommendation service. The platform extracts a concise "symptom" from each ticket and uses an AI model to produce compact numeric representations (embeddings) that capture meaning.

These embeddings are indexed so the platform can quickly find past tickets that are semantically similar to a new report. The UI surfaces nearest neighbors, suggested parts, and likely solutions based on what similar tickets used.

Core concepts

Embeddings & neighbor search

The platform uses an AI model to convert symptom text into compact numeric vectors (embeddings). These vectors capture meaning: tickets describing the same problem end up near each other in vector space even if they use different words.

When you submit a query (failure mode + issue), the platform computes a vector for the query and retrieves the nearest neighbors from the indexed historical data. Neighbors are ranked by similarity and then aggregated to produce part and solution suggestions.

Embeddings refresh (retrain)

The platform periodically (or on demand) recomputes embeddings to keep the index fresh. Refresh runs are recorded so operators can track progress and audit which documents were updated.

Feedback (voting)

Users can upvote or downvote suggested parts and solutions. Feedback is kept minimal (document id, target, value, timestamp, and a client identifier) and is used to gently nudge suggestions: positively-voted examples get a small boost when ranking neighbors.

Key behavior:

  • Authenticated or sessioned clients are deduplicated: a client can toggle their vote (clicking the same vote again removes it).
  • Anonymous clients can add votes but are not protected from duplicate submissions.
  • Votes are aggregated to provide counts and per-client state that's returned to the UI for active/toggle behavior.

API Reference (selected)

Public

PathMethodAuthPurpose
/api/healthGETNoSimple health check
/api/debugGETNoDB counts & basic diagnostics

Auth

PathMethodBodyNotes
/api/loginPOST{username,password}Demo auth (configurable via env vars)
/api/logoutPOSTClears session

Core (requireAuth)

PathMethodParams/BodyReturns
/api/recommendPOST{failureMode,issue}recommendedParts, recommendedSolutions, trendParts, trendSolutions
/api/searchSimilarPOST{query,limit}Array of matching docs (includes id projection used for feedback)
/api/retrainPOSTquery ?all=1 or body {all:true}starts retrain job
/api/retrain/statusGETCurrent in-memory retrain state (running, updated, total, history, currentRunId)
/api/retrain/runsGETquery ?limit=100Persisted runs (filters out type: 'update_batch')
/api/retrain/recoverPOSTRebuild minimal run docs from update_batch audit records
/api/feedbackPOST{docId,value,target,source,comment}Returns updated summary and myVote when session/user present
/api/feedback/summaryGETquery ?docId=...Aggregated counts and myVote for requester
/api/export/feedbackGETCSV export of feedback (auth required)
/api/export/runsGETCSV export of persisted runs (auth required)

Example responses

/api/recommend (200)
{
  "input": { "failureMode": "Electrical fault", "issue": "Instrument shuts down under load" },
  "recommendedParts": [ { "value": "E6409002", "score": 27.24 }, { "value": "BC001178", "score": 16.25 } ],
  "recommendedSolutions": [ { "value": "Replace PCBA", "score": 18.4 } ],
  "trendParts": [],
  "trendSolutions": []
}
/api/searchSimilar (200)
[
  { "id": "648f1a...", "score": 0.98, "FailureMode": "Electrical fault", "Issue": "Unit dies under load", "Part": "E6409002", "Solution": "Replace PCBA", "SubmitDate": "2025-08-21T12:34:00Z" },
  { "id": "648f2b...", "score": 0.76, "FailureMode": "Electrical fault", "Issue": "Intermittent power loss", "Part": "BC001178", "Solution": "Replace regulator", "SubmitDate": "2025-07-12T09:10:00Z" }
]
/api/feedback (POST) — sample responses
// When session/user present and vote created/changed/toggled
{
  "ok": true,
  "summary": { "up": 3, "down": 1 },
  "myVote": 1   // or -1 or null
}

// Anonymous insert
{
  "ok": true,
  "id": "64a1be...",
  "summary": { "up": 4, "down": 1 },
  "myVote": null
}
/api/feedback/summary (200)
{ "up": 12, "down": 2, "myVote": 1 }
/api/retrain/status (200)
{
  "running": true,
  "startedAt": "2025-09-03T10:12:00Z",
  "finishedAt": null,
  "updated": 420,
  "total": 1200,
  "mode": "missing",
  "error": null,
  "history": [],
  "currentRunId": "64bfae..."
}

Data & Indexing

Key fields used by the app:

  • emb.symptom — vector (array) used for vectorSearch index.
  • part_norm, solution_norm, fm_norm — normalized text used for aggregation & trends.

Admin tips

  • Enable UPDATES_COL to separate update-batch audit records from run docs; by default they are merged into RUNS_COL.
  • Set LOG_COL to a different collection if you want to preserve request logs separately.
  • To prevent polling from flooding logs, /api/retrain/status is excluded from request logging by default.

Future ideas

  • Integrate feedback weighting into ranking more deeply (user trust, recency-weight, confidence).
  • Rate-limit feedback and add authenticated-only voting to prevent gaming.
  • Provide per-user vote history and undo from a profile page.