PEPPER LIKES

言語

社内資料本番環境では削除予定

内部仕様・法務参考資料

PEPPER LIKES の技術仕様・DB設計・API仕様(開発者・法務担当向け)

1. 技術スタック

バックエンド(likes-api)

  • Laravel 10 / PHP 8.4
  • Laravel Sanctum(Bearer トークン認証)
  • Spatie Laravel Permission(ロール管理)
  • Laravel Cashier(Stripe サブスクリプション)
  • MySQL(本番・ステージング)/ SQLite(ローカル)
  • GitHub Actions → SSH 自動デプロイ(Cloudways)

フロントエンド(likes-web)

  • Next.js 16 / React 19 / TypeScript 5
  • Tailwind CSS v4 / shadcn/ui
  • Zustand v5(状態管理)/ Axios(APIクライアント)
  • @dnd-kit(ドラッグ&ドロップ)
  • next-intl(多言語: ja/en/zh-TW/zh-CN/ko)
  • Vercel 自動デプロイ

外部サービス

  • Stripe(サブスクリプション・Connect・Checkout)
  • TRUSTDOCK(eKYC 本人確認)
  • OpenAI GPT-4o(メッセージモデレーション)/ gpt-4o-mini(翻訳・AIアドバイス)
  • Google Maps Geocoding API(住所自動補完)
  • Web Push(VAPID キー・Push通知)

2. 認証・ロール

ロール

ロール説明ログインエンドポイント
sellerインフルエンサーPOST /api/auth/inf/login
buyer企業POST /api/auth/company/login

Cookie

  • gifting_token: Sanctum Bearer トークン(30日)
  • gifting_role: ロール(seller / buyer)

表示言語の自動切り替え(preferred_language)

  • ログイン成功時に APIレスポンスの preferred_language(ja/en/zh-TW/zh-CN/ko)を取得
  • 現在のURL locale と異なる場合は window.location.replace でリダイレクト
  • 例: ブラウザが /ja/home で preferred_language=en の場合 → /en/home へ即時遷移
  • ブラウザリフレッシュ後にも同様の判定を実行(next-intl middleware 経由)
  • 言語設定変更時は PATCH /api/auth/inf/profile で preferred_language を更新

3. DBスキーマ(主要テーブル)

users(インフルエンサー・企業共通)

カラム説明
is_overseasboolean海外在住フラグ
overseas_country/zipcode/addressstring/texteKYC 海外在住登録住所
shipping_countrystring配送先住所: 国(IPから自動検出して初期値に設定)
shipping_zipcodestring配送先住所: 郵便番号
shipping_addresstext配送先住所: 都道府県・市区町村・番地
shipping_address_2string配送先住所: マンション名・部屋番号(任意)
kyc_statusstringpending / verified
stripe_connect_idstringStripe Connect アカウントID
stripe_connect_statusstringStripe Connect 接続ステータス
preferred_languagestringja/en/zh-TW/zh-CN/ko(ログイン後自動切り替え)
rankstringsilver / gold / platinum / null

projects(キャンペーン)

カラム説明
typestringgifting / paid
project_formatstringoffline / remote
remote_delivery_typestringphysical / digital / null
overseas_okboolean海外在住INF参加可否
statusstringdraft / publish / pending
proposal_statusstringopen / closed
reward_typestringfixed / negotiable(有償のみ)

proposals(応募)

カラム説明
statusstringpending/new/hired/awaiting_confirmation/active/payment_pending/completed/declined
post_url / post_urlsstring/jsonSNS投稿URL
became_active_attimestamp提供済みになった日時
comment_translationsjsonspecial_comments の翻訳キャッシュ(全5言語)
digital_contenttextデジタルコンテンツ送付テキスト(URL/コード等)
digital_attachment_urlsjsonデジタル添付ファイルURL配列
shipping_tracking_numberstring送り状番号(物品配送案件)
shipping_carrierstring発送業者(yamato/sagawa/japanpost/dhl/fedex/ems/other 等)
shipped_attimestamp発送日時
digital_delivered_attimestampデジタルコンテンツ送付日時
pinned_attimestamp企業側ピン留め日時
pinned_orderint企業側ピン留め並び順
company_memotext企業側社内メモ(INF非表示)
company_labelstringhot(赤)/ watching(青)/ pending(黒)/ null
inf_pinned_attimestampINF側ピン留め日時
inf_pinned_orderintINF側ピン留め並び順
inf_memotextINF側個人メモ(本人のみ表示)

