Skip to content

セクション C: academic-api をモノレポ配下へ取り込み#3

Merged
kantacky merged 48 commits into
mainfrom
feat/c-academic-api
May 10, 2026
Merged

セクション C: academic-api をモノレポ配下へ取り込み#3
kantacky merged 48 commits into
mainfrom
feat/c-academic-api

Conversation

@kantacky

@kantacky kantacky commented May 9, 2026

Copy link
Copy Markdown
Member

やったこと

Notion 計画 §7-C に沿って、fun-dotto/academic-apicmd/academic-api/ + internal/modules/academic/ として git filter-repo で履歴ごと取り込み、モノレポ内で動く形に組み替える。

  • academic-api の取り込み (履歴保全)
    • git filter-repo --invert-pathsinternal/database/database.go (shared-go と重複) と internal/database/migrate.go (Atlas へ移行) のみ除外。go.mod / mise.toml / Dockerfile 等の競合トップレベルファイルと .claude / .codex / .github / .dockerignore も同時に除外して merge 衝突をゼロに
    • --path-renameinternal/internal/modules/academic/ の順で先に適用し、assets/ / cmd/server/ / openapi/ / generated/ を続けて再配置
    • git merge --allow-unrelated-histories で 44 commit を取り込み、blame と作者情報を保全
  • import path を一括書き換え
    • github.com/fun-dotto/academic-api/internal/<pkg>internal/modules/academic/<pkg>
    • github.com/fun-dotto/academic-api/assetsinternal/modules/academic/assets
    • github.com/fun-dotto/academic-api/generatedgen/academic
    • github.com/fun-dotto/shared-go/db/modelinternal/shared/model
  • API エントリの整理
    • DB 接続を internal/shared/db.ConnectWithConnectorIAMAuthN に切り替え。変数名は db パッケージとの衝突回避のため conn に統一
    • database.AutoMigrate 呼び出しを完全削除し、Atlas Cloud Run Job (cmd/migrate-job) 経由に統一する方針 (Notion 計画 §3 / §H) を反映
    • OpenAPI 仕様のロードを internal/modules/academic/openapispec パッケージで go:embed openapi.yaml し、LoadFromData に渡す形に切替 (distroless 対応)
  • コード生成設定の追従
    • api/openapi/academic/config.yamloutputgen/academic/api.gen.go に変更
  • 依存整理
    • gin / oapi-codegen / kin-openapi / godotenv 等を直接依存に追加し go mod tidy

確認したこと

  • mise exec -- go build ./... が成功
  • mise exec -- go test ./... が成功 (academic/domain と academic/handler のテスト群が通る)
  • cmd/academic-api/main.go から旧 database パッケージへの依存が完全に消えていることを grep で確認
  • git log で academic-api の 44 commit が feat/c-academic-api ブランチに取り込まれていることを確認

メモ

  • Notion 計画 §7-C は internal/database/ を全削除する前提だったが、対象ディレクトリには XxxFromDomain / XxxToDomain などの academic モジュール固有の変換ヘルパが同居しており、shared-go/db/model とは GORM タグ・型 (uuid vs string) も異なるため、本 PR では internal/database/database.go (Connect…) と internal/database/migrate.go (AutoMigrate) のみ除外し、変換ヘルパを含むファイル群は internal/modules/academic/database/ として保持した。internal/shared/model への一本化は §E (Atlas baseline) で atlas schema diff を踏まえて整合確認した上で別途対応する
  • ベースブランチは §B スタックの feat/b-shared-go

kantacky and others added 30 commits February 10, 2026 09:52
* Add models

* Convert関数をそれぞれのファイルに移した

* 命名を修正

* 修正

* Refactor

* Add ER diagram
* uuid

* CRUD

* Refactor

* なぜかidがuuidになっていなかった

* Update er diagram
* Update OpenAPI schema from dotto-typespec

* Update OpenAPI schema from dotto-typespec

* Generate code

* スキーマ変更への対応

* Update OpenAPI schema from dotto-typespec

* Generate

* スキーマ変更に対応

* Update comments

* Update comments

* Update OpenAPI schema from dotto-typespec

* Generate

* Update .env

* Update .env

* Update comment

---------

Co-authored-by: kantacky <51151242+kantacky@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: masaya-osuga <msyaaa456910@gmail.com>
* Update OpenAPI schema from dotto-typespec

* Update OpenAPI schema from dotto-typespec

* Generate

---------

Co-authored-by: kantacky <51151242+kantacky@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: masaya-osuga <msyaaa456910@gmail.com>
Co-authored-by: Masaya Osuga <136790650+masaya-osuga@users.noreply.github.com>
* 不必要なコードを削除

* 不必要なコードを削除

