πŸ” SRAG
Support Request RAG System

Semantic search over your Jira support history.

Premier Active v1.0.0 Auth Required meltuc.tech/srag/

SRAG is a Retrieval-Augmented Generation system built for IT support teams who need to search years of historical support tickets and email threads using natural language. Rather than grepping for keywords, SRAG lets you ask "What caused the certificate renewal failures in 2025?" and receive a grounded, cited answer drawn directly from your Jira support history.

The ingestion pipeline connects to your Jira instance via API, downloads each support ticket with its .msg email attachments, parses the full email thread (headers, body, HTML stripped), splits everything into overlapping text chunks, and generates 768-dimensional pgvector embeddings via the configured embedding model. Every chunk lands in PostgreSQL with its vector, source type, and ticket key β€” ready for millisecond-latency similarity search.

At query time you type a natural language question. SRAG embeds the query using the same model, runs a cosine similarity search over the full chunk corpus, retrieves the top matches, and optionally synthesises a plain-language answer via LLM β€” citing ticket keys inline so you can trace every claim back to its source ticket.

πŸ“·
Screenshots coming soon.
Capture at 1280px: ingestion browser, query results, ledger view.

Everything You Need to Mine Support History

πŸ”
Ingest

Paste a Jira key to fetch the ticket, parse .msg email attachments, chunk all content, and embed into pgvector. Tracks status per ticket in the ingestion ledger.

πŸ”Ž
Query

Ask natural language questions. Results are ranked by cosine similarity with a clickable slideout showing full chunk text, Jira link, email metadata, and an AI-synthesised answer citing ticket keys.

πŸ“¦
Chunks Browser

Browse, filter, and inspect every text chunk in the database. Filter by content search, Jira key, chunk type, or embedding status. Slideout shows full chunk text. Supports single and bulk delete, CSV export.

πŸ’š
Health Dashboard

Live corpus stats (tickets, chunks, vectors, pending) plus service connectivity checks for Jira API, Ollama embedder, database, and pgvector. Refresh on demand.

πŸ”—
Jira Ticket Ingestion

Auto-fetches tickets via the Jira REST API. Captures summary, description, status, priority, reporter, and all comment threads. Ingestion is idempotent β€” re-ingesting a ticket updates without duplicating.

πŸ“§
.msg Email Parsing

Downloads .msg email attachments from each ticket and parses them using the msg-parser library. Extracts sender, recipients, date, subject, and full body text with HTML stripped β€” including nested quoted replies.

🧩
pgvector Semantic Embeddings

Each chunk is embedded into a 768-dimensional vector and stored in PostgreSQL using pgvector. Supports cosine similarity search with no external search infrastructure β€” everything lives in your existing Supabase database.

πŸ”
Natural Language Query

Ask questions in plain English. SRAG embeds the query, performs nearest-neighbour search, retrieves the top-10 most similar chunks, and returns ranked results with source ticket keys and relevance scores. Click any result row for a full detail slideout.

πŸ”„
Re-Embedding Support

After updating the embedding model, use the re-embed endpoint to regenerate all vectors in bulk. Chunks with missing or stale embeddings are tracked via a pending_embedding flag and retried automatically.

πŸ“‹
Ingestion Status Ledger

Every ingested ticket is tracked in the ledger with its status (pending / complete / error), chunk count, embedding count, and last error message. Browse the full ingestion history from the app dashboard.

Three Steps From Ticket to Answer

SRAG implements a standard RAG pipeline optimised for structured support tickets and unstructured email bodies attached as .msg files.

01

Ingest

Paste a Jira ticket key or run auto-mode across your backlog. SRAG fetches the ticket via REST API, downloads .msg attachments, parses the email thread, and splits all content into overlapping chunks. Status is written to srag_ingest_ledger.

02

Embed

Each text chunk is sent to the configured embedding model to produce a 768-dimensional vector. Vectors are stored in srag_chunks via pgvector. Pending embeddings are retried via POST /api/reembed.

03

Query

Enter a natural language question. SRAG embeds the query, runs cosine similarity search over srag_chunks, ranks the top results, and returns grounded answers with Jira key citations. Every query is logged to srag_query_log.

From Jira Ticket to Searchable Knowledge

Every ticket goes through a 5-stage pipeline before it becomes queryable. Understanding this pipeline explains exactly what data you can find, why semantic search works, and what the system cannot do.

πŸ—‚
JIRA
REST API
ticket + attachments
status Β· priority
summary
β†’
πŸ“§
PARSE
.msg email files
from/to/date/subject
body text
strip HTML
β†’
🧩
CHUNK
split into ~500 char
overlapping segments
preserves context
across boundaries
β†’
🧠
EMBED
768-dim vector
via embedding model
captures semantic
meaning of text
β†’
πŸ—„
PGVECTOR
PostgreSQL + pgvector
text + vector stored
together per chunk
cosine search ready
10,879
Tickets Ingested
from ICISTWO Jira project
31,695
Text Chunks
emails + descriptions split
768
Dimensions Per Vector
31,695 vectors stored

Two Tables, One Purpose