application_messages

カラム説明
typestringmessage / schedule_proposal
image_urlstring画像添付URL
attachment_urlsjson[{url, original_name, size}] ファイル添付配列
translationsjson{ ja:"...", en:"...", "zh-TW":"...", "zh-CN":"...", ko:"..." } 翻訳キャッシュ。送信時に TranslateMessageJob で全5言語を事前生成
read_attimestamp既読日時

4. ステータス仕様

proposals.status 遷移

ステータス表示名説明
pending / new審査中企業が確認中
awaiting_confirmationオファー中有償応相談: INF承認待ち
hired調整中マッチング完了・メッセージで調整
active提供済み提供確認済み・アンケート・投稿URL受付(旧「体験済み」から変更)
payment_pending支払い処理中有償案件: 請求処理中
completed完了アンケート + 投稿URL 提出済み
declined見送り企業による不採用 or INF辞退(旧「不採用」から変更)

提供済み移行ボタン名(project_format 別)

案件形式ボタン表示名遷移条件
offline提供済みにするPATCH status=active
remote(physical)商品提供済みにするPATCH status=active
remote(digital)コンテンツを送付するPOST /digital-delivery → active 移行
デジタル案件のみ「コンテンツを送付する」ボタンで別エンドポイントを呼び出す。送付完了と同時に active に遷移する。

自動完了条件(無償・active時)

キャンペーン固有のアンケート提出 AND 投稿URL提出 → 自動で completed に移行。グローバルサーベイ(campaign_id=null)は条件に含まない。

5. API エンドポイント一覧(主要)

認証

  • POST /api/auth/inf/login・logout・register・me
  • POST /api/auth/company/login・logout・register・me
  • PATCH /api/auth/inf/profile(shipping_country/zipcode/address/address_2/preferred_language 含む)

案件

  • GET /api/campaigns(一覧・フィルター)
  • POST /api/campaigns(作成: remote_delivery_type 含む)
  • PATCH /api/campaigns/[id](更新)
  • GET /api/campaigns/[id]/applications(応募一覧)

応募(企業側)

  • PATCH /api/applications/[id]/status(hired/declined/active/completed 等)
  • PATCH /api/applications/[id]/tracking(発送業者 shipping_carrier + 送り状番号の登録)
  • POST /api/applications/[id]/digital-delivery(デジタルコンテンツ送付 + active 移行)
  • PATCH /api/applications/[id]/meta(企業側: pinned/label/memo の更新)

応募(INF側)

  • POST /api/campaigns/[id]/apply
  • PATCH /api/my/applications/[id]/post-url
  • PATCH /api/my/applications/[id]/confirm-scout
  • PATCH /api/my/applications/[id]/meta(INF側: pinned/memo の更新)

ファイルアップロード

  • POST /api/upload/campaign-image(案件画像: max 5MB)
  • POST /api/upload/message-image(チャット画像: max 10MB)
  • POST /api/upload/digital-content(デジタルコンテンツ: PDF/動画/ZIP等 max 50MB)
  • POST /api/upload/report-evidence(通報証拠: max 10MB)

翻訳

  • POST /api/translate/text(任意テキストを全5言語に翻訳してキャッシュ)
リクエスト: { "text": "...", "source_locale": "ja" }
レスポンス: { "translations": { "ja": "...", "en": "...", "zh-TW": "...", "zh-CN": "...", "ko": "..." } }

メッセージ

  • GET/POST /api/applications/[id]/messages(企業側)
  • GET/POST /api/my/applications/[id]/messages(INF側)
  • PATCH /api/applications/[id]/messages/read-all
  • PATCH /api/applications/[id]/messages/[msgId]/proposal(日程確定)

