Skip to content

Commit 6fb8693

Browse files
committed
Merge branch 'last-online' into 'master'
Last online See merge request joinimpact/api!77
2 parents 043582e + d316066 commit 6fb8693

File tree

6 files changed

+34
-4
lines changed

6 files changed

+34
-4
lines changed

internal/authentication/service.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ type Service interface {
3838
OauthLogin(serviceName, accessToken string) (*OauthResponse, error)
3939
// RefreshToken generates a new token pair from a refresh token.
4040
RefreshToken(ctx context.Context, refreshToken string) (*TokenPair, error)
41+
// UpdateLastOnline updates a user's last online time.
42+
UpdateLastOnline(ctx context.Context, userID int64) error
4143
}
4244

4345
// service represents the default authentication service of this package.
@@ -371,3 +373,24 @@ func (s *service) RefreshToken(ctx context.Context, refreshToken string) (*Token
371373
// No errors, generate a token pair.
372374
return s.generateTokenPair(claims.UserID)
373375
}
376+
377+
// UpdateLastOnline updates a user's last online time.
378+
func (s *service) UpdateLastOnline(ctx context.Context, userID int64) error {
379+
user, err := s.userRepository.FindByID(userID)
380+
if err != nil {
381+
return err
382+
}
383+
384+
if user.LastOnline != nil && time.Now().Sub(*user.LastOnline) < 30*time.Minute {
385+
return nil
386+
}
387+
388+
now := time.Now()
389+
390+
return s.userRepository.Update(models.User{
391+
Model: models.Model{
392+
ID: user.ID,
393+
},
394+
LastOnline: &now,
395+
})
396+
}

internal/core/middleware/auth/middleware.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ func AuthMiddleware(authService authentication.Service) func(next http.Handler)
5353
ctx = context.WithValue(ctx, KeyUserID, userID)
5454

5555
next.ServeHTTP(w, r.WithContext(ctx))
56+
57+
// Update the user's last online time.
58+
authService.UpdateLastOnline(ctx, userID)
5659
})
5760
}
5861
}

internal/database/postgres/opportunity_repository.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ func NewOpportunityRepository(db *gorm.DB, logger *zerolog.Logger) models.Opport
2525
// FindByID finds a single entity by ID.
2626
func (r *opportunityRepository) FindByID(ctx context.Context, id int64) (*models.Opportunity, error) {
2727
var opportunity models.Opportunity
28-
if err := r.db.Preload("OpportunityRequirements").Preload("OpportunityLimits").First(&opportunity, id).Error; err != nil {
28+
if err := r.db.Preload("OpportunityRequirements").Preload("OpportunityLimits").Preload("OpportunityTags").Preload("OpportunityTags.Tag").First(&opportunity, id).Error; err != nil {
2929
return &opportunity, err
3030
}
3131
return &opportunity, nil
@@ -34,7 +34,7 @@ func (r *opportunityRepository) FindByID(ctx context.Context, id int64) (*models
3434
// FindByIDs finds multiple entities by an array of IDs.
3535
func (r *opportunityRepository) FindByIDs(ctx context.Context, ids []int64) ([]models.Opportunity, error) {
3636
var opportunities []models.Opportunity
37-
if err := r.db.Preload("OpportunityRequirements").Preload("OpportunityLimits").
37+
if err := r.db.Preload("OpportunityRequirements").Preload("OpportunityLimits").Preload("OpportunityTags").Preload("OpportunityTags.Tag").
3838
Where("id IN (?) AND active = True", ids).
3939
Find(&opportunities).
4040
Error; err != nil {
@@ -46,7 +46,7 @@ func (r *opportunityRepository) FindByIDs(ctx context.Context, ids []int64) ([]m
4646
// FindByOrganizationID finds multiple entities by the organization ID.
4747
func (r *opportunityRepository) FindByOrganizationID(ctx context.Context, organizationID int64) ([]models.Opportunity, error) {
4848
var opportunities []models.Opportunity
49-
if err := r.db.Preload("OpportunityRequirements").Preload("OpportunityLimits").
49+
if err := r.db.Preload("OpportunityRequirements").Preload("OpportunityLimits").Preload("OpportunityTags").Preload("OpportunityTags.Tag").
5050
Limit(dbctx.Get(ctx).Limit).
5151
Offset(dbctx.Get(ctx).Page*dbctx.Get(ctx).Limit).
5252
Where("organization_id = ? AND active = True AND LOWER(title) LIKE ?", organizationID, strings.ToLower(fmt.Sprintf("%%%s%%", dbctx.Get(ctx).Query))).
@@ -60,7 +60,7 @@ func (r *opportunityRepository) FindByOrganizationID(ctx context.Context, organi
6060
// FindByCreatorID finds multiple entities by the creator ID.
6161
func (r *opportunityRepository) FindByCreatorID(ctx context.Context, creatorID int64) ([]models.Opportunity, error) {
6262
var opportunities []models.Opportunity
63-
if err := r.db.Preload("OpportunityRequirements").Preload("OpportunityLimits").Where("creator_id = ? AND active = True", creatorID).Find(&opportunities).Error; err != nil {
63+
if err := r.db.Preload("OpportunityRequirements").Preload("OpportunityLimits").Preload("OpportunityTags").Preload("OpportunityTags.Tag").Where("creator_id = ? AND active = True", creatorID).Find(&opportunities).Error; err != nil {
6464
return opportunities, err
6565
}
6666
return opportunities, nil

internal/models/user.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ type User struct {
1515
FirstName string `json:"firstName"` // the user's first name
1616
LastName string `json:"lastName"` // the user's last name
1717
DateOfBirth time.Time `json:"dateOfBirth" level:"1"` // the user's date of birth, used for calculating age
18+
LastOnline *time.Time `json:"lastOnline"` // the last time the user was online
1819
ProfileFields []UserProfileField `json:"profile"` // fields of the user's profile
1920
// ZIPCode string `json:"zipCode" level:"1"` // the user's zip code, used to find nearby opportunities
2021
LocationLatitude float64 `json:"-"` // the latitude of the user's city

internal/users/profile.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ type UserProfile struct {
1414
FirstName string `json:"firstName"` // the user's first name
1515
LastName string `json:"lastName"` // the user's last name
1616
Email string `json:"email,omitempty" scope:"owner"` // the user's email
17+
LastOnline *time.Time `json:"lastOnline,omitempty"` // the last time the user was online
1718
DateOfBirth time.Time `json:"dateOfBirth,omitempty" scope:"owner"` // the user's date of birth, used for calculating age
1819
CreatedAt time.Time `json:"createdAt,omitempty" scope:"owner"` // the time the user was created at
1920
Tags []models.Tag `json:"tags"` // the user's tags

internal/users/service.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ func (s *service) GetUserProfile(userID int64, self bool) (*UserProfile, error)
7878
profile.FirstName = user.FirstName
7979
profile.LastName = user.LastName
8080
profile.ProfilePicture = user.ProfilePicture
81+
profile.LastOnline = user.LastOnline
8182

8283
if self {
8384
profile.Email = user.Email
@@ -140,6 +141,7 @@ func (s *service) GetMinimalUserProfile(userID int64) (*UserProfile, error) {
140141
profile.FirstName = user.FirstName
141142
profile.LastName = user.LastName
142143
profile.ProfilePicture = user.ProfilePicture
144+
profile.LastOnline = user.LastOnline
143145

144146
return profile, nil
145147
}

0 commit comments

Comments
 (0)