1. oceanbeatとは

海と一緒に、毎回の体験を残すマリンレジャー基盤

oceanbeatは、スキューバダイビングを先行リリース対象としつつ、マリンレジャー領域(サーフィン・釣り・SUP・セーリング等)を 同じ共通モデルで扱うサービス基盤です。ログ・画像・ポイント・海況・事業者・予約を一つにまとめ、 ダイバーやサーファーなどの利用者と、ショップ・船・ガイドなどの事業者が同じ場所で動けるように設計しています。

oceanbeatのねらいは、紙ログ/旧電子ログ/SNSに流れる写真/別アプリの海況メモといった「散らばった海の記憶」を、再訪と判断に使える資産へ変えることです。 初期は scuba_divingのログ体験を最も深く提供しつつ、共通モデルは最初からマルチ種目を想定して固定します。

マリンレジャー基盤として揃える4条件

  1. 記録:Web / iOS / Android で同じログ、未ログインのローカル記録も後から同期
  2. 素材:ログ紐付け前から画像を保存、参照制御つきで配信
  3. 判断:ポイント別の海況・気象・潮汐+種目別の適性スコア/危険判定
  4. 接続:ショップ・船・ガイドの正規加盟/外部認証/SNS導線、催行可否、予約・振替

本マニュアルの構成

  • アカウントと利用範囲(CommonAuth/未ログインローカルワークスペース)
  • ツアーとログの記録(共通モデル + scuba_diving 拡張)/ライブラリ素材管理
  • ポイントと海況・気象・潮汐/SNS・レビュー・OCR取り込み
  • ショップ・船・ガイド向け運用(provider)/プラン・契約・課金(Hub)

2. アカウントと利用範囲

CommonAuth × 未ログインローカルワークスペース

oceanbeatは common-auth を共通認証基盤として利用し、 利用者の主体同定を行います。Web 版はセッションCookieによるログイン継続、iOS / Android 版はプラットフォーム別の native auth SDK と common-auth-backend 側の native endpoint 群に接続して継続します。oceanbeat 側ではパスワード/refresh token/セッション状態を持ちません。

利用主体の種別

  • コンシューマ:ダイバー/サーファー/釣り人/SUPプレイヤー 等
  • プロバイダー担当者:ショップ/船/ガイド/チャーター事業者の従業員
  • 運営:oceanbeat backoffice を扱う運営メンバー

consumer ユーザーは common-auth上では同じ主体として扱われ、契約に応じて provider 向けアプリへの入室可否が決まります。

利用範囲の判定

  1. 契約(Hub):標準利用契約/画像容量プラン/provider プラン
  2. スペース:consumer 用個人スペース/provider 用事業者スペース
  3. app entitlement:consumer アプリ/provider アプリ/backoffice の入室可否

未ログインローカルワークスペース(iOS / Android)

  • 未ログイン状態でも端末ローカルでログの作成・編集・閲覧が可能
  • 事前キャッシュしたポイント候補と自由記述を併用可能
  • ログイン/新規登録後に user_id 配下へ同期
  • サーバ側に principal を作らず、ローカルでだけ保持される

運用上のポイント

  • Web では登録後にログを作成・保存できる(標準利用契約は自動付与)
  • 同伴者・ショップスタッフ・ツアー参加者は会員ID未確定でも仮登録可能
  • 仮登録された相手は、後から会員に紐付け可能なデータ構造で保持される

3. ログの記録

共通 activity_log + scuba_diving 拡張

oceanbeatのログは、共通モデル activity_logを中心に、種目(activity_type)ごとの 拡張モデルで構成されます。初期 UI と入力必須項目は scuba_diving のみ提供しますが、 モデルは他種目拡張前提で固定します。

共通ログ(activity_log)の主項目

  • activity_type:scuba_diving/surfing/sup/shore_fishing 等
  • point_id:ポイントマスタへの参照(履歴参照のため版管理)
  • start_at / end_at:開始・終了日時。海況/予約と突合する起点
  • 同伴者:会員 / 非会員いずれも仮登録のうえ後から会員へ紐付け可能
  • メモ・タグ・気象メモ:自由記述で再訪時の手がかりに

