1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AI実装体験

Last updated at Posted at 2025-11-05

生成AIで作るアプリ

React+TypeScript × Supabase × Netlifyで「音楽アップロード→再生」まで(匿名サインイン版

TypeScriptの基礎は書籍等で学ぶのが望ましいですが、本記事はAIを活用した実装体験にフォーカスします。
ログインUIを省き、Supabaseの匿名サインインワンクリック(実質ノーログイン)にします。
RLS(行レベルセキュリティ)+非公開ストレージ
署名付きURLで、自分の曲だけ見える構成です。

対象: 初心者
使用技術: VSCode / Node / React(TypeScript) / Codex(OpenAI) / Supabase
ゴール: 起動 → 匿名サインイン → 音楽ファイルをアップロード → 一覧から再生
方針: フロントの src/Codex(プロンプト)で生成。この記事はDB・ストレージ・設定が中心。


事前準備

  1. Node.js LTS 18+ をインストール
  2. VSCode をインストール
  3. Supabase にログイン → New project を作成(後で Project URLanon key を使います)
  4. (任意)Netlify アカウント(公開しない学習用なら不要)

Supabase 設定(DB & ストレージ)

1) tracks テーブル + RLS(SQLエディタにそのまま貼る

目的:自分(匿名でもOK)の曲だけ見えて書き込める

create table if not exists public.tracks (
  id uuid primary key default gen_random_uuid(),
  user_id uuid not null references auth.users(id) on delete cascade,
  title text not null,
  path text not null,
  created_at timestamptz not null default now()
);

alter table public.tracks enable row level security;

-- 自分自身のレコードのみ作成/閲覧/削除を許可
create policy "tracks_insert_own" on public.tracks
  for insert with check (auth.uid() = user_id);

create policy "tracks_select_own" on public.tracks
  for select using (auth.uid() = user_id);

create policy "tracks_delete_own" on public.tracks
  for delete using (auth.uid() = user_id);

確認: Table editorで RLS enabled がON、Policies に3つ作成されている。


2) Storage バケット tracks非公開

目的:非公開tracks/<ユーザーID>/<timestamp>-<元ファイル名> にアップロード。再生は署名付きURL

  1. Supabase Storage → Create bucket

    • Name: tracks
    • Public: Off(必ず非公開)
  2. SQL Editor に以下をそのまま貼る(Storageポリシー)

-- 自分のID配下だけアップロード可(認証済ユーザー=匿名含む)
create policy "storage_upload_own_prefix" on storage.objects
  for insert to authenticated
  with check (
    bucket_id = 'tracks'
    and (storage.foldername(name))[1] = auth.uid()::text
  );

-- 読み取りは「認証済」に限定。再生は署名付きURLで行う
create policy "storage_read_signed" on storage.objects
  for select to authenticated
  using (bucket_id = 'tracks');

3) 匿名サインインを有効化

Supabase Auth → Providers → AnonymousEnable
(非公開の自己学習ならreCAPTCHAは任意。公開運用時は推奨)


環境変数

  • ローカル: プロジェクト直下 .env.local を作成し、以下を貼る
VITE_SUPABASE_URL=(SupabaseのProject URL)
VITE_SUPABASE_ANON_KEY=(anon key)
  • Netlify(任意): Site settings → Environment → 同名の2つを追加

プロジェクト雛形(Codexに任せる

ここから src/ 配下はすべてCodexが生成
手順:各プロンプトをそのまま貼る → 出力コードをファイルに反映

0) 共通の前置き(毎回最初に付けると精度UP)

あなたはフロントエンドエンジニアです。React+TypeScript+Vite と Supabase(auth/storage/postgres) を使って、
最小構成で安全に動くアプリを段階的に作ります。コードは「必要なファイルの差分のみ」「ファイルパス付き」で出力。
RLS前提・Storageは非公開・再生は署名付きURL。コメントは短く。日本語で説明してください。

1) Vite 雛形と依存関係(ターミナル手順を出力させる)

Vite(react-ts)で新規プロジェクトを作る端末コマンドを出力。
続けて @supabase/supabase-js の追加、ESLint導入、開発起動までのコマンドを提示してください。

要件:
- パッケージマネージャはnpm
- 失敗しやすい箇所の注意を1行添える
- 実行順でそのままコピペできる形式

2) Supabaseクライアント & .env(ファイルを作らせる)

.env.local に VITE_SUPABASE_URL と VITE_SUPABASE_ANON_KEY を置く前提で、
src/lib/supabase.ts を作る最小コードをファイルパス付きで出力。
authはセッション永続化とトークン自動更新を有効化してください。

3) 匿名サインインを自動化(UIなし・起動時に一度だけ)

アプリ起動時に匿名サインインを自動実行する初期化ロジックを追加してください。
要件:
- セッションが無ければ supabase.auth.signInAnonymously() を1回だけ実行
- supabase.auth.getSession() と onAuthStateChange で状態を監視
- ローディング中は "Initializing..." を表示
- Auth用のUIは不要 (メール入力フォーム等は削除)
- 変更が必要なファイルの差分のみ、ファイルパス付きで出力
- App.tsx に組み込み。日本語コメントは短く

4) Uploader(音声のみ・DB登録)

音声ファイル専用の Uploader コンポーネントを生成してください。
要件:
- 受け付ける拡張子: mp3, m4a, wav, ogg (MIMEで検証)
- pathは tracks/<user_id>/<timestamp>-<元ファイル名>
- Storageにアップロード成功後、DBの public.tracks に (title, path, user_id) をinsert
- 成功時はフォームをリセットし、軽くトーストまたはalert
- 20MB超はアップロード拒否(フロントでチェック)
- 差分のみ、ファイルパス付きで出力

5) 一覧&再生(署名付きURL 1時間)

TrackList と Player を作成してください。
要件:
- tracks表を created_at 降順で取得
- 各行に「再生」ボタン
- クリックで storage.createSignedUrl(path, 3600) を生成し、<audio controls> で再生
- App.tsx へ組み込みの差分も出力
- エラー時は簡潔にalert

6) アクセシビリティ + 軽量CSS

フォーム/ボタン/リスト/プレイヤーに最低限の aria-* とフォーカススタイルを付与。
モバイルでタップしやすい余白とフォントサイズを素のCSSで追加。
差分のみ、ファイルパス付きで出力。

ローカルで動かす(学習用・非公開)

  1. 依存関係をインストール(プロンプト1の出力どおり)
  2. プロジェクト直下に .env.local を作成し、SupabaseのURL/anon keyを貼る
  3. npm run dev
  4. 初回ロードで自動的に匿名サインイン → 音声をアップロード → 一覧から再生

(任意)Netlifyに公開する場合

今回は非公開の自己学習が前提なので任意。公開するなら以下。

  • GitHubにPush → NetlifyでImport
  • Build command: npm run build / Publish directory: dist
  • 環境変数:VITE_SUPABASE_URL / VITE_SUPABASE_ANON_KEY
  • SPA向け public/_redirects を作成(リポジトリに含める)
/* /index.html 200

片付けチェックリスト(最短ルート)

  • Supabaseで tracks 表&RLS
  • Storageに非公開バケットtracks + ポリシー
  • Anonymous sign-ins を Enable
  • Vite雛形(プロンプト1
  • Supabaseクライアント & .envプロンプト2
  • 匿名サインイン自動化プロンプト3
  • アップロード(プロンプト4
  • 一覧・再生(プロンプト5
  • (任意)Netlify環境変数&デプロイ
  • 動作確認(起動→匿名サインイン→アップロード→再生)
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?