コンテンツにスキップ

ソーシャル接続機能仕様書(Social Connections)

作成者: Claude (AI) · 作成日: 2026-04-19 · ステータス: 承認済み (Approved)

Notion レビューコメント(2026-04-18): 「大規模グループ(同窓会)や小規模グループ(友達間)に応じて、Friendsにおける機能については扱いが異なる可能性がある。大規模のイベントにおいては、Friends機能を利用して、多くのメンバーから特定の友人のみを抽出する可能性があるが、現状のフェーズではそこまでの構築(大規模グループ運用)は想定されない。よって、組織=メンバーシップとして利用する。『知り合いかも』として利用するほどの機能は不要、だが『つながりのあるメンバー』という項目は、別組織のUUIDと一致する場合には存在しても良い。」


1. 概要

ソーシャル接続は、Recerdo のコアバリュー「旧友・旧グループとの再接続」を実現する機能。従来のSNSで採用される「フレンドリクエスト」モデルは採用せず、**組織(Organization)メンバーシップを接続の基盤**とする。ユーザーが同じ組織(学校・部活・サークル等)に所属していることが、そのまま「つながり」を意味する。

1.1 設計方針(Notionコメント反映)

方針 内容
組織 = メンバーシップ org_id が同じユーザーは自動的に「つながりのあるメンバー」
フレンドリクエスト不採用 明示的な友人申請・承認フローは実装しない
「知り合いかも」不要 レコメンデーション機能は現フェーズ対象外
大規模グループ運用は対象外 同窓会規模(数百〜数千人)の大規模グループ管理は現フェーズでは想定しない
「つながりのあるメンバー」の範囲 別組織の UUID に一致するユーザーは「つながり」として表示可能

1.2 現フェーズスコープ

✅ 対象: 同一組織メンバーの一覧表示
✅ 対象: 別組織に共通メンバーがいる場合の「つながりのあるメンバー」表示
✅ 対象: 組織単位でのメンバー検索・フィルタリング
❌ 対象外: フレンドリクエスト・承認フロー
❌ 対象外: 「知り合いかも」(共通友人レコメンデーション)
❌ 対象外: 大規模グループ(数百人以上)に特化した友人抽出機能
❌ 対象外: グローバルなソーシャルグラフ

2. ドメインモデル

2.1 ソーシャル接続の概念モデル

User A ──── member of ──── Organization X (学校A 同窓生)
User B ──── member of ──── Organization X
User C ──── member of ──── Organization X
                                └── User A, B, C は「つながりのあるメンバー」

User A ──── member of ──── Organization Y (部活B OB)
User D ──── member of ──── Organization Y
                                └── User A と D は「別組織での共通つながり」

2.2 エンティティとの関係

ソーシャル接続に固有のエンティティは持たない。既存の Organization(org_id)と OrganizationMembership(user_id × org_id)の関係を活用する。

既存エンティティ 役割
Organization グループ(学校・部活・サークル等)の単位 = 接続グループ
OrganizationMembership ユーザーがどの組織に属するか = 接続関係
User 接続の主体

2.3 「つながりのあるメンバー」の定義

つながりのあるメンバー(user_id_A, user_id_B) = 
  ∃ org_id : 
    OrganizationMembership(user_id_A, org_id) AND
    OrganizationMembership(user_id_B, org_id)

つまり、同一の org_id を共有するメンバーシップレコードが1件でも存在すれば、「つながりのあるメンバー」 となる。

3. ユースケース詳細

3.1 UC1: 組織内のメンバー一覧を取得する

Who: 組織メンバーのユーザー

What: 自分が所属する組織のメンバー全員を一覧で確認する

When: アプリのメンバー一覧画面を開いた時

How: 1. ユーザーが GET /api/organizations/{org_id}/members を呼び出す 2. Events Service が OrganizationMembership から同一 org_id のユーザー一覧を返す 3. アプリがメンバー一覧画面に表示

データ例:

{
  "org_id": "org-uuid-abc123",
  "org_name": "○○高校 2008年度卒業生",
  "members": [
    { "user_id": "user-uuid-001", "display_name": "田中 太郎", "joined_at": "2026-01-10" },
    { "user_id": "user-uuid-002", "display_name": "鈴木 花子", "joined_at": "2026-01-15" }
  ],
  "total_count": 48
}

3.2 UC2: 「つながりのあるメンバー」を取得する(複数組織間)

Who: ユーザー

What: 別の組織に共通して所属しているメンバーを「つながりのあるメンバー」として表示する

When: プロフィール画面やメンバー検索画面

How: 1. ユーザー A(user_id_A)のメンバー詳細画面を閲覧 2. システムが以下のクエリを実行:

-- ユーザーAと別組織で共通する user_id を取得
SELECT DISTINCT m2.user_id, o.org_name
FROM organization_memberships m1
JOIN organization_memberships m2 ON m1.org_id = m2.org_id
JOIN organizations o ON m1.org_id = o.org_id
WHERE m1.user_id = :current_user_id
  AND m2.user_id = :target_user_id
  AND m1.user_id != m2.user_id
3. 共通組織が1件以上あれば「つながりのあるメンバー(X の共通メンバー)」として表示

制約: - 「つながり」の表示は、共通組織が存在する場合のみ - 「知り合いかも」(レコメンデーション)は表示しない - 共通組織が存在しないユーザー同士は「つながりなし」として扱う

データ例:

{
  "user_id": "user-uuid-002",
  "display_name": "鈴木 花子",
  "connected_via": [
    { "org_id": "org-uuid-abc123", "org_name": "○○高校 2008年度卒業生" },
    { "org_id": "org-uuid-xyz789", "org_name": "○○大学 テニスサークル" }
  ]
}

3.3 UC3: メンバーを組織内で検索する

Who: 組織メンバー

What: 組織内のメンバーを氏名や参加年度で絞り込む

When: 「特定の人を探したい」時

How: 1. GET /api/organizations/{org_id}/members?query=鈴木&joined_year=2008 でメンバー検索 2. Events Service が display_name または joined_at で絞り込み返答

制約: - 検索対象は現在のユーザーが所属している組織のメンバーのみ - 他組織のメンバーをランダムに検索する機能は提供しない(プライバシー保護)

4. 大規模グループ vs 小規模グループの扱い

Notionコメントの方針に基づき、グループ規模による機能差分を明記する。

項目 小規模グループ(友達間) 大規模グループ(同窓会) 現フェーズ対応
メンバー数の目安 〜20人 20〜数百人 両方サポート
特定友人の抽出 全員表示で十分 フィルタリングが必要 未対応(現フェーズ外)
フレンドリクエスト 不要 不要 採用しない
「知り合いかも」 不要 将来ニーズあり 未対応(現フェーズ外)
メンバー一覧表示 ✅(一覧表示のみ) 対応
つながりのあるメンバー 対応

注記: 大規模グループ(例: 卒業年度が同じ数百人のメンバーから特定の友人を抽出する機能)は、現フェーズでは必要とされない。将来的に大規模グループ運用が必要になる段階で、別途フィルタリング・グルーピング機能として検討する。

5. プライバシー設計

  • 組織メンバーシップは組織内でのみ公開: 自分が所属している組織のメンバーのみがお互いのプロフィールを閲覧できる
  • つながりのあるメンバー情報は当事者のみ: connected_via は閲覧者が共通組織のメンバーである場合のみ表示
  • 全体公開されないプロフィール: 組織に所属していないユーザーへのプロフィール公開はしない

6. API エンドポイント

エンドポイント メソッド 説明
GET /api/organizations/{org_id}/members GET 組織内メンバー一覧
GET /api/organizations/{org_id}/members?query= GET メンバー検索
GET /api/users/{user_id}/connections GET 特定ユーザーとのつながり(共通組織一覧)
GET /api/users/me/connected-members GET 自分の全つながりのあるメンバー一覧

7. 将来の拡張(現フェーズ対象外)

以下は現フェーズでは実装せず、将来の検討事項として記録する:

  • 大規模グループでの友人フィルタリング: 数百人の組織内から特定条件(入学年度・部署等)で友人を絞り込む
  • 「知り合いかも」レコメンデーション: 共通メンバーが多いユーザーや、組織履歴が似ているユーザーのサジェスト
  • 友人グループ(サブグループ): 組織内で任意の友人グループを作成する機能
  • 接続強度スコア: 共通組織数や交流頻度から「つながりの強さ」を算出する機能

8. 既存設計との整合性

本仕様は Recerdo の既存マルチテナントモデル(Organization / OrganizationMembership)を**そのまま活用**する。ソーシャルグラフのための新テーブルや専用サービスは現フェーズでは作成しない。

関連設計書: - Events Service DD - クリーンアーキテクチャ — Events Service

9. メディア表示に関するUX補足(Live Photo)

メンバーのプロフィールやイベントでLive Photoが共有された際、UI上は 1枚のカード(静止画表示 + ロングタップで動画再生) として扱う。Storage Service が Apple の asset_identifier で画像と動画をペアリング済みのため、ユーザーは2つのファイルを意識しない。非対応端末では静止画(JPEG/WebP)にフォールバックする。


最終更新: 2026-04-19 ポリシー適用