scuba_diving 拡張の主項目

  • 深度(最大/平均)、潜水時間、エントリー/エキジット
  • タンク(容量・種別・残圧)、ウェイト、ウェットスーツ/ドライスーツ
  • バディ、ガイド、ショップ/船
  • Cカード団体・ライセンスレベル・経験本数
  • 署名(バディ/インストラクター。受領は Phase 2 で UGC と連動)

ログ作成の流れ

  1. Web またはログイン済み iOS / Android からログ作成を開始
  2. ポイントマスタからポイントを選択(候補が無い場合は自由記述)
  3. 共通項目(日時・同伴者・メモ)+ scuba_diving 拡張項目を入力
  4. 保存 → 一覧/詳細/時系列で過去ログを参照
  5. 必要に応じて画像を添付(次節)/後日 SNS 投稿として共有(Phase 2)

未ログイン → ログイン後の同期

  • iOS / Android の未ログインローカルログは、ログイン / 新規登録時に user_id 配下へ同期
  • 同期後はチャネル間(Web / iOS / Android)で同じログを継続編集
  • 同期前に行った仮登録(同伴者など)はそのまま保持され、後から会員へ紐付け可能

他種目への拡張(後続フェーズ)

サーフィン・SUP・釣り・セーリング等の入力項目は02_要件定義/05_アクティビティタイプ別要件定義.mdを正本として段階追加します。共通モデル側のID(log_idpoint_id)は Phase 1 で固定し、 後続フェーズも同じ参照キーで動きます。

4. ライブラリ素材管理

ツアーやログに紐づける前後を問わず、素材を保管する(Phase 1 / MVP 1)

写真は ツアーやログとの紐付け前後を問わず、個人の記録素材として保管できます。 先に撮影だけ済ませ、あとからまとめてツアー配下のログへ紐づける運用に対応します。

保存と参照

  • iOS / Android は未ログインでもローカルに保存・一覧・削除が可能
  • ログイン後は個人のライブラリ素材として oceanbeat クラウドへ保存
  • 新規ログ作成時だけでなく、既存ログへの後付け紐づけに対応
  • ログ詳細 / 一覧でサムネイルと原寸を確認
  • 参照制御つきで配信し、本人以外には漏れない

未ログイン → ログイン後の同期

  • iOS / Android の未ログインローカル素材は、ログイン / 新規登録後に user_id 配下のライブラリ素材として同期
  • 素材本体と log_id / post_id への紐付けは分離設計
  • 将来の投稿転用や未紐付け保持にも耐える

容量プラン

  • 無料枠/有料枠を storage_plan_id ベースで判定
  • ライブラリ素材保存容量の契約/決済は Hub と Stripe を通じて oceanbeat 側で実行
  • 保存先・派生サムネイル・削除/非公開時の扱いを明確化(Facet 系の共通方針を踏襲)

よくある運用

  • 船上やビーチで撮影 → 帰宅後にツアーとログを作成 → 過去保存済み素材を紐づけ
  • 1 ダイブ = 複数画像(ワイド/マクロ/集合写真)をまとめて記録
  • 未紐付け素材をライブラリで眺めて、あとから「このログだった」と整理

5. ポイントと海況・気象・潮汐

ポイントマスタ × Ocean Conditions(Phase 3)

oceanbeatは ポイントマスタを共通参照源として、ログ・海況・事業者・予約の すべての軸を結びつけます。ポイント名のゆらぎや、種目別の対応可否を吸収するための 版管理/論理削除も最初から想定しています。

ポイントマスタの主項目

  • ポイント名・別名・座標・所在地
  • activity_type 別の対応可否(scuba_diving 可、surfing 可 等)
  • 難易度・エントリー種別(ビーチ/ボート/磯/港 等)
  • 注意事項・装備の前提・推奨レベル
  • 履歴参照を壊さない版管理(更新/削除しても過去表示は維持)

