Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

VoiceBookLM

このドキュメントは、AIを活用したボイスメモアプリケーションの設計と仕様についてまとめたものです。

概要

このボイスメモアプリは、音声を録音し、その内容を自動で文字起こし・要約することで、情報の記録と整理を効率化することを目的としています。会議の議事録、アイデアのメモ、日々のタスク管理など、様々なシーンでご活用いただけます。

Web版

公開URL: https://voicenotelm.app

リリース期間: 2026年1月28日 〜 2月中旬

※ iOS / Android版のリリース予定はありません。

主な機能

本アプリケーションが提供する主な機能は以下の通りです。

  • 音声録音: 簡単な操作でボイスメモを録音します。
  • 自動文字起こし: 録音された音声を高精度なAIがテキストに変換します。
  • 自動要約: 文字起こしされたテキストをAIが解析し、簡潔な要約を生成します。
  • タグ付け・自動振り分け: メモの内容に応じて自動でタグを付け、ジャンルごとに整理します。
  • 検索・閲覧: 過去のメモをキーワードで簡単に検索し、内容をすぐに確認できます。

リポジトリ

製品要件定義書(PRD)

項目内容
プロジェクト名思考崩壊防止型AI音声メモアプリ
バージョン1.1 (Draft)
作成日2025-12-15
ステータス企画・要件定義

1. 製品概要(Product Overview)

本アプリは、ユーザーが思いついた考えやアイデアを音声で話すだけで、 AIが内容を整理し、「読み返しても分かるメモ」に整形する思考整理特化型音声メモアプリである。

解決する主な課題

  • 書いている途中で思考が迷子になる
  • 文章化が難しい
  • 後で読み返した際に意味がわからない

2. 背景・課題(Background / Problem Statement)

ユーザーがメモを残す際に直面している問題は以下の通り。

2.1 書いている途中で迷走する

  • 頭の中では整理できているが、文章にすると論点がズレる
  • 文脈が散乱して一貫性が失われる

2.2 アイデアの文章化が難しい

  • 語彙が出てこない
  • どこから書き始めればよいか分からない
  • 文章構成が難しく、勢いが途切れる

2.3 読み返した時に意味が分からない

  • 説明不足
  • 断片的で文脈が繋がらない
  • 当初の意図を思い出せない

結論: 「メモしたのに役に立たない」「思考整理に活かせない」という問題が根本に存在する。


3. このアプリが提供する価値(Value Proposition)

  • 思考維持:書く途中で思考が崩壊する問題を防ぐ
  • 文章化代行:AIが文章化の苦手を代替し、整ったメモに変換
  • 自動整理:要点・背景・意図・次アクションまで自動で構造化
  • 高再利用性:思考の“本来の形”を保ち、読み返しやすく再利用しやすい

4. 製品目標(Goals)

  • G1: 思考崩壊を防ぐ音声入力を提供する
  • G2: AIが内容を再構成し、読み返し時の理解を保証する
  • G3: 誰でも「分かりやすいメモ」を作れる状態にする
  • G4: 思考の勢いを止めない最小ステップUIを実現する
  • G5: Markdownで構造化し、二次利用を容易にする

5. ペルソナ(Persona)

Persona 1:アイデアマン・学生

  • アイデアは浮かぶが文章整理が苦手
  • 思いついた瞬間に声で残したい
  • 読み返した際に意味不明になるメモが多い

Persona 2:文章を書くのが苦手な人

  • タイピングより話すほうが考えやすい
  • 書く途中で文脈が崩壊しがち
  • 読み返しやすい整理されたメモが必要

6. ユースケース(Use Cases)

  1. 通学中:アイデアを録音 → AIが整理しタイトル付きで保存
  2. 授業・作業中:その場の気づきを音声で記録 → 後で見返して理解できる状態に
  3. 就寝前:モヤモヤを吐き出す → AIが論点を整理してメモ化
  4. 代替入力:文章化が苦手な人が声でメモを残す

対象ユースケース(具体的な利用シーン)

シーン説明
面接の振り返り面接直後に歩きながら感想を話し、後で検索
自己分析ログ散歩中に気持ちを話し、タグで思考を整理
アイデア記録浮かんだ瞬間に話すだけで保存

7. スコープ(Scope)

In Scope(MVP)

  • 音声録音(モバイルアプリ)
  • Google Speech-to-Text APIによる高精度文字起こし
  • AIによる文字起こし内容整形、構造化
  • タイトル自動生成
  • 自動ディレクトリ作成、分類(AI)
  • 自動タグ付け(AI)
  • Markdown形式で保存
  • メモ一覧(タイトル+ディレクトリ構造)
  • 再要約機能

Out of Scope(MVP外)

  • リアルタイム文字起こし
  • obsidianのような編集と閲覧が同じような機能
  • 意味ベース検索(Semantic Search)
    • ニュアンス・文脈で検索可能
    • Embeddingによる類似度検索

8. コア機能(Core Features)

8.1 音声 → テキスト変換

  • Google Speech-to-Text API
  • 言い直し・雑談も保持し高精度で文字化

8.2 AI構造化メモ生成(Markdown)

出力構造:

  • タイトル(AI生成)
  • タグ(AI生成)
  • 本文(LLM整形)
  • 作成日時(属性)

Markdownテンプレ例

---
title: "自動生成タイトル"
tags: ["アイデア", "プロジェクトA"]
created: 2025-12-01
---

# タイトル

LLMが整形した本文がここに入る。
ユーザーの音声入力を元に、読みやすく構造化された文章が生成される。

8.3 自動分類

ジャンル例:アイデア / 日記 / 勉強 / 仕事 / 感情 / TODO

8.4 メモ一覧画面

  • 日付順 / カテゴリ別ソート
  • サマリ表示
  • 正確なキーワード不要
  • ニュアンス検索・文脈検索
  • Embedding による類似度検索

9. 非機能要件(NFR)

  • 安定性: アプリクラッシュ時でも音声データ保持・復旧
  • プライバシー: 音声データは端末内保存を基本とする

(※取り消し線項目は削除し、必要項目のみ残しました)


10. 技術要件(Technical Requirements)

  • フロント: React Native
  • 文字起こし: Google Speech-to-Text API
  • 要約・整形AI: Gemini 2.0 Flash
  • データ保存: PostgreSQ ( 必要に応じてAWS S3)
  • Markdown生成: フロントエンド側でフォーマット(詳細は未確定)

11. 競合分析(Competitive Analysis)

競合サービス特徴本アプリの優位性
TalkNotes会議・制作寄り思考整理に特化したテンプレ
BrainDump音声→Markdown化より強力な構造化・分類機能
Echo Notesライター向け・高品質文字起こし「要約・再構成」を重視
Cleft Notes構造化に強いが汎用的思考崩壊防止に特化したUX
v2mdObsidian特化初心者でも使いやすい構造化テンプレ

差別化ポイント:

  • 会議・議論録音ツールは多いが、個人の思考整理に特化したアプリは少ない
  • タグやディレクトリ構成をAIが自動で提案・整理
  • 「思考の崩壊を防ぐ」「読み返して分かる」出力品質とUX

12. 成果指標(KPI)

  • 理解できたメモ率
  • 1ユーザーあたりの再閲覧数
  • “意味不明メモ”の減少
  • 書くストレスの低減
  • 月間継続利用率
  • 意味検索からのメモ閲覧数
  • 探したいメモが見つかった成功率

13. エレベーターピッチ

「書くと途中で迷子になる思考を、AIが整えて“読み返して分かるメモ”に変換する音声メモアプリ。」

プロダクト概要

VoiceBookLM は、音声ファースト × 自動整理 をコンセプトとした AI 搭載ボイスメモアプリケーションです。

コンセプト

「話すだけで、整理されたメモが自動で作られる」

ユーザーは話すことに集中するだけ。AI がタイトル・本文・タグを自動生成し、クラウドに保存します。

解決する課題

graph TD
    subgraph 従来のメモアプリ
        A[テキスト入力] --> B[タイトル設定]
        B --> C[タグ付け]
        C --> D[整理・分類]
    end

    subgraph VoiceBookLM
        E[話す] --> F[AI が自動整理]
        F --> G[保存完了]
    end

    style D fill:#f99,stroke:#333
    style G fill:#9f9,stroke:#333
課題VoiceBookLM の解決策
キーボード入力は思考を阻害音声入力で思考の流れを保つ
整理作業がユーザー負担AI が自動でタイトル・タグ生成
会議向けが多い個人の思考ログに特化

主要機能

MVPに含む機能

  1. ワンタップ録音 - シンプルな操作で録音開始
  2. AI 自動整理 - タイトル・本文・タグを自動生成
  3. マークダウン対応 - 本文はマークダウン形式で記述・編集・表示
  4. クラウド保存 - どこからでもアクセス可能
  5. 全文検索 - 過去のメモを素早く発見
  6. Google 認証 - 安全なログイン

対象ユースケース

シーン説明
面接の振り返り面接直後に歩きながら感想を話し、後で検索
自己分析ログ散歩中に気持ちを話し、タグで思考を整理
アイデア記録浮かんだ瞬間に話すだけで保存

目標数値

指標目標
録音→AI整形完了30秒以内
検索レスポンス0.5秒以内
クラウド稼働率99%以上

アーキテクチャ

システム全体像

graph TB
    subgraph Client["📱 モバイルアプリ"]
        RN["React Native + Expo"]
    end

    subgraph Backend["🖥️ バックエンド"]
        API["REST API<br/>Spring Boot"]
        DB[(PostgreSQL)]
    end

    subgraph External["🌐 外部サービス"]
        ASR["Google Cloud<br/>Speech-to-Text"]
        AI["AI サービス<br/>Claude/GPT"]
        OAuth["Google OAuth"]
    end

    RN -->|HTTPS| API
    API --> DB
    API --> ASR
    API --> AI
    RN --> OAuth
    API --> OAuth

backend オニオンアーキテクチャ × DDD

バックエンドはオニオンアーキテクチャと**ドメイン駆動設計(DDD)**を採用しています。

graph TB
    subgraph Presentation["🎨 Presentation Layer"]
        Controller["Controller<br/>REST API"]
    end

    subgraph UseCase["⚙️ UseCase Layer"]
        UC["UseCase<br/>ビジネスロジック"]
    end

    subgraph Domain["💎 Domain Layer"]
        Entity["Entity"]
        Repo["Repository<br/>Interface"]
    end

    subgraph Infrastructure["🔧 Infrastructure Layer"]
        JPA["JPA Repository<br/>実装"]
        Client["外部API<br/>クライアント"]
    end

    Controller --> UC
    UC --> Entity
    UC --> Repo
    JPA -.->|implements| Repo
    Client --> ASR["Speech-to-Text"]

    style Domain fill:#ffd,stroke:#333

レイヤー責務

レイヤー責務依存
Domainエンティティ・ビジネスルールなし(純粋Kotlin)
UseCaseアプリケーション固有ロジックDomain のみ
PresentationREST API・DTO変換UseCase のみ
InfrastructureDB実装・外部APIDomain IF を実装

技術スタック

Backend

カテゴリ技術
言語Kotlin 2.0.21
フレームワークSpring Boot 3.4.12
ランタイムJDK 21 LTS
データベースPostgreSQL 16

技術的意思決定

アーキテクチャ選定

オニオンアーキテクチャ × DDD 採用理由

graph LR
    subgraph オニオンアーキテクチャ
        D[Controller] --> E[UseCase]
        E --> F[Domain]
        G[Infrastructure] -.->|implements| F
    end
観点採用理由
ドメイン独立性ビジネスロジックをフレームワークから隔離
テスタビリティDomain/UseCase は純粋Kotlinでテスト可能
拡張性DB変更やCQRS導入に強い構造

ボイスメモ ユースケース図

flowchart LR
    User((ユーザー))

    subgraph VoiceBookLM
        Login([Google でログイン])
        Record([ボイスメモを録音])
        ViewList([メモ一覧を閲覧])
        Search([メモを検索])
        Edit([タイトル・タグを編集])
    end

    User --> Login
    User --> Record
    User --> ViewList
    User --> Search
    User --> Edit

ユースケース一覧

MVP 機能(実装対象)

ユースケース説明アクター
Google でログインするGoogle OAuth で認証し、JWT トークンを取得ユーザー
ボイスメモを録音するワンタップで録音開始・停止ユーザー
音声をサーバーに送信する録音完了後に REST API 経由で音声ファイルを送信システム
文字起こしする録音完了後に ASR で一括テキスト化システム
AI でメモを整理するタイトル・本文・タグを自動生成システム
クラウドに保存するAI 整形済みメモのみを永続化システム
メモ一覧を閲覧する日付ソートでメモを表示ユーザー
メモを検索する全文検索でメモを検索ユーザー
タグでフィルタするタグ指定でメモを絞り込みユーザー
タイトル・タグを編集するAI 生成結果を手動で修正ユーザー

MVP 対象外

ユースケース理由
音声を永続保存するプライバシー重視設計により永久に含まない
要約を生成するMVP スコープ外
複数発話者を判定する個人メモ特化のため対象外
Apple/メールでログインするMVP では Google 認証のみ
オフラインで録音するMVP では対象外

データポリシー

データ種別永続保存説明
AI 整形済みメモ本文メモの主内容として保存
タイトルAI 生成または編集結果
タグAI 生成または編集結果
タイムスタンプ録音開始/終了の情報
音声データ処理完了後に削除
生文字起こしAI 整形前の生データは破棄

