Demo · 7 September 2026

TenderLens

HTML is split into chunks and indexed through a queue. Search runs in pgvector; answers link to the retrieved chunks. The demo has four test documents. Embeddings and the LLM are mocked; the external crawler is disabled.

Implementation history: since 20 August 2026. Public demo: 7 September 2026.Version a618d1e712 interface screenshots

01 / The task

Document search with FastAPI and pgvector

Search over a fixed document set. Answers need links to the source chunks. If there are no relevant matches, the response says so.

Use case: Searching and reading a document collection.

Work done

  • Document normalization, event-based indexing and chunk storage.
  • Search and answer API with source links. A separate response for empty context.
  • Test corpus, deterministic AI mocks and per-session limits.

Screenshots

Screens, forms, errors

Screenshots, diagrams and source evidence retain their original language; captions and descriptions are translated.

02 / Technology

Stack

FastAPI / Pydantic

HTTP contracts, validation and search responses.

NATS JetStream

Event delivery to the indexer and replay.

PostgreSQL / pgvector

Documents, attachments, chunks and cosine search.

SQLAlchemy / Python

Normalization, extraction, chunking and content_hash verification.

03 / Decisions

How the project works

  • Seed sends a real TenderChangedV1 event through NATS; the indexer extracts HTML and creates chunks.
  • PostgreSQL VECTOR(1024) performs cosine search. FakeAIProvider creates embeddings using the hashing trick.
  • Event replay uses content_hash: an unchanged document does not duplicate chunks.
  • Answers use an explicitly labeled template based on retrieved passages; the external crawler and Ollama are disabled.
Components of the published demo
Components of the published demo

04 / Verification

Demo workflows

  1. Find a document about servers or an Angular portal.
  2. Ask a question and open the answer's sources.
  3. Enter a query outside the corpus and check the missing-context response.
  4. Replay indexing events: the four documents and 16 chunks should remain without duplication.

Check results

  • 12 meaningful screenshots of the actual interface retained.
  • Each screenshot includes its date, scenario and code revision.
  • Peak container RAM in the short test: 127.04 MiB. Shared services are counted separately; the shop includes its own database.
  • 6 scenario repetitions measured; median 997.0 ms, maximum 2738 ms. Timing includes the browser and HTTPS; methodology and limitations are included.
  • Four ready documents, 16 chunks. Replaying four NATS events created no duplicates.

Limitations

  • Four synthetic documents and 16 chunks form a demonstration corpus, not a database of real procurement records.
  • Cosine scores and template answers are not an evaluation of a production model's quality.
  • Up to 30 requests per minute per session and 1,000 active demo keys. User queries are not stored.
  • Worker health confirms the connection at startup; a separate stalled-computation detector is not implemented.

Technical notes

Modules, API, data model, setup and check results.

Documentation →Materials ↓