Open10

「Cursor Webアプリハッカソン」の作業記録

なぎそらなぎそら

Cursor Webアプリハッカソン by Sunrise AI

https://connpass.com/event/331709/

ちょうどアプリを作ろうと思ってた所でAIハッカソンがあったので、参加してみることにしました!

Zennのスクラップに経過を残し、終わったらちゃんとした記事にまとめようと思います。

ハッカソンで提出するアプリのGitHubは以下のものです。
publicなので、良かったら参考にどうぞ~!
https://github.com/nagisora/mail-mag-reader

ハッシュタグ「#CursorSunHack」でつぶやく際は、以下のリンクが便利です。keitaroさんに感謝!
https://tinyurl.com/298cjxx4

なぎそらなぎそら

作業記録:20240924

ハッカソンの方針

  • できるだけお金をかけない(1,000円以下に収める)
  • できるだけコーディングしない(自然言語プログラミングはOK)
  • できるだけAIを使う(人力は極力避ける)
  • できるだけ情報はオープンにする(オープンソースプロジェクト)

アプリの企画

目的

中島聡さんの「週刊 Life is beautiful」(以下、wlib)を、自分がより活用するためのアプリを作る

具体案

  1. リーダーアプリ:メルマガの前回読み終えた位置を記録し、次回は続きから読めるアプリ
  2. RAGアプリ:wlibの内容についてAIが何でも答えてくれるアプリ

ハッカソンでは、リーダーアプリの完成をゴールとする。
余裕があればRAGアプリも作る

スケジュール

最終提出締切:2024年10月26日 21:00

  • ~9/28:準備(使えそうなAIツールを色々触ってみる)
  • ~10/6:企画
  • ~10/20:構築
  • 10/26:リリース

技術スタック

  • 要件定義書作成(Zoltraak、GEAR.indigo)
  • フロント作成(Next.js、LlamaCoder)
  • バックエンド(supabase)
  • Git管理(Claude-dev)

使ってみたいもの

  • markwhen
  • PDF2Audio
なぎそらなぎそら

作業記録

  • 20240925:Googleセミナー参加で疲れたのでサボり
  • 20240926:お仕事疲れたのでサボり
  • 20240927:ブログを書くのが楽しかったのでサボり

サボったことも正直に報告していくスタイル(笑)

なぎそらなぎそら

作業記録:20240928

  • キックオフに参加
  • きのぴーさんのCursor解説が非常に分かりやすかった
  • 学んだ点をまとめておくべきだったので、次回はそうする
  • ターミナルでCtrl+Kできるのが有用すぎ!docsとかも結構使えそう
  • AIツールの使い方セミナーが後半とかにあったりするので、自力&質問しながら進めないと間に合わなさそう
  • 明日は企画書を作ろう
なぎそらなぎそら

作業記録:20240929

  • 今日の目標:「GEAR.indigo」を使い、企画&要件定義を行う

GEAR.indigoへの入力をChatGPTで作成

プロンプト

メルマガリーダーを作りたい。以下の要件を含めて仕様を考えて。必要な部分は追記して。markdown形式で出力して。

- リーダーへのemailの入力は、eml形式のファイルのアップロードとする
- 将来的には、自身のメールクライアントから指定アドレスへemailを転送することで入力できるようにする
- Next.js、supabaseを使う
- メルマガを読んだ位置を記録し、次回同じメルマガを開いたら前回読み終えた位置の続きから読めるようにする
- フォントサイズ、ダークモードなど、テキストリーダーにあったほうが良い機能ももたせる
- authはgoogleのssoのみで行う
- メルマガ自体は個人のデータとして持つのではなく、システムで持つ
	- メルマガの入力があった場合に、タイトルや本文と比較を行い、既にあれば読み込み元をそれに、なければ、新規にメルマガを登録する
	- この目的は、DBの圧縮と冗長をなくすことである
	- 個人のアカウントと有効なメルマガを紐付けるようにする
- 将来的にメルマガのデータをAIに学習させて、メルマガの内容についてAIに問い合わせができるようにする
- 将来的に、色々なメルマガに対応させる。そのため、メルマガ単位の管理ができるようにしておく。