モデレーション

  • POST /api/moderation/preview(送信前プレチェック)

6. リモート配送フロー

物品配送(physical)フロー

  1. 案件作成時に remote_delivery_type=physical を設定
  2. INFが応募 → 企業がマッチング(hired)→ 自動メッセージ送信
  3. INFがアカウント設定で配送先住所を登録(shipping_address_2: マンション・部屋番号も任意入力可)
  4. 企業側応募詳細に住所(address + address_2)が表示される
  5. 企業が商品を発送 → 発送業者(shipping_carrier)を選択し送り状番号を入力(PATCH /tracking → INFにメッセージ通知)
  6. 企業が「商品提供済みにする」→ active 移行
  7. INFの詳細ページに「📦 商品を発送しました」セクション(水色)表示(発送業者・送り状番号を記載)
  8. INFがアンケート + 投稿URL提出 → completed

デジタル配信(digital)フロー

  1. 案件作成時に remote_delivery_type=digital を設定
  2. INFが応募 → 企業がマッチング(hired)→ 自動メッセージ送信
  3. 企業が「コンテンツを送付する」フォームでテキスト + ファイルを入力
  4. 送付ボタンで POST /digital-delivery → active 移行 + メッセージ通知
  5. INFの詳細ページに「💻 デジタルコンテンツが届きました」セクション(紫)表示
  6. テキストコンテンツ表示 + ファイルのダウンロードボタン
  7. INFがアンケート + 投稿URL提出 → completed

配送先住所フィールドの設計

  • users.shipping_address: 全INF共通の配送先(都道府県・市区町村・番地)
  • users.shipping_address_2: マンション名・部屋番号(任意・追加フィールド)
  • users.overseas_address: eKYC 海外在住登録用(別目的)
  • users.shipping_country: 登録時にIPアドレスから自動検出して初期値を設定
  • Google Maps Geocoding API で郵便番号から住所自動補完

7. 画面仕様(主要)

INF アカウント設定(/account)

  • 配送先住所フォームに shipping_address_2(マンション名・部屋番号)フィールドを追加
  • 言語設定セクション: preferred_language をドロップダウンで選択 → PATCH 後に自動リダイレクト
  • 国籍(nationality)フィールドは必須。一度登録すると変更不可(変更はCS対応)

INF 応募一覧(/applications)

  • タブ: Pill chips形式(調整中 / 提供済み / 完了 / 審査中 / 見送り)。各タブに件数バッジ表示
  • 「すべて」タブは廃止
  • 調整中タブを開くと紙吹雪アニメーションが表示される
  • 未読メッセージバッジ(赤数字)をカードに表示
  • ピン留めカードは一覧上部に固定表示(inf_pinned_order 順)
  • ピン留め・メモボタンはカード右上のアイコンから操作

INF 応募詳細(/applications/[id])

  • 横タイムライン: 応募日 → マッチング日 → 提供済み日 → 完了日 などをステップ表示
  • ステータスウィジェット(2段階): 現在ステータス表示 + 次のアクション案内
  • チャット部分: 各メッセージに AI翻訳トグル(TranslatableBody コンポーネント)
  • 応募文(special_comments): TranslatableText コンポーネントで翻訳トグル付き表示
  • デジタルコンテンツ受信時: 「💻 デジタルコンテンツが届きました」セクションを紫背景で表示
  • 物品発送通知時: 「📦 商品を発送しました」セクションを水色背景で表示(発送業者 + 送り状番号含む)
  • 個人メモ(inf_memo)入力エリア: 本人のみ表示

企業側 応募管理(/company/applications)

  • タブ: Pill chips形式(未対応 / 調整中 / 提供済み / 完了 / 見送り)。各タブに件数バッジ表示
  • ステータス別集計バー(審査中/調整中/提供済み/完了/見送り)
  • company_label によるバッジカラー: hot=赤 / watching=青 / pending=黒
  • ピン留めカードは一覧上部に固定(pinned_order 順)
  • マッチング時の自動メッセージ送信(案件形式に応じたテンプレート)