* Add Syllabus

* foundation

* Update main.go

* Update model

* Update handler.go

* Add model and migrate

* Impl

* Fix

* type:textを削除

* TODOを追加

* ファイルを分割した

* Update internal/database/migrate.go

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update internal/repository/subject.go

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* コンフリクトしないようにDBでUpsertするようにした

* serena

* 修正が必要な箇所にTODOコメントをつけた

* サブクエリにコンテキストが伝播するように修正

* Add TODO

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Fix

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update OpenAPI schema from dotto-typespec

* Update OpenAPI schema from dotto-typespec

* Generate

* Add stub implementations for new OpenAPI endpoints

* Fix

---------

Co-authored-by: kantacky <51151242+kantacky@users.noreply.github.com>
Co-authored-by: Kanta Oikawa <iam@kantacky.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: masaya-osuga <msyaaa456910@gmail.com>
* FacultyのDB追加

* Facltyのドメインモデル追加

* FacultyのRepository

* FacultyのService

* FacultyのHandler

* インターフェースに沿うように修正

* mainにFaculty追加

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* MigrateにFaculty追加

* 関数名修正に伴う変更

* 名前修正

* Repositoryの関数名修正

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* 不要な関数削除

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Subject-Facultyのトランザクション追加

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* エラー処理修正

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Update OpenAPI schema from dotto-typespec

* Generate

* エラー対応

---------

Co-authored-by: kantacky <51151242+kantacky@users.noreply.github.com>
Co-authored-by: Masaya Osuga <136790650+masaya-osuga@users.noreply.github.com>
Co-authored-by: masaya-osuga <msyaaa456910@gmail.com>
* Update OpenAPI schema from dotto-typespec

* task geneate

* パラメータ名修正

* スタブ実装

---------

Co-authored-by: kantacky <51151242+kantacky@users.noreply.github.com>
Co-authored-by: Hikaru Saito <beretta0602@gmail.com>
* Update OpenAPI schema from dotto-typespec

* roomのDB

* roomのドメイン

* Roomのリポジトリ

* RoomService

* RoomのCRUD

* Convert

* Handler実装

* Mainに追加

* task geneate

* パラメータ名修正

* スタブ実装

* RoomのFilter追加

---------

Co-authored-by: kantacky <51151242+kantacky@users.noreply.github.com>
* Update OpenAPI schema from dotto-typespec

* task generate

---------

Co-authored-by: kantacky <51151242+kantacky@users.noreply.github.com>
Co-authored-by: Hikaru Saito <beretta0602@gmail.com>
* Update OpenAPI schema from dotto-typespec

* roomのDB

* roomのドメイン

* Roomのリポジトリ

* RoomService

* RoomのCRUD

* Convert

* Handler実装

* Mainに追加

* task geneate

* パラメータ名修正

* スタブ実装

* TimetableのDB実装

* TimetableのDomain実装

* RoomのFilter追加

* DomainがSubjectとRoomを持つように変更

* TimetableのRepository実装

* TimetableのService実装

* Timetableの各Handler実装

* Convert修正

* NewHandler修正

* Main修正

* スキーマアップデートに伴う修正

* Update internal/repository/timetableitems.go

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* 不要なimport削除

* エラー修正

* ファイル名修正

---------

Co-authored-by: kantacky <51151242+kantacky@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update OpenAPI schema from dotto-typespec

* roomのDB

* roomのドメイン

* Roomのリポジトリ

* RoomService

* RoomのCRUD

* Convert

* Handler実装

* Mainに追加

* task geneate

* パラメータ名修正

* スタブ実装

* TimetableのDB実装

* TimetableのDomain実装

* RoomのFilter追加

* DomainがSubjectとRoomを持つように変更

* TimetableのRepository実装

* TimetableのService実装

* Timetableの各Handler実装

* Convert修正

* NewHandler修正

* Main修正

* DB実装

* Domain実装

* Repository実装

* Service実装

* Convert

* 各Handler実装

* NewHandler修正

* main修正

* 削除

* ファイル名修正

* 不要なエラー処理削除

* エラー処理修正

* 修正

---------

Co-authored-by: kantacky <51151242+kantacky@users.noreply.github.com>
* Faculty取得

* Preload修正

* Update internal/database/subject.go

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* デリファレンス

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* slotを作らない

* テスト作成
SubjectのListフィルタで、同一子テーブル(SubjectEligibleAttribute,
SubjectRequirement)への条件が別々のサブクエリに分かれていたため、
両方指定時にAND条件として正しく機能しなかったバグを修正。

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Update OpenAPI schema from dotto-typespec

* Generate

* スタブ実装

* 削除

* subjectのupsertを削除

* パラメータの削除

* 命名を変更

