{"id":31675037,"url":"https://github.com/umarmk/kanari-chatbot","last_synced_at":"2026-04-09T12:04:03.429Z","repository":{"id":316027457,"uuid":"1061202436","full_name":"umarmk/kanari-chatbot","owner":"umarmk","description":"Full-stack chatbot with a clean web interface and real-time chat with OpenRouter LLM models.","archived":false,"fork":false,"pushed_at":"2025-10-04T07:34:55.000Z","size":341,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-10-04T09:19:50.532Z","etag":null,"topics":["artificial-intelligence","chatbot","llm","microservice","nestjs","openrouter","postgresql","react","redis"],"latest_commit_sha":null,"homepage":"https://kanari-chatbot.netlify.app/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/umarmk.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-21T13:01:26.000Z","updated_at":"2025-10-04T07:34:58.000Z","dependencies_parsed_at":"2025-09-22T09:35:44.571Z","dependency_job_id":"175b9806-b974-4e19-a8e6-a998d778d82b","html_url":"https://github.com/umarmk/kanari-chatbot","commit_stats":null,"previous_names":["umarmk/kanari-chatbot"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/umarmk/kanari-chatbot","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/umarmk%2Fkanari-chatbot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/umarmk%2Fkanari-chatbot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/umarmk%2Fkanari-chatbot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/umarmk%2Fkanari-chatbot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/umarmk","download_url":"https://codeload.github.com/umarmk/kanari-chatbot/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/umarmk%2Fkanari-chatbot/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278891743,"owners_count":26063856,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-08T02:00:06.501Z","response_time":56,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["artificial-intelligence","chatbot","llm","microservice","nestjs","openrouter","postgresql","react","redis"],"created_at":"2025-10-08T04:59:19.890Z","updated_at":"2026-04-09T12:04:03.400Z","avatar_url":"https://github.com/umarmk.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Kanari Chatbot\n\nKanari (pronounced as canary) is a full-stack, production-ready  AI chatbot web app with a clean web interface and a secure backend. Users can sign in, create projects, upload files, and chat in real-time with fast LLM models provided by OpenRouter, while provider API keys stay safely on the server. It’s built for reliability and growth with streaming responses, rate limiting, usage tracking, and an event-driven architecture for scalability.\nBuilt with NestJS (backend), React + Vite + Tailwind (frontend), PostgreSQL/Prisma (data), and Redis (caching/queues).\n\n\u003cimg width=\"1919\" height=\"909\" alt=\"image\" src=\"https://github.com/user-attachments/assets/cc094a66-1af3-49e8-b6df-61e25b407ff1\" /\u003e\n\n## Tech Stack\n\n- Backend: NestJS (Gateway API)\n- Frontend: React + Vite + TailwindCSS (SPA)\n- Data: PostgreSQL (Prisma ORM), Redis (refresh sessions)\n- LLM: OpenRouter (streaming chat completions)\n- Auth: JWT (access), opaque refresh tokens (Redis), Google OAuth2 (PKCE)\n- Tooling: pnpm workspaces, Docker + Compose\n\n## Monorepo Layout\n\n```\n.\n├─ apps/\n│  └─ gateway        # REST API: auth, projects, files, chats, SSE streaming\n├─ web/              # React SPA (Vite)\n├─ prisma/           # Prisma schema and migrations\n├─ deploy/           # infra helpers (docker/compose/etc.)\n├─ docs/             # API and design docs\n└─ package.json      # workspace root\n```\n\n## Local Dev\n\nPorts:\n- Gateway API: `http://localhost:3000`\n- Web SPA: `http://localhost:5173`\n\n### Prerequisites\n\n- Node.js \u003e= 20\n- pnpm (v9 recommended)\n- Docker (optional, for local Postgres/Redis)\n\n### Environment variables\n\nCreate a `.env` file in the repository root (see `docs/api.md` for details):\n\n```\nNODE_ENV=development\nPORT=3000\n\n# Public URLs\nGATEWAY_PUBLIC_URL=http://localhost:3000\nWEB_URL=http://localhost:5173\n\n# Database / Cache\nDATABASE_URL=postgres://postgres:password@localhost:5432/kanari\nREDIS_URL=redis://localhost:6379\n\n# Auth\nJWT_ACCESS_SECRET=replace-with-a-long-random-string\nSESSION_SIGNING_KEY=replace-with-a-long-random-string\n\n# Google OAuth (optional)\nGOOGLE_CLIENT_ID=\nGOOGLE_CLIENT_SECRET=\n\n# OpenRouter (optional for free models)\nOPENROUTER_API_KEY=\nOPENROUTER_STREAM_TIMEOUT_MS=60000\n\n# Upload / context tuning (optional)\nFILE_MAX_BYTES=20971520\nCONTEXT_MAX_CHUNKS=6\nCONTEXT_MAX_CHARS_PER_CHUNK=1200\n```\n\nNotes:\n- `DATABASE_URL` is required (validated at startup).\n- `WEB_URL` may be a comma-separated list of allowed CORS origins; the first entry is used as the OAuth redirect base in production.\n- In production, `WEB_URL` and `SESSION_SIGNING_KEY` are required.\n- Models are allowlisted by the backend (`GET /models`). `Project.model` must be an allowed id (`400 invalid_model` otherwise).\n- Free models: Gateway uses `OPENROUTER_API_KEY` (server key) if set; otherwise emits a short stub stream for local dev.\n- Paid models: client must provide `x-openrouter-key` (stored locally in the browser); Gateway never uses the server key for paid models.\n- Google OAuth (PKCE): `/auth/google/start?redirect=...` only accepts safe relative paths (must start with `/`). Absolute URLs are ignored.\n- Uploaded files are stored under `uploads/`; deleting a project best-effort deletes its files from disk to avoid orphans.\n\n### Run with pnpm\n\n1) Install deps\n```\npnpm install\n```\n\n2) Start infra (optional, via Docker)\n```\ndocker compose -f deploy/compose/docker-compose.yml up -d postgres redis\n```\n\n3) Migrate DB + generate Prisma client\n```\npnpm exec prisma migrate dev --schema=prisma/schema.prisma\npnpm exec prisma generate --schema=prisma/schema.prisma\n```\n\n4) Start Gateway\n```\npnpm -F gateway start:dev\n```\n\n5) Start Web\n```\npnpm -F web dev\n```\n\n### Run with Docker Compose (backend + infra)\n\n```\ndocker compose -f deploy/compose/docker-compose.yml up --build\n```\n\nThen start the web app locally:\n```\npnpm -F web dev\n```\n\n## Common Commands\n\n- Gateway tests: `pnpm -F gateway test`\n- Gateway build: `pnpm -F gateway build`\n- Web build: `pnpm -F web build`\n\n## Security Notes\n\n- Paid models require OpenRouter key (`x-openrouter-key`); server key is only used for free models.\n- OAuth redirect hardening: `/auth/google/start?redirect=...` only accepts relative paths like `/auth/callback`.\n- Tokens are currently stored in browser `localStorage` (see `web/src/store/auth.ts`).\n=======\n- JWT access tokens; refresh tokens are opaque and rotated on use\n- CORS restricted to local dev origins by default\n- Apply least‑privilege secrets in production; rotate regularly\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fumarmk%2Fkanari-chatbot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fumarmk%2Fkanari-chatbot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fumarmk%2Fkanari-chatbot/lists"}