企業側 応募詳細(/company/applications/[id])

  • 2カラムレイアウト: 左=INF情報(SNS・応募文等)、右=ステータス+アクション
  • 横タイムライン: マッチング日・提供済み日・完了日をステップ表示
  • ランクバッジはアバター右下に重なって表示
  • 審査中の右カラムに「AIアドバイス」が自動表示(GPT-4o-mini使用、採用判断の参考情報)
  • 「マッチングする」ボタンは右カラムに配置(審査中時のみ)
  • 物品配送案件: 発送業者セレクト(国内: ヤマト/佐川/日本郵便等、国際: DHL/FedEx/EMS等)+ 送り状番号入力フォーム + 「商品提供済みにする」ボタン
  • デジタル案件: テキスト + ファイルアップロードフォーム(ドラッグ&ドロップ対応、max 50MB)+ 「コンテンツを送付する」ボタン
  • ラベル選択(hot/watching/pending)・社内メモ入力・ピン留めトグル
  • INFの配送先住所(address + address_2)をコピー可能な形式で表示

案件作成(/company/projects/new)

  • 実施形式選択: オフライン / リモート(物品)/ リモート(デジタル)
  • リモート選択時: 配信方式(physical/digital)ラジオボタンを追加表示
  • 海外INF参加可否チェックボックス(リモート時のみ)

8. AI翻訳アーキテクチャ

TranslationService(gpt-4o-mini)

  • モデル: gpt-4o-mini(コスト削減)
  • 対応言語: ja / en / zh-TW / zh-CN / ko
  • 「ターゲット言語に必ず翻訳せよ」という直接指示プロンプト(言語自動検出なし)
  • 改行・段落構造を保持する指示を含む

TranslateMessageJob

メッセージ送信時にディスパッチされ、全5言語を一括翻訳して application_messages.translations にキャッシュ。受信者がチャットを開いた際に即表示される。QUEUE_CONNECTION=sync の場合は同期実行。

翻訳対象

対象キャッシュ先タイミング
チャットメッセージ本文application_messages.translations送信時(TranslateMessageJob)
応募文(special_comments)proposals.comment_translations応募時 or 初回表示時
任意テキストサーバー側一時キャッシュPOST /api/translate/text 呼び出し時

フロントエンドコンポーネント

  • TranslatableBody: チャットメッセージバブル内(両サイド)の翻訳トグル
  • TranslatableText: 応募文等の任意テキストに使用する汎用コンポーネント
  • 翻訳中スピナー → 完了後「🌐 AI翻訳 · 原文」ラベル表示
  • 翻訳が translations に既にキャッシュされている場合はAPIコール不要(即時表示)

9. 通知・メール

通知チャンネル

  • database: アプリ内ベルアイコン(常時)
  • mail: メール通知(MAIL_MAILER 設定時)
  • webpush: プッシュ通知(VAPID キー設定時のみ)

VAPID / WebPush

VAPID_PUBLIC_KEYVAPID_PRIVATE_KEY が未設定の場合、webpush チャンネルは自動的にスキップされる(500エラーにならない)。

メールテンプレート

MAIL_MAILER=log の場合メールは送信されず storage/logs/laravel.log に記録される。

10. メッセージモデレーション

仕組み

  • 送信前に POST /api/moderation/preview でプレチェック
  • ルールベース(NGワードリスト)+ GPT-4o によるスコアリング
  • action=block: 送信不可(エラー表示)
  • action=warn: 警告ダイアログ表示 → ユーザーが選択
  • 多言語対応(日本語・英語・中国語・韓国語)

操作ログ・同意ログ

  • operation_logs: ステータス変更・スカウト・採用等の企業操作証跡を記録
  • consent_logs: スカウト承認・辞退・報酬合意等のINF同意記録
  • 両テーブルとも法務上の証跡として保存(削除不可)

11. ランクシステム

計算ロジック

  • 毎日深夜2時に自動再計算(rank:calculate Artisanコマンド)
  • 対象: 公開済みレビュー(published)のみ
  • 累計応募数・累計完了数・過去1年の完了数・過去1年のレビュー平均 で判定