Skip to content

Commit

Permalink
Merge pull request #61 from su-its/fix/api/v1/post-score
Browse files Browse the repository at this point in the history
Fix/api/v1/post-score
  • Loading branch information
KinjiKawaguchi authored Apr 3, 2024
2 parents ca0e2f6 + b942040 commit 87526de
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 32 deletions.
26 changes: 12 additions & 14 deletions typing-server/api/handler/score.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,28 +46,26 @@ func GetScoresRanking(w http.ResponseWriter, r *http.Request) {
func PostScore(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()

userIDStr := r.URL.Query().Get("user_id")
userID, err := uuid.Parse(userIDStr)
if err != nil {
http.Error(w, "Invalid user_id", http.StatusBadRequest)
return
// リクエストボディから値を取得
var requestBody struct {
UserID string `json:"user_id"`
Keystrokes int `json:"keystrokes"`
Accuracy float64 `json:"accuracy"`
}

keystrokesStr := r.URL.Query().Get("keystrokes")
keystrokes, err := strconv.Atoi(keystrokesStr)
if err != nil {
http.Error(w, "Invalid keystrokes", http.StatusBadRequest)
if err := json.NewDecoder(r.Body).Decode(&requestBody); err != nil {
http.Error(w, "Invalid request body", http.StatusBadRequest)
return
}

accuracyStr := r.URL.Query().Get("accuracy")
accuracy, err := strconv.ParseFloat(accuracyStr, 64)
// user_idをUUIDに変換
userID, err := uuid.Parse(requestBody.UserID)
if err != nil {
http.Error(w, "Invalid accuracy", http.StatusBadRequest)
http.Error(w, "Invalid user_id", http.StatusBadRequest)
return
}

if err := service.CreateScore(ctx, entClient, userID, keystrokes, accuracy); err != nil {
// スコアを作成
if err := service.CreateScore(ctx, entClient, userID, requestBody.Keystrokes, requestBody.Accuracy); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
Expand Down
78 changes: 60 additions & 18 deletions typing-server/api/repository/score.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package repository

import (
"context"
"database/sql"
"fmt"

"github.com/google/uuid"
Expand Down Expand Up @@ -90,10 +91,27 @@ func GetScoresRanking(ctx context.Context, client *ent.Client, sortBy string, st

return rankings, nil
}

func CreateScore(ctx context.Context, client *ent.Client, userID uuid.UUID, keystrokes int, accuracy float64) error {
// Create a new score
createdScore, err := client.Score.Create().
// トランザクションを開始
tx, err := client.Tx(ctx)
if err != nil {
return err
}
defer func() {
// txがコミット済みの場合はロールバックしない
if tx == nil {
return
}
if err := tx.Rollback(); err != nil {
if err != sql.ErrTxDone {
return
}
return
}
}()

// 新しいスコアを作成
createdScore, err := tx.Score.Create().
SetKeystrokes(keystrokes).
SetAccuracy(accuracy).
SetUserID(userID).
Expand All @@ -102,46 +120,70 @@ func CreateScore(ctx context.Context, client *ent.Client, userID uuid.UUID, keys
return err
}

// キーストロークと精度のチェック
if keystrokes < 120 || accuracy < 0.95 {
return nil
return tx.Commit()
}

// Get the user
user, err := client.User.Query().Where(user.ID(userID)).Only(ctx)
// ユーザーを取得
user, err := tx.User.Query().Where(user.ID(userID)).Only(ctx)
if err != nil {
return err
}

// Check if the new score has the maximum keystrokes
// 最大キーストロークと最大精度のスコアを取得
maxKeystrokeScore, maxAccuracyScore, err := getMaxScores(ctx, user)
if err != nil {
return err
}

// 以前の最大スコアのフラグを更新
err = updateMaxScoreFlags(ctx, maxKeystrokeScore, maxAccuracyScore, createdScore)
if err != nil {
return err
}

// トランザクションをコミット
return tx.Commit()
}

func getMaxScores(ctx context.Context, user *ent.User) (*ent.Score, *ent.Score, error) {
// 最大キーストロークのスコアを取得
maxKeystrokeScore, err := user.QueryScores().Where(score.IsMaxKeystrokes(true)).Only(ctx)
if err != nil && !ent.IsNotFound(err) {
return err
return nil, nil, err
}
isMaxKeystrokes := maxKeystrokeScore == nil || createdScore.Keystrokes >= maxKeystrokeScore.Keystrokes

// Check if the new score has the maximum accuracy
// 最大精度のスコアを取得
maxAccuracyScore, err := user.QueryScores().Where(score.IsMaxAccuracy(true)).Only(ctx)
if err != nil && !ent.IsNotFound(err) {
return err
return nil, nil, err
}

return maxKeystrokeScore, maxAccuracyScore, nil
}

func updateMaxScoreFlags(ctx context.Context, maxKeystrokeScore, maxAccuracyScore, createdScore *ent.Score) error {
isMaxKeystrokes := maxKeystrokeScore == nil || createdScore.Keystrokes >= maxKeystrokeScore.Keystrokes
isMaxAccuracy := maxAccuracyScore == nil || createdScore.Accuracy >= maxAccuracyScore.Accuracy

// Update the flags of the previous maximum scores
if maxKeystrokeScore != nil && !isMaxKeystrokes {
err = maxKeystrokeScore.Update().SetIsMaxKeystrokes(false).Exec(ctx)
// 以前の最大スコアのフラグを更新
if maxKeystrokeScore != nil && isMaxKeystrokes {
err := maxKeystrokeScore.Update().SetIsMaxKeystrokes(false).Exec(ctx)
if err != nil {
return err
}
}
if maxAccuracyScore != nil && !isMaxAccuracy {
err = maxAccuracyScore.Update().SetIsMaxAccuracy(false).Exec(ctx)

if maxAccuracyScore != nil && isMaxAccuracy {
err := maxAccuracyScore.Update().SetIsMaxAccuracy(false).Exec(ctx)
if err != nil {
return err
}
}

// Update the score with the maximum flags
err = createdScore.Update().
// 作成したスコアの最大フラグを更新
err := createdScore.Update().
SetIsMaxKeystrokes(isMaxKeystrokes).
SetIsMaxAccuracy(isMaxAccuracy).
Exec(ctx)
Expand Down

0 comments on commit 87526de

Please sign in to comment.