大学内教科書フリマ

https://github.com/coral-furukawa/webpro

GitHub

TypeScript

React

Node.js

PostgreSQL

慶應学内で教科書や授業ノートを売買できるアプリケーション.

古河純太郎

推しアイデア

教科書だけでなく,個人の授業ノートの売買も可能にしたことが推しアイデアである.授業によっては,教科書やレジュメが存在しなく,授業に行っていないと内容を把握できない授業もある.真面目に授業に行きノートをとっている生徒が金儲けができる素敵な仕組みである.

作った背景

学内の授業で購入を強制される教科書は高いので,一定数の生徒は某フリマアプリで安価での購入を検討する.しかし,目的の教科書を見つけるのは骨が折れる作業である.そこで学内のみで完結するフリマサイトならスムーズに売買ができると考えた.

推し技術

自分のGPAを設定できるようにしており,出品する商品の価値を自分の努力で高めることができる.ただ,現状として,認証などがなく,虚偽のプロフィールを設定し放題なので,これから機会があれば,GPAと慶應のメールアドレスの認証をできるようにしたい.

プロジェクト詳細

慶應大学内向け教材売買アプリ 設計メモ

1. 目的

慶應義塾大学の学生が、授業名・学部・学科・時間割から必要な教科書や授業ノートを探し、学内手渡しで売買できるサービスを作る。一般的なフリマサービスより教材を見つけやすく、送料なしで早く取引できることを価値とする。

2. 今回作るMVP

授業時間内に完成・デモできるよう、最初のリリースは次に限定する。

  1. 学部、学年、授業名、価格、GPA順で出品を検索する
  2. 教科書または授業ノートを出品する
  3. 商品へ「いいね」、授業へ「ほしい」を登録する
  4. 販売状態を出品中、取引中、販売済みで管理する
  5. 商品と出品者、授業、受渡し希望を表示する

慶應メール認証、画像ファイルのアップロード、チャット、時間割UI、取引評価画面は第2段階とする。MVPでは画像はURL入力、操作ユーザーは仮のユーザーIDで扱う。

3. インプット / アウトプット

インプット

  • プロフィール: 慶應メール、ニックネーム、学部、学科、学年、任意のGPA
  • 授業: 授業名、担当教員、曜日、時限
  • 出品: 商品名、教材種別、価格、状態、説明、画像URL、授業、受渡し場所・時間
  • 行動: 検索条件、いいね、需要登録、購入希望、取引評価

アウトプット

  • 条件に合う販売中の商品一覧と件数
  • 商品詳細、授業情報、出品者プロフィール、いいね数
  • 授業ごとの需要数と出品数
  • 取引状態、受渡し候補、取引相手の平均評価

4. 画面設計

画面主な体験MVP
ホーム・検索授業名、学部、学年、並び順から教材を探す対応
商品詳細教材・出品者・受渡し情報を見て購入判断する一覧カードで一部対応
出品教材情報を入力して公開するAPI対応、画面は次
授業・時間割コマから関連商品と需要を確認するAPI対応、画面は次
取引購入希望から完了まで状態を進めるDB対応、画面/APIは次
評価完了後に双方を5段階評価するDB対応、画面/APIは次

Reactは状態管理とAPI通信、HTMLは意味構造、CSSはレスポンシブな検索フォームと商品カードを担当する。開発中はViteがExpressへプロキシし、本番では環境変数でAPI URLを切り替える。

5. バックエンドのプロセス

Reactの入力 → Expressで形式・範囲を検証 → Prismaで検索または更新 → PostgreSQLへ永続化 → 関連データと集計値をJSONで返す → Reactが一覧を再描画
  • GET /items: 販売中商品の検索・並び替え
  • POST /items: 出品登録
  • POST /likes: いいねの登録・解除
  • POST /demands: 授業への需要登録
  • GET /courses: 授業検索、出品数・需要数の集計
  • GET /health: Renderのヘルスチェック

認証導入後は、userId をリクエスト本文から受け取らず認証セッションから決定する。

6. 永続化するデータ

User 1 ── * Item * ── 1 Course User * ── * Item (Like経由) User * ── * Course (Demand経由) Item 1 ── 0..1 Transaction * ── 1 User(購入者) Transaction 1 ── * Review
  • User: メール、名前、学部、学科、学年、GPA
  • Course: 授業名、教員、所属、曜日、時限
  • Item: 商品情報、種別、状態、価格、画像URL、受渡し希望、販売状態
  • Like: ユーザーと商品の組み合わせ。一人一商品一件
  • Demand: ユーザーと授業の組み合わせ。一人一授業一件
  • Transaction: 購入者、受渡し、進行状態、完了日時
  • Review: 取引、評価者、評価対象者、点数、コメント

いいね数、需要数、平均評価、取引回数は整合性を保つため重複保存せず、元データから集計する。

受け渡し決定フロー

  1. 出品者は出品時に大まかな希望場所・希望時間帯を任意入力する
  2. 購入者が商品詳細から購入希望を送る
  3. 出品者と購入者がチャットで具体的な場所・日時を相談する
  4. 合意した内容を取引データの確定受け渡し場所・日時として保存する
  5. 手渡し後に双方が取引完了を確認し、評価へ進む

商品に保存する handoffPlace / handoffTime は希望情報であり、取引に保存する値が最終合意情報となる。

7. 非機能・安全面

  • GPAは個人情報として任意入力・公開範囲を再検討する。本番では検索順位の主要指標にしない選択肢も必要
  • 慶應メールのドメインだけで所属を完全保証できないため、メール確認を必須にする
  • 画像はDBへ直接保存せず、CloudinaryやS3等へ置いてURLのみ保存する
  • 金銭の事前決済はMVP対象外。学内手渡し時の支払いとし、利用規約・禁止物を明示する
  • APIの入力検証、認可、レート制限、XSS対策をデプロイ前に追加する

8. マイルストーン

  • 三層構成を作成
  • DB設計と商品検索API
  • React検索画面
  • 出品・いいね・需要API
  • サンプルデータと出品画面
  • 慶應メール認証
  • 取引・評価UI
  • GitHubリポジトリURLをREADMEへ記載
  • Render API URLとフロントエンドURLをREADMEへ記載

9. チーム共有で確認すること

  1. GPAを表示・検索条件に使うことへの合意
  2. 授業ノートや過去資料の著作権・大学ルール
  3. 受渡し場所を自由入力にするか候補選択にするか
  4. MVPの完成条件と担当分担
  5. 公開リポジトリへ秘密情報や個人情報を含めないこと

古河純太郎

@41dd3b65a0cb5d85