From ec1ff5f25a745ee67594b80f25cdd1b8706f973f Mon Sep 17 00:00:00 2001 From: TT-RR Date: Sat, 23 Sep 2023 11:07:10 +0900 Subject: [PATCH 1/2] =?UTF-8?q?=E4=BA=88=E7=B4=84=E7=A2=BA=E5=AE=9A?= =?UTF-8?q?=E6=A9=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- entity/event.go | 32 +++++++++++++++++++------------- repository/event.go | 18 ++++++++++++++++++ usecase/event.go | 13 +++++++++++++ 3 files changed, 50 insertions(+), 13 deletions(-) diff --git a/entity/event.go b/entity/event.go index 5201e9b..ee8233d 100644 --- a/entity/event.go +++ b/entity/event.go @@ -7,21 +7,27 @@ import ( ) type Event struct { - ID ulid.ULID `json:"id"` - OwnerID ulid.ULID `json:"ownerId"` - Name string `json:"name"` - Description string `json:"description"` - DurationAbout string `json:"durationAbout"` - UnitSeconds int `json:"unitSeconds"` - Units []EventTimeUnit `json:"units"` - UserAnswers []UserEventAnswer `json:"userAnswers"` + ID ulid.ULID `json:"id"` + OwnerID ulid.ULID `json:"ownerId"` + Name string `json:"name"` + Description string `json:"description"` + DurationAbout string `json:"durationAbout"` + UnitSeconds int `json:"unitSeconds"` + Units []EventTimeUnit `json:"units"` + UserAnswers []UserEventAnswer `json:"userAnswers"` + NotifyByEmail bool `json:"notifyByEmail"` + NumberOfParticipants int `json:"numberOfParticipants"` + ConfirmationEmail string `json:"confirmationEmail"` } type EventRequest struct { - Name string `json:"name"` - Description string `json:"description"` - DurationAbout string `json:"durationAbout"` - UnitSeconds int `json:"unitDuration"` - Units []EventTimeUnitRequest `json:"units"` + Name string `json:"name"` + Description string `json:"description"` + DurationAbout string `json:"durationAbout"` + UnitSeconds int `json:"unitDuration"` + Units []EventTimeUnitRequest `json:"units"` + NotifyByEmail bool `json:"notifyByEmail"` + NumberOfParticipants int `json:"numberOfParticipants"` + ConfirmationEmail string `json:"confirmationEmail"` } type EventResponse struct { ID string `json:"id"` diff --git a/repository/event.go b/repository/event.go index e0c718e..058a365 100644 --- a/repository/event.go +++ b/repository/event.go @@ -28,6 +28,8 @@ type EventRepository interface { FetchEventTimeUnits(ctx context.Context, tx *sql.Tx, eventId ulid.ULID) ([]entity.EventTimeUnit, error) // イベントの全ユーザー回答(Unit付き)を取得する FetchEventAnswersWithUnits(ctx context.Context, tx *sql.Tx, eventId ulid.ULID) ([]entity.UserEventAnswer, error) + // 回答したユーザーの数を取得する + FetchUserAnswerCount(ctx context.Context, tx *sql.Tx, eventId ulid.ULID) (int, error) // イベントの指定ユーザー回答(Unit無し)を取得する FetchEventAnswer(ctx context.Context, tx *sql.Tx, eventId ulid.ULID, userId ulid.ULID) (entity.UserEventAnswer, error) @@ -259,6 +261,22 @@ func (er *eventRepository) FetchEventAnswer(ctx context.Context, tx *sql.Tx, eve }, nil } +// FetchUserAnswerCount implements EventRepository. +func (er *eventRepository) FetchUserAnswerCount(ctx context.Context, tx *sql.Tx, eventId ulid.ULID) (int, error) { + var exc boil.ContextExecutor = tx + if tx == nil { + exc = er.db + } + + count, err := models.UserEventAnswers( + models.UserEventAnswerWhere.EventID.EQ(util.ULIDToString(eventId)), + ).Count(ctx, exc) + if err != nil { + return 0, err + } + return int(count), nil +} + // UpdateEventAnswer implements EventRepository. func (er *eventRepository) UpdateEventAnswer(ctx context.Context, tx *sql.Tx, answer entity.UserEventAnswer) (entity.UserEventAnswer, error) { var exc boil.ContextExecutor = tx diff --git a/usecase/event.go b/usecase/event.go index f539c9a..51fc46e 100644 --- a/usecase/event.go +++ b/usecase/event.go @@ -11,6 +11,7 @@ import ( "github.com/geekcamp-vol11-team30/backend/apperror" "github.com/geekcamp-vol11-team30/backend/entity" "github.com/geekcamp-vol11-team30/backend/repository" + "github.com/geekcamp-vol11-team30/backend/util" "github.com/oklog/ulid/v2" "github.com/volatiletech/sqlboiler/v4/boil" ) @@ -156,6 +157,18 @@ func (eu *eventUsecase) CreateUserAnswer(ctx context.Context, eventId ulid.ULID, } newAnswer.Units = ansUnits + // メールの通知を希望するなら + if event.NotifyByEmail { + // ユーザーの回答数を数える + userAnswerCount, err := eu.er.FetchUserAnswerCount(ctx, tx, eventId) + if userAnswerCount != event.NumberOfParticipants { + util.SendMail(event.ConfirmationEmail, "マジスケ", "イベント参加者が集まりました") + if err != nil { + return entity.UserEventAnswer{}, apperror.NewUnknownError(fmt.Errorf("failed to send confirmation email: %w", err), nil) + } + } + } + // commit! err = tx.Commit() if err != nil { From 085b24d65a076192cef53c8eb8eb3f33c1603411 Mon Sep 17 00:00:00 2001 From: Takuya Takahashi Date: Sat, 23 Sep 2023 14:04:43 +0900 Subject: [PATCH 2/2] fix --- controller/event.go | 13 +- db/migrations/20230923042107_add_email.sql | 15 ++ entity/event.go | 12 +- main.go | 7 +- repository/event.go | 15 +- .../internal/converter/event_converter.go | 19 +- repository/internal/models/event.go | 171 ++++++++++++------ .../internal/models/goose_db_version.go | 9 - usecase/event.go | 47 +++-- util/util.go | 1 + 10 files changed, 197 insertions(+), 112 deletions(-) create mode 100644 db/migrations/20230923042107_add_email.sql diff --git a/controller/event.go b/controller/event.go index 4ea50af..b58c77e 100644 --- a/controller/event.go +++ b/controller/event.go @@ -164,11 +164,14 @@ func eventRequestToEvent(er entity.EventRequest) entity.Event { } } return entity.Event{ - Name: er.Name, - Description: er.Description, - DurationAbout: er.DurationAbout, - UnitSeconds: er.UnitSeconds, - Units: units, + Name: er.Name, + Description: er.Description, + DurationAbout: er.DurationAbout, + UnitSeconds: er.UnitSeconds, + Units: units, + NotifyByEmail: er.NotifyByEmail, + NumberOfParticipants: er.NumberOfParticipants, + ConfirmationEmail: er.ConfirmationEmail, } } diff --git a/db/migrations/20230923042107_add_email.sql b/db/migrations/20230923042107_add_email.sql new file mode 100644 index 0000000..d67e661 --- /dev/null +++ b/db/migrations/20230923042107_add_email.sql @@ -0,0 +1,15 @@ +-- +goose Up +-- +goose StatementBegin +SELECT 'up SQL query'; +ALTER TABLE `event` +ADD COLUMN `enables_email_notification` BOOLEAN NOT NULL DEFAULT FALSE, + ADD COLUMN `expected_participants_number` INT NOT NULL DEFAULT 0, + ADD COLUMN `notification_email` VARCHAR(255) NOT NULL DEFAULT ''; +-- +goose StatementEnd +-- +goose Down +-- +goose StatementBegin +SELECT 'down SQL query'; +ALTER TABLE `event` DROP COLUMN `enables_email_notification`, + DROP COLUMN `expected_participants_number`, + DROP COLUMN `notification_email`; +-- +goose StatementEnd diff --git a/entity/event.go b/entity/event.go index ee8233d..bd0ac7b 100644 --- a/entity/event.go +++ b/entity/event.go @@ -15,9 +15,9 @@ type Event struct { UnitSeconds int `json:"unitSeconds"` Units []EventTimeUnit `json:"units"` UserAnswers []UserEventAnswer `json:"userAnswers"` - NotifyByEmail bool `json:"notifyByEmail"` - NumberOfParticipants int `json:"numberOfParticipants"` - ConfirmationEmail string `json:"confirmationEmail"` + NotifyByEmail bool `json:"enablesEmailNotification"` + NumberOfParticipants int `json:"expectedParticipantsNumber"` + ConfirmationEmail string `json:"notificationEmail"` } type EventRequest struct { Name string `json:"name"` @@ -25,9 +25,9 @@ type EventRequest struct { DurationAbout string `json:"durationAbout"` UnitSeconds int `json:"unitDuration"` Units []EventTimeUnitRequest `json:"units"` - NotifyByEmail bool `json:"notifyByEmail"` - NumberOfParticipants int `json:"numberOfParticipants"` - ConfirmationEmail string `json:"confirmationEmail"` + NotifyByEmail bool `json:"enablesEmailNotification"` + NumberOfParticipants int `json:"expectedParticipantsNumber"` + ConfirmationEmail string `json:"notificationEmail"` } type EventResponse struct { ID string `json:"id"` diff --git a/main.go b/main.go index 07f174f..c54e40e 100644 --- a/main.go +++ b/main.go @@ -13,7 +13,6 @@ import ( "github.com/geekcamp-vol11-team30/backend/router" "github.com/geekcamp-vol11-team30/backend/service" "github.com/geekcamp-vol11-team30/backend/usecase" - "github.com/geekcamp-vol11-team30/backend/util" "github.com/geekcamp-vol11-team30/backend/validator" _ "github.com/go-sql-driver/mysql" "github.com/volatiletech/sqlboiler/v4/boil" @@ -53,7 +52,7 @@ func run(ctx context.Context, logger *zap.Logger) error { uv := validator.NewUserValidator() uu := usecase.NewUserUsecase(ur, oar, er, uv, gs, ms) au := usecase.NewAuthUsecase(cfg, logger, ar) - eu := usecase.NewEventUsecase(er) + eu := usecase.NewEventUsecase(cfg, er) oau := usecase.NewOauthUsecase(cfg, oar, ur, gs, ms, uu) em := middleware.NewErrorMiddleware(logger, uu) @@ -69,8 +68,8 @@ func run(ctx context.Context, logger *zap.Logger) error { if err != nil { logger.Fatal("failed to listen port", zap.Error(err)) } - err = util.SendMail(*cfg, "tak848.0428771@gmail.com", "konnitiha", "hello") - fmt.Println(err) + // err = util.SendMail(*cfg, "tak848.0428771@gmail.com", "konnitiha", "hello") + // fmt.Println(err) e := router.NewRouter(cfg, logger, em, atm, am, uc, ac, ec, oc) s := NewServer(e, l, logger) diff --git a/repository/event.go b/repository/event.go index 4bbe7c0..892df98 100644 --- a/repository/event.go +++ b/repository/event.go @@ -68,12 +68,15 @@ func (er *eventRepository) CreateEvent(ctx context.Context, tx *sql.Tx, event en id := util.GenerateULID(ctx) e := &models.Event{ - ID: util.ULIDToString(id), - OwnerID: util.ULIDToString(event.OwnerID), - Name: event.Name, - Description: event.Description, - DurationAbout: event.DurationAbout, - UnitSeconds: uint64(event.UnitSeconds), + ID: util.ULIDToString(id), + OwnerID: util.ULIDToString(event.OwnerID), + Name: event.Name, + Description: event.Description, + DurationAbout: event.DurationAbout, + UnitSeconds: uint64(event.UnitSeconds), + EnablesEmailNotification: event.NotifyByEmail, + ExpectedParticipantsNumber: event.NumberOfParticipants, + NotificationEmail: event.ConfirmationEmail, } err := e.Insert(ctx, exc, boil.Infer()) if err != nil { diff --git a/repository/internal/converter/event_converter.go b/repository/internal/converter/event_converter.go index bd911b6..52e88c6 100644 --- a/repository/internal/converter/event_converter.go +++ b/repository/internal/converter/event_converter.go @@ -19,13 +19,16 @@ func EventModelToEntity(ctx context.Context, em *models.Event, units []entity.Ev return entity.Event{}, fmt.Errorf("failed to parse ULID(%s): %w", em.OwnerID, err) } return entity.Event{ - ID: id, - OwnerID: ownerId, - Name: em.Name, - Description: em.Description, - DurationAbout: em.DurationAbout, - UnitSeconds: int(em.UnitSeconds), - Units: units, - UserAnswers: userAnswers, + ID: id, + OwnerID: ownerId, + Name: em.Name, + Description: em.Description, + DurationAbout: em.DurationAbout, + UnitSeconds: int(em.UnitSeconds), + Units: units, + UserAnswers: userAnswers, + NotifyByEmail: em.EnablesEmailNotification, + NumberOfParticipants: em.ExpectedParticipantsNumber, + ConfirmationEmail: em.NotificationEmail, }, nil } diff --git a/repository/internal/models/event.go b/repository/internal/models/event.go index 4f82eaa..944e605 100644 --- a/repository/internal/models/event.go +++ b/repository/internal/models/event.go @@ -23,57 +23,72 @@ import ( // Event is an object representing the database table. type Event struct { - ID string `boil:"id" json:"id" toml:"id" yaml:"id"` - OwnerID string `boil:"owner_id" json:"owner_id" toml:"owner_id" yaml:"owner_id"` - Name string `boil:"name" json:"name" toml:"name" yaml:"name"` - Description string `boil:"description" json:"description" toml:"description" yaml:"description"` - DurationAbout string `boil:"duration_about" json:"duration_about" toml:"duration_about" yaml:"duration_about"` - UnitSeconds uint64 `boil:"unit_seconds" json:"unit_seconds" toml:"unit_seconds" yaml:"unit_seconds"` - CreatedAt time.Time `boil:"created_at" json:"created_at" toml:"created_at" yaml:"created_at"` - UpdatedAt time.Time `boil:"updated_at" json:"updated_at" toml:"updated_at" yaml:"updated_at"` + ID string `boil:"id" json:"id" toml:"id" yaml:"id"` + OwnerID string `boil:"owner_id" json:"owner_id" toml:"owner_id" yaml:"owner_id"` + Name string `boil:"name" json:"name" toml:"name" yaml:"name"` + Description string `boil:"description" json:"description" toml:"description" yaml:"description"` + DurationAbout string `boil:"duration_about" json:"duration_about" toml:"duration_about" yaml:"duration_about"` + UnitSeconds uint64 `boil:"unit_seconds" json:"unit_seconds" toml:"unit_seconds" yaml:"unit_seconds"` + CreatedAt time.Time `boil:"created_at" json:"created_at" toml:"created_at" yaml:"created_at"` + UpdatedAt time.Time `boil:"updated_at" json:"updated_at" toml:"updated_at" yaml:"updated_at"` + EnablesEmailNotification bool `boil:"enables_email_notification" json:"enables_email_notification" toml:"enables_email_notification" yaml:"enables_email_notification"` + ExpectedParticipantsNumber int `boil:"expected_participants_number" json:"expected_participants_number" toml:"expected_participants_number" yaml:"expected_participants_number"` + NotificationEmail string `boil:"notification_email" json:"notification_email" toml:"notification_email" yaml:"notification_email"` R *eventR `boil:"-" json:"-" toml:"-" yaml:"-"` L eventL `boil:"-" json:"-" toml:"-" yaml:"-"` } var EventColumns = struct { - ID string - OwnerID string - Name string - Description string - DurationAbout string - UnitSeconds string - CreatedAt string - UpdatedAt string + ID string + OwnerID string + Name string + Description string + DurationAbout string + UnitSeconds string + CreatedAt string + UpdatedAt string + EnablesEmailNotification string + ExpectedParticipantsNumber string + NotificationEmail string }{ - ID: "id", - OwnerID: "owner_id", - Name: "name", - Description: "description", - DurationAbout: "duration_about", - UnitSeconds: "unit_seconds", - CreatedAt: "created_at", - UpdatedAt: "updated_at", + ID: "id", + OwnerID: "owner_id", + Name: "name", + Description: "description", + DurationAbout: "duration_about", + UnitSeconds: "unit_seconds", + CreatedAt: "created_at", + UpdatedAt: "updated_at", + EnablesEmailNotification: "enables_email_notification", + ExpectedParticipantsNumber: "expected_participants_number", + NotificationEmail: "notification_email", } var EventTableColumns = struct { - ID string - OwnerID string - Name string - Description string - DurationAbout string - UnitSeconds string - CreatedAt string - UpdatedAt string + ID string + OwnerID string + Name string + Description string + DurationAbout string + UnitSeconds string + CreatedAt string + UpdatedAt string + EnablesEmailNotification string + ExpectedParticipantsNumber string + NotificationEmail string }{ - ID: "event.id", - OwnerID: "event.owner_id", - Name: "event.name", - Description: "event.description", - DurationAbout: "event.duration_about", - UnitSeconds: "event.unit_seconds", - CreatedAt: "event.created_at", - UpdatedAt: "event.updated_at", + ID: "event.id", + OwnerID: "event.owner_id", + Name: "event.name", + Description: "event.description", + DurationAbout: "event.duration_about", + UnitSeconds: "event.unit_seconds", + CreatedAt: "event.created_at", + UpdatedAt: "event.updated_at", + EnablesEmailNotification: "event.enables_email_notification", + ExpectedParticipantsNumber: "event.expected_participants_number", + NotificationEmail: "event.notification_email", } // Generated where @@ -147,24 +162,62 @@ func (w whereHelpertime_Time) GTE(x time.Time) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.GTE, x) } +type whereHelperbool struct{ field string } + +func (w whereHelperbool) EQ(x bool) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.EQ, x) } +func (w whereHelperbool) NEQ(x bool) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.NEQ, x) } +func (w whereHelperbool) LT(x bool) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.LT, x) } +func (w whereHelperbool) LTE(x bool) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.LTE, x) } +func (w whereHelperbool) GT(x bool) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.GT, x) } +func (w whereHelperbool) GTE(x bool) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.GTE, x) } + +type whereHelperint struct{ field string } + +func (w whereHelperint) EQ(x int) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.EQ, x) } +func (w whereHelperint) NEQ(x int) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.NEQ, x) } +func (w whereHelperint) LT(x int) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.LT, x) } +func (w whereHelperint) LTE(x int) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.LTE, x) } +func (w whereHelperint) GT(x int) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.GT, x) } +func (w whereHelperint) GTE(x int) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.GTE, x) } +func (w whereHelperint) IN(slice []int) qm.QueryMod { + values := make([]interface{}, 0, len(slice)) + for _, value := range slice { + values = append(values, value) + } + return qm.WhereIn(fmt.Sprintf("%s IN ?", w.field), values...) +} +func (w whereHelperint) NIN(slice []int) qm.QueryMod { + values := make([]interface{}, 0, len(slice)) + for _, value := range slice { + values = append(values, value) + } + return qm.WhereNotIn(fmt.Sprintf("%s NOT IN ?", w.field), values...) +} + var EventWhere = struct { - ID whereHelperstring - OwnerID whereHelperstring - Name whereHelperstring - Description whereHelperstring - DurationAbout whereHelperstring - UnitSeconds whereHelperuint64 - CreatedAt whereHelpertime_Time - UpdatedAt whereHelpertime_Time + ID whereHelperstring + OwnerID whereHelperstring + Name whereHelperstring + Description whereHelperstring + DurationAbout whereHelperstring + UnitSeconds whereHelperuint64 + CreatedAt whereHelpertime_Time + UpdatedAt whereHelpertime_Time + EnablesEmailNotification whereHelperbool + ExpectedParticipantsNumber whereHelperint + NotificationEmail whereHelperstring }{ - ID: whereHelperstring{field: "`event`.`id`"}, - OwnerID: whereHelperstring{field: "`event`.`owner_id`"}, - Name: whereHelperstring{field: "`event`.`name`"}, - Description: whereHelperstring{field: "`event`.`description`"}, - DurationAbout: whereHelperstring{field: "`event`.`duration_about`"}, - UnitSeconds: whereHelperuint64{field: "`event`.`unit_seconds`"}, - CreatedAt: whereHelpertime_Time{field: "`event`.`created_at`"}, - UpdatedAt: whereHelpertime_Time{field: "`event`.`updated_at`"}, + ID: whereHelperstring{field: "`event`.`id`"}, + OwnerID: whereHelperstring{field: "`event`.`owner_id`"}, + Name: whereHelperstring{field: "`event`.`name`"}, + Description: whereHelperstring{field: "`event`.`description`"}, + DurationAbout: whereHelperstring{field: "`event`.`duration_about`"}, + UnitSeconds: whereHelperuint64{field: "`event`.`unit_seconds`"}, + CreatedAt: whereHelpertime_Time{field: "`event`.`created_at`"}, + UpdatedAt: whereHelpertime_Time{field: "`event`.`updated_at`"}, + EnablesEmailNotification: whereHelperbool{field: "`event`.`enables_email_notification`"}, + ExpectedParticipantsNumber: whereHelperint{field: "`event`.`expected_participants_number`"}, + NotificationEmail: whereHelperstring{field: "`event`.`notification_email`"}, } // EventRels is where relationship names are stored. @@ -215,9 +268,9 @@ func (r *eventR) GetUserEventAnswers() UserEventAnswerSlice { type eventL struct{} var ( - eventAllColumns = []string{"id", "owner_id", "name", "description", "duration_about", "unit_seconds", "created_at", "updated_at"} - eventColumnsWithoutDefault = []string{"id", "owner_id", "name", "description", "duration_about", "unit_seconds"} - eventColumnsWithDefault = []string{"created_at", "updated_at"} + eventAllColumns = []string{"id", "owner_id", "name", "description", "duration_about", "unit_seconds", "created_at", "updated_at", "enables_email_notification", "expected_participants_number", "notification_email"} + eventColumnsWithoutDefault = []string{"id", "owner_id", "name", "description", "duration_about", "unit_seconds", "notification_email"} + eventColumnsWithDefault = []string{"created_at", "updated_at", "enables_email_notification", "expected_participants_number"} eventPrimaryKeyColumns = []string{"id"} eventGeneratedColumns = []string{} ) diff --git a/repository/internal/models/goose_db_version.go b/repository/internal/models/goose_db_version.go index 5e8c507..90c2526 100644 --- a/repository/internal/models/goose_db_version.go +++ b/repository/internal/models/goose_db_version.go @@ -82,15 +82,6 @@ func (w whereHelperint64) NIN(slice []int64) qm.QueryMod { return qm.WhereNotIn(fmt.Sprintf("%s NOT IN ?", w.field), values...) } -type whereHelperbool struct{ field string } - -func (w whereHelperbool) EQ(x bool) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.EQ, x) } -func (w whereHelperbool) NEQ(x bool) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.NEQ, x) } -func (w whereHelperbool) LT(x bool) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.LT, x) } -func (w whereHelperbool) LTE(x bool) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.LTE, x) } -func (w whereHelperbool) GT(x bool) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.GT, x) } -func (w whereHelperbool) GTE(x bool) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.GTE, x) } - type whereHelpernull_Time struct{ field string } func (w whereHelpernull_Time) EQ(x null.Time) qm.QueryMod { diff --git a/usecase/event.go b/usecase/event.go index 51fc46e..06d2ac7 100644 --- a/usecase/event.go +++ b/usecase/event.go @@ -9,6 +9,7 @@ import ( "time" "github.com/geekcamp-vol11-team30/backend/apperror" + "github.com/geekcamp-vol11-team30/backend/config" "github.com/geekcamp-vol11-team30/backend/entity" "github.com/geekcamp-vol11-team30/backend/repository" "github.com/geekcamp-vol11-team30/backend/util" @@ -30,13 +31,15 @@ type EventUsecase interface { } type eventUsecase struct { - er repository.EventRepository + cfg *config.Config + er repository.EventRepository // uv validator.UserValidator } -func NewEventUsecase(er repository.EventRepository) EventUsecase { +func NewEventUsecase(cfg *config.Config, er repository.EventRepository) EventUsecase { return &eventUsecase{ - er: er, + cfg: cfg, + er: er, // uv: uv, } } @@ -157,24 +160,38 @@ func (eu *eventUsecase) CreateUserAnswer(ctx context.Context, eventId ulid.ULID, } newAnswer.Units = ansUnits - // メールの通知を希望するなら - if event.NotifyByEmail { - // ユーザーの回答数を数える - userAnswerCount, err := eu.er.FetchUserAnswerCount(ctx, tx, eventId) - if userAnswerCount != event.NumberOfParticipants { - util.SendMail(event.ConfirmationEmail, "マジスケ", "イベント参加者が集まりました") - if err != nil { - return entity.UserEventAnswer{}, apperror.NewUnknownError(fmt.Errorf("failed to send confirmation email: %w", err), nil) - } - } - } - // commit! err = tx.Commit() if err != nil { return entity.UserEventAnswer{}, err } + go func() { + log.Println("start goroutine", event) + // メールの通知を希望するなら + fmt.Println("aaaaaaaaaaaaaa", event.NotifyByEmail, event.ConfirmationEmail) + if event.NotifyByEmail && event.ConfirmationEmail != "" { + // ユーザーの回答数を数える + userAnswerCount, err := eu.er.FetchUserAnswerCount(ctx, nil, eventId) + fmt.Println("aaaaaaaaaaaaaa", userAnswerCount, event.NumberOfParticipants) + if userAnswerCount == event.NumberOfParticipants { + title := `[マジスケ]「` + event.Name + `」イベント参加者が集まりました!` + idstr := util.ULIDToString(eventId) + body := `マジスケをご利用頂き誠にありがとうございます。 +回答者数が,予定人数の` + fmt.Sprintf("%d", event.NumberOfParticipants) + + `人に到達しました。 + +https://magi-sche.net/detail/` + idstr + `から確認できます。 +今後ともマジスケをよろしくお願いいたします。` + util.SendMail(*eu.cfg, event.ConfirmationEmail, title, body) + if err != nil { + log.Printf("failed to send confirmation email: %v", err) + // return entity.UserEventAnswer{}, apperror.NewUnknownError(fmt.Errorf("failed to send confirmation email: %w", err), nil) + } + } + } + }() + return newAnswer, nil } diff --git a/util/util.go b/util/util.go index cad8a82..c9511f9 100644 --- a/util/util.go +++ b/util/util.go @@ -119,6 +119,7 @@ func MakeRandomStr(digit int) (string, error) { } func SendMail(cfg config.Config, targetAddrs string, title string, body string) error { + fmt.Println("send email called!!!!!!", targetAddrs, title, body) hostname := cfg.SMTP.Host // SMTPサーバーのホスト名 port := cfg.SMTP.Port // SMTPサーバーのポート番号 password := cfg.SMTP.Password