Commit 38ed55f
Antonio Mika
·
2026-10-10 16:53:16 -0400 EDT
parent c6e626e
fix(tui): show usage stats for users without pages projects
3 files changed,
+32,
-3
+6,
-1
| ... | ... | @@ -2041,13 +2041,18 @@ func (me *PsqlDB) findPagesStats(userID string) (*db.UserServiceStats, error) { | |
| 2041 | 2041 | stats := db.UserServiceStats{ | |
| 2042 | 2042 | Service: "pgs", | |
| 2043 | 2043 | } | |
| 2044 | + | // the aggregates are NULL when the user has no projects | |
| 2045 | + | var first, latestCreated, latestUpdated sql.NullTime | |
| 2044 | 2046 | err := me.Db.QueryRow( | |
| 2045 | 2047 | `SELECT count(id), min(created_at), max(created_at), max(updated_at) FROM projects WHERE user_id=$1`, | |
| 2046 | 2048 | userID, | |
| 2047 | - | ).Scan(&stats.Num, &stats.FirstCreatedAt, &stats.LastestCreatedAt, &stats.LatestUpdatedAt) | |
| 2049 | + | ).Scan(&stats.Num, &first, &latestCreated, &latestUpdated) | |
| 2048 | 2050 | if err != nil { | |
| 2049 | 2051 | return nil, err | |
| 2050 | 2052 | } | |
| 2053 | + | stats.FirstCreatedAt = first.Time | |
| 2054 | + | stats.LastestCreatedAt = latestCreated.Time | |
| 2055 | + | stats.LatestUpdatedAt = latestUpdated.Time | |
| 2051 | 2056 | ||
| 2052 | 2057 | return &stats, nil | |
| 2053 | 2058 | } |
+17,
-0
| ... | ... | @@ -1278,6 +1278,23 @@ func TestFindUserStats(t *testing.T) { | |
| 1278 | 1278 | } | |
| 1279 | 1279 | } | |
| 1280 | 1280 | ||
| 1281 | + | func TestFindUserStats_NoProjects(t *testing.T) { | |
| 1282 | + | cleanupTestData(t) | |
| 1283 | + | ||
| 1284 | + | user, _ := testDB.RegisterUser("statsempty", "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI statsempty", "comment", "") | |
| 1285 | + | ||
| 1286 | + | stats, err := testDB.FindUserStats(user.ID) | |
| 1287 | + | if err != nil { | |
| 1288 | + | t.Fatalf("FindUserStats failed: %v", err) | |
| 1289 | + | } | |
| 1290 | + | if stats.Pages.Num != 0 { | |
| 1291 | + | t.Errorf("expected 0 projects, got %d", stats.Pages.Num) | |
| 1292 | + | } | |
| 1293 | + | if !stats.Pages.FirstCreatedAt.IsZero() { | |
| 1294 | + | t.Errorf("expected zero first created at, got %s", stats.Pages.FirstCreatedAt) | |
| 1295 | + | } | |
| 1296 | + | } | |
| 1297 | + | ||
| 1281 | 1298 | // ============ Tuns Event Logs Tests ============ | |
| 1282 | 1299 | ||
| 1283 | 1300 | func TestInsertTunsEventLog(t *testing.T) { |
+9,
-2
| ... | ... | @@ -39,12 +39,19 @@ func (m *UsageInfo) getKv() []Kv { | |
| 39 | 39 | } | |
| 40 | 40 | kv := []Kv{ | |
| 41 | 41 | {Key: label, Value: fmt.Sprintf("%d", m.stats.Num)}, | |
| 42 | - | {Key: "oldest", Value: m.stats.FirstCreatedAt.Format(time.DateOnly)}, | |
| 43 | - | {Key: "newest", Value: m.stats.LastestCreatedAt.Format(time.DateOnly)}, | |
| 42 | + | {Key: "oldest", Value: formatUsageDate(m.stats.FirstCreatedAt)}, | |
| 43 | + | {Key: "newest", Value: formatUsageDate(m.stats.LastestCreatedAt)}, | |
| 44 | 44 | } | |
| 45 | 45 | return kv | |
| 46 | 46 | } | |
| 47 | 47 | ||
| 48 | + | func formatUsageDate(t time.Time) string { | |
| 49 | + | if t.IsZero() { | |
| 50 | + | return "-" | |
| 51 | + | } | |
| 52 | + | return t.Format(time.DateOnly) | |
| 53 | + | } | |
| 54 | + | ||
| 48 | 55 | type UserInfo struct { | |
| 49 | 56 | shared *SharedModel | |
| 50 | 57 | } |