Ocean Conditions(Phase 3)

  • ポイント別の時系列で、海況・気象・潮汐を表示
  • 外部 API をサービス側で集約し、ポイント別キャッシュで安定供給
  • 鮮度(最終更新時刻)・取得元・更新間隔をユーザーにも提示
  • 過去ログとの突合(「あの日のコンディションだった」を再現)

種目別 適性スコア/危険判定(ルールエンジン)

  • scuba_diving:透視度・水温・うねり・流れなどから適性スコア
  • surfing:波高・波周期・風向・風速から適性スコア
  • shore_fishing / boat_fishing:時化・潮回り・タイドサイクルから判断軸
  • sup / sailing:風向・風速・潮位の安全側ルール
  • 判定ルールは差し替え可能で、種目を増やしても表示は同じ流れ

ショップ/予約への接続

  • ポイント詳細から、そのポイントを扱うショップ/船/ガイドへ遷移可能
  • 催行可否・空き枠・振替連絡まで、Phase 5 で予約流通に接続

6. SNS・レビュー・OCR取り込み

ログを共有価値へ変える(Phase 2)

Phase 2 では、ログを共有可能な投稿へ変換し、ポイント単位のレビュー・海況速報・写真投稿を 蓄積して UGC の量と検索価値を作ります。

投稿の種類

  • ログ起点の投稿:自分のログから1タップで投稿生成(深度・本数等は公開設定で制御)
  • 写真単体投稿:未紐付け画像から直接シェア
  • ポイントレビュー:ポイント単位で評価・コメント・タグ
  • 海況速報投稿:「いま現地でこう」を短文で共有

投稿の保持項目

  • point_idlog_id/投稿時刻
  • activity_type(検索軸を壊さないため必須)
  • タグ(生物・海域・コンディション・ショップ)

署名(ダイビング)

  • ログへの署名依頼/受領を、バディ/インストラクターと相互運用
  • 会員ID未確定の相手にも依頼可能で、後から会員へ紐付け可能

OCRによるログ取り込み

  • 紙ログ/既存電子ログ画像をアップロード → OCRで本数・日付・項目を抽出
  • 抽出結果をユーザーが補正してログ化(画像も合わせて移行)
  • 同伴者・ショップ等は仮登録のまま取り込み、後から会員へ紐付け可能

検索・モデレーション

  • ポイント/海域/生物タグによる検索
  • 軽量モデレーションで不適切投稿・スパムを除去
  • 検索インデックスはイベント更新基盤で即時反映

7. ショップ・船・ガイド向け運用

Provider × Booking(Phase 3 → Phase 5)

事業者向けの管理画面は PC 中心の Web で提供します。ショップ/船/ガイド/フィッシング事業者を同じ事業者モデルで扱い、催行可否・公開情報・予約・振替・送客までを順次つなぎます。

事業者モデル

  • ショップ/船/ガイド/チャーター事業者を統一スキーマで保持
  • provider 担当者は common-auth 上は consumer ユーザー
  • 契約に応じて provider 向けアプリ/backoffice への入室可否を判定
  • 権限・スペース・グループ運用は service-suite-hubservice-suite-portal 実装をクローン元に oceanbeat 側で保持

公開ページ(Phase 3)

  • 正規加盟・外部認証(Cカード団体/業界認証)の表示
  • SNS・公式サイト導線
  • 取り扱いポイント・対応 activity_type・難易度
  • レビュー・海況速報投稿の集約

催行可否・振替連絡(Phase 5)

  • 催行情報・空き状況の公開/更新
  • 振替連絡・キャンセル連絡を oceanbeat 内で完結
  • 既存の予約管理/外部カレンダー運用は段階移行(運用を壊さない設計)

予約流通(Phase 5)

  • oceanbeat 経由の予約に対して送客手数料を発生
  • 予約の主データ(contract/space/booking)は oceanbeat 側に保持
  • Hub / Stripe を通じて手数料の請求・入金管理を一体運用

