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?

子ども予防接種スケジューラーアプリを作ってみた【ブラウザプッシュ通知機能あり】

0
Last updated at Posted at 2026-03-16

はじめに

4人の子どもを育てているんですが、予防接種のスケジュール管理って本当に大変で…😅

  • ロタウイルス、ヒブ、小児用肺炎球菌、BCG…種類が多すぎて把握しきれない!
  • 「あれ、次はいつだっけ?」ってなることが多い
  • 結局、全部自分で管理しないといけない

「これ、アプリで管理できたら楽になるのでは?」 と思って作ったのがこのアプリです!

家族みんなで一括管理・確認できるようにすることで、接種漏れや「忘れてた!」という不安をなくすことを目指しました。


実装した機能一覧

機能 説明
認証機能 ログイン・新規登録
子ども管理 複数の子どもを登録・編集・削除
接種スケジュール自動生成 生年月日をもとに接種予定日を自動計算
接種済みチェック 接種日を記録してステータス管理
副反応記録 接種後の症状を記録
医療機関管理 かかりつけ医の情報を登録
予約管理 医療機関・ワクチンと紐づけた予約管理
ワクチンガイド 各ワクチンの説明・接種時期を表示
母子手帳写真保存 母子手帳の写真をアップロード・保存
ゴミ箱機能 削除したデータの復元・完全削除
家族共有機能 招待コードでパートナーとデータを共有
ブラウザプッシュ通知 接種予定日の1ヶ月前・2週間前・1週間前・前日に通知

ブラウザプッシュ通知機能について

このアプリの中で特にこだわった機能がブラウザプッシュ通知です!

ブラウザプッシュ通知の実装には laravel-notification-channels/webpush というライブラリを使用しました。

このライブラリ、特に日本語の情報が少ないので、実装を検討している方の参考になれば嬉しいです😊

🔗 https://github.com/laravel-notification-channels/webpush

ダッシュボード画面

image.png

ダッシュボードを開くと、こんな感じで情報が一目でわかります!

  • ✅ 接種期限アラート(30日以内)が上部に表示される
  • ✅ お子さん一覧がカード形式で表示される
  • ✅ 次回接種予定が一覧表示される
  • ✅ 接種予定日が近いワクチンに「もうすぐ」の表示が出る

こだわったコード紹介

1. 接種スケジュール自動生成

子どもを登録すると、生年月日と各ワクチンの推奨接種月齢をもとに、接種予定日を自動で計算して一括登録します。

private function generateSchedule(Child $child)
{
    $vaccines = Vaccine::all();
    foreach ($vaccines as $vaccine) {
        $scheduledDate = $child->birth_date->copy()
            ->addMonths($vaccine->recommended_months);

        VaccinationSchedule::create([
            'child_id'       => $child->id,
            'vaccine_id'     => $vaccine->id,
            'status'         => 'pending',
            'scheduled_date' => $scheduledDate,
        ]);
    }
}

生年月日を登録するだけで「何ヶ月後に接種するか」を自動で計算してくれるのが感動ポイントです✨
日付の計算には Carbon というライブラリを使いました。正確に表示されたときはとても嬉しかったです!

image.png

  • ✅定期接種9種類が表示されている
  • ✅任意接種が別セッションで表示されている
  • ✅摂取予定日が生年月日から正しく計算されている
  • ✅ステータスが「⏳未接種」で」表示されている

ワクチンを「接種済みにする」ボタンをクリックすると:

  • ✅ ステータスが「✅ 接種済」に更新される
  • ✅ 接種日が記録される

2. ブラウザプッシュ通知

laravel-notification-channels/webpush を使用して、接種予定日の1ヶ月前・2週間前・1週間前・前日にブラウザプッシュ通知を送信します。

Notificationクラス:

public function toWebPush($notifiable, $notification)
{
    if ($this->daysUntil === 0) {
        $body = "今日は{$this->childName}{$this->vaccineName}の接種日です!";
    } else {
        $body = "{$this->childName}{$this->vaccineName}の接種予定日まであと{$this->daysUntil}日です。";
    }

    return (new WebPushMessage)
        ->title('💉 予防接種リマインダー')
        ->body($body)
        ->action('スケジュールを確認する', 'check_schedule')
        ->data(['url' => url('/dashboard')]);
}

スケジューラー(毎日朝9時に自動実行):

