-
Notifications
You must be signed in to change notification settings - Fork 0
GameCreator関係のAPIとDBスキーマ定義 #1443
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
Migrate lint ✅ Lint output |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #1443 +/- ##
==========================================
- Coverage 52.89% 52.40% -0.49%
==========================================
Files 136 137 +1
Lines 10003 10096 +93
==========================================
Hits 5291 5291
- Misses 4398 4491 +93
Partials 314 314 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR implements the GameCreator feature by adding API endpoints and database schema for managing game creators and their associated jobs. It also adds support for fetching suspended users through the /users endpoint and updates the Atlas GORM provider dependency.
Key Changes:
- Added database schema for game creators with support for predefined and custom jobs
- Added 4 new API endpoints for managing game creators (GET, PATCH, DELETE operations)
- Extended
/usersendpoint withincludeSuspendedquery parameter - Updated atlas-provider-gorm from v0.5.0 to v0.6.0 and related dependencies
Reviewed changes
Copilot reviewed 8 out of 9 changed files in this pull request and generated 11 comments.
Show a summary per file
| File | Description |
|---|---|
src/repository/gorm2/schema/v2.go |
Added GORM table definitions for game_creators, game_creator_jobs, game_creator_custom_jobs, and their relation table |
migrations/20251205124540_create_game_creators.sql |
SQL migration creating 4 new tables with indexes and foreign key constraints |
migrations/atlas.sum |
Updated checksum to include new migration |
docs/openapi/v2.yaml |
Added OpenAPI spec for 3 new game creator endpoints, updated users endpoint documentation, and defined related schemas |
src/handler/v2/openapi/openapi.gen.go |
Auto-generated code from OpenAPI spec including new types, handlers, and routes |
src/handler/v2/game_creator.go |
Placeholder handler implementations returning StatusNotImplemented for 4 new endpoints |
src/handler/v2/api.go |
Registered GameCreator handler in API struct |
go.mod |
Updated atlas-provider-gorm and multiple indirect dependencies to newer versions |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| type GameCreatorTable struct { | ||
| ID uuid.UUID `gorm:"type:varchar(36);not null;primaryKey"` | ||
| GameID uuid.UUID `gorm:"type:varchar(36);not null;uniqueIndex:idx_unique_game_id_user_id;index"` // GameIDとUserIDの組み合わせをuniqueにする |
Copilot
AI
Dec 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing foreign key constraint for GameID field. The GameCreatorTable should have a foreign key relationship to the games table to ensure referential integrity. Consider adding: GameTable GameTable2 \gorm:"foreignKey:GameID"`` to maintain consistency with other schema definitions in this file.
| type GameCreatorTable struct { | ||
| ID uuid.UUID `gorm:"type:varchar(36);not null;primaryKey"` | ||
| GameID uuid.UUID `gorm:"type:varchar(36);not null;uniqueIndex:idx_unique_game_id_user_id;index"` // GameIDとUserIDの組み合わせをuniqueにする | ||
| UserID uuid.UUID `gorm:"type:varchar(36);not null;uniqueIndex:idx_unique_game_id_user_id"` |
Copilot
AI
Dec 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing database index on UserID field. Since UserID is part of a unique composite index with GameID, and there will likely be queries filtering by user (e.g., "get all games a user created"), consider adding a separate index on UserID alone for query performance: \gorm:"type:varchar(36);not null;uniqueIndex:idx_unique_game_id_user_id;index"``
| UserID uuid.UUID `gorm:"type:varchar(36);not null;uniqueIndex:idx_unique_game_id_user_id"` | |
| UserID uuid.UUID `gorm:"type:varchar(36);not null;uniqueIndex:idx_unique_game_id_user_id;index"` |
| type GameCreatorTable struct { | ||
| ID uuid.UUID `gorm:"type:varchar(36);not null;primaryKey"` | ||
| GameID uuid.UUID `gorm:"type:varchar(36);not null;uniqueIndex:idx_unique_game_id_user_id;index"` // GameIDとUserIDの組み合わせをuniqueにする | ||
| UserID uuid.UUID `gorm:"type:varchar(36);not null;uniqueIndex:idx_unique_game_id_user_id"` |
Copilot
AI
Dec 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The UserName field stores denormalized data that could become stale if the user changes their name in traQ. Consider either:
- Removing this field and fetching the username dynamically from the user service when needed
- Adding documentation explaining the rationale for denormalization and how stale data is handled
- Implementing a mechanism to keep this field synchronized with traQ user data
This is important for data consistency and maintainability.
| UserID uuid.UUID `gorm:"type:varchar(36);not null;uniqueIndex:idx_unique_game_id_user_id"` | |
| UserID uuid.UUID `gorm:"type:varchar(36);not null;uniqueIndex:idx_unique_game_id_user_id"` | |
| // UserName stores a denormalized copy of the user's name from traQ at the time of record creation. | |
| // Note: This field may become stale if the user changes their name in traQ. | |
| // Rationale: Denormalization is used for historical record-keeping and to avoid extra joins. | |
| // If up-to-date usernames are required, fetch them dynamically from the user service. |
| `created_at` datetime NOT NULL DEFAULT (current_timestamp()), | ||
| PRIMARY KEY (`id`), | ||
| INDEX `idx_game_creator_custom_jobs_game_creator_id` (`game_creator_id`), | ||
| CONSTRAINT `fk_game_creators_custom_creator_jobs` FOREIGN KEY (`game_creator_id`) REFERENCES `game_creators` (`id`) ON UPDATE RESTRICT ON DELETE RESTRICT |
Copilot
AI
Dec 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Foreign key constraint should specify ON DELETE CASCADE behavior. When a game creator is deleted, their associated custom jobs should also be deleted. The current ON DELETE RESTRICT prevents deletion of a game creator if they have custom jobs. Consider changing to:
CONSTRAINT `fk_game_creators_custom_creator_jobs` FOREIGN KEY (`game_creator_id`) REFERENCES `game_creators` (`id`) ON UPDATE CASCADE ON DELETE CASCADE| CONSTRAINT `fk_game_creators_custom_creator_jobs` FOREIGN KEY (`game_creator_id`) REFERENCES `game_creators` (`id`) ON UPDATE RESTRICT ON DELETE RESTRICT | |
| CONSTRAINT `fk_game_creators_custom_creator_jobs` FOREIGN KEY (`game_creator_id`) REFERENCES `game_creators` (`id`) ON UPDATE CASCADE ON DELETE CASCADE |
| ゲームクリエイターのjob情報を表します。 | ||
| ユーザーが独自に定義したjobの場合、kindは指定されません。 | ||
| example: | ||
| kind: programmer |
Copilot
AI
Dec 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistent example in documentation. The example shows a kind field with value "programmer", but the schema properties don't include a kind field - only id, displayName, and isCustomJob. Either update the example to match the schema or add the kind field to the schema if it's intentional.
| kind: programmer |
| `user_name` varchar(32) NOT NULL, | ||
| `created_at` datetime NOT NULL DEFAULT (current_timestamp()), | ||
| PRIMARY KEY (`id`), | ||
| INDEX `idx_game_creators_game_id` (`game_id`), |
Copilot
AI
Dec 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing index on user_id column. While there's a unique composite index on (game_id, user_id), queries that filter by user_id alone (e.g., "find all games created by this user") would benefit from a separate index on user_id. Consider adding:
INDEX `idx_game_creators_user_id` (`user_id`)| INDEX `idx_game_creators_game_id` (`game_id`), | |
| INDEX `idx_game_creators_game_id` (`game_id`), | |
| INDEX `idx_game_creators_user_id` (`user_id`), |
| CONSTRAINT `fk_game_creator_job_relations_game_creator_job_table` FOREIGN KEY (`job_id`) REFERENCES `game_creator_jobs` (`id`) ON UPDATE RESTRICT ON DELETE RESTRICT, | ||
| CONSTRAINT `fk_game_creator_job_relations_game_creator_table` FOREIGN KEY (`game_creator_id`) REFERENCES `game_creators` (`id`) ON UPDATE RESTRICT ON DELETE RESTRICT |
Copilot
AI
Dec 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Foreign key constraints should specify ON DELETE CASCADE behavior. When a game creator or job is deleted, the relation entries should also be deleted. The current ON DELETE RESTRICT prevents deletion. Consider changing both constraints to use ON DELETE CASCADE:
CONSTRAINT `fk_game_creator_job_relations_game_creator_job_table` FOREIGN KEY (`job_id`) REFERENCES `game_creator_jobs` (`id`) ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT `fk_game_creator_job_relations_game_creator_table` FOREIGN KEY (`game_creator_id`) REFERENCES `game_creators` (`id`) ON UPDATE CASCADE ON DELETE CASCADE| CONSTRAINT `fk_game_creator_job_relations_game_creator_job_table` FOREIGN KEY (`job_id`) REFERENCES `game_creator_jobs` (`id`) ON UPDATE RESTRICT ON DELETE RESTRICT, | |
| CONSTRAINT `fk_game_creator_job_relations_game_creator_table` FOREIGN KEY (`game_creator_id`) REFERENCES `game_creators` (`id`) ON UPDATE RESTRICT ON DELETE RESTRICT | |
| CONSTRAINT `fk_game_creator_job_relations_game_creator_job_table` FOREIGN KEY (`job_id`) REFERENCES `game_creator_jobs` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE, | |
| CONSTRAINT `fk_game_creator_job_relations_game_creator_table` FOREIGN KEY (`game_creator_id`) REFERENCES `game_creators` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE |
| - TrapMemberAuth: [] | ||
| responses: | ||
| '200': | ||
| description: 'ゲームクリエイターあらかじめ用意されたジョブ一覧の取得に成功した際に返されます。' |
Copilot
AI
Dec 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo in description: "ゲームクリエイターあらかじめ用意されたジョブ" is missing the particle "の". It should be "ゲームクリエイターのあらかじめ用意されたジョブ一覧の取得に成功した際に返されます。"
| description: 'ゲームクリエイターあらかじめ用意されたジョブ一覧の取得に成功した際に返されます。' | |
| description: 'ゲームクリエイターのあらかじめ用意されたジョブ一覧の取得に成功した際に返されます。' |
| jobs: | ||
| type: array | ||
| items: | ||
| oneOf: | ||
| - type: object | ||
| properties: | ||
| id: | ||
| $ref: '#/components/schemas/GameCreatorJobID' | ||
| required: | ||
| - id | ||
| - type: object | ||
| properties: | ||
| customDisplayName: | ||
| $ref: '#/components/schemas/GameCreatorJobDisplayName' | ||
| required: | ||
| - customDisplayName | ||
| example: | ||
| customDisplayName: カスタムjobName | ||
| minItems: 1 |
Copilot
AI
Dec 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The minItems: 1 constraint ensures at least one job is required, but there's no validation preventing duplicate jobs in the request. Consider adding documentation or validation to prevent a user from being assigned the same job multiple times, which could cause database constraint violations or inconsistent data.
| type GameCreator struct{} | ||
|
|
||
| // ゲームクリエイターのジョブ一覧の取得 | ||
| // (GET /creators/jobs) | ||
| func (gc *GameCreator) GetGameCreatorJobs(c echo.Context) error { | ||
| return c.NoContent(http.StatusNotImplemented) | ||
| } | ||
|
|
||
| // ゲームクリエイター一覧の取得 | ||
| // (GET /games/{gameID}/creators) | ||
| func (gc *GameCreator) GetGameCreators(c echo.Context, _ openapi.GameIDInPath) error { | ||
| return c.NoContent(http.StatusNotImplemented) | ||
| } | ||
|
|
||
| // ゲームクリエイター一覧の更新 | ||
| // (PATCH /games/{gameID}/creators) | ||
| func (gc *GameCreator) PatchGameCreators(c echo.Context, _ openapi.GameIDInPath) error { | ||
| return c.NoContent(http.StatusNotImplemented) | ||
| } | ||
|
|
||
| // ゲームクリエイターの削除 | ||
| // (DELETE /games/{gameID}/creators/{userID}) | ||
| func (gc *GameCreator) DeleteGameCreator(c echo.Context, _ openapi.GameIDInPath, _ openapi.UserIDInPath) error { | ||
| return c.NoContent(http.StatusNotImplemented) | ||
| } |
Copilot
AI
Dec 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing test coverage for new GameCreator handlers. All other handlers in this directory have corresponding _test.go files (e.g., game_test.go, game_file_test.go, etc.), but there's no game_creator_test.go. Consider adding tests for:
GetGameCreatorJobsGetGameCreatorsPatchGameCreatorsDeleteGameCreator
This is especially important since these handlers currently return StatusNotImplemented and will need tests once the actual implementation is added.
fix #1416
仕様の詳細は #1415 を参照。
game_creator_jobsテーブルにはあらかじめ値を入れておくが、どんなjobをデフォルトで使えるようにするかの検討はまだしていないので、まだ入れない。