Skip to content

Conversation

@keshav0479
Copy link
Contributor

@keshav0479 keshav0479 commented Jan 11, 2026

Description

Fixes #1998

Sorts "Recently Used Apps" by settled transactions instead of LastUsedAt, so apps that actively move value appear at the top.

Changes

  • api/api.go: Modified ListApps to LEFT JOIN transactions where state = 'SETTLED' and sort by MAX(transactions.created_at).
  • nip47/event_handler.go: Minor cleanup (fixed log field name).

Notes

  • LastUsedAt still tracks connection activity (useful for debugging).
  • No database schema changes required.

Summary by CodeRabbit

  • New Features
    • Apps can now be sorted by most-recent settled transaction time, with secondary sorting by last activity for clearer organization.
  • Bug Fixes
    • Improved error logging for app activity updates to provide clearer diagnostic information.

✏️ Tip: You can customize this high-level summary in your review settings.

@rolznz
Copy link
Contributor

rolznz commented Jan 12, 2026

Hi,

Thanks for the PR. But I still think it's important to know when there was any activity at all, as well as if there was monetary activity.

There are also problems with the current solution that simply requesting an invoice (but it not being paid) would count as monetary activity. I think this needs more planning before working on an implementation.

@rolznz rolznz marked this pull request as draft January 12, 2026 04:52
@keshav0479
Copy link
Contributor Author

Fair point,it is useful to know when an app was last online/connected, even if it didn't spend anything.

To fix the sorting without losing that data, how about we split it into two fields?
LastConnectedAt (updates on everything, like get_balance) and LastActionAt (updates only on value movements)
Then we can just update the UI to sort by LastActionAt so the list stays relevant.Curious to know what u think?

@rolznz
Copy link
Contributor

rolznz commented Jan 12, 2026

I wonder if it is possible already to find these apps by doing a DB query that joins apps on the transaction list? then there's no DB changes needed. (as long as the query is efficient enough)

@keshav0479
Copy link
Contributor Author

Oh that's a great point, i hadn't considered using the existing transactions table.
I just checked and Transaction does have AppId, so i can try updating the ListApps query to join on settled transactions instead of relying on LastUsedAt for sorting.
Would it be correct to filter by settled_at IS NOT NULL (or a specific state) to only count completed payments? Just want to make sure i get the right definition of "movement of value."
Once you confirm, i'll revert my current changes and try this approach!

@rolznz
Copy link
Contributor

rolznz commented Jan 12, 2026

@keshav0479 only settled payments count. I think you can look at the transaction state as the settled constant (in constants.go)

@keshav0479
Copy link
Contributor Author

Got it, that makes perfect sense regarding the SETTLED state.
So checking the transactions table where state = 'SETTLED' seems like the best approach.
This way we get the best of both worlds: LastUsedAt can stay as "Last Connected" (useful for debugging), while the UI sorts purely by confirmed financial activity.
Does that sound like the right direction? happy to update the PR if you agree!

@rolznz
Copy link
Contributor

rolznz commented Jan 13, 2026

@keshav0479 sounds good to me, thanks!

@keshav0479 keshav0479 force-pushed the fix/recently-used-apps branch from dc8d2cd to 25c5517 Compare January 13, 2026 11:48
@keshav0479 keshav0479 changed the title fix: only update 'last used' on value-moving requests fix: sort Recently Used Apps by settled transactions Jan 13, 2026
@keshav0479 keshav0479 marked this pull request as ready for review January 13, 2026 11:56
api/api.go Outdated

if orderBy == "" {
orderBy = "last_used_at"
var totalCount int64
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is incorrect - counting must be done after filtering.

Also, I would undo your changes and make a new sorting parameter for last_economic_activity or something like that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or last_settled_transaction maybe

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated! Changed the log field to app_id and added last_settled_transaction as a new sorting option, keeping the original logic intact

@keshav0479 keshav0479 force-pushed the fix/recently-used-apps branch from 25c5517 to 1e5cbd8 Compare January 24, 2026 14:23
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 24, 2026

📝 Walkthrough

Walkthrough

Adds a new ListApps ordering option "last_settled_transaction" that orders apps by the timestamp of their most recent settled transaction, and fixes a log field name in the event handler.

Changes

Cohort / File(s) Summary
App Listing Query Logic
api/api.go
Adds branch for orderBy == "last_settled_transaction": LEFT JOINs settled transactions, selects MAX(transactions.created_at) as last_transaction_at, groups by apps.id, and orders by last_transaction_at IS NULL, last_transaction_at DESC, then apps.last_used_at.
Event Logging
nip47/event_handler.go
Adjusts error log field key from "it" to "app_id" when logging failure to update app last-used time; removes an extraneous blank line.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐰 I hop through rows and timestamps bright,
Chasing coins that settle right.
Not every ping earns a cheer—only value in flight—
Now recent apps shine true by last settled light. ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: sorting Recently Used Apps by settled transactions. It directly reflects the primary modification in api/api.go and addresses the linked issue #1998.
Linked Issues check ✅ Passed The PR addresses issue #1998 by implementing settled transaction sorting in ListApps query via LEFT JOIN on settled transactions, achieving the goal of surfacing apps with actual monetary activity.
Out of Scope Changes check ✅ Passed All changes are scoped to the objectives: api/api.go implements the settled transaction sorting logic, and nip47/event_handler.go change is minor cleanup (log field name fix) unrelated to core functionality.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
api/api.go (1)

526-531: Count query may return incorrect results with GROUP BY.

When orderBy == "last_settled_transaction", the query has a GROUP BY apps.id clause. Calling .Model(&db.App{}).Count(&totalCount) on this grouped query may not return the correct total count of apps—it could count the number of groups or behave unexpectedly depending on the database driver.

Consider computing the count before applying the grouping/aggregation for the last_settled_transaction case, or use a separate unmodified query for counting.

🔧 Suggested approach
+	// Count before applying aggregation for last_settled_transaction
+	countQuery := api.db
+	if filters.Name != "" {
+		if api.db.Dialector.Name() == "postgres" {
+			countQuery = countQuery.Where("name ILIKE ?", filters.Name+"%")
+		} else {
+			countQuery = countQuery.Where("name LIKE ?", filters.Name+"%")
+		}
+	}
+	// ... apply other filters to countQuery ...
+
 	var totalCount int64
-	result := query.Model(&db.App{}).Count(&totalCount)
+	result := countQuery.Model(&db.App{}).Count(&totalCount)

Alternatively, you could clone the query before adding the SELECT/JOIN/GROUP BY clauses and use the clone for counting.

🤖 Fix all issues with AI agents
In `@api/api.go`:
- Around line 514-521: The orderBy string already contains DESC and causes a
duplicated "DESC" in query.Order(orderBy + " DESC"), and NULL
last_transaction_at values need to be ordered to the end; when handling the
last_settled_transaction branch (the block that calls query.Select(...
MAX(transactions.created_at) as last_transaction_at) / Joins(...) /
Group("apps.id")), set orderBy to a value that includes NULL-safe ordering (for
example using COALESCE(last_transaction_at, '1970-01-01') DESC,
apps.last_used_at DESC) and then stop appending " DESC" later — change the final
call to use query.Order(orderBy) (or ensure orderBy contains no direction if you
intend to append " DESC"), so you neither produce duplicate DESC nor leave NULL
last_transaction_at entries unordered.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Recently Used Apps should be based on movement of value, not any NWC request

2 participants