将来の対応事業者

初期主対象はダイビングショップですが、サーフショップ/釣り船・チャーターボート/セーリング事業者/ シーカヤック事業者なども同じ事業者モデルで扱う前提で設計します。

8. プラン・契約・課金

Hub × Stripe を一体で運用

oceanbeatの契約・課金は Hubを SSOT として、Stripe と一体で運用します。コンシューマは標準利用契約が自動付与され、 画像容量プラン・provider プランは個別契約として上乗せします。

プラン体系

  • Free(コンシューマ):ログ作成・編集・閲覧。画像は無料枠まで。
  • Storage Plus:画像保存容量の有料枠(複数容量を用意予定)。
  • Provider:事業者向け。公開ページ・催行連絡・予約流通(段階提供)。

標準利用契約の自動付与

  • Phase 1 / MVP 0 では、サインアップ時または初回同期時に標準利用契約を自動付与
  • 決済連携なしで、Web とログイン済み iOS / Android の利用可否判定が成立
  • consumer ユーザーの利用可能アプリは oceanbeat 側の契約 / スペース / app entitlement で判定

画像容量プラン

  • storage_plan_id ベースで無料枠/有料枠を判定
  • Hub から申込・解約・プラン変更(容量アップ/ダウン)
  • Stripe 経由で決済・請求・入金管理を一体で運用

事業者プラン(Phase 5 に向け段階提供)

  • 事業者ページ公開/催行連絡/予約流通/送客手数料を段階提供
  • Marketplace 手数料相当(流通額 × 手数料率)として収益化
  • 事業者向け解約・返金条件は契約締結時に明示

メータリング対象(例)

  • 画像容量:保存容量、保持期間
  • 外部API集約:海況/気象/潮汐の取得量、ポイント単位の更新頻度
  • 予約流通:成約件数、流通額(Phase 5)
  • OCR 取り込み:ページ数、画像枚数(Phase 2)

9. ヒント・FAQ

導入と運用のコツ

よくある質問

  • Q: ダイビング以外の種目はいつから使えますか?
    A: 共通モデルは最初から `activity_type` 拡張前提で設計しています。初期 UI は scuba_diving のみですが、 サーフィン・SUP・釣り・セーリング等は要件定義 `05_アクティビティタイプ別要件定義.md` に基づき順次拡張します。
  • Q: 紙ログ・旧電子ログから移行できますか?
    A: Phase 2 でOCR取り込みに対応します。同伴者・ショップ等は仮登録のまま取り込み、 後から会員へ紐付け可能なデータ構造で保持されます。
  • Q: 海況データの鮮度は?
    A: ポイント別キャッシュの最終更新時刻・取得元・更新間隔を画面に提示します。 非機能要件 `03_非機能要件.md` で鮮度の指標を整理しています。
  • Q: 未ログインで使い始めたデータはどうなりますか?
    A: iOS / Android の未ログインローカルログ/画像は、ログイン / 新規登録時に `user_id` 配下へ同期できます。仮登録した同伴者もそのまま引き継がれます。
  • Q: ショップとして導入したいのですが、既存の予約管理は維持できますか?
    A: はい。段階移行を前提に、催行可否・振替連絡から oceanbeat 上に寄せていくことを想定しています。 既存の予約管理/外部カレンダー運用を一度に置き換える設計にはしていません。

運用のコツ

  • 船上・ビーチでは未ログインのまま下書きを残し、帰宅後に同期する運用が安定
  • 画像は撮影 → クラウド保存を先に済ませ、ログ作成時に既存画像から選んで添付
  • ポイント名は表記ゆれが起きやすいため、ポイントマスタの候補から選ぶのが最優先
  • 海況の適性スコア/危険判定は参考値。最終判断は現地確認とインストラクター指示を優先
  • 事業者ページの正規加盟・外部認証は更新時にも反映漏れがないよう、定期チェックを推奨