{
  "markdown": "# ☕ Kissaten - Coffee Bean Discovery Platform\n\nA coffee bean database and search application that scrapes coffee bean information from roasters worldwide (~400 roasters) and provides a modern interface to discover and explore specialty coffee.\n\n## ✨ Features\n\n- **🔍 Unified Search**: Search and filter across beans, roasters, origins, tasting notes, varietals, processes, and flavours with a single query or advanced filters\n- **🏷️ Faceted Filtering**: Refine results by origin, roaster, process, varietal, roast level, price, and availability\n- **🫘 Bean Detail Pages**: Tasting notes, processing, elevation, cupping scores, pricing, and direct links to roaster sites\n- **🏭 Roaster & Origin Exploration**: Browse roasters, origins by country → region → farm, and roasted-in locations with stats\n- **🤖 AI Features**: AI-powered bean search (including image search) and a guided brew assistant\n- **📊 Analytics & Insights**: Visualize statistics on origins, processes, varietals, and price trends\n- **🧭 Guided Discovery**: Explore by flavour, process, or varietal with curated links and educational content\n- **🗄️ Personal Vault**: Save and organize your favourite beans\n- **🌗 Theme Toggle**: Light/dark mode\n- **📱 Fully Responsive**: Mobile-first design with collapsible filters\n\n## 🏗️ Architecture\n\n### Backend (FastAPI + DuckDB)\n- **FastAPI**: Modern, fast web framework for the API\n- **DuckDB**: High-performance analytical database\n- **Pydantic v2**: Data validation and serialization\n- **Scrapers**: One module per roaster (~400), using httpx, BeautifulSoup4/lxml, or Playwright for JavaScript-heavy sites\n- **Typer CLI**: `kissaten` command-line interface for scraping, refresh, and validation workflows\n- **Logfire**: Observability and telemetry\n\n### Frontend (SvelteKit + shadcn-svelte)\n- **SvelteKit**: Full-stack web framework (Svelte 5 runes)\n- **shadcn-svelte / bits-ui**: Accessible UI components\n- **Tailwind CSS v4**: Utility-first CSS\n- **TypeScript**: Type-safe JavaScript\n- **Bun**: Package manager and dev server\n\n### Data\nScraped data is stored as per-bean JSON files with incremental diff updates, then loaded into DuckDB for querying. See [docs/INCREMENTAL_DATABASE_UPDATES.md](docs/INCREMENTAL_DATABASE_UPDATES.md) for details.\n\n## 🛠️ Getting Started\n\n### Prerequisites\n- Python 3.10+\n- [uv](https://github.com/astral-sh/uv) (Python package manager)\n- [Bun](https://bun.sh) 1.0+\n- (Optional) HTTP proxy if scraping from behind one\n\n### Backend Setup\n\n```bash\nuv sync\ncp env.example .env   # optional: add API keys / proxy settings\n```\n\nStart the API server:\n\n```bash\nuv run kissaten serve              # API at http://localhost:8000\nuv run kissaten serve --reload     # dev mode with auto-reload\nuv run kissaten dev --frontend     # API + frontend together\n```\n\n> Note: `serve` opens the production database read-only. Writes happen through the refresh pipeline — see [docs/TESTING.md](docs/TESTING.md) for the database modes.\n\n### Frontend Setup\n\n```bash\ncd frontend\nbun install\nbun run dev\n```\n\nThe frontend will be available at `http://localhost:5173` and proxies API calls to `:8000`.\n\n## 🔄 Data Pipeline\n\n1. **Scrape**: `kissaten run-all-scrapers` (or `kissaten scrape <roaster>`) writes per-bean JSON + diff artifacts into `data/roasters/<roaster>/<YYYYMMDD>/`\n2. **Refresh**: `kissaten refresh --incremental` applies the diffs to the read-write DuckDB\n3. **Validate**: `kissaten validate-db` runs integrity checks before promotion\n4. **Promote**: `cp data/rw_kissaten.duckdb data/kissaten.duckdb` swaps the validated database into production\n\nSee [docs/SCHEDULING.md](docs/SCHEDULING.md) for the recommended hourly scheduling setup.\n\n## 🧭 CLI Commands\n\nCommon `kissaten` commands:\n\n| Command | Purpose |\n| --- | --- |\n| `scrape <roaster>` / `test-scraper` | Scrape or test a single roaster |\n| `run-all-scrapers` | Run all scrapers (supports batched scheduling) |\n| `refresh` | Apply scraped diffs to the read-write database |\n| `validate-db` | Validate the database before promotion |\n| `serve` / `dev` | Run the API (and optionally the frontend) |\n| `show-bean` | Inspect a scraped bean record |\n| `apply-review-decisions` | Apply admin tasting-kit review decisions |\n| `categorize-*` / `validate-mappings` | Manage origin, process, varietal, and tasting-note mappings |\n\n## 🔌 API Endpoints\n\nAll routes live under `/v1`:\n\n- `GET /v1/search` - Search coffee beans with filters\n- `GET /v1/beans/{roaster_slug}/{bean_slug}` - Get a specific bean (+ `/recommendations`)\n- `GET /v1/roasters` - List roasters\n- `GET /v1/origins` - Explore origins, regions, and farms\n- `GET /v1/processes` / `GET /v1/varietals` - Processing methods and varietals\n- `GET /v1/tasting-note-categories` - Tasting notes and flavour categories\n- `POST /v1/ai/search` (+ `/extract`, `/imagesearch`) - AI-powered search\n- `POST /v1/brew-assistant` - Guided brew recommendations\n- `GET /v1/stats` / `GET /v1/health` - Statistics and health checks\n\nThe full route list lives in `src/kissaten/api/main.py`.\n\n## 🧪 Development\n\n### Adding New Scrapers\n\nSee [ADDING_SCRAPERS.md](ADDING_SCRAPERS.md) for the full walkthrough. Platform-specific patterns (Shopify, Squarespace, and general) are documented as skills in `.opencode/skills/` — each comes with a ready-made scraper template. Register new scrapers in `src/kissaten/scrapers/registry.py` and add tests in `tests/unit/`.\n\n### Proxy Configuration\n\nScrapers support HTTP/HTTPS proxies via environment variables in `.env`:\n\n```bash\nHTTP_PROXY=http://proxy.example.com:8080\nHTTPS_PROXY=http://proxy.example.com:8080\n```\n\nBoth httpx and Playwright use the configured proxy; `HTTPS_PROXY` wins when both are set. See [docs/PROXY_CONFIGURATION.md](docs/PROXY_CONFIGURATION.md).\n\n### Tests\n\n```bash\nuv run pytest        # backend tests (DB isolation handled automatically)\ncd frontend && bun run test   # frontend unit + integration tests\n```\n\n## 🤝 Contributing\n\nContributions are welcome! See [AGENTS.md](AGENTS.md) for project conventions, then open a pull request.\n\n## 🙏 Acknowledgments\n\nThanks to all the specialty coffee roasters who make their bean information publicly available, enabling this project to help coffee enthusiasts discover amazing beans from around the world.",
  "bytes": 6241,
  "sha": "a4d567a0d59234b94e53ae23d10fd4f18e4c2d4ed01cb1aae68a42f2db3e4c34",
  "repo_slug": "dldx/kissaten",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/okf_dldx_kissaten_openwiki_index_md_cca7407c/readme"
}