0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

整理券アプリを作る(要件定義編)

Last updated at Posted at 2024-12-30

要件定義・仕様書(概要)

経緯・目的

昨年の学祭にて、滞在時間のほとんどが行列に並んだ無駄な時間、あぁ、芸能人のイベント見たかったなぁ...
ってことで整理券アプリ作れば待ち時間を有効活用できるのでは?
じゃあ頑張って作りますか!

システム概要

大学祭の屋台で「整理券」をデジタル化し、効率的な行列管理を行うためのWebアプリケーションを構築する。ユーザー(客)はメール認証によるアカウント登録後、希望する店舗の整理券をオンラインで取得することが可能。また、店舗側は管理用アカウントでログインし、現在の待ち状況や整理券情報の閲覧、呼び出し(商品引き渡し)の通知送信が可能。

システム構成(あまり分かっていない)

 ・フロントエンド(React,TypeScript)
 ・バックエンド(何にしよう)
 ・データベース(多分MySQL)

利用者一覧

1.客
 ・整理券の取得、待ち状況の確認、呼び出し通知の受信
 ・プロフィール管理(氏名、ふりがな、ニックネーム、年齢、誕生日、性別、メールアドレス、電話番号など)
2.店舗
 ・自店舗の整理券発行状況、待ち行列管理、呼び出し通知の送信
 ・プロフィール管理 (店舗名、責任者名、メールアドレス、電話番号など)

機能要件

1.ユーザー登録・認証
 ・メールアドレスとパスワードを用いたアカウント登録フォーム
 ・メールアドレスの有効性確認(メールに送信されるURLクリックによる認証)
 ・ログイン・ログアウト機能
 ・パスワードリセット機能(メール経由)、機能自体はできたらやる
 ・店側、客側でアカウント種別が異なるため、「種別選択」で選択可能

2.整理券管理(客側)
 ・店舗一覧表示(取得可能な整理券の数、待ち時間予測)
 ・整理券発行(特定の店舗を選択して「整理券を取得」)
 ・現在の自分の順番や待ち人数の確認

3.整理券管理(店側)
 ・発行済みの整理券一覧の表示
 ・呼び出し機能:順番が来た整理券に紐づくユーザーに通知送信
 ・整理券ステータス変更(「待ち中」→「呼び出し中」→「商品引渡し完了(クローズ)」)

4.通知機能
 ・呼び出し時にメール通知、もしくはプッシュ通知(Web Pushなど)を行う
 ・店側が「呼び出し」を行った際、客側はリアルタイムで更新(WebSocket等を利用)または一定間隔ポーリングで通知を受け取る

5.UI要件
・Reactを用いてSPA的なUI
・レスポンシブデザイン(スマホ/PC対応)
・ナビゲーションバーから自分のプロフィール、取得した整理券状況、ログアウトへのアクセスが可能

6.セキュリティ要件
・パスワードはハッシュ化(サーバー側処理)
・SQLインジェクション対策(Prepared Statements)
・XSS/CSRF対策 (CSRFトークン、Reactでの適切なエスケープ処理)
・HTTPS通信

7.拡張性
・将来的な機能拡張を考慮し、API設計はRESTful
・将来的に多店舗対応や分析機能追加を想定

データベース設計

userテーブル(客)

カラム名 Not Null 説明
id INT PK AUTO_INC YES ユーザーID(主キー)
email VARCHAR(255) YES メールアドレス(ユニーク)
password_hash VARCHAR(255) YES パスワードハッシュ
last_name VARCHAR(50) YES
first_name VARCHAR(50) YES
last_name_kana VARCHAR(50) YES 姓(カナ)
first_name_kana VARCHAR(50) YES 名(カナ)
nickname VARCHAR(50) YES ニックネーム
gender VARCHAR(10) YES 性別(男性, 女性)
birthdate DATE YES 生年月日
age INT YES 年齢
phone_number VARCHAR(20) YES 電話番号
email_verified BOOLEAN YES メール認証完了フラグ
created_at DATETIME YES 登録日時
updated_at DATETIME YES 更新日時

storeテーブル(店舗)

カラム名 Not Null 説明
id INT PK AUTO_INC YES 店舗ID(主キー)
email VARCHAR(255) YES メールアドレス(ユニーク)
password_hash VARCHAR(255) YES パスワードハッシュ
store_name VARCHAR(100) YES 店舗名
manager_name VARCHAR(100) YES 責任者名
phone_number VARCHAR(20) YES 電話番号
email_verified BOOLEAN YES メール認証完了フラグ
created_at DATETIME YES 登録日時
updated_at DATETIME YES 更新日時

ticketテーブル(整理券情報)

カラム名 Not Null 説明
id INT PK AUTO_INC YES 整理券ID(主キー)
store_id INT YES 発行元店舗ID(fk: stores.id)
user_id INT YES 整理券取得ユーザーID(fk: users.id)
status VARCHAR(20) YES 状態("waiting", "calling", "completed")
issued_at DATETIME YES 発行日時
called_at DATETIME NO 呼び出し日時(null可)
completed_at DATETIME NO 完了日時(null可)

APIエンドポイント(例)

客認証系

POST /api/auth/user/register : 客ユーザー登録(メール送信)
POST /api/auth/user/verify : 客ユーザー認証完了処理
POST /api/auth/user/login : ログイン
POST /api/auth/user/logout : ログアウト
POST /api/auth/user/forgot_password : パスワードリセット要求
POST /api/auth/user/reset_password : パスワードリセット実行

店舗認証系

POST /api/auth/store/register
POST /api/auth/store/verify
POST /api/auth/store/login
・...(上記と同様)

整理券系

GET /api/stores : 店舗一覧取得
POST /api/tickets : 整理券発行(パラメータ: store_id, user_id)
GET /api/tickets/user : ログイン中の客の整理券一覧取得
GET /api/tickets/store : ログイン中の店の整理券一覧取得
PATCH /api/tickets/:id/call : 店側が整理券を呼び出しステータスへ変更、通知処理
・PATCH /api/tickets/:id/complete : 整理券完了処理

通知手順

・呼び出し時、サーバーサイドでメールまたはWeb Pushを送信
・React側はWebSocketやSSEなどでリアルタイム更新、または一定間隔でステータスチェック
WebSocket:リアルタイム通信の仕組み。サーバーとクライアント間で常時接続を維持し、双方向にデータを送受信できるプロトコル。
SSE:サーバーからクライアントへの一方向のリアルタイム通信を実現する技術

インストール・デプロイ

・Webで完結させるため、バックエンドはクラウド上のサーバー(APIサーバー)、フロントエンドはホスティングサービス(Firebase HostingやVercel等)で提供
・React側はSPAとしてビルド後にデプロイ
・DBはクラウドDB(RDS等)を想定
ホスティングサービス:WebアプリやAPIをインターネット上に公開するサービス。
SPA(Single Page Application):1枚のHTMLで構成されるWebアプリ

感想

とりあえず要件定義したけど後々仕様変更するだろうな...トホホ

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?