甲子園NOWは、甲子園球場での観戦をより楽しくするためのSNSアプリです。
今の興奮、感動を共有しよう!
甲子園球場の盛り上がりや興奮を文字と画像で投稿でき、コメントやいいね機能もあるので、ユーザー同士の交流ができます。
自分の投稿にコメントが来たときは、LINE通知がくるように設定できます。
位置情報にアイコンを一緒に登録することができ、今日の観戦位置をユーザー同士で共有することができます。
また、観戦カレンダーでは試合、イベント情報の閲覧と、自身の観戦予定の登録、履歴の閲覧が可能です。
・ユーザー登録 ( gem devise )
・いいね・コメント機能 ( turbo )
・位置情報登録機能 ( GeolocationAPI、Javascript )
・アイコンの表示機能 ( turbo、Javascript )
・カレンダー機能 ( gem simple_calendar )
・コメント通知機能 ( line-bot-api )
・OmniOAuth認証機能 ( Google+ API、LINEログイン )
甲子園球場での観戦中、試合の盛り上がりを近場の方々だけでなくもっと広い範囲で、甲子園球場全体のファンの方々と共有したいと思った経験から、このサービスを思いつきました。
観戦しているときに、隣の席の人との会話が盛り上がったり、SNSで「今ここにいる!」と共有したりする楽しさをアプリで提供したいと思いました。
X : リアルタイムでのシェアに特化していますが、位置情報やアイコンなどは使用できません。
Instagram: 位置情報は表示できますが、文章のみの表示になり、投稿もリアルタイム性に欠けストーリーも1日で消えてしまいます。
上記の欠点を補う新しいSNSサービスとして、甲子園NOWは登場します。
位置情報画面を一覧で表示できるようにして、実際の甲子園の盛り上がりが目視でき、ファン同士のコミュニケーションの場として活躍できるアプリです。
甲子園球場で観戦するファン:
理由: 球場内でのリアルタイムな交流を促進し、甲子園観戦での同じファンとの交流という野球観戦においての楽しみを増やすため。
SNS好きの若年層:
理由: リアルタイムでの位置情報付き投稿や、いいね・コメント機能で、SNS感覚で楽しめるため。
また、ビールやチューハイ、カレーやたこ焼きなどのアイコンを使った投稿機能で、観戦の楽しさを共有できるため。
阪神タイガースファン:
理由: タイガースファンならわかるはず。
身近な阪神ファンに向けて: まず初めに使ってみてもらい、フィードバックをいただく。その後、SNSでの告知や口コミに移行する。
SNSでのユーザー獲得: 若年層にリーチするため、TwitterやInstagramで阪神ファンの方に触ってもらう。
口コミ: 利用者がアプリの楽しさを共有し、自然な形で利用者を増やす。
機能の実装方針 | |
---|---|
技術スタック | 開発環境: Docker |
サーバサイド | Ruby on Rails 7系: 高速な開発サイクルを提供。 |
Ruby 3.2.2 | |
Rails 7.0.4.3 | |
フロントエンド | ERBファイルを使用したHTML: フロントエンドはシンプルに黄色と黒で構成。 |
JavaScript | |
CSSフレームワーク: | |
Bootstrap 5系: レスポンシブデザインを実装し、ユーザービリティを意識したシンプルなデザインを採用。 | |
WebAPI | Google Maps API: 投稿に位置情報を追加。 |
LINE Messaging API: コメント通知を送信。 | |
OpenWeather API: 天気情報の取得。 | |
Google+ API: Googleログイン認証 | |
LINEログイン: LINEログイン認証 | |
画像アップロード | ActiveStorage: 画像のアップロード機能を提供。 |
インフラ | Webアプリケーションサーバ: Render |
ファイルサーバ: Amazon S3 | |
その他 | VCS: GitHub |
画面遷移図: https://www.figma.com/board/I7TWuNN9Id1z2tpi35RQI0/%E7%84%A1%E9%A1%8C?node-id=0-1&t=HprCttfLc6lzSBqo-0
ER図:
erDiagram
users ||--o{ posts: "ユーザーは複数の投稿を持つ"
users ||--o{ comments: "ユーザーは複数のコメントを持つ"
users ||--o{ like_posts: "ユーザーは複数のいいねを持つ"
users ||--o{ user_locations: "ユーザーは複数のユーザー球場位置を持つ"
users ||--o{ user_matches: "ユーザーは複数の試合情報を持つ"
users ||--o| notifications: "ユーザーは1つの通知機能を持つ"
users ||--o| one_time_codes: "ユーザーは1つのワンタイムコードを持つ"
users ||--o{ sns_credentials: "ユーザーは複数の認証を持つ"
posts ||--o{ comments: "投稿は複数のコメントを持つ"
posts ||--o{ like_posts: "投稿は複数のいいねを持つ"
posts ||--o| notifications: "投稿は1つの通知を持つ"
locations ||--o{ user_locations: "球場位置は複数のユーザー球場位置を持つ"
locations ||--o{ seats: "球場位置は複数のシート位置を持つ"
events ||--o{ event_dates: "イベントは複数のイベント日時を持つ"
matches ||--o{ user_matches: "試合は複数のユーザー試合を持つ"
matches ||--o| events: "試合は0か1つのイベントを持つ"
seats ||--o{ user_locations: "シート位置は複数のユーザー球場位置を持つ"
users {
bigint id PK "ユーザーID"
string email "メールアドレス"
string encrypted_password "暗号化パスワード"
string reset_password_token "パスワードリセットトークン"
datetime reset_password_sent_at "パスワードリセット送信時間"
datetime remember_created_at "ログイン状態の記録クッキーの作成日"
datetime created_at "作成日"
datetime updated_at "更新日"
string user_name "ユーザーネーム"
string first_name "名"
string last_name "姓"
string avatar "ユーザー画像"
string favorite_player "推し選手"
integer favorite_viewing_block "いつもの場所"
bigint location_id "シートID"
integer role "権限"
string line_user_id "LINEユーザーID"
string oauth_token "OAuthトークン"
datetime oauth_expires_at "OAuth有効期限"
string confirmation_token "メールアドレス確認トークン"
datetime confirmed_at "メールアドレス確認日時"
datetime confirmation_sent_at "メールアドレス確認メール送信日時"
string unconfirmed_email "未確認メールアドレス"
}
posts {
bigint id PK ""
bigint user_id FK ""
text body ""
string image ""
datetime created_at ""
datetime update_at ""
}
comments {
bigint id PK "ID"
bigint user_id FK "ユーザーID"
bigint post_id FK "投稿ID"
text body "本文"
datetime created_at "作成日"
datetime updated_at "更新日"
}
like_posts {
bigint id PK "ID"
bigint user_id FK "ユーザーID"
bigint post_id FK "投稿ID"
datetime created_at "作成日"
datetime updated_at "更新日"
}
locations {
bigint id PK "ID"
bigint user_id FK "ユーザーID"
string seat_name "座席名"
jsonb points "座席範囲(表示)"
integer location_type "座席タイプ"
datetime created_at "作成日"
datetime updated_at "更新日"
}
user_locations {
bigint id PK "ID"
bigint user_id FK "ユーザーID"
bigint location_id FK "座席ID"
integer offset_x "X座標のオフセット"
integer offset_y "Y座標のオフセット"
integer index "インデックス"
integer icon "アイコン"
date date "日付"
datetime created_at "作成日"
datetime updated_at "更新日"
}
seats {
bigint id PK "ID"
bigint location_id FK "座席ID"
string seat_name "座席名"
float latitude "緯度"
float longitude "軽度"
integer location_type "座席タイプ"
jsonb spots "座席範囲"
datetime created_at "作成日"
datetime updated_at "更新日"
}
matches {
bigint id PK "ID"
bigint event_id FK "イベントID"
integer opponent "対戦相手"
string stadium "試合会場"
integer result "勝敗"
integer team_score "チームスコア"
integer away_team_score "相手のスコア"
datetime match_date "試合日程"
datetime created_at "作成日"
datetime updated_at "更新日"
}
user_matches {
bigint id PK "ID"
bigint user_id FK "ユーザーID"
bigint match_id FK "試合ID"
date date "日付"
datetime created_at "作成日"
datetime updated_at "更新日"
}
events {
bigint id PK "ID"
string title "イベントタイトル"
string body "イベント内容"
string detail_url "詳細URL"
datetime created_at "作成日"
datetime updated_at "更新日"
}
event_dates {
bigint id PK "ID"
bigint event_id FK "イベントID"
date start_date "開始日"
date end_date "終了日"
datetime created_at "作成日"
datetime updated_at "更新日"
}
notifications {
bigint id PK "ID"
bigint user_id FK "ユーザーID"
bigint post_id FK "投稿ID"
text message "メッセージ"
datetime created_at "作成日"
datetime updated_at "更新日"
}
one_time_codes {
bigint id PK "ID"
bigint user_id FK "ユーザーID"
integer code "コード"
datetime expires_at "有効期限"
datetime created_at "作成日"
datetime updated_at "更新日"
}
sns_credentials {
bigint id PK "ID"
bigint user_id FK "ユーザーID"
string provider "プロバイダー名"
string uid "UID"
datetime created_at "作成日"
datetime updated_at "更新日"
}