* Converterを分割

---------

Co-authored-by: kantacky <51151242+kantacky@users.noreply.github.com>
Co-authored-by: masaya-osuga <msyaaa456910@gmail.com>
* events.jsonを追加

* DI

* 振替や休講補講を気にせず取得する実装

* subjectの全フィールドを埋めて返すようにした

* subjectListで足りていなかったフィールドを追加

* personal_calendarのレスポンスを修正

* 命名を修正

* 振替授業日のためのJSONファイルの読み込み

* 振替授業日判定
* events.jsonを追加

* DI

* 振替や休講補講を気にせず取得する実装

* subjectの全フィールドを埋めて返すようにした

* subjectListで足りていなかったフィールドを追加

* personal_calendarのレスポンスを修正

* 命名を修正

* 振替授業日のためのJSONファイルの読み込み

* 振替授業日判定

* Converterのテストを追加
* Update OpenAPI schema from dotto-typespec

* Generate

---------

Co-authored-by: kantacky <51151242+kantacky@users.noreply.github.com>
Co-authored-by: masaya-osuga <msyaaa456910@gmail.com>
* Add submodule

* Add symbolic links

* Delete .serena
* Add submodule

* Add symbolic links

* Delete .serena

* Update OpenAPI schema from dotto-typespec

* 生成コードを更新: date-time → date 型変更に追従

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* handler の openapi_types.Date 型変更に追従

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Kanta Oikawa <iam@kantacky.com>
Co-authored-by: kantacky <51151242+kantacky@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Update OpenAPI schema from dotto-typespec

* Generate