ボイスメモ アクティビティ図

メインフロー(録音〜保存)

flowchart TD
    Start((開始))
    Start --> Login[Google ログイン]
    Login --> Home[ホーム画面]
    Home --> Record[録音ボタンをタップ]
    Record --> Speaking[話す]
    Speaking --> Stop[録音停止]
    Stop --> Upload[音声ファイル送信]
    Upload --> Transcribe[文字起こし]
    AI --> Save[クラウドに保存]
    Save --> Done((完了))
    Transcribe --> AI[AI でタイトル・本文・タグ生成]

メモ閲覧フロー

flowchart TD
    Home((ホーム画面))
    Home --> Directory[ディレクトリ構造]
    Home --> Search[キーワード検索]
    Directory --> Detail[メモを選択して閲覧]
    Search --> List[メモ一覧を表示]
    List --> Detail

フローの説明

録音フロー

  1. Google ログイン → JWT トークン取得
  2. 録音ボタンをタップ → 録音開始
  3. 話す → 音声を端末に一時保存
  4. 録音停止 → 音声ファイル確定
  5. 音声ファイル送信 → REST API 経由でサーバーに送信
  6. 文字起こし → ASR で一括テキスト化
  7. AI 処理 → タイトル・本文・タグを自動生成
  8. クラウドに保存 → AI 整形済みメモのみ永続化

メモ閲覧フロー

  • 一覧表示: 日付ソートでメモを表示
  • 検索: キーワードやタグで絞り込み
  • 閲覧: メモを選択して内容を確認

シーケンス図

システムの主要なフローを時系列で図示したシーケンス図です。


1. 音声メモ生成フロー(メインフロー)

アプリのコア機能「音声 → 文字起こし → AI整形 → 保存」の全体フローです。

sequenceDiagram
    autonumber
    participant App as 📱 Mobile App
    participant API as 🖥️ Backend API
    participant STT as 🎤 Google Speech-to-Text
    participant AI as 🤖 Gemini AI
    participant DB as 🗄️ PostgreSQL

    Note over App: ユーザーが録音完了

    App->>API: POST /api/voice/memos<br/>multipart/form-data<br/>(file, language)
    activate API

    Note over API: JWT検証

    API->>STT: 音声ファイル送信
    activate STT
    STT-->>API: 文字起こしテキスト
    deactivate STT

    alt 文字起こし成功
        API->>AI: 文字起こしテキスト送信
        activate AI
        Note over AI: タイトル生成<br/>本文整形<br/>タグ抽出
        AI-->>API: 整形結果<br/>(title, content, tags)
        deactivate AI

        alt AI整形成功
            API->>DB: メモ保存
            activate DB
            DB-->>API: 保存完了
            deactivate DB
            API-->>App: 201 Created<br/>{memoId, title, content, tags, ...}
        else AI整形失敗
            Note over API: フォールバック処理<br/>文字起こしテキストをそのまま使用
            API->>DB: メモ保存(フォールバック)
            DB-->>API: 保存完了
            API-->>App: 201 Created<br/>{..., fallback: {formatting: true}}
        end
    else 文字起こし失敗
        API-->>App: 500 Internal Server Error
    end

    deactivate API

フローの詳細

ステップ処理内容処理時間目安
1音声ファイルアップロードファイルサイズ依存
2-3JWT認証 + 文字起こし2-10秒
4-5AI整形処理1-3秒
6-7DB保存100ms以下

エラーハンドリング

  • 文字起こし失敗: 500エラーを返却
  • AI整形失敗: フォールバックモードで文字起こしテキストをそのまま保存
  • DB保存失敗: 500エラーを返却

2. Google OAuth ログインフロー

Google Sign-In を使用した認証フローです。

sequenceDiagram
    autonumber
    participant App as 📱 Mobile App
    participant Google as 🌐 Google OAuth
    participant API as 🖥️ Backend API
    participant DB as 🗄️ PostgreSQL

    App->>Google: Google Sign-In 開始
    activate Google
    Note over Google: ユーザー認証<br/>同意画面
    Google-->>App: ID Token
    deactivate Google

    App->>API: POST /api/auth/google<br/>{idToken}
    activate API

    API->>Google: ID Token 検証<br/>/tokeninfo
    activate Google
    Google-->>API: Token Info<br/>(sub, email, name, ...)
    deactivate Google

    alt トークン検証成功
        API->>DB: ユーザー検索<br/>(googleSub)
        activate DB

        alt 既存ユーザー
            DB-->>API: User
        else 新規ユーザー
            API->>DB: ユーザー作成
            DB-->>API: User
        end

        Note over API: JWT生成<br/>・accessToken (1日)<br/>・refreshToken (180日)

        API->>DB: RefreshToken 保存
        DB-->>API: 保存完了
        deactivate DB

        API-->>App: 200 OK<br/>{accessToken, refreshToken}
    else トークン検証失敗
        API-->>App: 401 Unauthorized
    end

    deactivate API

セキュリティポイント

項目内容
ID Token 検証Google の /tokeninfo エンドポイントで検証
aud クレーム確認クライアントIDとの一致を確認
メール検証確認email_verified: true を確認
UUIDv7 使用時系列順でソート可能なID

3. トークンリフレッシュフロー

アクセストークン更新時のトークンローテーションフローです。

sequenceDiagram
    autonumber
    participant App as 📱 Mobile App
    participant API as 🖥️ Backend API
    participant DB as 🗄️ PostgreSQL

    Note over App: accessToken 期限切れ検知

    App->>API: POST /api/auth/refresh<br/>{refreshToken}
    activate API

    API->>DB: RefreshToken 検証<br/>(token, revoked=false, expires > now)
    activate DB
    DB-->>API: RefreshToken (valid/invalid)
    deactivate DB

    alt トークン有効
        API->>DB: ユーザー取得
        activate DB
        DB-->>API: User
        deactivate DB

        API->>DB: 旧 RefreshToken 無効化<br/>(revoked = true)
        activate DB
        DB-->>API: 更新完了
        deactivate DB

        Note over API: 新規JWT生成<br/>・accessToken<br/>・refreshToken

        API->>DB: 新 RefreshToken 保存
        activate DB
        DB-->>API: 保存完了
        deactivate DB

        API-->>App: 200 OK<br/>{accessToken, refreshToken}
    else トークン無効/期限切れ
        API-->>App: 401 Unauthorized
        Note over App: 再ログイン必要
    end

    deactivate API

トークンローテーションの意義

旧トークン使用 → 無効化 → 新トークン発行
  • リプレイ攻撃防止: 古いトークンは使えなくなる
  • トークン漏洩検知: 無効化済みトークンの使用で検知可能
  • セッション管理: アクティブなセッションのみ有効

4. 認証付きAPI呼び出しフロー

JWT認証が必要なAPIの共通フローです。

sequenceDiagram
    autonumber
    participant App as 📱 Mobile App
    participant Filter as 🔐 JwtAuthFilter
    participant Controller as 📋 Controller
    participant UseCase as ⚙️ UseCase

    App->>Filter: API Request<br/>Authorization: Bearer {token}
    activate Filter

    Filter->>Filter: JWT検証

    alt 有効なアクセストークン
        Filter->>Filter: SecurityContext設定<br/>(userId, email)
        Filter->>Controller: Request継続
        activate Controller
        Controller->>UseCase: ビジネスロジック実行
        activate UseCase
        UseCase-->>Controller: 結果
        deactivate UseCase
        Controller-->>App: 200 OK / 201 Created
        deactivate Controller
    else 無効/期限切れトークン
        Filter-->>App: 401 Unauthorized
    else リフレッシュトークン使用
        Filter-->>App: 401 Unauthorized<br/>(アクセストークンが必要)
    end

    deactivate Filter

5. ログアウトフロー

sequenceDiagram
    autonumber
    participant App as 📱 Mobile App
    participant API as 🖥️ Backend API
    participant DB as 🗄️ PostgreSQL

    App->>API: POST /api/auth/logout<br/>{refreshToken}
    activate API

    API->>DB: RefreshToken 無効化<br/>(revoked = true)
    activate DB
    DB-->>API: 更新完了
    deactivate DB

    API-->>App: 204 No Content
    deactivate API

    Note over App: ローカルトークン削除

6. アカウント削除フロー

sequenceDiagram
    autonumber
    participant App as 📱 Mobile App
    participant API as 🖥️ Backend API
    participant DB as 🗄️ PostgreSQL

    App->>API: DELETE /api/auth/account<br/>Authorization: Bearer {token}
    activate API

    Note over API: JWT検証(userId取得)

    API->>DB: メモ削除<br/>(user_id = ?)
    activate DB
    DB-->>API: 削除完了
    deactivate DB

    API->>DB: RefreshToken 削除<br/>(user_id = ?)
    activate DB
    DB-->>API: 削除完了
    deactivate DB

    API->>DB: User 削除<br/>(id = ?)
    activate DB
    DB-->>API: 削除完了
    deactivate DB

    API-->>App: 204 No Content
    deactivate API

    Note over App: ログイン画面へ遷移

削除順序の重要性

外部キー制約を考慮し、以下の順序で削除:

  1. VoiceMemo (user_id 参照)
  2. RefreshToken (user_id 参照)
  3. User (親テーブル)

7. エラーハンドリング全体像

sequenceDiagram
    participant App as 📱 Mobile App
    participant API as 🖥️ Backend API

    Note over App,API: 想定されるエラーパターン

    rect rgb(255, 230, 230)
        Note right of App: 認証エラー
        App->>API: 無効なJWT
        API-->>App: 401 Unauthorized<br/>{error, code: "UNAUTHORIZED"}
    end

    rect rgb(255, 245, 230)
        Note right of App: 入力エラー
        App->>API: 不正なリクエスト
        API-->>App: 400 Bad Request<br/>{error, code: "BAD_REQUEST"}
    end

    rect rgb(255, 230, 245)
        Note right of App: リソースエラー
        App->>API: 存在しないリソース
        API-->>App: 404 Not Found<br/>{error, code: "NOT_FOUND"}
    end

    rect rgb(230, 230, 255)
        Note right of App: サーバーエラー
        App->>API: 外部API障害
        API-->>App: 500 Internal Server Error<br/>{error, code: "INTERNAL_SERVER_ERROR"}
    end

処理時間の目安

フロー想定処理時間ボトルネック
ログイン500ms - 1sGoogle Token検証
トークンリフレッシュ100ms - 200msDB操作
音声メモ生成3s - 15sSpeech-to-Text + AI整形
ログアウト50ms - 100msDB操作
アカウント削除200ms - 500ms複数テーブル削除

関連ドキュメント

画面遷移図

VoiceBookLM モバイルアプリの画面遷移を図示します。


全体概要

stateDiagram-v2
    [*] --> スプラッシュ
    スプラッシュ --> ログイン: 未認証
    スプラッシュ --> ホーム: 認証済み

    state ログイン {
        [*] --> ログイン画面
        ログイン画面 --> Google認証
        Google認証 --> ログイン画面: 失敗
    }
    ログイン --> ホーム: 認証成功

    state ホーム {
        [*] --> メモ一覧
        メモ一覧 --> 検索
        検索 --> メモ一覧
    }

    ホーム --> 録音: 録音ボタン
    録音 --> 処理中: 録音完了
    処理中 --> メモ詳細: 生成完了
    メモ詳細 --> ホーム: 戻る

    ホーム --> メモ詳細: メモ選択
    ホーム --> 設定: 設定アイコン

    設定 --> ログイン: ログアウト
    設定 --> [*]: アカウント削除

1. 認証フロー

flowchart TD
    subgraph 起動["📱 アプリ起動"]
        Splash[スプラッシュ画面]
    end

    subgraph 認証チェック["🔐 認証チェック"]
        Check{JWT有効?}
        Refresh{リフレッシュ<br/>可能?}
    end

    subgraph ログイン["🔑 ログイン"]
        Login[ログイン画面]
        GoogleAuth[Google Sign-In]
        AuthError[認証エラー<br/>ダイアログ]
    end

    subgraph メイン["🏠 メイン"]
        Home[ホーム画面]
    end

    Splash --> Check
    Check -->|有効| Home
    Check -->|期限切れ| Refresh
    Refresh -->|成功| Home
    Refresh -->|失敗| Login

    Check -->|なし| Login
    Login -->|Googleでログイン| GoogleAuth
    GoogleAuth -->|成功| Home
    GoogleAuth -->|失敗| AuthError
    AuthError -->|再試行| Login

    style Splash fill:#e1f5fe
    style Home fill:#c8e6c9
    style Login fill:#fff3e0
    style AuthError fill:#ffcdd2

画面詳細

画面説明主要アクション
スプラッシュアプリロゴ表示、JWT検証自動遷移
ログインGoogle Sign-In ボタンGoogleでログイン
認証エラーエラーメッセージ表示再試行、閉じる

2. メイン画面フロー

