summaryrefslogtreecommitdiff
path: root/README.md
blob: 7347bfca750f3f5c4c296432a5c042ba9154f5c0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# 東京ライブハウス イベント情報

東京の主要ライブハウスのイベント情報を自動収集・集約するフルスタック 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=<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 <会場名> <URL>` を実行するとスクレイパー追加を自動的にガイドする。

## プロジェクト構成

```
app/
├── lib/
│   ├── db.server.ts              # SQLite 操作(better-sqlite3)
│   ├── scraper-runner.server.ts  # スクレイプ実行 + Markdown 生成
│   ├── markdown-writer.server.ts # events/<venue-id>.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 の利用を検討する