About the project
Search over a fixed document set. Answers need links to the source chunks. If there are no relevant matches, the response says so.
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.
- 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.
Screenshots, diagrams and source evidence retain their original language; captions and descriptions are translated.
Architecture and diagrams
- 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.
Code map: files and dependencies
This map is tied to version a618d1e7be8a. The table lists the screen or API, related module and data.
| Feature | Screen / API | Module | Data / verification |
|---|---|---|---|
| Initial indexing | CLI portfolio | cli._upsert_demo_record, NatsBroker, IndexerService | sources, tenders, attachments, chunks |
| Search / answer | api/v1/search, ask | SearchService, FakeAIProvider | chunks VECTOR(1024) |
| Sources | local HTML | web/demo | original corpus |
| Event replay | api/demo/replay | NatsBroker / hash guard | shared read-only corpus |
| Session and rate limit | cookie / middleware | portfolio, auth, rate_limit | api_keys (hash and counters only) |
Using the code map
- Before making a change, find the feature and trace its links to the API, state and storage.
- Check inputs, errors, repeated events and dependent workflows.
- After making a change, update the map and affected diagrams alongside the code.
- Run the related checks and link the new evidence to the source version.
Workflows and API
- Find a document about servers or an Angular portal.
- Ask a question and open the answer's sources.
- Enter a query outside the corpus and check the missing-context response.
- Replay indexing events: the four documents and 16 chunks should remain without duplication.
Verification of the published version
CI: CI ↗ · 84c37f0f · historical run of a different version · 2026-08-27T06:43:00Z
CI: Documentation ↗ · 84c37f0f · historical run of a different version · 2026-08-27T06:43:00Z
- 118 unit tests passed; 18 integration/external checks were excluded from this run.
- Search and Ask return sources; unrelated query returns no context
- Queue replay preserves 16 chunks and ready status
- Independent signed expiring HttpOnly sessions
- No verified GitHub CI run is available for this SHA; the listed evidence covers local checks and published-version scenarios. Historical CI links, where available, are labeled separately.
These checks apply to the listed version. Business metrics and model quality on an independent dataset were not measured.
Measurements
- 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.
Running and operating
The original project has a crawler and an AI provider integration. The demo disables live AI in its config and only accepts documents from the test corpus.
Dockerfile.portfolio is built outside the VPS; the API and worker share one pinned image with separate limits. PostgreSQL and NATS are accessible only on the internal network; the API is served through localhost:18403 and Nginx.
Run migrations and the portfolio seed CLI at startup. API readiness checks its dependencies. Reindexing is safe because of content_hash; after a restart, verify four ready documents and 16 chunks. Session ApiKeys expire by TTL and are cleaned up every five minutes.
Builds run outside the VPS; the server receives static files and versioned images. Secrets are kept separately. Logs rotate; changing log options requires recreating the container. No server-wide docker prune.
The code map links a screen or API to its module and data. A change needs those links checked, the map updated and the affected flows rerun: normal path, error, retry and reset. Diagrams can go stale, so their version is listed alongside them.
Rollback checked at 2026-09-07T01:04:24.534304+00:00: 20260907-verified → 20260907c → 20260907-verified. HTTPS, readiness and SHA were confirmed after each switch. This checks configuration and artifacts at one verified SHA; no reverse database migration was performed.
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. |
Materials and source code
Implementation history: since 20 August 2026. Public demo: 7 September 2026.
The evidence archive retains its original language.