flowchart TD
    subgraph ホーム["🏠 ホーム画面"]
        MemoList[メモ一覧<br/>日付順表示]
        Directory[ディレクトリ<br/>ツリー表示]
        SearchBar[検索バー]
        RecordBtn((🎤<br/>録音))
        SettingsBtn[⚙️]
    end

    subgraph 検索["🔍 検索"]
        SearchInput[キーワード入力]
        TagFilter[タグフィルター]
        SearchResults[検索結果一覧]
    end

    subgraph メモ詳細["📄 メモ詳細"]
        MemoView[メモ表示<br/>Markdown]
        MemoTags[タグ表示]
        MemoMeta[作成日時]
        ResummarizeBtn[再要約ボタン]
    end

    subgraph 録音["🎤 録音画面"]
        Recording[録音中<br/>波形表示]
        StopBtn[停止ボタン]
    end

    subgraph 処理中["⏳ 処理中"]
        Uploading[アップロード中]
        Transcribing[文字起こし中]
        Formatting[AI整形中]
    end

    subgraph 設定["⚙️ 設定"]
        Profile[プロフィール]
        Language[言語設定]
        Logout[ログアウト]
        DeleteAccount[アカウント削除]
    end

    MemoList --> SearchBar
    SearchBar --> SearchInput
    SearchInput --> SearchResults
    TagFilter --> SearchResults
    SearchResults --> MemoView

    MemoList --> MemoView
    Directory --> MemoView

    RecordBtn --> Recording
    Recording --> StopBtn
    StopBtn --> Uploading
    Uploading --> Transcribing
    Transcribing --> Formatting
    Formatting --> MemoView

    MemoView --> ResummarizeBtn
    ResummarizeBtn --> Formatting

    SettingsBtn --> Profile
    Profile --> Language
    Profile --> Logout
    Profile --> DeleteAccount

    style RecordBtn fill:#f44336,color:#fff
    style MemoList fill:#e3f2fd
    style MemoView fill:#e8f5e9
    style Recording fill:#ffebee
    style Formatting fill:#fff3e0

3. 録音〜保存フロー(詳細)

flowchart TD
    subgraph 録音準備["📱 録音準備"]
        Home[ホーム画面]
        RecordButton((🎤))
        PermissionCheck{マイク<br/>許可?}
        PermissionRequest[許可リクエスト]
    end

    subgraph 録音中["🔴 録音中"]
        RecordingScreen[録音画面]
        Waveform[波形表示]
        Timer[経過時間]
        StopButton[停止ボタン]
        CancelButton[キャンセル]
    end

    subgraph 確認["✅ 確認"]
        Preview[録音プレビュー]
        PlayButton[再生]
        RetryButton[録り直し]
        SubmitButton[送信]
    end

    subgraph 処理["⚙️ 処理中"]
        Progress[プログレス表示]
        Step1[1. アップロード中...]
        Step2[2. 文字起こし中...]
        Step3[3. AI整形中...]
        Step4[4. 保存中...]
    end

    subgraph 完了["🎉 完了"]
        Result[生成結果画面]
        Title[タイトル]
        Content[整形済み本文]
        Tags[自動タグ]
        SaveButton[保存して閉じる]
    end

    subgraph エラー["❌ エラー"]
        ErrorDialog[エラーダイアログ]
        RetryOption[再試行]
        DismissOption[閉じる]
    end

    Home --> RecordButton
    RecordButton --> PermissionCheck
    PermissionCheck -->|許可済み| RecordingScreen
    PermissionCheck -->|未許可| PermissionRequest
    PermissionRequest -->|許可| RecordingScreen
    PermissionRequest -->|拒否| Home

    RecordingScreen --> Waveform
    RecordingScreen --> Timer
    RecordingScreen --> StopButton
    RecordingScreen --> CancelButton
    CancelButton --> Home

    StopButton --> Preview
    Preview --> PlayButton
    Preview --> RetryButton
    Preview --> SubmitButton
    RetryButton --> RecordingScreen

    SubmitButton --> Progress
    Progress --> Step1 --> Step2 --> Step3 --> Step4

    Step4 -->|成功| Result
    Step1 -->|失敗| ErrorDialog
    Step2 -->|失敗| ErrorDialog
    Step3 -->|失敗| ErrorDialog

    ErrorDialog --> RetryOption
    ErrorDialog --> DismissOption
    RetryOption --> Progress
    DismissOption --> Home

    Result --> Title
    Result --> Content
    Result --> Tags
    Result --> SaveButton
    SaveButton --> Home

    style RecordButton fill:#f44336,color:#fff
    style RecordingScreen fill:#ffcdd2
    style Progress fill:#fff3e0
    style Result fill:#c8e6c9
    style ErrorDialog fill:#ffcdd2

4. 画面一覧

認証系

#画面名パス説明
1スプラッシュ/splashアプリ起動時のロード画面
2ログイン/loginGoogle Sign-In ボタン

メイン系

#画面名パス説明
3ホーム/homeメモ一覧、ディレクトリ表示
4検索/searchキーワード・タグ検索
5メモ詳細/memo/:idMarkdown形式でメモ表示

録音系

#画面名パス説明
6録音/record音声録音画面
7録音確認/record/preview録音プレビュー・送信確認
8処理中/record/processingアップロード〜AI整形のプログレス
9生成結果/record/result生成されたメモの確認

設定系

#画面名パス説明
10設定/settings設定メニュー
11プロフィール/settings/profileユーザー情報表示
12言語設定/settings/language文字起こし言語選択

5. 画面コンポーネント構成

flowchart TB
    subgraph App["📱 App"]
        subgraph Navigation["🧭 Navigation"]
            BottomTab[BottomTabNavigator]
            Stack[StackNavigator]
        end

        subgraph Screens["📄 Screens"]
            subgraph Auth["認証"]
                SplashScreen
                LoginScreen
            end

            subgraph Main["メイン"]
                HomeScreen
                SearchScreen
                MemoDetailScreen
            end

            subgraph Record["録音"]
                RecordScreen
                PreviewScreen
                ProcessingScreen
                ResultScreen
            end

            subgraph Settings["設定"]
                SettingsScreen
                ProfileScreen
                LanguageScreen
            end
        end

        subgraph Components["🧩 共通コンポーネント"]
            Header[Header]
            MemoCard[MemoCard]
            TagChip[TagChip]
            LoadingIndicator[LoadingIndicator]
            ErrorDialog[ErrorDialog]
            FAB[FloatingActionButton]
        end
    end

    BottomTab --> HomeScreen
    BottomTab --> SearchScreen
    BottomTab --> SettingsScreen

    Stack --> MemoDetailScreen
    Stack --> RecordScreen
    Stack --> PreviewScreen
    Stack --> ProcessingScreen
    Stack --> ResultScreen

    HomeScreen --> MemoCard
    HomeScreen --> FAB
    SearchScreen --> MemoCard
    SearchScreen --> TagChip
    MemoDetailScreen --> TagChip

    RecordScreen --> Header
    ProcessingScreen --> LoadingIndicator
    ResultScreen --> TagChip

6. ナビゲーション構造

App
├── AuthStack (未認証時)
│   ├── Splash
│   └── Login
│
└── MainStack (認証済み)
    ├── BottomTabs
    │   ├── HomeTab
    │   │   └── Home
    │   ├── SearchTab
    │   │   └── Search
    │   └── SettingsTab
    │       └── Settings
    │
    └── Modals / Stacks
        ├── MemoDetail
        ├── RecordFlow
        │   ├── Record
        │   ├── Preview
        │   ├── Processing
        │   └── Result
        ├── Profile
        └── Language

7. 状態遷移表

認証状態

現在の状態イベント次の状態アクション
未認証アプリ起動スプラッシュJWT確認
スプラッシュJWT有効ホーム自動遷移
スプラッシュJWT無効ログイン自動遷移
ログインGoogle認証成功ホームトークン保存
ログインGoogle認証失敗ログインエラー表示
認証済みログアウトログイントークン削除
認証済みアカウント削除ログインデータ削除

録音状態

現在の状態イベント次の状態アクション
ホーム録音ボタン録音画面権限確認
録音画面停止プレビュー録音停止
録音画面キャンセルホーム録音破棄
プレビュー送信処理中API呼び出し
プレビュー録り直し録音画面録音リセット
処理中完了結果画面レスポンス表示
処理中エラーエラーダイアログエラー表示
結果画面保存ホーム一覧更新

8. ワイヤーフレーム概要

ホーム画面

┌─────────────────────────────────┐
│  📱 VoiceBookLM          ⚙️    │
├─────────────────────────────────┤
│  🔍 メモを検索...               │
├─────────────────────────────────┤
│                                 │
│  📁 アイデア                    │
│    └─ 📄 新機能のアイデア       │
│    └─ 📄 改善案メモ             │
│                                 │
│  📁 日記                        │
│    └─ 📄 今日の振り返り         │
│                                 │
│  📁 仕事                        │
│    └─ 📄 会議メモ               │
│                                 │
│                                 │
│                        ┌─────┐  │
│                        │ 🎤  │  │
│                        └─────┘  │
├─────────────────────────────────┤
│   🏠      🔍      ⚙️           │
└─────────────────────────────────┘

録音画面

┌─────────────────────────────────┐
│  ← 録音                         │
├─────────────────────────────────┤
│                                 │
│                                 │
│         ╭──────────────╮        │
│         │              │        │
│         │   🔴 録音中   │        │
│         │              │        │
│         ╰──────────────╯        │
│                                 │
│     ∿∿∿∿∿∿∿∿∿∿∿∿∿∿∿∿∿         │
│     波形表示                    │
│                                 │
│           00:15                 │
│                                 │
│         ┌─────────┐             │
│         │  停止   │             │
│         └─────────┘             │
│                                 │
│     キャンセル                   │
│                                 │
└─────────────────────────────────┘

メモ詳細画面

┌─────────────────────────────────┐
│  ←  メモ詳細              ⋮    │
├─────────────────────────────────┤
│                                 │
│  # 新機能のアイデア             │
│                                 │
│  📅 2025-12-17                  │
│  🏷️ アイデア  機能  MVP         │
│                                 │
│  ─────────────────────────────  │
│                                 │
│  ## 概要                        │
│  音声入力でメモを取れる         │
│  アプリを作りたい。             │
│                                 │
│  ## ポイント                    │
│  - AIで自動整形                 │
│  - タグ自動付与                 │
│  - Markdown形式                 │
│                                 │
│  ## 次のアクション              │
│  - 技術選定を進める             │
│                                 │
│         ┌─────────┐             │
│         │ 再要約  │             │
│         └─────────┘             │
└─────────────────────────────────┘

関連ドキュメント

ER図