* 休講補講、教室変更のCRD(Putは未実装)とPersonalCalendarItemsV1_listの休講補講対応 (#30)

---------

Co-authored-by: kantacky <51151242+kantacky@users.noreply.github.com>
Co-authored-by: Kanta Oikawa <iam@kantacky.com>
Co-authored-by: Masaya Osuga <136790650+masaya-osuga@users.noreply.github.com>
* 科目IDのみで教室検索

* 同じ科目IDの全教室を重複無しで返すように修正

* subjectPeriodYoRooms削除

* 教室の順序ソート

* コメント修正
* 日付からsemester

* Update internal/service/personal_calendar_item.go

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
dotto-api-schema-updater Bot and others added 18 commits April 14, 2026 17:09
* Update OpenAPI schema from dotto-typespec

* NotifyIrregularities エンドポイント削除に伴う生成コード更新

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* NotifyIrregularities ハンドラの削除

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: kantacky <51151242+kantacky@users.noreply.github.com>
Co-authored-by: Kanta Oikawa <iam@kantacky.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* HTTPタイムアウトを導入

* タイムアウト時に504を返すよう修正

* http.ErrServerClosed を正常終了として扱うよう分岐を追加

* タイムアウトエラーレスポンスのキーを "msg" に統一し、DeadlineErrorMapper のコメントを整理
* SIGTERM時にグレースフルシャットダウンを実装

Cloud RunのSIGTERM送信時に、in-flightリクエストの完了を待ってから
HTTPサーバーとDBコネクションを閉じるようにする。従来は即座にプロセスが
終了し、TCPレベルでRSTが送られコネクションが中途半端に切断されていた。

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* サーバー終了処理を堅牢化

ListenAndServe の終了結果を serverErr チャネル経由で必ず 1 回送る
形に変更し、受信側で http.ErrServerClosed を判定するようにした。
close を使った曖昧な同期をやめ、起動失敗時は早期 return するフロー
を明示化している。

また Shutdown がタイムアウト等で失敗した場合は srv.Close で強制
クローズし、さらに ListenAndServe goroutine の終了を待ってから
main を return する。これにより defer database.Close(db) 実行時
に HTTP ハンドラ goroutine が DB を触り続ける可能性を排除した。

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* 起動失敗時にdeferを実行するようlog.Fatalをlog.Printfに変更

log.Fatalはos.Exit(1)を呼びdeferをスキップするため、
SIGTERMでのクリーンアップ方針と矛盾していた。
起動直後のListenAndServeエラーでもdatabase.Closeを走らせるため、
log.Printfとreturnで正常終了パスに揃える。

* shutdownTimeoutをCloud Run猶予より短い8秒に調整

shutdownTimeoutがCloud Runのデフォルト猶予10秒と同値だと、
srv.Shutdownが上限まで粘った場合に後続のdatabase.Closeへ
割ける時間がなくなる。2秒の余裕を残して安全側に倒す。

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Update OpenAPI schema from dotto-typespec

* 教員室エンドポイントの生成コードを更新

OpenAPIスキーマで追加されたFacultyRooms関連エンドポイント(list/create/delete)と、Room.Number・RoomRequest.FacultyId削除を再生成に反映。

* 教員室エンドポイントの未実装ハンドラを追加

StrictServerInterfaceを満たすため、FacultyRoomsV1List/Create/Deleteの3つを"not implemented"を返すスタブとして追加。

* スキーマから削除されたRoom.Numberのテストアサーションを削除

OpenAPIスキーマからRoom.Numberが削除され、生成コードに当該フィールドが存在しなくなったため、テスト側のチェックを外してビルドを通す。

---------

Co-authored-by: kantacky <51151242+kantacky@users.noreply.github.com>
Co-authored-by: masaya-osuga <msyaaa456910@gmail.com>
* Update OpenAPI schema from dotto-typespec

* Generate

* Update OpenAPI schema from dotto-typespec

---------

Co-authored-by: masaya-osuga <136790650+masaya-osuga@users.noreply.github.com>
Co-authored-by: masaya-osuga <msyaaa456910@gmail.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* 忘れていたコードgenerateを実行

* 削除されたエンドポイントの未実装スタブハンドラを削除

OpenAPIスキーマ更新により以下のエンドポイントが削除されたため、
対応する未実装(not implemented)スタブハンドラを削除する。

- CancelledClassesV1_fetch (PUT /v1/cancelledClasses)
- MakeupClassesV1_fetch (PUT /v1/makeupClasses)
- RoomChangesV1_fetch (PUT /v1/roomChanges)
- ReservationsV1_detail (GET /v1/reservations/{id})

再生成済みの api.gen.go からも対応する型・ルートが消えており、
これらのハンドラは StrictServerInterface の要求を満たすためだけに
存在していたため、ファイルごと削除する。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
* 教員室のドメイン型とDBモデルを追加

OpenAPIスキーマに追加されたFacultyRoomリソースの実装に備え、
以下の土台を整備する。

- domain.FacultyRoom および検索フィルタ型
- 4月始まりの年度を計算する domain.CurrentAcademicYear
- database.FacultyRoom GORMモデル
  - (facultyId, year), (roomId, year) をそれぞれ複合ユニーク制約で保護し、
    「1教員1部屋/年度」「1部屋1教員/年度」を維持する
- AutoMigrate対象への追加

* 教員削除で教員室をcascade、教室削除をrestrictに変更

FacultyRoom導入に伴い、既存リソースの削除挙動を整える。

- FacultyRepository.Delete: 教員削除時に紐づく FacultyRoom も
  トランザクション内で一括削除する(cascade)
- RoomRepository.Delete: 教室は基本削除しない運用方針のため、
  FacultyRoom が紐づいている場合は ErrRoomInUse を返し削除を拒否する
  (restrict)。履歴を伴う誤削除を防ぐ

* 教員室リポジトリを追加

FacultyRoom の永続化を担うリポジトリを追加する。

- List: year フィルタに対応し、Faculty と Room を Preload する
- Create: ID未指定時は UUID を採番し、作成後に Preload 済みの
  レコードを再取得して返す
- Delete: トランザクション内で存在確認し、見つからなければ
  gorm.ErrRecordNotFound を返す

* 教員室サービスを追加

FacultyRoom 用のサービス層を追加する。
現時点ではリポジトリ呼び出しの薄いラッパだが、ハンドラが
リポジトリに直接依存しないようにするために挟む。

* 教員室エンドポイントを実装

未実装のまま追加されていた FacultyRoom の3エンドポイントを
実装する。

- GET /v1/facultyRooms: year 未指定時は domain.CurrentAcademicYear で
  今年度を既定値として補完する
- POST /v1/facultyRooms: UUID を採番して作成
- DELETE /v1/facultyRooms/{id}: gorm.ErrRecordNotFound を 404 にマップ

あわせて Handler に facultyRoomService の依存を追加し、
main.go でリポジトリ・サービス・ハンドラの配線を行う。

* fmt

* 教員室作成のUUID採番をリポジトリに一元化

* 年度判定関数の境界テストを追加

* 年度判定関数をJST基準に変更

CurrentAcademicYear は受け取った time.Time の Month/Year をローカルタイムゾーンで解釈していたため、
サーバのTZ設定によって年度の境界(4/1 00:00 JST)が最大9時間ズレる恐れがあった。
関数内部で JST に変換してから判定するよう修正し、日本の年度という概念に沿った挙動にした。
テストも JST で構築した時刻で検証するよう書き直し、UTC 入力でも JST 境界を跨ぐケースを追加して回帰を防ぐ。

* 教員室一覧コンバータに単体テストを追加

buildFacultyRoomListFilter は year 未指定時に現在年度へフォールバックする分岐を持つが、
time.Now() 直接呼び出しのため年度境界付近でフレークしやすくテストが書けていなかった。
パッケージ変数 nowFunc を介して時刻取得を差し替え可能にし、固定時刻を注入したうえで
year 指定あり/なしの両ケースをカバーするテストを追加した。
併せて facultyRoomToAPI と toDomainFacultyRoomFromRequest の変換テストも他のコンバータと同じ粒度で追加している。

* 教員室リポジトリのユニーク制約違反をドメインエラーに変換

教員室テーブルの (教員,年度) および (教室,年度) のユニーク制約に違反した
INSERT が発生した場合、PostgreSQL の 23505 を該当の制約名に限って
ErrFacultyRoomAlreadyExists へ翻訳する。上位層が DB ドライバの詳細を
知らずに重複登録を判別できるようにするための下準備。

* 教員室作成時の重複登録を409で返す

リポジトリが返す ErrFacultyRoomAlreadyExists を検出し、
同一年度で同じ教員または同じ教室の教員室が既に存在するケースを
409 Conflict として応答するようにする。該当しないエラーは従来通り
500 に相当するエラーとして上位へ伝播する。

* 教室削除時の使用中エラーを409で返す

教員室に割り当てられている教室を削除しようとした際にリポジトリが返す
ErrRoomInUse を検出し、409 Conflict として応答する。既存の
404 判定と並べる形で分岐を追加し、他のエラーは従来通り上位へ伝播する。

* 教員室削除の First エラー分岐を整理

FacultyRoomRepository.Delete 内で gorm.ErrRecordNotFound かどうかを
判定してから同じ err を返していた実質的に無意味な分岐を削除し、
いずれの場合もそのまま err を返すよう単純化する。振る舞いは変わらない。
* Json追加

* assetsに追加

* Jsonから休日データ取得

* 休日判定

* 処理呼び出し追加
* 休講・補講・教室変更のListを日付・時限順にソート

UI 側で時系列に扱いやすくするため、各 List の GORM クエリに
`ORDER BY date ASC, period ASC` を追加する。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* 同一date・period時は subject の syllabus_id でソート

休講・補講・教室変更の List で、date/period が同じ場合に順序が
安定するよう、subjects テーブルを JOIN して syllabus_id 昇順で
タイブレークする。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* 教員一覧をEmail昇順でソート

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* 教員室一覧を年度・フロア・教室名の昇順でソート

Floor/Nameはroomsテーブル側の列でPreloadによる別クエリ経由で
取得しているため、リポジトリ層でin-memoryソートする。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* 教員室一覧のソートをJOIN + ORDER BYに変更

in-memoryソートからDB側での並び替えに切り替え、
rooms テーブルと JOIN して year, floor, name の昇順で取得する。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* 教室一覧を教室名の昇順でソート

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* 教室一覧をフロア・教室名の昇順でソート

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
git filter-repo で配置した internal/modules/academic/ 配下の import を
新リポジトリのパスに揃える (Notion 計画 §7-C)。
- github.com/fun-dotto/academic-api/internal/<pkg> →
  github.com/fun-dotto/server/internal/modules/academic/<pkg>
- github.com/fun-dotto/academic-api/assets →
  github.com/fun-dotto/server/internal/modules/academic/assets
- github.com/fun-dotto/academic-api/generated →
  github.com/fun-dotto/server/gen/academic
- github.com/fun-dotto/shared-go/db/model →
  github.com/fun-dotto/server/internal/shared/model

api wiring (cmd/academic-api/main.go) や config.yaml の出力先など
振る舞いを伴う変更は別コミットで扱い、本コミットはパッケージ参照だけを
書き換えた純粋な機械的置換に留める。
oapi-codegen の生成先を generated/api.gen.go から
gen/academic/api.gen.go に変更し、Notion 計画 §2 で定めた
gen/<module>/ 配下に集約する構造へ追従させる。Taskfile の
generate:academic タスクから直接呼べる前提に揃える。
distroless ランタイムにはファイルが置かれないため (Notion 計画 §2)、
academic API が起動時に LoadFromFile していた openapi.yaml を
バイナリ同梱に切り替える。internal/modules/academic/openapispec/
パッケージを新設し、//go:embed openapi.yaml で取り込んだバイト列を
Spec として公開する。yaml は api/openapi/academic/openapi.yaml の
コピーで、Taskfile の generate:academic からの再生成と
位置を揃える運用ルールはモジュールガイド (§I) で別途明文化する。
Atlas 専用 Cloud Run Job (cmd/migrate-job) を一本のマイグレーション経路に
統一する方針 (Notion 計画 §3 / §7-C / §H) に合わせ、academic API の
起動シーケンスから AutoMigrate を完全に削除する。あわせて以下を行う:
- DB 接続を internal/shared/db.ConnectWithConnectorIAMAuthN に切替え、
  shared 層をモノレポ全体の単一接続ソースとして扱う。conn 変数名で
  パッケージ名 db との衝突を避ける
- OpenAPI 仕様の読み込みを openapispec.Spec (go:embed) に切替え、
  distroless ランタイムでも動作する形にする
- repository 各種の wiring 引数を conn に置換
academic-api 由来の handler/repository/service が要求する
gin/oapi-codegen/kin-openapi/joho-godotenv 等の直接依存を
go.mod に追加し、go mod tidy で間接依存を整理した。
go test ./... がローカルで通ることを確認した上で確定する。
@kantacky kantacky self-assigned this May 9, 2026
@kantacky kantacky marked this pull request as ready for review May 9, 2026 13:23
Copilot AI review requested due to automatic review settings May 9, 2026 13:23

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

fun-dotto/academic-api をモノレポ配下(cmd/academic-api / internal/modules/academic)へ履歴付きで取り込み、モノレポ内で起動・運用できる形に再配線する PR です(DB接続の shared 化、Atlas 運用方針への追従、OpenAPI の embed 化など)。

Changes:

  • academic モジュール(domain/service/repository/handler/middleware)をモノレポ構成へ移植し、cmd/academic-api を追加
  • OpenAPI 仕様を go:embed で同梱し、gin + oapi-codegen strict server でルーティング/バリデーション
  • shared DB connector(IAM AuthN)へ切替、依存関係(gin / kin-openapi / oapi-codegen 等)を go.mod に追加

Reviewed changes

Copilot reviewed 112 out of 114 changed files in this pull request and generated 12 comments.

Show a summary per file
File Description
internal/modules/academic/service/timetable_items.go 時間割サービス層の追加
internal/modules/academic/service/subject.go 科目/シラバス取得サービスの追加
internal/modules/academic/service/room.go 教室サービス層の追加
internal/modules/academic/service/room_change.go 教室変更サービス層の追加
internal/modules/academic/service/personal_calendar_item.go 個人カレンダー生成ロジックの追加
internal/modules/academic/service/makeup_class.go 補講サービス層の追加
internal/modules/academic/service/faculty.go 教員サービス層の追加
internal/modules/academic/service/faculty_room.go 教員室割当サービス層の追加
internal/modules/academic/service/course_registration.go 履修登録サービス層の追加
internal/modules/academic/service/cancelled_class.go 休講サービス層の追加
internal/modules/academic/repository/timetable_items.go 時間割のGORM Repository追加
internal/modules/academic/repository/syllabus.go シラバスRepository追加
internal/modules/academic/repository/subject.go 科目検索/取得/削除Repository追加
internal/modules/academic/repository/room.go 教室CRUD Repository追加
internal/modules/academic/repository/room_change.go 教室変更CRUD Repository追加
internal/modules/academic/repository/makeup_class.go 補講CRUD Repository追加
internal/modules/academic/repository/faculty.go 教員CRUD Repository追加
internal/modules/academic/repository/faculty_room.go 教員室割当CRUD Repository追加
internal/modules/academic/repository/course_registration.go 履修登録CRUD Repository追加
internal/modules/academic/repository/cancelled_class.go 休講CRUD Repository追加
internal/modules/academic/openapispec/openapi.go OpenAPI 仕様の embed 用パッケージ追加
internal/modules/academic/middleware/timeout.go gin timeout middleware 追加
internal/modules/academic/middleware/deadline.go strict handler の deadline error マッピング追加
internal/modules/academic/handler/timetable_item_list.go 時間割一覧ハンドラ追加
internal/modules/academic/handler/timetable_item_delete.go 時間割削除ハンドラ追加
internal/modules/academic/handler/timetable_item_create.go 時間割作成ハンドラ追加
internal/modules/academic/handler/syllabus_detail.go シラバス詳細ハンドラ追加
internal/modules/academic/handler/subject_list.go 科目一覧ハンドラ追加
internal/modules/academic/handler/subject_detail.go 科目詳細ハンドラ追加
internal/modules/academic/handler/subject_delete.go 科目削除ハンドラ追加
internal/modules/academic/handler/room_update.go 教室更新ハンドラ追加
internal/modules/academic/handler/room_list.go 教室一覧ハンドラ追加
internal/modules/academic/handler/room_detail.go 教室詳細ハンドラ追加
internal/modules/academic/handler/room_delete.go 教室削除ハンドラ追加
internal/modules/academic/handler/room_create.go 教室作成ハンドラ追加
internal/modules/academic/handler/room_change_list.go 教室変更一覧ハンドラ追加
internal/modules/academic/handler/room_change_delete.go 教室変更削除ハンドラ追加
internal/modules/academic/handler/room_change_create.go 教室変更作成ハンドラ追加
internal/modules/academic/handler/reservation_list.go 予約一覧ハンドラ(未実装スタブ)追加
internal/modules/academic/handler/reservation_delete.go 予約削除ハンドラ(未実装スタブ)追加
internal/modules/academic/handler/reservation_create.go 予約作成ハンドラ(未実装スタブ)追加
internal/modules/academic/handler/personal_calendar_item_list.go 個人カレンダー一覧ハンドラ追加
internal/modules/academic/handler/makeup_class_list.go 補講一覧ハンドラ追加
internal/modules/academic/handler/makeup_class_delete.go 補講削除ハンドラ追加
internal/modules/academic/handler/makeup_class_create.go 補講作成ハンドラ追加
internal/modules/academic/handler/handler.go strict server Handler 集約の追加
internal/modules/academic/handler/faculty_update.go 教員更新ハンドラ追加
internal/modules/academic/handler/faculty_room_list.go 教員室割当一覧ハンドラ追加
internal/modules/academic/handler/faculty_room_delete.go 教員室割当削除ハンドラ追加
internal/modules/academic/handler/faculty_room_create.go 教員室割当作成ハンドラ追加
internal/modules/academic/handler/faculty_list.go 教員一覧ハンドラ追加
internal/modules/academic/handler/faculty_detail.go 教員詳細ハンドラ追加
internal/modules/academic/handler/faculty_delete.go 教員削除ハンドラ追加
internal/modules/academic/handler/faculty_create.go 教員作成ハンドラ追加
internal/modules/academic/handler/course_registration_list.go 履修登録一覧ハンドラ追加
internal/modules/academic/handler/course_registration_delete.go 履修登録削除ハンドラ追加
internal/modules/academic/handler/course_registration_create.go 履修登録作成ハンドラ追加
internal/modules/academic/handler/converter_timetable_item.go 時間割のDTO変換追加
internal/modules/academic/handler/converter_timetable_item_test.go 変換ロジックのテスト追加
internal/modules/academic/handler/converter_syllabus.go シラバスDTO変換追加
internal/modules/academic/handler/converter_syllabus_test.go 変換ロジックのテスト追加
internal/modules/academic/handler/converter_subject.go 科目DTO/フィルタ変換追加
internal/modules/academic/handler/converter_subject_test.go 変換ロジックのテスト追加
internal/modules/academic/handler/converter_room.go 教室DTO/フィルタ変換追加
internal/modules/academic/handler/converter_room_test.go 変換ロジックのテスト追加
internal/modules/academic/handler/converter_room_change.go 教室変更DTO/フィルタ変換追加
internal/modules/academic/handler/converter_personal_calendar_item.go 個人カレンダーDTO変換追加
internal/modules/academic/handler/converter_personal_calendar_item_test.go 変換ロジックのテスト追加
internal/modules/academic/handler/converter_makeup_class.go 補講DTO/フィルタ変換追加
internal/modules/academic/handler/converter_faculty.go 教員DTO変換追加
internal/modules/academic/handler/converter_faculty_test.go 変換ロジックのテスト追加
internal/modules/academic/handler/converter_faculty_room.go 教員室割当DTO/フィルタ変換追加
internal/modules/academic/handler/converter_faculty_room_test.go 変換ロジックのテスト追加
internal/modules/academic/handler/converter_course_registration.go 履修登録DTO/フィルタ変換追加
internal/modules/academic/handler/converter_course_registration_test.go 変換ロジックのテスト追加
internal/modules/academic/handler/converter_cancelled_class.go 休講DTO/フィルタ変換追加
internal/modules/academic/handler/cancelled_class_list.go 休講一覧ハンドラ追加
internal/modules/academic/handler/cancelled_class_delete.go 休講削除ハンドラ追加
internal/modules/academic/handler/cancelled_class_create.go 休講作成ハンドラ追加
internal/modules/academic/event/event.go 祝日/振替授業イベントのロード追加
internal/modules/academic/domain/timetable_items.go 時間割関連ドメイン追加
internal/modules/academic/domain/syllabus.go シラバスドメイン追加
internal/modules/academic/domain/subject.go 科目ドメイン/フィルタ追加
internal/modules/academic/domain/room.go 教室ドメイン/フィルタ追加
internal/modules/academic/domain/room_change.go 教室変更ドメイン/フィルタ追加
internal/modules/academic/domain/personal_calendar_item.go 個人カレンダードメイン追加
internal/modules/academic/domain/makeup_class.go 補講ドメイン/フィルタ追加
internal/modules/academic/domain/foundation.go 共通enum系ドメイン追加
internal/modules/academic/domain/faculty.go 教員ドメイン追加
internal/modules/academic/domain/faculty_room.go 教員室割当ドメイン/フィルタ追加
internal/modules/academic/domain/course_registration.go 履修登録ドメイン/フィルタ追加
internal/modules/academic/domain/cancelled_class.go 休講ドメイン/フィルタ追加
internal/modules/academic/domain/academic_year.go 日本の年度計算ヘルパ追加
internal/modules/academic/domain/academic_year_test.go 年度計算のテスト追加
internal/modules/academic/database/timetablei_tems.go 時間割DBモデル/変換追加
internal/modules/academic/database/syllabus.go シラバスDBモデル/変換追加
internal/modules/academic/database/subject.go 科目DBモデル/変換追加
internal/modules/academic/database/room.go 教室DBモデル/変換追加
internal/modules/academic/database/room_change.go 教室変更DBモデル/変換追加
internal/modules/academic/database/makeup_class.go 補講DBモデル/変換追加
internal/modules/academic/database/faculty.go 教員DBモデル/変換追加
internal/modules/academic/database/faculty_room.go 教員室割当DBモデル/変換追加
internal/modules/academic/database/course_registration.go 履修登録DBモデル/変換追加
internal/modules/academic/database/cancelled_class.go 休講DBモデル/変換追加
internal/modules/academic/assets/holidays.json 祝日データ追加
internal/modules/academic/assets/events.json 学内イベント/振替授業データ追加
internal/modules/academic/assets/assets.go assets の embed 追加
cmd/academic-api/main.go academic-api エントリポイント追加
api/openapi/academic/config.yaml oapi-codegen 設定(出力先変更)追加
go.mod academic-api 取り込みに伴う依存追加
go.sum 依存追加に伴う更新

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +33 to +36
if filter.Q != nil {
// TODO: filter.Q に含まれる LIKE ワイルドカード文字(%, _)をエスケープする。現状ユーザー入力がそのまま LIKE パターンに埋め込まれる。
query = query.Where("name ILIKE ?", "%"+*filter.Q+"%")
}
Comment on lines +118 to +122
// デフォルトで今年度を設定
// TODO: このデフォルト値設定のロジックは service 層に移すべき。
// また、日本の大学の年度は4月始まりのため、1〜3月は前年度を返す必要がある。
currentYear := time.Now().Year()
filter.Year = &currentYear
Comment on lines +16 to +20
// TODO: このデフォルト値設定のロジックは service 層に移すべき。
// また、日本の大学の年度は4月始まりのため、1〜3月は前年度を返す必要がある。
currentYear := time.Now().Year()
filter.Year = &currentYear
}
Comment on lines +32 to +35
} else {
currentYear := time.Now().Year()
filter.Year = &currentYear
}
Comment on lines +69 to +74
registrations, err := s.courseRegistrationRepo.List(ctx, domain.CourseRegistrationListFilter{
UserID: userID,
})
if err != nil {
return nil, err
}
Comment on lines +10 to +11
func (h *Handler) ReservationsV1Create(ctx context.Context, request api.ReservationsV1CreateRequestObject) (api.ReservationsV1CreateResponseObject, error) {
return nil, fmt.Errorf("not implemented")
Comment on lines +10 to +11
func (h *Handler) ReservationsV1Delete(ctx context.Context, request api.ReservationsV1DeleteRequestObject) (api.ReservationsV1DeleteResponseObject, error) {
return nil, fmt.Errorf("not implemented")
Comment on lines +53 to +57
func (r *RoomRepository) Create(ctx context.Context, room domain.Room) (domain.Room, error) {
// TODO: room.ID が空の場合に uuid.New().String() で採番する(空のまま渡すと primary key 制約違反で INSERT 失敗)
dbRoom := database.RoomFromDomain(room)
if err := r.db.WithContext(ctx).Create(&dbRoom).Error; err != nil {
return domain.Room{}, err
Comment on lines +46 to +51
func (r *FacultyRepository) Create(ctx context.Context, faculty domain.Faculty) (domain.Faculty, error) {
// TODO: faculty.ID が空の場合に uuid.New().String() で採番する(空のまま渡すと primary key 制約違反で INSERT 失敗)
dbFaculty := database.FacultyFromDomain(faculty)
if err := r.db.WithContext(ctx).Create(&dbFaculty).Error; err != nil {
return domain.Faculty{}, err
}
@@ -0,0 +1,82 @@
package database
Base automatically changed from feat/b-shared-go to main May 10, 2026 04:25
@kantacky kantacky merged commit e8e3644 into main May 10, 2026
4 checks passed
@kantacky kantacky deleted the feat/c-academic-api branch May 10, 2026 04:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants