What I can do, and what proves it
Every skill below names the shipped projects that back it. Follow a tag to the running app, or to the case study when there is nothing deployed to open.
Databases and data
Postgres schema, indexing, migrations | |
Drizzle ORM typed schema, generated migrations | |
Full-text search pg_trgm trigrams, and generated tsvector columns indexed twice — simple for identifiers, english for prose | |
Background work a monthly cron job, advisory-locked queues, backfill with retry and backoff, durable partial progress |
AI and retrieval
Retrieval-augmented generation three arms — vector, identifier and BM25 prose — combined by reciprocal rank fusion; nothing retrieved refuses the question instead of guessing at it | |
Vector search pgvector with an HNSW cosine index over 384-dimension embeddings computed in-process, so indexed text never leaves the container | |
LLM integration four answering providers behind one interface, with per-user and deployment-wide spend ceilings checked before a call can cost anything | |
Prompt injection defence retrieved text travels inside tags the application writes, tag-shaped spans are escaped rather than stripped, and citations are validated before the first word of prose streams | |
PII anonymisation names, e-mail addresses and phone numbers become placeholders before anything crosses a network boundary; the mapping back lives in the request and dies with it |
Backend and integrations
FastAPI typed routes, service layer | |
Third-party APIs Steam, TMDB, OpenRouter, with tag-based cache revalidation and an on-demand purge endpoint | |
Auth OAuth sign-in and sessions, and OIDC against a Keycloak realm with role claims read from the token |
Frontend
React and Next.js App Router, server components by default | |
Streaming UI server-sent events for live price ticks, NDJSON for token-by-token answers | |
Accessible interaction drag and drop that is keyboard-operable, with the ARIA roles the pattern actually calls for | |
Design systems Tailwind v4, semantic tokens, no dark: variants |
Delivery
Testing unit, integration and Playwright end-to-end — and 170 tests on the Node runner alone, with no test framework installed | |
Docker multi-stage builds, one origin, no CORS layer; a compose file that brings up the app, its database and an identity provider together | |
CI/CD typecheck, lint and both suites on every pull request |