@@ -93,7 +93,7 @@ func (r *LocalUserRepository) Create(req *models.CreateLocalUserRequest) (*model
9393func (r * LocalUserRepository ) GetByID (id string ) (* models.LocalUser , error ) {
9494 query := `
9595 SELECT u.id, u.logto_id, u.username, u.email, u.name, u.phone, u.organization_id, u.user_role_ids, u.custom_data,
96- u.created_at, u.updated_at, u.logto_synced_at, u.active,
96+ u.created_at, u.updated_at, u.logto_synced_at, u.latest_login_at, u. active,
9797 COALESCE(d.name, r.name, c.name) as organization_name,
9898 COALESCE(d.id, r.id, c.id) as organization_local_id
9999 FROM users u
@@ -110,7 +110,7 @@ func (r *LocalUserRepository) GetByID(id string) (*models.LocalUser, error) {
110110 err := r .db .QueryRow (query , id ).Scan (
111111 & user .ID , & user .LogtoID , & user .Username , & user .Email , & user .Name , & user .Phone ,
112112 & user .OrganizationID , & userRoleIDsJSON , & customDataJSON ,
113- & user .CreatedAt , & user .UpdatedAt , & user .LogtoSyncedAt , & user .Active ,
113+ & user .CreatedAt , & user .UpdatedAt , & user .LogtoSyncedAt , & user .LatestLoginAt , & user . Active ,
114114 & user .OrganizationName , & user .OrganizationLocalID ,
115115 )
116116
@@ -149,7 +149,7 @@ func (r *LocalUserRepository) GetByID(id string) (*models.LocalUser, error) {
149149func (r * LocalUserRepository ) GetByLogtoID (logtoID string ) (* models.LocalUser , error ) {
150150 query := `
151151 SELECT u.id, u.logto_id, u.username, u.email, u.name, u.phone, u.organization_id, u.user_role_ids, u.custom_data,
152- u.created_at, u.updated_at, u.logto_synced_at, u.active,
152+ u.created_at, u.updated_at, u.logto_synced_at, u.latest_login_at, u. active,
153153 COALESCE(d.name, r.name, c.name) as organization_name,
154154 COALESCE(d.id, r.id, c.id) as organization_local_id
155155 FROM users u
@@ -166,7 +166,7 @@ func (r *LocalUserRepository) GetByLogtoID(logtoID string) (*models.LocalUser, e
166166 err := r .db .QueryRow (query , logtoID ).Scan (
167167 & user .ID , & user .LogtoID , & user .Username , & user .Email , & user .Name , & user .Phone ,
168168 & user .OrganizationID , & userRoleIDsJSON , & customDataJSON ,
169- & user .CreatedAt , & user .UpdatedAt , & user .LogtoSyncedAt , & user .Active ,
169+ & user .CreatedAt , & user .UpdatedAt , & user .LogtoSyncedAt , & user .LatestLoginAt , & user . Active ,
170170 & user .OrganizationName , & user .OrganizationLocalID ,
171171 )
172172
@@ -292,6 +292,28 @@ func (r *LocalUserRepository) Delete(id string) error {
292292 return nil
293293}
294294
295+ // UpdateLatestLogin updates the latest_login_at field for a user
296+ func (r * LocalUserRepository ) UpdateLatestLogin (userID string ) error {
297+ query := `UPDATE users SET latest_login_at = $2, updated_at = $2 WHERE id = $1`
298+
299+ now := time .Now ()
300+ result , err := r .db .Exec (query , userID , now )
301+ if err != nil {
302+ return fmt .Errorf ("failed to update latest login: %w" , err )
303+ }
304+
305+ rowsAffected , err := result .RowsAffected ()
306+ if err != nil {
307+ return fmt .Errorf ("failed to get rows affected: %w" , err )
308+ }
309+
310+ if rowsAffected == 0 {
311+ return fmt .Errorf ("user not found" )
312+ }
313+
314+ return nil
315+ }
316+
295317// List returns paginated list of users based on hierarchical RBAC (matches other repository patterns)
296318func (r * LocalUserRepository ) List (userOrgRole , userOrgID , excludeUserID string , page , pageSize int ) ([]* models.LocalUser , int , error ) {
297319 // Get all organization IDs the user can access hierarchically
@@ -343,7 +365,7 @@ func (r *LocalUserRepository) ListByOrganizations(allowedOrgIDs []string, exclud
343365
344366 query := fmt .Sprintf (`
345367 SELECT u.id, u.logto_id, u.username, u.email, u.name, u.phone, u.organization_id, u.user_role_ids, u.custom_data,
346- u.created_at, u.updated_at, u.logto_synced_at, u.active,
368+ u.created_at, u.updated_at, u.logto_synced_at, u.latest_login_at, u. active,
347369 COALESCE(d.name, r.name, c.name) as organization_name,
348370 COALESCE(d.id, r.id, c.id) as organization_local_id
349371 FROM users u
@@ -369,7 +391,7 @@ func (r *LocalUserRepository) ListByOrganizations(allowedOrgIDs []string, exclud
369391 err := rows .Scan (
370392 & user .ID , & user .LogtoID , & user .Username , & user .Email , & user .Name ,
371393 & user .Phone , & user .OrganizationID , & userRoleIDsJSON , & customDataJSON ,
372- & user .CreatedAt , & user .UpdatedAt , & user .LogtoSyncedAt , & user .Active ,
394+ & user .CreatedAt , & user .UpdatedAt , & user .LogtoSyncedAt , & user .LatestLoginAt , & user . Active ,
373395 & user .OrganizationName , & user .OrganizationLocalID ,
374396 )
375397 if err != nil {
0 commit comments