出力

# メルマガリーダー仕様書

## 概要
本仕様書は、Next.jsとsupabaseを使用したメルマガリーダーアプリケーションの仕様を記載しています。このアプリでは、ユーザーがeml形式のメールをアップロードし、将来的には指定アドレスへ転送することでメルマガの管理と閲覧が可能になります。さらに、メルマガの読書履歴やカスタマイズ可能なリーダー機能を提供します。

## 要件

### 1. Emailの入力方法
- **現在の入力方法**: eml形式のファイルをアップロードしてメルマガをリーダーに取り込む。
- **将来の入力方法**: ユーザーが自身のメールクライアントから指定されたシステムのメールアドレスにメルマガを転送することで、リーダーに取り込むことができるようにする。

### 2. 読書履歴の管理
- メルマガを読んだ位置を記録し、次回同じメルマガを開いた際に、前回の読み終えた位置から続きが読めるようにする。

### 3. テキストリーダー機能
- フォントサイズ変更機能を提供し、ユーザーが快適にメルマガを閲覧できるようにする。
- ダークモードを搭載し、環境に合わせた表示設定ができるようにする。

### 4. 認証
- GoogleのSSOを用いたシンプルなログインを提供する。Googleアカウントのみで認証を行い、アカウント管理を簡便にする。

### 5. メルマガの管理
- **メルマガのデータ保存**: 個人が所有するデータとしてではなく、システムで一元的に管理する。
  - メルマガの入力があった際、タイトルや本文を比較し、既にデータベースに登録されているメルマガであれば、それを読み込み、そうでなければ新規に登録する。
  - これにより、データの冗長化を避け、データベースを効率的に運用する。
  - 各ユーザーのアカウントに対して、システム内で有効なメルマガと紐付ける。

### 6. 将来的なAI連携
- メルマガの内容をAIに学習させ、ユーザーがメルマガの内容について質問した際に、AIから適切な回答が得られる機能を導入する。

### 7. メルマガ単位の管理
- 複数の異なるメルマガに対応できるよう、メルマガ単位でデータを管理する仕組みを持たせる。
  - 将来的には、複数の種類のメルマガ(週刊誌、月刊誌、ビジネスニュースなど)に対応できるように拡張する。

## 使用技術
- **フロントエンド**: Next.js
- **バックエンド**: Supabase(認証、データベース、ストレージ管理)
- **認証**: Google SSO

## データベース設計

### テーブル構造
#### `users`
- `id` (主キー)
- `email` (Google SSOから取得)

#### `newsletters`
- `id` (主キー)
- `title` (メルマガのタイトル)
- `body` (メルマガ本文)
- `created_at` (登録日時)

#### `user_newsletter_progress`
- `id` (主キー)
- `user_id` (外部キー: users)
- `newsletter_id` (外部キー: newsletters)
- `last_read_position` (前回の読書位置)
- `created_at` (作成日時)
- `updated_at` (更新日時)

## UI/UX機能

### 1. メルマガアップロード画面
- emlファイルをアップロードするフォーム。
- アップロードされたファイルの解析を行い、既存のメルマガデータベースと照合してデータ登録。

### 2. メルマガリーダー画面
- メルマガを表示し、フォントサイズやダークモードの切り替えが可能。
- ユーザーが読んだ位置を記録し、次回から自動的にその位置から表示する。

### 3. ユーザー設定画面
- フォントサイズやダークモードの設定を管理する。
- Google SSOでログイン済みか確認する画面。

## 将来的な機能拡張
- メルマガの内容をAIが学習し、質問に応じて情報を提供する機能。
- 複数メルマガの管理と、それぞれの読書履歴の管理機能。

GEAR.indigoでの操作

  • 入力にChatGPTが出力したテキストを貼り付けて実行
  • プロジェクトに必要なテキストが1分くらいで出力されてすごい
  • 0→1、はこれで出来たので、これをたたき台として作っていくか
  • ソース生成は有料なので、Zoltraakも試してみよう

