# 東京ライブハウス イベント情報 東京の主要ライブハウスのイベント情報を自動収集・集約するフルスタック Web サービス。 React Router v7 (SSR) + SQLite + Tailwind CSS で構築。 ## 機能 - 複数ライブハウスのイベントをスクレイピングで自動取得 - キーワード・会場・期間によるフィルタリング - 出演者・日時・場所・チケットURL・料金を一覧表示 - 会場ごとのイベント Markdown ファイルを自動生成(開発参照用) - スクレイパーをモジュールとして追加可能な設計 ## 対応ライブハウス(初期) | 会場 | エリア | |------|--------| | LIQUID ROOM | 恵比寿 | | WWW / WWW X | 渋谷 | | 渋谷 O-EAST / O-WEST | 渋谷 | | 新宿 LOFT | 新宿 | | CLUB QUATTRO | 渋谷 | ## セットアップ ### 必要環境 - Node.js 20.12 以上(`styleText` API が必要) - npm ```bash npm install npm run dev ``` `http://localhost:5173` にアクセス。 ### 本番ビルド ```bash npm run build npm start ``` ## 画面構成 | パス | 内容 | |------|------| | `/events` | イベント一覧(フィルタ付き) | | `/events/:id` | イベント詳細 | | `/venues` | 会場一覧 | | `GET /api/scrape` | 全会場スクレイプ実行 | | `GET /api/scrape?venue_id=` | 特定会場のみ実行 | ## 新しい会場を追加する ### 1. スクレイパーファイルを作成 `app/scrapers/` に新しいファイルを追加し、`Scraper` インターフェースを実装する。 既存のファイル(例: [`app/scrapers/liquid-room.ts`](app/scrapers/liquid-room.ts))を参考にする。 ```ts import type { Scraper, VenueMeta } from "./base"; export const venue: VenueMeta = { id: "my-venue", // URL 等から小文字ハイフン区切りで name: "MY VENUE", url: "https://example.com", area: "渋谷", }; export const scraper: Scraper = { venue, async scrape() { // fetch → cheerio でパース → EventInput[] を返す }, }; ``` ### 2. インデックスに登録 [`app/scrapers/index.ts`](app/scrapers/index.ts) に追記するだけで自動的に全機能に反映される。 ```ts import { scraper as myVenue } from "./my-venue"; export const ALL_SCRAPERS: Scraper[] = [ // 既存... myVenue, ]; ``` ### Claude Code スキル プロジェクト内に `/add-livehouse` スキルを定義済み。 Claude Code から `/add-livehouse <会場名> ` を実行するとスクレイパー追加を自動的にガイドする。 ## プロジェクト構成 ``` app/ ├── lib/ │ ├── db.server.ts # SQLite 操作(better-sqlite3) │ ├── scraper-runner.server.ts # スクレイプ実行 + Markdown 生成 │ ├── markdown-writer.server.ts # events/.md 生成(開発参照用) │ └── venue-meta.server.ts # サーバー専用スクレイパーメタデータ ├── scrapers/ │ ├── base.ts # Scraper インターフェース定義 │ ├── index.ts # スクレイパーレジストリ(ここに追加) │ ├── liquid-room.ts │ ├── www-shibuya.ts │ ├── shibuya-o.ts │ ├── shinjuku-loft.ts │ └── club-quattro.ts ├── components/ │ ├── EventCard.tsx # イベントカード(出演者・日時・会場・料金・URL) │ └── FilterBar.tsx # 検索フィルタ └── routes/ ├── events._index.tsx ├── events.$id.tsx ├── venues.tsx └── api.scrape.ts events/ # スクレイプ後に自動生成される Markdown(開発参照用) ``` ## 注意事項 - 各ライブハウスの HTML 構造はサイトによって異なるため、スクレイパーのセレクタは実際のページを確認しながら調整が必要 - JavaScript レンダリングが必要なサイトは `fetch` ではなく公式 RSS / API の利用を検討する