@@ -34,10 +34,10 @@ type AttendanceSearchDoc struct {
|
||||
CheckinAt time.Time `json:"checkin_at"`
|
||||
}
|
||||
|
||||
func (self *Attendance) GetAttendance(userId, eventId uuid.UUID) (*Attendance, error) {
|
||||
func (self *Attendance) GetAttendance(ctx context.Context, userId, eventId uuid.UUID) (*Attendance, error) {
|
||||
var checkin Attendance
|
||||
|
||||
err := Database.
|
||||
err := Database.WithContext(ctx).
|
||||
Where("user_id = ? AND event_id = ?", userId, eventId).
|
||||
First(&checkin).Error
|
||||
|
||||
@@ -57,10 +57,10 @@ type AttendanceUsers struct {
|
||||
CheckinAt time.Time `json:"checkin_at"`
|
||||
}
|
||||
|
||||
func (self *Attendance) GetUsersByEventID(eventID uuid.UUID) (*[]AttendanceUsers, error) {
|
||||
func (self *Attendance) GetUsersByEventID(ctx context.Context, eventID uuid.UUID) (*[]AttendanceUsers, error) {
|
||||
var result []AttendanceUsers
|
||||
|
||||
err := Database.
|
||||
err := Database.WithContext(ctx).
|
||||
Model(&Attendance{}).
|
||||
Select("user_id, checkin_at").
|
||||
Where("event_id = ?", eventID).
|
||||
@@ -75,10 +75,10 @@ type AttendanceEvent struct {
|
||||
CheckinAt time.Time `json:"checkin_at"`
|
||||
}
|
||||
|
||||
func (self *Attendance) GetEventsByUserID(userID uuid.UUID) (*[]AttendanceEvent, error) {
|
||||
func (self *Attendance) GetEventsByUserID(ctx context.Context, userID uuid.UUID) (*[]AttendanceEvent, error) {
|
||||
var result []AttendanceEvent
|
||||
|
||||
err := Database.
|
||||
err := Database.WithContext(ctx).
|
||||
Model(&Attendance{}).
|
||||
Select("event_id, checkin_at").
|
||||
Where("user_id = ?", userID).
|
||||
@@ -88,12 +88,12 @@ func (self *Attendance) GetEventsByUserID(userID uuid.UUID) (*[]AttendanceEvent,
|
||||
return &result, err
|
||||
}
|
||||
|
||||
func (self *Attendance) Create() error {
|
||||
func (self *Attendance) Create(ctx context.Context) error {
|
||||
self.UUID = uuid.New()
|
||||
self.AttendanceId = uuid.New()
|
||||
|
||||
// DB transaction for strong consistency
|
||||
err := Database.Transaction(func(tx *gorm.DB) error {
|
||||
err := Database.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
||||
if err := tx.Create(&self).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -103,17 +103,17 @@ func (self *Attendance) Create() error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := self.UpdateSearchIndex(); err != nil {
|
||||
if err := self.UpdateSearchIndex(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *Attendance) Update(attendanceId uuid.UUID, checkinTime *time.Time) (*Attendance, error) {
|
||||
func (self *Attendance) Update(ctx context.Context, attendanceId uuid.UUID, checkinTime *time.Time) (*Attendance, error) {
|
||||
var attendance Attendance
|
||||
|
||||
err := Database.Transaction(func(tx *gorm.DB) error {
|
||||
err := Database.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
||||
// Lock the row for update
|
||||
if err := tx.
|
||||
Where("attendance_id = ?", attendanceId).
|
||||
@@ -148,32 +148,32 @@ func (self *Attendance) Update(attendanceId uuid.UUID, checkinTime *time.Time) (
|
||||
}
|
||||
|
||||
// Sync to MeiliSearch (eventual consistency)
|
||||
if err := attendance.UpdateSearchIndex(); err != nil {
|
||||
if err := attendance.UpdateSearchIndex(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &attendance, nil
|
||||
}
|
||||
|
||||
func (self *Attendance) SearchUsersByEvent(eventID string) (*meilisearch.SearchResponse, error) {
|
||||
func (self *Attendance) SearchUsersByEvent(ctx context.Context, eventID string) (*meilisearch.SearchResponse, error) {
|
||||
index := MeiliSearch.Index("attendance")
|
||||
|
||||
return index.Search("", &meilisearch.SearchRequest{
|
||||
return index.SearchWithContext(ctx, "", &meilisearch.SearchRequest{
|
||||
Filter: "event_id = \"" + eventID + "\"",
|
||||
Sort: []string{"checkin_at:asc"},
|
||||
})
|
||||
}
|
||||
|
||||
func (self *Attendance) SearchEventsByUser(userID string) (*meilisearch.SearchResponse, error) {
|
||||
func (self *Attendance) SearchEventsByUser(ctx context.Context, userID string) (*meilisearch.SearchResponse, error) {
|
||||
index := MeiliSearch.Index("attendance")
|
||||
|
||||
return index.Search("", &meilisearch.SearchRequest{
|
||||
return index.SearchWithContext(ctx, "", &meilisearch.SearchRequest{
|
||||
Filter: "user_id = \"" + userID + "\"",
|
||||
Sort: []string{"checkin_at:asc"},
|
||||
})
|
||||
}
|
||||
|
||||
func (self *Attendance) UpdateSearchIndex() error {
|
||||
func (self *Attendance) UpdateSearchIndex(ctx context.Context) error {
|
||||
doc := AttendanceSearchDoc{
|
||||
AttendanceId: self.AttendanceId.String(),
|
||||
EventId: self.EventId.String(),
|
||||
@@ -188,21 +188,20 @@ func (self *Attendance) UpdateSearchIndex() error {
|
||||
PrimaryKey: &primaryKey,
|
||||
}
|
||||
|
||||
if _, err := index.UpdateDocuments([]AttendanceSearchDoc{doc}, opts); err != nil {
|
||||
if _, err := index.UpdateDocumentsWithContext(ctx, []AttendanceSearchDoc{doc}, opts); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *Attendance) DeleteSearchIndex() error {
|
||||
func (self *Attendance) DeleteSearchIndex(ctx context.Context) error {
|
||||
index := MeiliSearch.Index("attendance")
|
||||
_, err := index.DeleteDocument(self.AttendanceId.String(), nil)
|
||||
_, err := index.DeleteDocumentWithContext(ctx, self.AttendanceId.String(), nil)
|
||||
return err
|
||||
}
|
||||
|
||||
func (self *Attendance) GenCheckinCode(eventId uuid.UUID) (*string, error) {
|
||||
ctx := context.Background()
|
||||
func (self *Attendance) GenCheckinCode(ctx context.Context, eventId uuid.UUID) (*string, error) {
|
||||
ttl := viper.GetDuration("ttl.checkin_code_ttl")
|
||||
rng := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
|
||||
@@ -223,9 +222,7 @@ func (self *Attendance) GenCheckinCode(eventId uuid.UUID) (*string, error) {
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Attendance) VerifyCheckinCode(checkinCode string) error {
|
||||
ctx := context.Background()
|
||||
|
||||
func (self *Attendance) VerifyCheckinCode(ctx context.Context, checkinCode string) error {
|
||||
val, err := Redis.Get(ctx, "checkin_code:"+checkinCode).Result()
|
||||
if err != nil {
|
||||
return errors.New("[Attendance Data] invalid or expired checkin code")
|
||||
@@ -250,13 +247,13 @@ func (self *Attendance) VerifyCheckinCode(checkinCode string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
attendanceData, err := self.GetAttendance(userId, eventId)
|
||||
attendanceData, err := self.GetAttendance(ctx, userId, eventId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
time := time.Now()
|
||||
_, err = self.Update(attendanceData.AttendanceId, &time)
|
||||
_, err = self.Update(ctx, attendanceData.AttendanceId, &time)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user