erDiagram
    users {
        UUID id PK "UUIDv7"
        VARCHAR google_sub UK "Google User ID (sub claim)"
        VARCHAR email UK "メールアドレス"
        VARCHAR name "表示名"
        TIMESTAMPTZ created_at "作成日時"
        TIMESTAMPTZ updated_at "更新日時"
    }

    memos {
        UUID id PK "UUIDv7"
        UUID user_id FK "ユーザーID"
        VARCHAR transcription_status "文字起こしステータス"
        VARCHAR formatting_status "AI整形ステータス"
        TEXT transcription "文字起こし結果"
        VARCHAR title "AIタイトル"
        TEXT content "AI整形本文(Markdown)"
        TIMESTAMPTZ created_at "作成日時"
        TIMESTAMPTZ updated_at "更新日時"
        BOOLEAN deleted "論理削除フラグ"
    }

    memo_tags {
        UUID memo_id PK,FK "メモID"
        VARCHAR tag PK "タグ名"
    }

    refresh_tokens {
        UUID id PK "UUIDv7"
        VARCHAR token UK "リフレッシュトークン"
        UUID user_id FK "ユーザーID"
        TIMESTAMPTZ expires_at "有効期限"
        TIMESTAMPTZ created_at "作成日時"
        BOOLEAN revoked "無効化フラグ"
    }

    users ||--o{ memos : "has"
    users ||--o{ refresh_tokens : "has"
    memos ||--o{ memo_tags : "has"

テーブル概要

テーブル名説明
usersユーザーアカウント情報(Google OAuth 認証)
memosAI 整形済みボイスメモ(文字起こし→AI整形の2段階処理)
memo_tagsメモタグ(AI 生成またはユーザー編集)
refresh_tokensJWT リフレッシュトークン(トークンローテーション対応)

リレーションシップ

  • users → memos: 1対多(1ユーザーが複数のメモを持つ)
  • users → refresh_tokens: 1対多(1ユーザーが複数のトークンを持つ)
  • memos → memo_tags: 1対多(1メモが複数のタグを持つ)

ステータス値

transcription_status / formatting_status

説明
PENDING処理待ち
PROCESSING処理中
COMPLETED完了
FAILED失敗

認証

VoiceBookLM Backend の認証システムは、Google OAuth 認証と JWT トークン管理を提供するクリーンアーキテクチャベースの実装です。

アーキテクチャ概要

flowchart TB
    subgraph Presentation["Presentation Layer"]
        AuthController["AuthController (/api/auth)<br/>POST /google : Google OAuth ログイン<br/>POST /refresh : トークンリフレッシュ<br/>POST /logout : ログアウト<br/>DELETE /account : アカウント削除<br/>GET /me : 現在のユーザー情報取得"]
    end

    subgraph UseCase["UseCase Layer"]
        LoginUseCase
        RefreshTokenUseCase
        LogoutUseCase
        GetCurrentUserUseCase
        DeleteAccountUseCase
    end

    subgraph Domain["Domain Layer"]
        subgraph Models
            User
            RefreshToken
            OAuthUserInfo
        end
        subgraph Interfaces
            UserRepository
            RefreshTokenRepo
            OAuthClient
        end
    end

    subgraph Infrastructure["Infrastructure Layer"]
        JwtTokenProvider
        JwtAuthenticationFilter
        GoogleOAuthClient
        UserRepositoryImpl["UserRepositoryImpl (JPA)"]
        RefreshTokenRepositoryImpl
    end

    Presentation --> UseCase
    UseCase --> Domain
    Domain --> Infrastructure

Domain Layer

User

ファイル: src/main/kotlin/com/assari/voicebooklm/domain/model/User.kt

Google OAuth 認証で取得したユーザー情報を表現するドメインモデル。

class User(
    val id: UUID,           // UUIDv7 (時系列順)
    val googleSub: String,  // Google の一意識別子
    val email: String,      // メールアドレス
    var name: String,       // 表示名
    val createdAt: Instant,
    var updatedAt: Instant
)

メソッド:

メソッド説明
updateName(newName: String)ユーザー名を更新し、updatedAt を現在時刻に設定

RefreshToken

ファイル: src/main/kotlin/com/assari/voicebooklm/domain/model/RefreshToken.kt

JWT リフレッシュトークンの情報を表現するドメインモデル。トークンローテーションをサポート。

class RefreshToken(
    val id: UUID,           // UUIDv7
    val token: String,      // JWT トークン文字列
    val userId: UUID,       // 所有ユーザーの ID
    val expiresAt: Instant, // 有効期限
    val createdAt: Instant,
    var revoked: Boolean    // 無効化フラグ
)

メソッド:

メソッド戻り値説明
isExpired()Boolean有効期限切れかどうか
isValid()Boolean有効かどうか(未失効 かつ 期限内)
revoke()Unitトークンを無効化

OAuthUserInfo

ファイル: src/main/kotlin/com/assari/voicebooklm/domain/model/OAuthUserInfo.kt

OAuth プロバイダーから取得したユーザー情報を表現する値オブジェクト。

data class OAuthUserInfo(
    val providerId: String,  // プロバイダー固有 ID (Google: sub)
    val email: String,
    val name: String,
    val picture: String?     // プロフィール画像 URL
)

OAuthClient (Interface)

ファイル: src/main/kotlin/com/assari/voicebooklm/domain/gateway/OAuthClient.kt

OAuth 認証プロバイダーとの通信を抽象化するゲートウェイインターフェース。

interface OAuthClient {
    fun verifyIdTokenAndGetUserInfo(idToken: String): OAuthUserInfo?
}

実装:

  • GoogleOAuthClient - Google OAuth 認証

UserRepository (Interface)

ファイル: src/main/kotlin/com/assari/voicebooklm/domain/repository/UserRepository.kt

interface UserRepository {
    fun save(user: User): User
    fun findById(id: UUID): User?
    fun findByEmail(email: String): User?
    fun findByGoogleSub(googleSub: String): User?
    fun deleteById(id: UUID)
}

RefreshTokenRepository (Interface)

ファイル: src/main/kotlin/com/assari/voicebooklm/domain/repository/RefreshTokenRepository.kt

interface RefreshTokenRepository {
    fun save(token: RefreshToken): RefreshToken
    fun findByTokenAndValid(token: String, now: Instant): RefreshToken?
    fun revokeByToken(token: String)
    fun revokeByUserId(userId: UUID)    // ログアウト時
    fun deleteByUserId(userId: UUID)    // アカウント削除時
}

UseCase Layer

LoginUseCase

ファイル: src/main/kotlin/com/assari/voicebooklm/usecase/auth/LoginUseCase.kt

OAuth 認証フローを処理し、JWT トークンペアを発行する。

入力: LoginCommand(idToken: String)

出力: LoginResult(accessToken, refreshToken, userId)

フロー:

  1. OAuthClient で ID トークンを検証
  2. ユーザーを取得または新規作成
  3. アクセストークン・リフレッシュトークンを生成
  4. リフレッシュトークンを DB に保存

例外:

  • InvalidIdTokenException - ID トークンの検証失敗

RefreshTokenUseCase

ファイル: src/main/kotlin/com/assari/voicebooklm/usecase/auth/RefreshTokenUseCase.kt

リフレッシュトークンローテーションを実装。旧トークンを無効化し、新しいトークンペアを発行。

入力: RefreshTokenCommand(refreshToken: String)

出力: RefreshTokenResult(accessToken, refreshToken, userId)

フロー:

  1. 保存済みリフレッシュトークンを検証
  2. ユーザーを取得
  3. 旧トークンを無効化(ローテーション)
  4. 新しいトークンペアを生成・保存

例外:

  • InvalidRefreshTokenException - トークンが無効または期限切れ

LogoutUseCase

ファイル: src/main/kotlin/com/assari/voicebooklm/usecase/auth/LogoutUseCase.kt

リフレッシュトークンを無効化してログアウト。

入力: LogoutCommand(refreshToken: String)

出力: なし


GetCurrentUserUseCase

ファイル: src/main/kotlin/com/assari/voicebooklm/usecase/auth/GetCurrentUserUseCase.kt

JWT から取得したユーザー ID でユーザー情報を取得。

入力: GetCurrentUserCommand(userId: UUID)

出力: UserInfo(id, email, name)


DeleteAccountUseCase

ファイル: src/main/kotlin/com/assari/voicebooklm/usecase/auth/DeleteAccountUseCase.kt

ユーザーのすべてのデータを物理削除。

入力: DeleteAccountCommand(userId: UUID)

削除順序(参照整合性維持):

  1. メモ
  2. リフレッシュトークン
  3. ユーザー

Infrastructure Layer

JwtTokenProvider

ファイル: src/main/kotlin/com/assari/voicebooklm/infrastructure/security/JwtTokenProvider.kt

JWT アクセストークン・リフレッシュトークンの生成・検証を行う。HS256 アルゴリズムを使用。

設定:

プロパティ説明
jwt.secret署名用シークレットキー
jwt.access-token-expirationアクセストークン有効期限(ms)
jwt.refresh-token-expirationリフレッシュトークン有効期限(ms)

メソッド:

メソッド説明
generateAccessToken(userId, email)アクセストークン生成
generateRefreshToken(userId)リフレッシュトークン生成
validateToken(token)トークン検証
isAccessToken(token)アクセストークン判定
isRefreshToken(token)リフレッシュトークン判定
getUserIdFromToken(token)トークンからユーザー ID 抽出
getEmailFromToken(token)トークンからメール抽出

トークンクレーム:

  • userId - ユーザー ID
  • email - メールアドレス(アクセストークンのみ)
  • tokenType - access または refresh

JwtAuthenticationFilter

ファイル: src/main/kotlin/com/assari/voicebooklm/infrastructure/security/JwtAuthenticationFilter.kt

Authorization ヘッダーから JWT トークンを抽出し、検証する Spring Security フィルタ。

動作:

  1. Authorization: Bearer <token> ヘッダーからトークン抽出
  2. JwtTokenProvider でトークン検証
  3. アクセストークンの場合のみ認証情報を SecurityContext に設定

GoogleOAuthClient

ファイル: src/main/kotlin/com/assari/voicebooklm/infrastructure/api/GoogleOAuthClient.kt

OAuthClient インターフェースの Google 実装。Google ID トークンの検証とユーザー情報の取得を行う。

検証フロー:

  1. https://oauth2.googleapis.com/tokeninfo エンドポイントで検証
  2. aud クレームがクライアント ID と一致するか確認
  3. メール検証済みか確認
  4. OAuthUserInfo に変換して返却

Presentation Layer

AuthController

ファイル: src/main/kotlin/com/assari/voicebooklm/presentation/controller/auth/AuthController.kt

Base Path: /api/auth

メソッドパス説明認証
POST/googleGoogle OAuth ログイン不要
POST/refreshトークンリフレッシュ不要
POST/logoutログアウト不要
DELETE/accountアカウント削除必要
GET/me現在のユーザー情報取得必要

リクエスト/レスポンス

GoogleAuthRequest

{
  "idToken": "eyJhbGciOiJSUzI1NiIsInR..."
}

RefreshTokenRequest / LogoutRequest

{
  "refreshToken": "eyJhbGciOiJIUzI1NiIsInR..."
}

TokenResponse

{
  "accessToken": "eyJhbGciOiJIUzI1NiIsInR...",
  "refreshToken": "eyJhbGciOiJIUzI1NiIsInR..."
}

UserResponse

{
  "id": "01916f54-1234-7abc-def0-123456789abc",
  "email": "user@example.com",
  "name": "田中太郎"
}

ErrorResponse

{
  "error": "認証に失敗しました",
  "code": "UNAUTHORIZED"
}

認証フロー

1. ログインフロー

sequenceDiagram
    participant App as Mobile App
    participant Backend
    participant Google

    App->>Google: Google Sign-In
    Google-->>App: ID Token

    App->>Backend: POST /api/auth/google<br/>{ idToken }
    Backend->>Google: Verify Token
    Google-->>Backend: Token Info

    Note over Backend: Create/Find User<br/>Generate JWT Pair<br/>Save Refresh Token

    Backend-->>App: TokenResponse<br/>{ accessToken, refreshToken }

2. トークンリフレッシュフロー

sequenceDiagram
    participant App as Mobile App
    participant Backend

    App->>Backend: POST /api/auth/refresh<br/>{ refreshToken }

    Note over Backend: Validate Stored Token<br/>Revoke Old Token (Rotation)<br/>Generate New JWT Pair<br/>Save New Refresh Token

    Backend-->>App: TokenResponse<br/>{ accessToken, refreshToken }

セキュリティ考慮事項

  1. トークンローテーション: リフレッシュトークン使用時に旧トークンを無効化
  2. JWT 署名検証: HS256 アルゴリズムによる改ざん検知
  3. トークンタイプ分離: アクセストークンとリフレッシュトークンを区別
  4. メール検証: Google 認証時にメール検証済みを確認
  5. クライアント ID 検証: ID トークンの aud クレームを検証

API

API リファレンス

VoiceBookLM バックエンド API の詳細仕様です。

Note

バージョン: 0.0.1-SNAPSHOT
開発環境: http://localhost:8080
本番環境: https://api.voicebooklm.example.com


認証 API (/api/auth)

POST /api/auth/google - Google OAuth ログイン

Google ID トークンを検証し、JWT トークンペアを発行します。新規ユーザーの場合はアカウントを作成します。

認証: 不要

リクエスト:

{
  "idToken": "string (必須) - Google ID トークン"
}

レスポンス:

ステータス説明
200 OKログイン成功
401 Unauthorized認証失敗
{
  "accessToken": "string - アクセストークン(1日有効)",
  "refreshToken": "string - リフレッシュトークン(180日間有効)"
}

POST /api/auth/refresh - トークンリフレッシュ

リフレッシュトークンを使用して新しいトークンペアを発行します(トークンローテーション)。

認証: 不要

リクエスト:

{
  "refreshToken": "string (必須) - リフレッシュトークン"
}

レスポンス:

ステータス説明
200 OKリフレッシュ成功
401 Unauthorizedリフレッシュトークンが無効または期限切れ
{
  "accessToken": "string - 新しいアクセストークン",
  "refreshToken": "string - 新しいリフレッシュトークン"
}

POST /api/auth/logout - ログアウト

リフレッシュトークンを無効化してログアウトします。

認証: 不要

リクエスト:

{
  "refreshToken": "string (必須) - リフレッシュトークン"
}

レスポンス:

ステータス説明
204 No Contentログアウト成功
400 Bad Requestリクエスト形式が不正

DELETE /api/auth/account - アカウント削除

ユーザーアカウントとすべての関連データを完全に削除します。

認証: 必須(JWT Bearer トークン)

レスポンス:

ステータス説明
204 No Content削除成功
401 Unauthorized認証失敗
404 Not Foundユーザーが見つからない

GET /api/auth/me - 現在のユーザー情報取得

認証済みユーザーの情報を取得します。

認証: 必須(JWT Bearer トークン)

レスポンス:

ステータス説明
200 OK取得成功
401 Unauthorized認証失敗
404 Not Foundユーザーが見つからない
{
  "id": "UUID - ユーザー ID",
  "email": "string - メールアドレス",
  "name": "string - ユーザー名"
}

音声メモ API (/api/voice)

POST /api/voice/memos - 音声ファイルからメモを生成

音声ファイルをアップロードし、文字起こし → AI整形 → 保存を行います。60秒以内のレスポンスを想定。

認証: 必須(JWT Bearer トークン)

Content-Type: multipart/form-data

リクエスト:

フィールド必須説明
fileFile音声ファイル
languageString×言語コード(例: ja-JP, en-US

レスポンス:

ステータス説明
201 Createdメモ生成成功
400 Bad Request入力不正(音声が空、Content-Type 不正など)
401 Unauthorized認証エラー(JWT 不正)
500 Internal Server Errorサーバエラー
{
  "memoId": "UUID - メモ ID",
  "title": "string - タイトル",
  "content": "string - 整形されたメモ内容",
  "tags": ["string"],
  "transcription": "string | null - 文字起こしテキスト",
  "transcriptionStatus": "COMPLETED | FAILED | PENDING",
  "formattingStatus": "COMPLETED | FAILED | PENDING",
  "processingTimeMillis": {
    "transcription": "number (ms)",
    "formatting": "number (ms)",
    "persistence": "number (ms)",
    "total": "number (ms)"
  },
  "fallback": {
    "transcription": "boolean",
    "formatting": "boolean"
  }
}

メモ API (/api/memos)

GET /api/memos - メモ一覧取得

認証ユーザーのメモを取得します。フォルダーによるフィルタリング、キーワード検索、ソート、件数制限が可能。

認証: 必須(JWT Bearer トークン)

クエリパラメータ:

パラメータ必須デフォルト説明
folderIdUUID×-フォルダーIDでフィルタリング
includeDescendantsboolean×falsetrue の場合、子孫フォルダーのメモも含める
uncategorizedOnlyboolean×falsetrue の場合、未分類メモのみ取得
keywordstring×-キーワード検索(タイトルまたはコンテントに含まれるメモを検索)
sortstring×updated_atソート項目(updated_at, created_at, title
orderstring×descソート順序(asc, desc
limitinteger×-取得件数制限

レスポンス:

ステータス説明
200 OK取得成功
401 Unauthorized認証エラー
{
  "memos": [
    {
      "memoId": "UUID",
      "title": "string | null",
      "tags": ["string"],
      "transcriptionStatus": "COMPLETED | FAILED | PENDING",
      "formattingStatus": "COMPLETED | FAILED | PENDING",
      "folder": {
        "id": "UUID",
        "name": "string",
        "path": "string"
      },
      "createdAt": "ISO 8601 datetime",
      "updatedAt": "ISO 8601 datetime"
    }
  ]
}

GET /api/memos/{id} - メモ詳細取得

指定されたIDのメモの詳細情報を取得します。セキュリティ上、権限のないメモも404として返します。

認証: 必須(JWT Bearer トークン)

パスパラメータ:

パラメータ必須説明
idUUIDメモ ID

レスポンス:

ステータス説明
200 OK取得成功
401 Unauthorized認証失敗
404 Not Foundメモが見つからない(存在しない、削除済み、または権限なし)
{
  "memoId": "UUID",
  "title": "string | null",
  "content": "string | null",
  "tags": ["string"],
  "transcriptionText": "string | null",
  "transcriptionStatus": "COMPLETED | FAILED | PENDING",
  "formattingStatus": "COMPLETED | FAILED | PENDING",
  "createdAt": "ISO 8601 datetime",
  "updatedAt": "ISO 8601 datetime"
}

PATCH /api/memos/{id} - メモ更新

メモの部分更新を行います。指定されたフィールドのみ更新されます。

認証: 必須(JWT Bearer トークン)

パスパラメータ:

パラメータ必須説明
idUUIDメモ ID

リクエスト:

{
  "title": "string (任意, 最大100文字)",
  "content": "string (任意)",
  "tags": ["string (任意)"]
}

レスポンス:

ステータス説明
200 OK更新成功
400 Bad Requestバリデーションエラー
401 Unauthorized認証失敗
404 Not Foundメモが見つからない(存在しない、削除済み、または権限なし)
422 Unprocessable Entityメモの整形が完了していない、またはフォルダーが存在しない
{
  "memoId": "UUID",
  "title": "string | null",
  "content": "string | null",
  "tags": ["string"],
  "transcriptionText": "string | null",
  "transcriptionStatus": "COMPLETED | FAILED | PENDING",
  "formattingStatus": "COMPLETED | FAILED | PENDING",
  "createdAt": "ISO 8601 datetime",
  "updatedAt": "ISO 8601 datetime"
}

DELETE /api/memos/{id} - メモ削除

指定されたメモを削除します。

認証: 必須(JWT Bearer トークン)

パスパラメータ:

パラメータ必須説明
idUUIDメモ ID

レスポンス:

ステータス説明
204 No Content削除成功
401 Unauthorized認証失敗
403 Forbiddenアクセス権限なし
404 Not Foundメモが見つからない

POST /api/memos/{id}/resummarize - 再要約

編集された文字起こしテキストから再度AI整形(要約)を行います。

認証: 必須(JWT Bearer トークン)

パスパラメータ:

パラメータ必須説明
idUUIDメモ ID

リクエスト:

{
  "editedTranscription": "string (必須) - 編集された文字起こしテキスト"
}

レスポンス:

ステータス説明
200 OK再要約成功
400 Bad Requestバリデーションエラー
401 Unauthorized認証失敗
404 Not Foundメモが見つからない(存在しない、削除済み、または権限なし)
422 Unprocessable Entity処理エラー(整形失敗など)
{
  "memoId": "UUID",
  "title": "string | null",
  "content": "string | null",
  "tags": ["string"],
  "transcriptionText": "string | null",
  "transcriptionStatus": "COMPLETED | FAILED | PENDING",
  "formattingStatus": "COMPLETED | FAILED | PENDING",
  "createdAt": "ISO 8601 datetime",
  "updatedAt": "ISO 8601 datetime"
}

フォルダー API (/api/folders)

GET /api/folders - フォルダー一覧取得

認証ユーザーのフォルダー一覧をパス情報付きで取得します。

認証: 必須(JWT Bearer トークン)

レスポンス:

ステータス説明
200 OK取得成功
401 Unauthorized認証エラー
{
  "folders": [
    {
      "id": "UUID",
      "name": "string",
      "parentId": "UUID | null",
      "path": "string"
    }
  ]
}

POST /api/folders - フォルダー作成

新しいフォルダーを作成します。親フォルダーを指定して階層構造を作成可能。

認証: 必須(JWT Bearer トークン)

リクエスト:

{
  "name": "string (必須, 最大50文字)",
  "parentId": "UUID (任意) - 親フォルダー ID"
}

レスポンス:

ステータス説明
201 Created作成成功
401 Unauthorized認証エラー
404 Not Found親フォルダーが見つからない
409 Conflict同名フォルダーが既に存在する
{
  "id": "UUID",
  "name": "string",
  "parentId": "UUID | null",
  "path": "string"
}

PATCH /api/folders/{id} - フォルダー更新

フォルダーのリネームまたは移動を行います。両方同時に指定可能。

認証: 必須(JWT Bearer トークン)

パスパラメータ:

パラメータ必須説明
idUUIDフォルダー ID

リクエスト:

{
  "name": "string (任意, 最大50文字)",
  "parentId": "UUID (任意) - 新しい親フォルダー ID",
  "moveToRoot": "boolean (必須) - ルートに移動する場合 true"
}

レスポンス:

ステータス説明
200 OK更新成功
401 Unauthorized認証エラー
404 Not Foundフォルダーが見つからない
409 Conflict同名フォルダーが既に存在する / 循環参照が発生する
{
  "id": "UUID",
  "name": "string",
  "parentId": "UUID | null",
  "path": "string"
}

DELETE /api/folders/{id} - フォルダー削除

フォルダーを削除します。子フォルダーまたはメモが存在する場合は削除できません。

認証: 必須(JWT Bearer トークン)

パスパラメータ:

パラメータ必須説明
idUUIDフォルダー ID

レスポンス:

ステータス説明
204 No Content削除成功
401 Unauthorized認証エラー
404 Not Foundフォルダーが見つからない
409 Conflict子フォルダーまたはメモが存在するため削除できない

タグ API (/api/tags)

GET /api/tags - タグ一覧取得

認証ユーザーが使用している全タグを取得します。ソート順と件数制限が指定可能。

認証: 必須(JWT Bearer トークン)

クエリパラメータ:

パラメータ必須デフォルト説明
sortstring×nameソート項目(name: 名前順, usage_count: 使用回数順)
orderstring×ascソート順序(asc, desc
limitinteger×-取得件数制限

使用例:

  • 人気タグを取得: GET /api/tags?sort=usage_count&order=desc&limit=10

レスポンス:

ステータス説明
200 OK取得成功
401 Unauthorized認証エラー
{
  "tags": ["開発", "コード", "ミーティング"]
}

開発用 API (/api/dev)

Caution

これらの API は 開発環境(dev)でのみ有効です。本番環境では使用できません。

POST /api/dev/token - 開発用トークン取得

指定したメールアドレスのユーザーのアクセストークンを取得します。OAuth不要で、Swagger UIからすぐにAPIテストができます。

認証: 不要

クエリパラメータ:

パラメータ必須説明
emailstringユーザーのメールアドレス

レスポンス:

ステータス説明
200 OKトークン取得成功
404 Not Foundユーザーが見つからない
{
  "accessToken": "string - アクセストークン(JWT)",
  "userId": "string - ユーザーID",
  "email": "string - メールアドレス",
  "message": "string - 使い方の説明"
}

POST /api/dev/seed - テストデータ作成

認証ユーザー用にテスト用のフォルダーとメモを作成します。データは seed-data.yml から読み込まれます。冪等性を持ち、既にフォルダーが存在する場合はスキップします。

認証: 必須(JWT Bearer トークン)

レスポンス:

ステータス説明
200 OK作成成功(またはスキップ)
401 Unauthorized認証エラー
{
  "foldersCreated": 3,
  "memosCreated": 10,
  "skipped": false,
  "message": "string - 結果メッセージ"
}

共通仕様

認証方式

JWT (JSON Web Token) を使用。

トークン種別有効期限
アクセストークン1日
リフレッシュトークン180日

認証が必要な API には Authorization ヘッダーを設定:

Authorization: Bearer <access_token>

エラーレスポンス

{
  "error": "string - エラーメッセージ",
  "code": "string - エラーコード"
}
コード説明
UNAUTHORIZED認証失敗
FORBIDDENアクセス権限なし
NOT_FOUNDリソースが見つからない
BAD_REQUESTリクエスト形式が不正
CONFLICTリソースの競合
UNPROCESSABLE_ENTITY処理不能なエンティティ
INTERNAL_SERVER_ERRORサーバー内部エラー

OpenAPI ドキュメント

  • Swagger UI: http://localhost:8080/swagger-ui.html
  • API 仕様 (JSON): http://localhost:8080/v3/api-docs

画面一覧

VoiceBookLM の画面仕様書一覧です。

画面ID採番ルール

プレフィックス種別
SCR画面(Screen)SCR-001
CMN共通(Common)CMN-001

画面一覧

画面ID画面名パス概要
SCR-001ウェルカム画面/未認証ユーザー向け初期画面・ファイルアップロード
SCR-002ホーム画面/homeログイン済みユーザーのメイン画面
SCR-003録音画面/recording音声メモを録音する画面

共通コンポーネント一覧

コンポーネントIDコンポーネント名概要
CMN-001AI処理通知トーストAI整形処理の進行状況を通知するフローティングトースト

ウェルカム画面

基本情報

項目内容
画面IDSCR-001
画面名ウェルカム画面
URL/パス/
認証要否不要(未認証でも閲覧可)

画面概要

VoiceBookLMアプリ起動時に未認証ユーザーに表示されるウェルカム画面。アプリの概要と主な機能を紹介し、Googleアカウントでのログインを促す。

画面イメージ

ウェルカム画面

画面要素一覧

要素ID要素名種別必須説明
app_iconアプリアイコン画像-画面最上部に配置
app_nameアプリ名ラベル-「VoiceBookLM」
catchphraseキャッチフレーズラベル-アプリの簡潔な説明
feature_1_icon機能1アイコンアイコン-機能1のアイコン
feature_1_name機能1名ラベル-機能1の名称
feature_1_desc機能1説明ラベル-機能1の説明文
feature_2_icon機能2アイコンアイコン-機能2のアイコン
feature_2_name機能2名ラベル-機能2の名称
feature_2_desc機能2説明ラベル-機能2の説明文
feature_3_icon機能3アイコンアイコン-機能3のアイコン
feature_3_name機能3名ラベル-機能3の名称
feature_3_desc機能3説明ラベル-機能3の説明文
btn_google_loginGoogleでログインボタンボタン-Googleアカウントで認証後、ホーム画面へ遷移
terms_notice利用規約同意文ラベル-「ログインすることで、利用規約とプライバシーポリシーに同意したものとみなされます。」

画面遷移

遷移元

なし

API連携

メソッドエンドポイント用途
POST/api/auth/googleGoogle認証処理

バリデーション

なし

状態

状態説明
初期状態静的表示、操作待ち状態

備考

  • 未認証状態でのみ表示される画面
  • ログイン済みユーザーはホーム画面へリダイレクト
  • 利用規約・プライバシーポリシーへのリンクを含む

ホーム画面

基本情報

項目内容
画面IDSCR-002
画面名ホーム画面
URL/パス/home
認証要否要(ログイン済みユーザー)

画面概要

ログイン済みユーザーのメイン画面。最近作成・編集したメモの一覧と、フォルダによるメモの整理機能を提供する。また、音声入力ボタンから新規メモの作成が可能。

画面イメージ

通常状態

ホーム画面

AI整形実行中

ホーム画面AI整形実行中

AI整形完了

ホーム画面AI整形完了

AI整形に失敗

ホーム画面AI整形に失敗

画面要素一覧

ヘッダー部

要素ID要素名種別必須説明
btn_search検索ボタンアイコン-メモ検索画面へ遷移
btn_setting設定ボタンアイコン-設定画面へ遷移(歯車アイコン)

最近のメモセクション

要素ID要素名種別必須説明
section_recent最近のメモセクション-セクションヘッダー
memo_cardメモカードカード-メモのプレビューカード(複数)
memo_titleメモタイトルラベル-メモのタイトル表示
memo_tagsタグバッジ-メモに付与されたタグ(デザイン、UIなど)
memo_date更新日時ラベル-最終更新日時(YYYY-MM-DD HH:mm)
btn_memo_menuメモメニューボタンアイコン-メモの編集・削除メニュー(︙)

フォルダセクション

要素ID要素名種別必須説明
section_folderフォルダセクション-セクションヘッダー
folder_itemフォルダ項目リストアイテム-フォルダ名と件数を表示
folder_nameフォルダ名ラベル-フォルダ名(受信トレイ、仕事など)
folder_countメモ件数ラベル-フォルダ内のメモ件数
folder_expand展開アイコンアイコン-サブフォルダの展開/折りたたみ(>)

音声入力ボタン

要素ID要素名種別必須説明
btn_voice音声入力ボタンFAB-音声入力で新規メモ作成開始

通知トースト(グローバルコンポーネント)

AI処理通知トーストの詳細仕様は CMN-001 AI処理通知トースト を参照してください。

メモメニュー(ポップアップ)

メモカードの︙ボタンをタップすると表示されるコンテキストメニュー。

メモメニュー

要素ID要素名種別必須説明
menu_delete削除ボタン-メモ削除確認ダイアログを表示(赤字)

画面遷移

遷移元

遷移元条件/アクション
ウェルカム画面ログイン成功後
各画面戻るボタン押下

API連携

メソッドエンドポイント用途
GET/api/memos?sort=updated_at&order=desc&limit=3メモ一覧取得(更新日時降順、最新3件)
GET/api/foldersフォルダ階層取得(memoCount含む)
GET/api/memos?folder_id=:idフォルダ内メモ取得(フォルダ展開時)
GET/api/memos/:id/statusメモのAI処理状態確認(将来実装予定)

バリデーション

なし

状態

状態説明画像
通常状態メモ一覧とフォルダ一覧を表示SCR-002_ホーム画面.png
AI整形実行中通知トースト表示SCR-002_ホーム画面AI整形実行中.png
AI整形完了通知トーストで確認を案内SCR-002_ホーム画面AI整形完了.png
AI整形に失敗通知トーストでエラー表示SCR-002_ホーム画面AI整形に失敗.png

備考

  • ログイン済みユーザー専用画面
  • 未認証ユーザーはウェルカム画面へリダイレクト
  • 最近のメモは更新日時の降順で表示
  • フォルダは階層構造をサポート(サブフォルダあり)
  • AI整形処理はバックグラウンドで実行され、完了時にトースト通知

録音画面

基本情報

項目内容
画面IDSCR-003
画面名録音画面
URL/パス/recording
認証要否要(ログイン済みユーザー)

画面概要

音声メモを録音するための画面。リアルタイムで音声波形を表示し、録音の一時停止・再開が可能。録音完了後はAIによる整形処理へ遷移する。

画面イメージ

録音中

録音画面

一時停止中

録音画面一時停止

画面要素一覧

ヘッダー部

要素ID要素名種別必須説明
btn_back戻るボタンアイコン-前画面へ戻る(録音破棄確認あり)
recording_indicator録音インジケーターバッジ-赤い●と経過時間を表示(MM:SS形式)

波形表示エリア

要素ID要素名種別必須説明
waveform_area波形表示エリアコンテナ-音声波形を表示するエリア
waveform音声波形グラフィック-リアルタイムで音声入力レベルを波形で可視化(青→ピンクのグラデーション)

操作ボタン

要素ID要素名種別必須説明
btn_pause一時停止ボタンアイコン-録音を一時停止(⏸アイコン)
btn_resume再開ボタンアイコン-一時停止中に表示、録音を再開(▷アイコン)
btn_complete完了ボタンボタン-「完了してAI整形する」録音を終了しAI処理開始

画面遷移

遷移元

遷移元条件/アクション
ホーム画面音声入力ボタン(FAB)押下

遷移先

遷移先条件/アクション
ホーム画面完了してAI整形するボタン押下(通知トーストを表示して遷移)

API連携

メソッドエンドポイント用途
POST/api/voice/memos音声アップロード・文字起こし・AI整形を一括処理する

バリデーション

項目ルールエラーメッセージ例
録音時間最低1秒以上の録音が必要録音時間が短すぎます
録音時間最大60分まで録音時間の上限に達しました
マイク権限マイクへのアクセス許可が必要マイクへのアクセスを許可してください

状態

状態説明画像
録音中波形がアニメーションし、経過時間が更新されるSCR-003_録音画面.png
一時停止中波形が静止し、再開ボタンが表示されるSCR-003_録音画面一時停止.png

備考

  • ログイン済みユーザー専用画面
  • 録音中は画面スリープを無効化
  • バックグラウンド移行時は録音を自動的に一時停止
  • 録音データはローカルに一時保存され、完了時にサーバーへアップロード
  • 戻るボタン押下時は録音破棄確認ダイアログを表示
  • 録音インジケーターの●は録音中に点滅アニメーション

メモ検索画面

基本情報

項目内容
画面IDSCR-004
画面名メモ検索画面
URL/パス/search
認証要否要(ログイン済みユーザー)

画面概要

キーワードによるメモの全文検索機能を提供する画面。検索履歴とよく使うタグからの絞り込みにも対応し、目的のメモに素早くアクセスできる。

画面イメージ

初期状態(検索前)

メモ検索画面

検索結果あり

検索結果あり

検索結果なし

検索結果なし

画面要素一覧

ヘッダー部

要素ID要素名種別必須説明
btn_back戻るボタンアイコン-前画面(ホーム画面)へ戻る
page_title画面タイトルラベル-「検索」を表示

検索入力部

要素ID要素名種別必須説明
input_search検索入力欄テキスト-プレースホルダー「メモを検索…」
btn_clearクリアボタンアイコン-検索文字列をクリア(×アイコン)

検索履歴セクション(初期状態のみ表示)

要素ID要素名種別必須説明
section_history検索履歴セクション-セクションヘッダー「検索履歴」
history_item履歴項目リストアイテム-過去の検索キーワード(タップで再検索)
history_expand展開アイコンアイコン-履歴詳細へ遷移(>アイコン)

よく使うタグセクション(初期状態のみ表示)

要素ID要素名種別必須説明
section_tagsよく使うタグセクション-セクションヘッダー「よく使うタグ」
tag_chipタグチップチップ-タグバッジ(開発、コード、ミーティング等)

検索結果セクション(検索実行後に表示)

要素ID要素名種別必須説明
section_results検索結果セクション-「検索結果 (N件)」を表示
result_item検索結果項目リストアイテム-ヒットしたメモの一覧
result_titleメモタイトルラベル-メモのタイトル表示
result_tagsタグバッジ-メモに付与されたタグ
result_date更新日時ラベル-最終更新日時(YYYY-MM-DD HH:mm形式)
btn_result_menuメニューボタンアイコン-メモの編集・削除メニュー(︙)

検索結果なし表示

要素ID要素名種別必須説明
empty_state結果なしメッセージメッセージ-「該当するメモが見つかりませんでした」

画面遷移

遷移元

遷移元条件/アクション
ホーム画面検索ボタン押下

遷移先

遷移先条件/アクション
ホーム画面戻るボタン押下
メモ詳細画面検索結果のメモ項目タップ

API連携

メソッドエンドポイント用途
GET/api/memos/search?q=:keywordキーワードによるメモ全文検索
GET/api/search/history検索履歴取得
GET/api/tags?sort=usage&limit=10よく使うタグ取得(使用頻度順)

バリデーション

項目ルールエラーメッセージ例
検索文字列最低1文字以上入力が必要検索キーワードを入力してください
検索文字列最大100文字まで検索キーワードが長すぎます

状態

状態説明画像
初期状態検索履歴とよく使うタグを表示SCR-004_メモ検索画面.png
検索結果あり検索結果一覧を表示(件数付き)SCR-004_メモ検索画面_検索ヒットあり.png
検索結果なし「該当するメモが見つかりませんでした」を表示SCR-004_検索画面_検索ヒットなし.png

備考

  • ログイン済みユーザー専用画面
  • 検索はメモのタイトル・本文・タグを対象とした全文検索
  • 検索は入力完了後に自動実行(デバウンス処理あり)
  • 検索履歴は最新10件まで保持
  • タグチップタップ時は該当タグでフィルタリング検索を実行
  • 検索結果はスクロールによる無限ロード対応

AI処理通知トースト

基本情報

項目内容
コンポーネントIDCMN-001
コンポーネント名AI処理通知トースト
種別グローバルコンポーネント(フローティング)

概要

AI整形処理(要約生成)の進行状況をユーザーに通知するフローティングトースト。録音完了後にホーム画面へ遷移した際に表示され、どの画面に遷移しても画面上部に表示され続ける。処理完了後はタップして作成されたメモへ遷移可能。

画面イメージ

処理中

AI整形を実行中

処理完了

AI整形が完了

処理失敗

AI整形に失敗

要素一覧

処理中状態

要素ID要素名種別説明
toast_processing処理中トーストトーストフローティングトーストコンテナ
processing_text処理中テキストラベル「AI整形を実行中」
processing_sub_textサブテキストラベル「バックグラウンドで処理中」
processing_indicatorプログレス表示アイコンローディングインジケーター(青丸)

完了状態

要素ID要素名種別説明
toast_completed完了トーストトーストフローティングトーストコンテナ
completed_text完了テキストラベル「AI整形が完了」
completed_action確認リンクリンク「タップして確認する」
completed_icon完了アイコンアイコンチェックマークアイコン(緑丸)

失敗状態

要素ID要素名種別説明
toast_failed失敗トーストトーストフローティングトーストコンテナ
failed_text失敗テキストラベル「AI整形に失敗」
failed_actionリトライ案内ラベル「長押しで破棄 / タップで再試行」
failed_icon失敗アイコンアイコン×アイコン(赤丸)

表示条件

条件動作
AI整形処理開始処理中トーストを表示
AI整形処理完了完了トーストに切り替え
AI整形処理失敗失敗トーストに切り替え
完了トーストタップ作成されたメモ詳細画面へ遷移、トーストを非表示
失敗トーストタップAI整形処理を再試行
失敗トースト長押し処理を破棄、トーストを非表示
トーストスワイプトーストを非表示(任意で閉じる)
画面遷移遷移先でもトーストを継続表示

表示トリガー

トリガー説明
録音画面で「完了してAI整形する」押下処理中トーストを表示し、ホーム画面へ遷移

API連携

メソッドエンドポイント用途
GET/api/memos/:id/statusメモのAI処理状態をポーリングで確認

ステータス値

status説明トースト表示
processingAI整形処理中処理中トースト
completedAI整形完了完了トースト
failedAI整形失敗失敗トースト

備考

  • 処理はバックグラウンドで実行されるため、アプリ操作を妨げない
  • 複数の処理が同時に走る場合の仕様は将来検討
  • ネットワークエラー時はリトライ案内を表示予定

12-17

{
  "memoId": "3fe8b039-f867-4403-a8bb-06e217f94b5a",
  "title": "## ボイスブックLM 開発音声メモ",
  "content": "## ボイスブックLM 開発音声メモ\n\nボイスブックLMの開発状況と今後の展望について音声で記録。\n*   React NativeアプリのビルドでNode.jsのバージョン問題\n*   Google Speech to TextとGemini APIによる文字起こしと整形\n*   リアルタイム文字起こし、タグ自動付与の検討\n*   来週までにMVP完成を目指す\n\nTags: `Voicebook`, `AI`, `Development`, `Memo`",
  "tags": [
    "*",
    "リアルタイム文字起こし、タグ自動付与の検討"
  ],
  "transcription": "今日はボイスブック LM のテストも兼ねて今考えてることを音声でメモして行こうと思いますまず最初に今日行って作業振り返りから話します今日は午前中にリアクトネイティブとエキスポを使ったアプリのビルド周りを触っていました EAS ビルドを使って開発ビルドを作ろうとしたんですが NPM の警告がたくさん出てインフライトがディプリケーターだったりり胸付のバージョンが古いとかグローブの性格も出ていました後 Windows 環境のとアセンションふぇーみたいな色も出て喉 JS のバージョン磯ぽいなと感じましたこの辺りは後で整理して Node のバージョンを20系に固定するか nvm をちゃんと使うのかドキュメントにまとめたいと思っています次にボイスブック NM 自体の話をしますこのアプリでは音声を一気に録音してバックエンドに送信して Google Speech to text で文字起こしをしてその後に地味に\nゼロフラッシュを使ってタイトル先生とか本文の整形タグ付けを行う想定です例えば今日やったこととホームがやりたいことと悩んでいることが混ざった音声でもうまく整理してくれるかを試したいですここで今後やりたいことを話します直近ではリアルタイム文字起こしも行ってみたいなと思っています今は一括音声アップロード方式なんですが夜ソケットを使ってストリーミングで文字文字起こしてきたら会議メモとかにも使えそうだなと考えていますあとタグの児童扶養ももっと賢くしたくて例えば開発 react Native 音声認識 AI みたいなタグをユーザーが何もしなくてもつけてくれると嬉しいです少し話題を変えて個人的なメモを残しときます来週までにボイスケイレブの MVP を一旦完成させたいです最低限必要なのは音声録音文字起こし AI 整形一覧表示検索機能ですツールとしては一つ目音声アップロード API\n エラーハンドリング改善フタツメ文字起こしパイ市のリトライ処理見つめジェミニ API のレスポンスをもう少し安定させることこの三つは遊星の高めです最後にこの音声がちゃんと自然な文章に成形されて読みやすいメモになっていたら成功かなと思っていますもし可能ならタイトルはボイスブック LM 開発メモ SR とメモ AI 整形の継承みたいな感じになると嬉しいです以上です",
  "transcriptionStatus": "COMPLETED",
  "formattingStatus": "COMPLETED",
  "processingTimeMillis": {
    "transcription": 62634,
    "formatting": 1421,
    "persistence": 18,
    "total": 64074
  },
  "fallback": {
    "transcription": false,
    "formatting": false
  }
}

🎤 テスト音声 台本(そのまま読んでOK)

えーっと、今日は VoiceBook LM のテストも兼ねて、 今考えていることを音声でメモしていこうと思います。

まず最初に、今日やった作業の振り返りから話します。

今日は午前中に、React Native と Expo を使ったアプリのビルド周りを触っていました。 EAS Build を使って開発ビルドを作ろうとしたんですが、 npm の警告が結構たくさん出て、 inflight が deprecated だったり、rimraf のバージョンが古いとか、 glob の警告も出ていました。

あと、Windows 環境だと Assertion failed: new_time >= loop->time みたいなエラーも出て、 Node.js のバージョン依存っぽいなと感じました。

このあたりは後で整理して、 Node のバージョンを 20 系に固定するか、 nvm をちゃんと使うか、 ドキュメントにまとめたいと思っています。

次に、VoiceBook LM 自体の話をします。

このアプリでは、 音声を一気に録音して、 バックエンドに送信して、 Google Speech-to-Text で文字起こしをして、 その後に Gemini 2.0 Flash を使って タイトル生成とか、本文の整形、タグ付けを行う想定です。

例えば、 「今日やったこと」と 「今後やりたいこと」と 「悩んでいること」 が混ざった音声でも、 うまく整理してくれるかを試したいです。

ここで、今後やりたいことを話します。

直近では、 リアルタイム文字起こしもやってみたいなと思っています。 今は一括音声アップロード方式なんですけど、 WebSocket とかを使って ストリーミングで文字起こしできたら、 会議メモとかにも使えそうだなと考えています。

あと、 タグの自動付与ももっと賢くしたくて、 例えば 「開発」「React Native」「音声認識」「AI」 みたいなタグを ユーザーが何もしなくても付けてくれると嬉しいです。

少し話題を変えて、 個人的なメモも残しておきます。

来週までに、 VoiceBook LM の MVP を一旦完成させたいです。 最低限必要なのは、 音声録音、 文字起こし、 AI 整形、 一覧表示、 検索機能です。

TODO としては、

一つ目、 音声アップロード API のエラーハンドリング改善。

二つ目、 文字起こし失敗時のリトライ処理。

三つ目、 Gemini API のレスポンスを もう少し安定させること。

この三つは優先度高めです。

最後に、 この音声がちゃんと 自然な文章に整形されて、 読みやすいメモになっていたら成功かなと思っています。

もし可能なら、 タイトルは 「VoiceBook LM 開発メモ:ASR と AI 整形の検証」 みたいな感じになると嬉しいです。

文字起こし結果

今日はボイスブック LM のテストも兼ねて今考えてることを音声でメモして行こうと思いますまず最初に今日行って作業振り返りから話します今日は午前中にリアクトネイティブとエキスポを使ったアプリのビルド周りを触っていました EAS ビルドを使って開発ビルドを作ろうとしたんですが NPM の警告がたくさん出てインフライトがディプリケーターだったりり胸付のバージョンが古いとかグローブの性格も出ていました後 Windows 環境のとアセンションふぇーみたいな色も出て喉 JS のバージョン磯ぽいなと感じましたこの辺りは後で整理して Node のバージョンを20系に固定するか nvm をちゃんと使うのかドキュメントにまとめたいと思っています次にボイスブック NM 自体の話をしますこのアプリでは音声を一気に録音してバックエンドに送信して Google Speech to text で文字起こしをしてその後に地味に\nゼロフラッシュを使ってタイトル先生とか本文の整形タグ付けを行う想定です例えば今日やったこととホームがやりたいことと悩んでいることが混ざった音声でもうまく整理してくれるかを試したいですここで今後やりたいことを話します直近ではリアルタイム文字起こしも行ってみたいなと思っています今は一括音声アップロード方式なんですが夜ソケットを使ってストリーミングで文字文字起こしてきたら会議メモとかにも使えそうだなと考えていますあとタグの児童扶養ももっと賢くしたくて例えば開発 react Native 音声認識 AI みたいなタグをユーザーが何もしなくてもつけてくれると嬉しいです少し話題を変えて個人的なメモを残しときます来週までにボイスケイレブの MVP を一旦完成させたいです最低限必要なのは音声録音文字起こし AI 整形一覧表示検索機能ですツールとしては一つ目音声アップロード API\n エラーハンドリング改善フタツメ文字起こしパイ市のリトライ処理見つめジェミニ API のレスポンスをもう少し安定させることこの三つは遊星の高めです最後にこの音声がちゃんと自然な文章に成形されて読みやすいメモになっていたら成功かなと思っていますもし可能ならタイトルはボイスブック LM 開発メモ SR とメモ AI 整形の継承みたいな感じになると嬉しいです以上です

AI整形結果

ボイスブックLM 開発音声メモ\n\nボイスブックLMの開発状況と今後の展望について音声で記録。\n* React NativeアプリのビルドでNode.jsのバージョン問題\n* Google Speech to TextとGemini APIによる文字起こしと整形\n* リアルタイム文字起こし、タグ自動付与の検討\n* 来週までにMVP完成を目指す\n\nTags: Voicebook, AI, Development, Memo

AI整形

えーっと、来月あたりに京都へ旅行に行こうかなって考えていて、  
期間は2泊3日くらいを想定しています。

初日はまず嵐山に行きたいなと思っていて、  
竹林を歩いたりとか、時間があれば周辺も少し散策できたらいいなって感じです。  
2日目は清水寺と祇園あたりを回る予定で、  
いわゆる京都っぽい景色をゆっくり見て回りたいなと思っています。

最終日は伏見稲荷に行くつもりで、  
あの鳥居がずっと続いているところを一度ちゃんと歩いてみたいなって思ってます。  
体力と時間を見ながら、行けるところまで行けたらいいかなと。

宿については、移動しやすそうなので四条あたりで探そうと思っていて、  
全体の予算はだいたい5万円くらいを目安に考えています。  
そんな感じで、京都旅行の計画を立てているところです。

AI整形後

京都旅行の概要

来月、2泊3日の日程で京都旅行を計画している。 全体の予算は5万円を目安に検討を進めている。

観光スケジュール

1日目

初日は嵐山を訪れる予定だ。 竹林の散策を中心に、時間があれば周辺エリアも巡りたいと考えている。

2日目

2日目は清水寺祇園を中心に観光する。 京都らしい風情をゆっくりと楽しむ一日とする予定だ。

3日目

最終日には伏見稲荷大社へ足を運ぶ。 千本鳥居を歩くことを目的とし、体力と時間に応じて散策範囲を決める。

宿泊地

宿泊先は移動の利便性を重視し、四条エリアで探す予定だ。

AI整形前

えーっと、今週の買い物なんですけど、まず食品で言うと、牛乳と卵とパンは買っておきたいなと思ってます。
あと、野菜も必要で、キャベツとかにんじんを買う予定です。
それから日用品なんですけど、洗剤がそろそろなくなりそうなので補充したいのと、ティッシュも在庫が少ないので一緒に買っておこうかなと思ってます。

AI整形後

今週の買い物について計画をまとめました。 主に食品と日用品の補充が必要となります。

食品の購入リスト

食品では、牛乳パンを優先的に購入します。 また、野菜はキャベツにんじんが必要となるため、これらも購入する予定です。

日用品の補充

日用品では、洗剤の残量が少なくなっているため補充します。 加えて、ティッシュの在庫も減少しているため、この機会に購入する予定です。

TODO

  • 食料品(牛乳、卵、パン、キャベツ、にんじん)を購入する
  • 日用品(洗剤、ティッシュ)を購入する

AI整形前

えーっと、最近ちょっと思ったんですけど、音声で日記をつけられるアプリがあったら、けっこう便利なんじゃないかなって思ってて。
毎日こう、5分くらいでいいから、その日にあったこととか、感じたことをそのまま話すだけで、AIがいい感じに要約してくれたら楽だなって思うんですよね。
文字で日記を書くのって、正直ちょっと面倒な日もあるじゃないですか。
でも、話すだけなら通勤中とか、寝る前とかでもできそうだなって。
で、あとから読み返したときに、ちゃんと分かる文章にまとまってたら嬉しいなと思ってます。
それに、内容に応じて自動でタグ付けしてくれたり、あとから「あのとき何考えてたっけ」みたいに検索できる機能があったら、日記としても振り返りやすくなる気がします。
ただ記録するだけじゃなくて、自分の考えとか感情を整理するのを手伝ってくれる、そんな感じの音声日記アプリがあったらいいな、って思いました。

AI整形後

音声日記アプリの構想

最近、音声で手軽に日記をつけられるアプリがあれば、非常に便利だと感じています。毎日、約5分程度の短い時間で、その日にあった出来事や感じたことを話すだけで完結するのが理想です。

文字で日記を書くことは、正直なところ面倒に感じる日もありますが、音声入力であればそのハードルを下げられます。通勤中や寝る前など、隙間時間を活用して気軽に利用できるでしょう。

期待する機能

このアプリには、入力された音声をAIが自動で要約し、後から読み返したときに理解しやすい自然な文章にまとめる機能が必要です。これにより、日々の記録が簡潔に整理されます。

また、記録内容に応じて自動でタグ付けされる機能や、過去の記録をキーワードで検索できる機能も備わっていると便利です。これらの機能があれば、「あの時何を考えていたか」といった振り返りが容易になり、日記としての価値が高まります。

アプリの価値

単に日々の出来事を記録するだけでなく、自分の考えや感情を整理する手助けをしてくれるようなアプリを目指したいです。このような音声日記アプリは、忙しい現代において個人の内省を促し、自己理解を深める上で非常に有用だと考えられます。

VoiceBookLM 中間発表

発表日: 2024年12月18日


1. プロジェクト概要

VoiceBookLM は音声メモをAIで自動要約・整理するアプリケーションです。


2. 現在の実装状況(中間発表時点)

2.1 バックエンド(API)

実装完了 API(6/20)

カテゴリAPI説明
認証POST /api/auth/googleGoogle OAuth ログイン
認証POST /api/auth/refreshトークンリフレッシュ
認証POST /api/auth/logoutログアウト
認証DELETE /api/auth/accountアカウント削除
認証GET /api/auth/meユーザー情報取得
音声メモPOST /api/voice/memos音声ファイルからメモ生成

バックエンド達成率

実装済み: 6 / 20 API(30%)
├── 認証 API:     5/5  ████████████████████ 100%
├── 音声メモ API: 1/1  ████████████████████ 100%
├── メモ API:     0/7  ░░░░░░░░░░░░░░░░░░░░   0%
├── フォルダ API: 0/4  ░░░░░░░░░░░░░░░░░░░░   0%
└── タグ API:     0/3  ░░░░░░░░░░░░░░░░░░░░   0%

2.2 フロントエンド(画面)

実装完了画面(4/12)

カテゴリ画面パス状態
認証ログイン/login
録音録音/record
録音録音確認/record/preview
録音処理中/record/processing

フロントエンド達成率

実装済み: 4 / 12 画面(33%)
├── 認証系:   1/2  ██████████░░░░░░░░░░  50%
├── メイン系: 0/3  ░░░░░░░░░░░░░░░░░░░░   0%
├── 録音系:   3/4  ███████████████░░░░░  75%
└── 設定系:   0/3  ░░░░░░░░░░░░░░░░░░░░   0%

2.3 実装済み機能の詳細

認証システム(バックエンド完成・フロント一部完成)

  • Google OAuth によるソーシャルログイン
  • JWT トークンによるセッション管理
  • リフレッシュトークンによる自動更新
  • セキュアなログアウト処理
  • アカウント削除機能

音声メモ生成(バックエンド完成・フロント一部完成)

  • 音声ファイルのアップロード
  • AI による文字起こし
  • 自動要約生成
  • 録音〜処理中画面の実装

3. 合評会までの実装予定(全機能完成目標)

3.1 バックエンド(残り14 API)

メモ API(7個)

メソッドエンドポイント説明
GET/api/memosメモ一覧取得
GET/api/memos/{id}メモ詳細取得
PATCH/api/memos/{id}メモ更新
DELETE/api/memos/{id}メモ削除
POST/api/memos/{id}/resummarize再要約
GET/api/memos/{id}/transcription文字起こしテキスト取得
POST/api/memos/search/semantic意味検索(AI)

フォルダ API(4個)

メソッドエンドポイント説明
GET/api/foldersフォルダ一覧取得
POST/api/foldersフォルダ作成
PATCH/api/folders/{id}フォルダ更新
DELETE/api/folders/{id}フォルダ削除

タグ API(3個)

メソッドエンドポイント説明
GET/api/tagsタグ一覧取得
DELETE/api/tags/{name}タグ削除
POST/api/tags/mergeタグ統合

バックエンド目標達成率

目標: 20 / 20 API(100%)
├── 認証 API:     5/5  ████████████████████ 100%
├── 音声メモ API: 1/1  ████████████████████ 100%
├── メモ API:     7/7  ████████████████████ 100%
├── フォルダ API: 4/4  ████████████████████ 100%
└── タグ API:     3/3  ████████████████████ 100%

3.2 フロントエンド(残り8画面)

残り実装予定画面

カテゴリ画面パス説明
認証スプラッシュ/splashアプリ起動時のロード画面
メインホーム/homeメモ一覧、ディレクトリ表示
メイン検索/searchキーワード・タグ検索
メインメモ詳細/memo/:idMarkdown形式でメモ表示
録音生成結果/record/result生成されたメモの確認
設定設定/settings設定メニュー
設定プロフィール/settings/profileユーザー情報表示
設定言語設定/settings/language文字起こし言語選択

フロントエンド目標達成率

目標: 12 / 12 画面(100%)
├── 認証系:   2/2  ████████████████████ 100%
├── メイン系: 3/3  ████████████████████ 100%
├── 録音系:   4/4  ████████████████████ 100%
└── 設定系:   3/3  ████████████████████ 100%

4. 開発ロードマップ

┌───────────────────────────────────────────────────────────────────────┐
│                          開発タイムライン                              │
├───────────────────────────────────────────────────────────────────────┤
│                                                                       │
│  中間発表 ───────────────────────────────────────► 合評会             │
│  (12/18)                                           (全機能完成)       │
│                                                                       │
│  【バックエンド】                                                     │
│  ✅ 認証 API (5個)                                                    │
│  ✅ 音声メモ API (1個)                                                │
│  ┌────────────────────────────────────────────┐                      │
│  │  🚧 メモ API (7個)                          │                      │
│  │  🚧 フォルダ API (4個)                      │                      │
│  │  🚧 タグ API (3個)                          │                      │
│  └────────────────────────────────────────────┘                      │
│                                                                       │
│  【フロントエンド】                                                   │
│  ✅ ログイン画面 (1画面)                                              │
│  ✅ 録音フロー (3画面)                                                │
│  ┌────────────────────────────────────────────┐                      │
│  │  🚧 スプラッシュ画面 (1画面)                │                      │
│  │  🚧 メイン画面 (3画面)                      │                      │
│  │  🚧 生成結果画面 (1画面)                    │                      │
│  │  🚧 設定画面 (3画面)                        │                      │
│  └────────────────────────────────────────────┘                      │
│                                                ↓                      │
│                                           全機能完成                  │
│                                    (20 API + 12 画面)                 │
│                                                                       │
└───────────────────────────────────────────────────────────────────────┘

5. まとめ

現在の進捗状況

項目中間発表時点合評会目標
バックエンド6 / 20 API(30%)20 / 20 API(100%)
フロントエンド4 / 12 画面(33%)12 / 12 画面(100%)

中間発表時点で完成している機能

カテゴリバックエンドフロントエンド
認証✅ 完成(5 API)🚧 一部完成(1/2画面)
音声メモ生成✅ 完成(1 API)🚧 一部完成(3/4画面)
メモ管理🚧 未着手🚧 未着手
フォルダ🚧 未着手🚧 未着手
タグ🚧 未着手🚧 未着手
設定-🚧 未着手

次のマイルストーンまでの主要タスク

バックエンド

  1. メモ CRUD 機能の実装

    • 一覧取得・詳細取得・更新・削除
  2. 再要約・文字起こし機能の実装

    • 既存メモの要約を再生成
    • 文字起こしテキスト取得
  3. 意味検索機能の実装

    • AIによるセマンティック検索
  4. フォルダ機能の実装

    • メモの整理・分類機能
  5. タグ機能の実装

    • タグ一覧・削除・統合

フロントエンド

  1. メイン画面の実装

    • ホーム(メモ一覧)
    • 検索画面
    • メモ詳細画面
  2. 録音フローの完成

    • 生成結果画面
  3. 認証フローの完成

    • スプラッシュ画面
  4. 設定画面の実装

    • 設定メニュー
    • プロフィール
    • 言語設定

付録: ステータス凡例

マーク意味
実装済み
🚧未実装(MVP必須)
📋未実装(追加機能)
🔮将来実装予定

VoiceBookLM 中間発表

現在実装済み

  • Google ログイン機能
  • 音声録音・アップロード
  • AI 文字起こし・要約生成
  • ログイン画面
  • 録音〜処理中画面

合評会までに実装予定

  • メモ一覧・詳細・編集・削除
  • 再要約・意味検索
  • フォルダ管理
  • タグ管理
  • ホーム・検索・メモ詳細画面
  • 設定画面

全体サマリー

機能現在合評会目標
認証ほぼ完成完成
音声メモ生成ほぼ完成完成
メモ管理未着手完成
フォルダ未着手完成
タグ未着手完成
設定未着手完成

VoiceBookLM 操作説明書

1. はじめに

VoiceBookLMは、話すだけで整理されたメモが自動で作られるAI搭載ボイスメモアプリです。 本書では、アプリの基本的な操作方法について説明します。


2. アプリ起動・ログイン

2.1 アプリの起動

  1. ホーム画面で「VoiceBookLM」アイコンをタップします
  2. ウェルカム画面が表示されます

2.2 ログイン

  1. ウェルカム画面で「Googleでサインイン」ボタンをタップします
  2. Googleアカウントを選択してログインします
  3. ログイン完了後、ホーム画面に遷移します

3. ホーム画面の操作

3.1 画面構成

要素説明
ヘッダーアプリロゴ、検索アイコンを表示
メモ一覧保存されたメモをカード形式で表示
録音ボタン画面下部中央の丸いボタン

3.2 メモの確認

  • メモ一覧から確認したいメモをタップします
  • メモ詳細画面で内容を確認できます

3.3 メモの検索

  1. ヘッダーの検索アイコンをタップします
  2. 検索画面でキーワードを入力します
  3. 該当するメモが一覧表示されます

4. 録音操作

4.1 録音の開始

  1. ホーム画面下部の録音ボタン(マイクアイコン)をタップします
  2. 録音画面に遷移し、自動的に録音が開始されます
  3. 画面に録音時間が表示されます

4.2 録音の一時停止・再開

  • 一時停止:一時停止ボタンをタップします
  • 再開:再生ボタンをタップして録音を再開します

4.3 録音の完了とAI整形

  1. 録音が完了したら「完了してAI整形する」ボタンをタップします
  2. ホーム画面に戻り、画面下部にAI処理中のトーストが表示されます
  3. 処理完了後、メモ一覧に自動整形されたメモが追加されます

4.4 録音のキャンセル

  • 録音を破棄する場合は「キャンセル」ボタンをタップします
  • 確認ダイアログで「破棄」を選択すると録音データが削除されます

5. AI自動整形機能

5.1 自動生成される項目

項目説明
タイトルメモ内容から自動生成
本文マークダウン形式で整形
タグ内容に基づいて自動付与

5.2 処理時間

  • 通常30秒以内で処理が完了します
  • 処理中も他の操作が可能です

6. メモの管理

6.1 メモの編集

  1. メモ詳細画面で「編集」ボタンをタップします
  2. タイトル、本文、タグを編集できます
  3. 「保存」ボタンで変更を保存します

6.2 メモの削除

  1. メモ詳細画面で「削除」ボタンをタップします
  2. 確認ダイアログで「削除」を選択します

7. トラブルシューティング

よくある問題と解決方法

問題解決方法
録音が開始されないマイク権限を確認してください
AI整形が完了しないネットワーク接続を確認してください
ログインできないGoogleアカウント設定を確認してください

8. お問い合わせ

アプリに関するお問い合わせは、設定画面の「サポート」からご連絡ください。


最終更新日:2026年1月20日

VoiceBookLM ビルド手順書

1. 概要

VoiceBookLMは以下の2つのリポジトリで構成されています。 各リポジトリのREADMEに詳細なビルド手順が記載されています。


2. リポジトリ一覧

フロントエンド(モバイルアプリ)

項目内容
リポジトリvoicebooklm-frontend
技術スタックReact Native + Expo
詳細手順READMEを参照

バックエンド

項目内容
リポジトリvoicebooklm-backend
技術スタックSpring Boot (Kotlin) + PostgreSQL
詳細手順READMEを参照

3. システム構成

┌─────────────────────────────────────────────────────┐
│                   VoiceBookLM                        │
├──────────────────────┬──────────────────────────────┤
│   📱 Frontend        │   🖥️ Backend                  │
│   React Native       │   Spring Boot                │
│   + Expo             │   + PostgreSQL               │
└──────────────────────┴──────────────────────────────┘

4. 参考リンク

  • フロントエンド: https://github.com/assari-harassment/voicebooklm-frontend
  • バックエンド: https://github.com/assari-harassment/voicebooklm-backend

最終更新日:2026年1月20日

VoiceBookLM インストール手順書

1. 概要

VoiceBookLMは以下のプラットフォームで利用可能です。


2. 公開状況

プラットフォーム状況公開予定日
🌐 Web版公開予定2026年1月26日
🍎 App Store (iOS)準備中未定
🤖 Google Play (Android)準備中未定

3. Web版

アクセス方法

公開後、以下のURLからアクセスできます:

URL: (2026年1月26日 公開予定)

動作環境

項目要件
対応ブラウザChrome、Safari、Firefox、Edge(最新版推奨)
マイク音声録音に必要

利用開始手順

  1. WebブラウザでURLにアクセスします
  2. 「Googleでサインイン」をクリックします
  3. Googleアカウントでログインします
  4. ログイン完了後、すぐに利用開始できます

4. iOS版(App Store)

準備中 - 公開日が決まり次第、更新します web 公開予定

公開後の予定

  • App Storeで「VoiceBookLM」を検索してインストール

動作環境(予定)

項目要件
対応OSiOS 15.0以上
対応デバイスiPhone 8以降

5. Android版(Google Play)

準備中 - 公開日が決まり次第、更新します

公開後の予定

  • Google Playストアで「VoiceBookLM」を検索してインストール

動作環境(予定)

項目要件
対応OSAndroid 10.0以上

6. 初回起動時の設定

権限の許可

アプリ利用時に以下の権限を許可してください:

権限用途必須
マイク音声録音
通知AI処理完了通知推奨

Googleアカウントでログイン

  1. 「Googleでサインイン」をタップ/クリックします
  2. 使用するGoogleアカウントを選択します
  3. ログイン完了後、ホーム画面に遷移します

7. サポート

ご不明な点がございましたら、以下までお問い合わせください:

  • GitHub Issues: https://github.com/assari-harassment/voicebooklm-frontend/issues

最終更新日:2026年1月20日

VoiceNoteLM デプロイシステム構成図

全体構成

外部サービス連携

セキュリティグループ構成

データフロー

1. ユーザー認証フロー

2. 音声文字起こしフロー

コンポーネント詳細

Frontend (Vercel)

項目
フレームワークReact Native Web / Expo
ホスティングVercel
ドメインvoicenotelm.app
SSLVercel自動SSL
ビルド自動(Git push時)

環境変数:

変数名
EXPO_PUBLIC_GOOGLE_WEB_CLIENT_IDGoogle OAuth Client ID
EXPO_PUBLIC_API_BASE_URLhttps://api.voicenotelm.app
EXPO_PUBLIC_WS_BASE_URLwss://api.voicenotelm.app

Backend (AWS EC2)

項目
インスタンスタイプt3.micro
AMIAmazon Linux 2023
JavaAmazon Corretto 21
フレームワークSpring Boot (Kotlin)
パス/opt/voicenotelm/
サービス管理systemd (voicenotelm)

Database (AWS RDS)

項目
エンジンPostgreSQL 16
インスタンスクラスdb.t4g.micro
ストレージ20 GiB gp2
自動バックアップ無効
パブリックアクセスなし
データベース名voicenotelm

Nginx設定

server {
    listen 80;
    server_name api.voicenotelm.app;

    location / {
        proxy_pass http://localhost:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # WebSocket対応
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_read_timeout 86400;
    }
}

DNS設定 (Cloudflare)

レコードタイプ名前Proxy
APIAapiEC2 Elastic IPDNS only (灰色)
FrontendCNAME@cname.vercel-dns.comDNS only (灰色)
FrontendCNAMEwwwcname.vercel-dns.comDNS only (灰色)

想定コスト (月額)

サービス費用
EC2 t3.micro無料枠(750時間/月)
RDS db.t4g.micro無料枠(750時間/月)
Elastic IP無料(EC2起動中)
Vercel無料(Hobby)
Cloudflare無料
合計$0〜5

運用コマンド

EC2操作

# SSH接続
ssh -i <your-key.pem> ec2-user@<Elastic IP>

# アプリケーション再起動
sudo systemctl restart voicenotelm

# ステータス確認
sudo systemctl status voicenotelm

# ログ確認
sudo journalctl -u voicenotelm -n 50 --no-pager

# メモリ確認
free -h

RDS接続

# EC2経由でRDSに接続
psql -h <RDSエンドポイント> -U <username> -d <database>

デプロイ手順

# ローカルでビルド
cd voicebooklm-backend
./gradlew bootJar

# EC2に転送
scp -i <your-key.pem> build/libs/*.jar ec2-user@<IP>:/path/to/app.jar

# EC2で再起動
sudo systemctl restart voicenotelm