Tetra · Documentation
← Back to MainThis 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
| Path | Method | Auth | Purpose |
|---|---|---|---|
/api/health | GET | No | Simple health check |
/api/debug | GET | No | DB counts & basic diagnostics |
Auth
| Path | Method | Body | Notes |
|---|---|---|---|
/api/login | POST | {username,password} | Demo auth (configurable via env vars) |
/api/logout | POST | — | Clears session |
Core (requireAuth)
| Path | Method | Params/Body | Returns |
|---|---|---|---|
/api/recommend | POST | {failureMode,issue} | recommendedParts, recommendedSolutions, trendParts, trendSolutions |
/api/searchSimilar | POST | {query,limit} | Array of matching docs (includes id projection used for feedback) |
/api/retrain | POST | query ?all=1 or body {all:true} | starts retrain job |
/api/retrain/status | GET | — | Current in-memory retrain state (running, updated, total, history, currentRunId) |
/api/retrain/runs | GET | query ?limit=100 | Persisted runs (filters out type: 'update_batch') |
/api/retrain/recover | POST | — | Rebuild minimal run docs from update_batch audit records |
/api/feedback | POST | {docId,value,target,source,comment} | Returns updated summary and myVote when session/user present |
/api/feedback/summary | GET | query ?docId=... | Aggregated counts and myVote for requester |
/api/export/feedback | GET | — | CSV export of feedback (auth required) |
/api/export/runs | GET | — | CSV 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_COLto separate update-batch audit records from run docs; by default they are merged intoRUNS_COL. - Set
LOG_COLto a different collection if you want to preserve request logs separately. - To prevent polling from flooding logs,
/api/retrain/statusis 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.