-
Notifications
You must be signed in to change notification settings - Fork 0
Labels
Size-L開発時間の目安は20時間開発時間の目安は20時間✨Backendバックエンドのタスク. 主にGo, TypeScriptを使用バックエンドのタスク. 主にGo, TypeScriptを使用✨Databaseデータベースのタスク. 主にPostgreSQLを使用データベースのタスク. 主にPostgreSQLを使用優先度0Must, Minimum・最低限実装しないといけない枠Must, Minimum・最低限実装しないといけない枠
Description
開発概要
目的
- モックリポジトリ(
/workspace/seeft-slack-notification_mock)のシフト通知機能を本番リポジトリ(/workspace/SeeFT)へ移植する - 1セル(15分)ごとのスパム通知を解消するグルーピングロジックを実装する
- 同一ユーザー・同一日付の変更を1通にまとめ、連続時間を期間表示し、変更内容をリスト化する
変更前: undefinedバグを修正する
開発期間
- 開始日:
- 締切日:
考えられる開発内容
Phase 1: 基盤整備
データベーススキーマの追加
-
mysql/db/create_action_log.sqlを作成(action_logテーブル定義)- id (SERIAL PRIMARY KEY)
- shift_id (INTEGER, FOREIGN KEY to shifts)
- user_id (INTEGER, FOREIGN KEY to users) - グルーピング用
- date_id (INTEGER, FOREIGN KEY to dates) - グルーピング用
- action_type (VARCHAR(50)) - "CREATE", "UPDATE", "DELETE"
- diff_payload (JSONB) - 変更内容
- is_sent (BOOLEAN DEFAULT FALSE) - 送信済みフラグ
- created_at (TIMESTAMP)
-
mysql/db/add_slack_user_id_to_users.sqlを作成(usersテーブルにslack_user_idカラム追加)ALTER TABLE users ADD COLUMN slack_user_id VARCHAR(255)
-
api/lib/entity/action_log.goを作成(ActionLogエンティティ定義) -
api/lib/entity/user.goを更新(SlackUserIDフィールド追加)
リポジトリ層の実装
-
api/lib/internals/repository/action_log_repository.goを作成Create(ctx, shiftID, userID, dateID, actionType, diffPayload) errorメソッド実装GetUnsentLogs(ctx) (*sql.Rows, error)メソッド実装(未送信ログ取得)GetUnsentLogsByUserAndDate(ctx, userID, dateID) (*sql.Rows, error)メソッド実装(グルーピング用)MarkAsSent(ctx, logIDs []int) errorメソッド実装(送信済みフラグ更新)
Phase 2: 通知機能の移植
Slack通知サービスの実装
-
api/lib/externals/slack/slack_service.goを作成- Slack APIクライアントの初期化
- メッセージ送信機能(チャンネル + DM)
- 環境変数から設定読み込み(
SLACK_BOT_TOKEN,SLACK_CHANNEL_ID) - 参考:
/workspace/seeft_slackNotification_mock/backend/internal/service/slack_service.go
ShiftUseCaseへの統合
-
api/lib/usecase/shift_usecase.goのUpdateShiftsFromGASメソッドを更新- シフト変更時に
action_logへ記録する処理を追加 oldValがnilの場合のハンドリング(CREATE時)newValがnilの場合のハンドリング(DELETE時)undefinedバグの修正(nilチェック追加)- 参考:
/workspace/seeft_slackNotification_mock/backend/internal/service/shift_service.goのlogActionメソッド
- シフト変更時に
Phase 3: グルーピングロジック実装(最重要)
NotificationUseCaseの実装
-
api/lib/usecase/notification_usecase.goを作成ProcessUnsentNotifications(ctx) errorメソッド実装(未送信通知を処理)GroupNotificationsByUserAndDate(logs []ActionLog) map[string][]ActionLogメソッド実装(ユーザー・日付でグルーピング)CalculateTimeRange(timeIDs []int) (startTime, endTime string)メソッド実装(連続時間を計算)- 例: [25, 26, 27] -> "07:30 〜 09:00"
BuildGroupedMessage(group []ActionLog) stringメソッド実装(グルーピング済みメッセージ生成)- メッセージフォーマット例:
✨ シフト変更通知 ユーザー: 田中太郎 日付: 1日目 天気: 晴れ 【変更内容】 07:30 〜 09:00 - タスク: 受付 → 案内 - タスク: 受付 → 撤収 09:30 〜 10:30 - タスク: 撤収 → 受付
Phase 4: バッチ処理実装
通知ワーカーの実装
-
api/lib/usecase/notification_worker.goを作成(オプション、またはNotificationUseCaseに統合)- 定期的に未送信ログを取得する処理(例: 5分ごと)
NotificationUseCase.ProcessUnsentNotifications()を呼び出し- エラーハンドリングとリトライロジック
-
api/main.goを更新- ワーカーをgoroutineで起動する処理を追加
- 例:
go func() { ticker := time.NewTicker(5 * time.Minute) defer ticker.Stop() for range ticker.C { if err := notificationUseCase.ProcessUnsentNotifications(ctx); err != nil { log.Printf("Failed to process notifications: %v", err) } } }()
DI(依存性注入)の更新
-
api/lib/di/di.goを更新ActionLogRepositoryの初期化を追加SlackServiceの初期化を追加NotificationUseCaseの初期化を追加(必要な依存関係を注入)
環境変数の追加
-
api/env/dev.envを更新SLACK_BOT_TOKEN=xoxb-...を追加SLACK_CHANNEL_ID=C1234567890を追加
備考
- usersテーブルのslack_user_id: 既存データへの影響を考慮し、NULL許可とする
- 送信タイミング: 即座送信ではなく、バッチ処理で定期的に送信(5分間隔を推奨)
- エラーハンドリング: Slack送信失敗時もログを残し、リトライ可能にする
- パフォーマンス: 大量の未送信ログがある場合の処理時間を考慮
- 確認事項:
- usersテーブルにslack_user_idカラムを追加する方針で問題ないか
- 通知の送信間隔(5分)で問題ないか
- Slackチャンネルへの通知も必要か(現状はDMのみの想定)
参考
データフロー
GASからのシフト変更
↓
UpdateShiftsFromGAS (ShiftUseCase)
↓
action_logに記録 (ActionLogRepository)
↓
action_logテーブル (DB保存)
↓
NotificationWorker (定期的に未送信ログ取得)
↓
user_id, date_idでグルーピング (NotificationUseCase)
↓
連続時間を計算
↓
グルーピング済み通知
↓
Slack送信 (SlackService)
↓
送信済みフラグ更新
ディレクトリ構造
api/lib/
├── entity/
│ ├── action_log.go (新規)
│ └── user.go (slack_user_idフィールド追加)
├── internals/
│ ├── repository/
│ │ └── action_log_repository.go (新規)
│ └── controller/
│ └── notification_controller.go (新規、オプション)
├── externals/
│ └── slack/
│ └── slack_service.go (新規)
└── usecase/
├── notification_usecase.go (新規)
└── notification_worker.go (新規、オプション)
参考ファイル
- モックリポジトリ:
/workspace/seeft_slackNotification_mock/backend/internal/service/slack_service.go - モックリポジトリ:
/workspace/seeft_slackNotification_mock/backend/internal/service/shift_service.go - モックリポジトリ:
/workspace/seeft_slackNotification_mock/backend/internal/repository/action_log_repository.go - 本番リポジトリ:
/workspace/SeeFT/api/lib/usecase/shift_usecase.go(1360行目〜) - 本番リポジトリ:
/workspace/SeeFT/api/lib/internals/repository/shift_repository.go
開発の流れ
- PMにIssue(タスク)をもらう
- 開発をする(↓の「リンク」の『開発のやり方』を見よう!)
- チェックボックスを押していこう
- ヤバい状況になったらIssueの右側にあるStatusを「Help」にしてPMにSlackで連絡しよう
- チェックボックスが全部押せたらプルリクを作ろう
- レビューを待とう
- 修正点があれば修正しよう。なければPMがマージします!お疲れ様!
SeeFTのタスク管理のルール
- タスクは全てGit-Hub Projectで管理する
- 全てのタスクに期日を決める
- 毎週タスクの進捗を確認する(MTに出られない人はSlackで報告)
- 毎週忙しさ(消化できるタスク量)を共有する
- Helpは余裕のある人がいれば巻き取る。いなければ期日を変更する
リンク
Sub-issues
Metadata
Metadata
Assignees
Labels
Size-L開発時間の目安は20時間開発時間の目安は20時間✨Backendバックエンドのタスク. 主にGo, TypeScriptを使用バックエンドのタスク. 主にGo, TypeScriptを使用✨Databaseデータベースのタスク. 主にPostgreSQLを使用データベースのタスク. 主にPostgreSQLを使用優先度0Must, Minimum・最低限実装しないといけない枠Must, Minimum・最低限実装しないといけない枠