Babel&Zoltraak

  • Babel&Zoltraak:アプリ生成AIツール。ハッカソンの審査員である元木さん作成
  • ChatGPTに入れたテキストをそのままBabelに入れてみた
  • ずっとポヨポヨして何かしている。気長に待つ
  • エディタ左下の「最近の変更」が増えなくなったら完成?
  • 右上にあるボタンからコードをダウンロードして、Cursorで開発する

出力

まとめ

  • webアプリの「ポン出し」(最小限の指示でアプリが作れる)AIツールの、GEAR.indigoとBabel&Zoltraakを使ってみた。
  • GEAR.indigoは、プロジェクトを進める上で必要な資料を用意してくれるので、そこに頭を使わなくてよいのが非常に助かる。特にE-R図の自動作成など、各種図示がとても便利。
  • Babel&Zoltraakは、システムに必要なファイルを全部作ってくれる。これをダウンロードしてカスタマイズすれば良いだけなので、助かりすぎる。
  • どちらも無料範囲内のみを使った感想だが、両方使うことでアプリ開発に必要なものが全て揃った感じ。すごい時代だ。
  • 明日は、ダウンロードしたコードを実際にCursorで動かしてみる
  • その次は、YouTube見てnextjs, supabaseの理解を深める
なぎそらなぎそら

作業記録:20240930(20:00~22:30)

  • 今日の目標:生成AIで作ったファイルを動かしてみる

Zoltraak.appでコード作成

  • 「Babel&Zoltraakが難しい」という話をDiscordでしていたので、ダイブツさんのZoltraak.appを使うことにした。
  • 要件定義がjsになっていたので、TypeScriptに直してもらった

Next.jsプロジェクト作成

  • wslのubuntuにnvmを入れて、以下コマンドでプロジェクト作成