All SRAG data lives in PostgreSQL (Supabase). No external search index, no Redis, no Elasticsearch. pgvector extends PostgreSQL to store and query embedding vectors directly alongside the original text.

πŸ“‹
srag_ingest_ledger
One row per Jira ticket β€” tracks ingestion state
jira_key TEXT PK e.g. ICISTWO-36500
jira_summary TEXT ticket title from Jira
jira_status TEXT Open / In Progress / Done
jira_priority TEXT High / Medium / Low
status TEXT pending / complete / error
chunk_count INT number of chunks created
embedding_count INT chunks with vectors stored
ingested_at TIMESTAMPTZ when last processed
🧩
srag_chunks
One row per text chunk β€” stores text + vector
id UUID PK unique chunk identifier
jira_key TEXT FK links back to ledger
chunk_text TEXT raw text content (~500 chars)
chunk_type TEXT description / email_body
email_from TEXT sender if from email
email_subject TEXT subject line if from email
email_date TIMESTAMPTZ email timestamp
embedding VECTOR(768) pgvector β€” the search index
Why pgvector? Standard SQL databases store text and numbers. pgvector adds a VECTOR(n) column type that stores a list of floating-point numbers (your embedding). The {'<=>'}' operator computes cosine distance between any two vectors in a single SQL query β€” no external infrastructure needed. All 31,695 chunk vectors live inside your existing Supabase database alongside the text they represent.

Why "Login Failed" Finds "Access Denied"

Keyword search matches exact words. Semantic search matches meaning. The same embedding model that compressed your ticket text into vectors also compresses your query β€” then the database finds the chunk vectors closest in direction.

Your Question
What login errors have been reported?
↓ embedding model
[0.12, -0.83, 0.41, ...]
768 numbers
⟺
cosine
distance
Chunk Vectors in DB
97%
ICISTWO-4201 β€” User cannot log in, password rejected
94%
ICISTWO-8812 β€” Access denied on shared drive login
91%
ICISTWO-2167 β€” Authentication failure, credentials expired
76%
ICISTWO-9100 β€” Server error on submit
β†’
top 10
returned
AI Synthesises Answer
"Login failures appear across multiple tickets. ICISTWO-4201 reports password rejection after a maintenance window. ICISTWO-8812 involves shared drive access denied errors…"
Every claim cites a Jira key.
You can verify in Jira directly.
βœ“ Works Well For
  • Conceptual questions ("What login errors…")
  • Pattern discovery ("Common SSL problems")
  • Phrasing variation ("can't access" finds "denied")
  • Topic clustering ("all PPOB-related issues")
~ Works Partially For
  • Specific ticket lookups (use Jira for known keys)
  • Exact counts ("how many tickets about X")
  • Date ranges ("tickets from last month")
βœ— Does Not Work For
  • Tickets not yet ingested
  • Real-time status ("is ICISTWO-9000 open?")
  • Negative queries ("tickets WITHOUT attachments")

Writing Queries That Work

Write queries as if you're asking a colleague who has read every ticket. Full sentences work better than keywords. The richer your question, the more precisely the embedding model can locate relevant chunks.

βœ“ Good Queries
What types of problems do registered agents report most often?
Broad β€” finds pattern across many tickets
What issues have been reported with package regeneration?
Topic-specific β€” surfaces a whole category
What does a typical resolution process look like for filing errors?
Process question β€” draws from many resolved tickets
Which users or companies submit the most support requests?
Entity extraction across the corpus
What problems occur after system maintenance windows?
Event-correlated β€” finds related clusters
βœ— Weak Queries
login
Too short β€” matches everything loosely
β†’ "What login or authentication failures have been reported?"
ICISTWO-36500
Key lookup β€” use Jira instead
β†’ "What kind of issue is described in a CTF funding request?"
how many tickets
Counting across corpus unreliable
β†’ "What are the most common categories of support requests?"
error
Too generic β€” half the corpus matches
β†’ "What errors occur when submitting entity filings?"
yes or no: is this system working
Not what RAG is for
β†’ Ask a question about ticket patterns or history
Using the Query Page β€” Step by Step
1
Go to the Query tab
Click "πŸ”Ž Query" in the sidebar from any SRAG screen. The sidebar has four links: πŸ” Ingest, πŸ”Ž Query, πŸ“¦ Chunks, and πŸ’š Health.
2
Type a full-sentence question
Write what you want to know. Min 5 words. More context = better matches. Hit Search RAG or press Ctrl+Enter.
3
Wait ~10 seconds
The system embeds your query, searches 31k vectors, then runs AI synthesis. A progress banner shows while it works.
4
Read the AI Synthesis first
The AI answer at the bottom of results cites Jira keys inline. This is your summary. If it says "excerpts do not contain..." your query needs to be rephrased.
5
Check the source table
10 ranked rows show the actual chunks the AI used. Score % = similarity. Click any Jira key to open that ticket in Jira.
6
Refine and iterate
If results are weak, rephrase to be more specific. Add domain context ("in the ICISTWO project", "related to entity filings"). Try synonyms.

INGEST. EMBED. QUERY.

Build a semantic knowledge base from your support ticket history. Every ingested ticket makes the next answer better.

Launch App β†’

Premier app β€” requires MelTuc account