protected function schedule(Schedule $schedule): void
{
    $schedule->command('reminders:send')->dailyAt('09:00');
}

ブラウザへの通知を送るには、PHPに BCMath という追加の機能が必要でした。Dockerにこの機能を追加しました。

最初はメールでの通知にしようかと思ってたんですが、メールって見逃しやすいし、開封するひと手間もありますよね。それに比べてプッシュ通知は画面の端にポップアップで出てくるので、リアルタイムで気づけるし、通知を見るだけで内容がわかるのがいい!

私自身もメールがたくさん届いて受信ボックスがいっぱいになりがちなので…笑
今回はプッシュ通知にしました。

image.png

ブラウザプッシュ通知が届きました!!

  • ✅「予防接種リマインダー」というタイトルで通知が届いた
  • ✅「すずちゃんのヒブ(Hib)の接種予定日まであと1日です」というメッセージも正確!

3. 家族共有機能

招待コードを発行してパートナーを招待し、同じ子どものデータを家族で共有できます。

// 招待コード自動生成
public static function generateInviteCode()
{
    do {
        $code = strtoupper(Str::random(8));
    } while (self::where('invite_code', $code)->exists());

    return $code;
}

// 招待コードで参加
public function join(Request $request)
{
    $group = FamilyGroup::where('invite_code', $request->invite_code)->first();

    if (!$group) {
        return redirect()->route('family_groups.index')
            ->with('error', '招待コードが正しくありません。');
    }

    $group->members()->attach(Auth::id());

    return redirect()->route('family_groups.index')
        ->with('success', 'グループに参加しました!');
}

8桁のランダムな招待コードが自動で生成されます。パートナーにそのコードを教えて入力してもらうだけでグループに参加できるので、操作が簡単なのがポイントです😊

image.png

  • ✅ グループが作成された
  • ✅ 招待コードが自動生成された
  • ✅ メンバー管理画面が表示されている
  • ✅ 招待コードで参加できる入力欄がある

4. 副反応記録

接種済みのワクチンに対して、副反応の症状・期間・メモを記録できます。「熱が出た」「発疹が出た」などをその場でメモしておけるので、次回の受診時にも役立ちます!

public function store(Request $request, Child $child)
{
    $request->validate([
        'vaccination_schedule_id' => 'required|exists:vaccination_schedules,id',
        'symptom'                 => 'required|string|max:255',
        'start_date'              => 'required|date',
        'end_date'                => 'nullable|date|after_or_equal:start_date',
        'memo'                    => 'nullable|string',
    ]);

    SideEffect::create([
        'child_id'                => $child->id,
        'vaccination_schedule_id' => $request->vaccination_schedule_id,
        'symptom'                 => $request->symptom,
        'start_date'              => $request->start_date,
        'end_date'                => $request->end_date,
        'memo'                    => $request->memo,
    ]);

    return redirect()->route('side_effects.index', $child)
        ->with('success', '副反応を記録しました!');
}

image.png

子どもごとに副反応の履歴を確認できます。記録しておくと後から見返せるので便利です😊

  • ✅ 副反応記録一覧画面が表示されている
  • ✅「+ 副反応を記録する」ボタンが表示されている
  • ✅ B型肝炎の副反応「発熱」が記録されている
  • ✅ 開始日・終了日が正しく表示されている
  • ✅ メモ「38度の熱がでた。翌日には回復した。」が記録されている
  • ✅ 削除ボタンも表示されている

開発を振り返って

Docker環境の問題

Dockerのコンテナを再起動すると、追加でインストールした機能がリセットされてしまう問題がありました。毎回手動で再インストールが必要な状態なので、今後改善したいと思っています!


今後の課題

① Docker環境の改善
今はコンテナを再起動するたびに手動で設定し直す必要があります😅 設定ファイル(Dockerfile)に最初から書いておけば自動で設定されるので、そこを直したいです。

② スマホでも見やすくする
今はパソコン向けのデザインのみなので、スマホからも使いやすいように画面を整えたいと思っています。

今後は上記の内容を改善としたアプリを開発していきたいです!


おわりに

このアプリを作ることで、Laravelの基本的なCRUD操作(データの登録・表示・編集・削除)からプッシュ通知・家族共有といった応用機能まで、幅広く実装することができました!

まだまだ勉強中ですが、「Create(作成)」「Read(読み取り)」「Update(更新)」「Delete(削除)」など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?