$ npx create-next-app@latest --typescript
✔ What is your project named? … mail-mag-reader
✔ Would you like to use ESLint? … No / Yes
✔ Would you like to use Tailwind CSS? … No / Yes
✔ Would you like to use `src/` directory? … No / Yes
✔ Would you like to use App Router? (recommended) … No / Yes
✔ Would you like to customize the default import alias (@/*)? … No / Yes
Creating a new Next.js app in /home/junya/dev/MailReader00/mail-mag-reader.

Using npm.
  • yarn devで以下のエラーが出る
r$ yarn dev
00h00m00s 0/0: : ERROR: [Errno 2] No such file or directory: 'dev'
  • npmだと動く。謎。
~/dev/MailReader00/mail-mag-reader$ npm run dev
Debugger listening on ws://127.0.0.1:53608/8be3a637-5318-4ed3-a4c8-be44126fa005
For help, see: https://nodejs.org/en/docs/inspector
Debugger attached.

> mail-mag-reader@0.1.0 dev
> next dev

Debugger listening on ws://127.0.0.1:53478/1af5564f-25a5-46bd-a87e-36bd97e33092
For help, see: https://nodejs.org/en/docs/inspector
Debugger attached.
Debugger listening on ws://127.0.0.1:53370/2346c87b-94d3-4481-b809-cc590b3236c2
For help, see: https://nodejs.org/en/docs/inspector
Debugger attached.
  ▲ Next.js 14.2.13
  - Local:        http://localhost:3000

 ✓ Starting...
  • Zoltraak.appのソースを組み込もうとしたけどよく分からない

v0を試す

  • nextjsならv0ってことで、要件定義書をポイしてみた
  • なんか良さげなのできたからsupabase入れようとしたら、プロジェクト作成コマンドが違ったみたいで作り直し
npx create-next-app -e with-supabase
  • npm run devで起動して、v0のコード貼り付けて画面は出来た
  • でも、フォルダが色々あってよく分からない。

今日のまとめ

追記

  • 吉波さんのXのポストを見て自分も試してみた。
  • こんな感じでできた。
  • You have 2 message remaining today.って言われたし疲れたので、動くかは明日やる。
  • 1時間くらい動かしてダメだったら、YouTubeで勉強する
なぎそらなぎそら

作業記録:20241001(21:00~22:30)

  • 今日の目標:v0のコードを動かしてみる(1h以下)
  • Youtubeで勉強

v0のコードを組み込む

  • 組み込んだけどモジュールとか色々必要で、よく分からんかった。断念。
  • Discordに最小構成から少しずつ作ったほうが良いというアドバイスがあったから、そうする

YouTube見つつ作成

まとめ

  • まだ、「よろしく!」でAIが作ってくれないので、少しずつパーツ単位で作っていくのが良さそう。
  • 明日は、Googleのセミナーに参加して時間が取れないので、お休みの予定です。
  • 使ったプロンプトも開示した方が、皆の参考になると思うので、次回からそうする
  • 次回はデータベース構成を考える
  • DBが出来たら、emlの実際のメルマガを登録して画面で見てみる
  • メルマガがアップロードされたら、タイトルと本文の一致を調べる
  • 愉快犯にファイルをアップロードされまくったらどうする?
なぎそらなぎそら

作業記録:20241002

  • Googleの起業セミナー参加で疲れたのでお休み

作業記録:20241003(20:00~23:30)

今日の予定

  • .cursorrulesの比較記事を書く
  • データベース構成を考える

.cursorrulesの比較記事

データベース構成

  • ハッカソンのDiscordで聞いたら、https://postgres.new/ がオススメと教えていただいたので、使ってみる。
  • 要件定義をペタ
# メルマガリーダーを作りたい。

- リーダーへのemailの入力は、eml形式のファイルのアップロードとする
- Next.js(TypeScript), Vercel, supabaseを使う
- メルマガを読んだ位置を記録し、次回同じメルマガを開いたら前回読み終えた位置の続きから読めるようにする
- authはgoogleのssoで行う
- メルマガ自体は個人のデータとして持つのではなく、システムで持つ
	- メルマガの入力があった場合に、タイトルや本文と比較を行い、既にあれば読み込み元をそれに、なければ、新規にメルマガを登録する
	- この目的は、DBの圧縮と冗長をなくすことである
	- 個人のアカウントと有効なメルマガを紐付けるようにする
  - メルマガは、メルマガ名と号数で管理ができるようにしておく。
  • 良い感じ。図示してくれるし、SQLも吐いてくれる。
## users テーブル

| カラム名         | データ型                | 制約                  | 説明               |
|------------------|-------------------------|-----------------------|--------------------|
| id               | BIGINT                  | PRIMARY KEY, IDENTITY | ユーザーID         |
| google_user_id   | TEXT                    | UNIQUE, NOT NULL      | GoogleユーザーID   |
| email            | TEXT                    | UNIQUE, NOT NULL      | ユーザーのメールアドレス |
| created_at       | TIMESTAMPTZ             | DEFAULT NOW()         | 作成日時           |

## newsletters テーブル

| カラム名         | データ型                | 制約                  | 説明               |
|------------------|-------------------------|-----------------------|--------------------|
| id               | BIGINT                  | PRIMARY KEY, IDENTITY | メルマガID         |
| name             | TEXT                    | NOT NULL              | メルマガ名         |
| issue_number     | INT                     | NOT NULL              | 号数               |
| title            | TEXT                    | NOT NULL              | メルマガのタイトル |
| content          | TEXT                    | NOT NULL              | メルマガの内容     |
| created_at       | TIMESTAMPTZ             | DEFAULT NOW()         | 作成日時           |

## user_newsletter_progress テーブル

| カラム名         | データ型                | 制約                  | 説明               |
|------------------|-------------------------|-----------------------|--------------------|
| id               | BIGINT                  | PRIMARY KEY, IDENTITY | 進捗ID             |
| user_id          | BIGINT                  | REFERENCES users(id)  | ユーザーID         |
| newsletter_id    | BIGINT                  | REFERENCES newsletters(id) | メルマガID     |
| last_read_position | INT                   | DEFAULT 0             | 最後に読んだ位置   |
| updated_at       | TIMESTAMPTZ             | DEFAULT NOW()         | 更新日時           |

開発

  • プロジェクトにsupabaseを追加
npm install @supabase/supabase-js
  • emlファイルを文字コード変換しつつconsole.logに表示するところまで出来た
  • 4o-miniが微妙なので、cloude-3.5-sonnetに頼った。
  • Cursor無課金なのにコードの予測提案された。謎。ありがとう~
  • あと何かずっとエラー吐いてる。悲しい。
Warning: Prop `className` did not match. Server: 

まとめ

  • emlファイルの読み込みがクソ大変だった
  • メルマガタイトルとか、何からどう引っ張れば良いんだ?
  • とりま、ハードコーディングした
  • メルマガ毎にテンプレ用意してそれで分けるか、AIにタイトル食わせて分けさせるか
  • ハッカソンではwlibだけに対応して、今後やる気があったら他のにも対応する
  • 明日は、emlのデータを画面に表示する、データをsupabaseに保存する
  • 中島さんが7月くらいにメルマガの日付を間違えてたので、日付が同じでタイトルが違ったら、日付+7する
なぎそらなぎそら

作業記録:20241004(20:30~22:30)

  • 金曜日なので疲れて1hくらいゴロゴロして、「今日くらいはゴロゴロしてもいいよね?」とか思ったけど、やることやって罪悪感をなくしてから思う存分ゴロゴロしようと思って始めた。
  • みなさんはどうでしょうか!?

今日の予定

  • emlのデータを画面に表示する
  • データをsupabaseに保存する

emlのデータを画面に表示する

  • ダミーデータをemlのデータでuseState使って上書きしただけ

データをsupabaseに保存する

  • supabaseを入れたタイミングでコードをcursorが作ってくれてたので、コメントアウトを外したらちゃんと保存された

次何を作るかの検討

  • ログインしたら前回のメルマガの続きが表示される
    • ログイン機能
    • ユーザーとメルマガの紐づけ
    • ユーザーが読み終えた位置の記録

ログイン機能の作成

  • 以下のプロンプトとコードをv0に渡したら、それっぽいのができた。
以下のnext.jsのコードにサインボタンを作り、supabaseの認証を使ってgoogleアカウントでサインインさせたい
  • 疲れたので今日は終わり。
  • 次はsupabaseとGCPの設定をして認証ができるようにする

まとめ

  • テストデータとしてメルマガになる前のweb版のLife is beautifulが使えそう
  • 手動でemlデータにしたけど、webから直接取得したい
  • ハッカソンで見せる用のゲストユーザーにはこれを見せればよいと思った
  • supabaseは保存が楽で助かる
  • 認証周りはよく分からないから、勉強しながらかな。
  • 次は、認証周りくらいかなあ
  • boltでやってみる
なぎそらなぎそら

作業記録:20241005(19:00~21:00)

  • ハッカソンのセミナー参加。良かった内容のメモを残す
  • セミナー参加以外は何もせず。家事やらで土日は追われています

kkさんセミナー

  • Canvaでスライド作っていた。とても見やすい。
  • 有料級とか言うの薄っぺらい感じで好きじゃないんだけど、マジ有料級だった!
  • プロンプトもAIに考えてもらうのがいいよ!メタプロンプト
  • LPサイトの画像をCursorに入れて、そのままコード化できる
  • Email.jsで簡単にメールが送れる。本番は秘匿させるために、Next.jsを使う
  • Netlifyは1時間限定のデプロイ機能がある
  • ソースコードはコンポーネントに分けて小さくしてAIに渡した方が精度が良い
  • なぎそらの感想:今後は、AIに与えるプロンプトに使わせるライブラリを自分で指定できる、っていうのがエンジニアの腕の見せ所になってくるかと思った。
  • localstorageを使うことで、簡易DBとして使える
  • UIデザインも参考にしたいURLを@で渡して真似させると良い

りくおさんセミナー

  • 初心者さん向けだったので、私は流し見。

Git

  • Ctrl+KでAcceptする前にLive Serverを更新すると、変更後の画面が見れる

Next.js

  • Next.jsの基本的な使い方
  • ルーティングについて、app以下にフォルダを作って、page.tsxを作ればよい
  • 認証機能は、「supabaseで認証機能付けて」で作ってくれる

明日

  • 友達とランチに行くので、開発はできないかも。