feat: add /api/v1/usertransactions endpoint#65
Conversation
…tion history Wallet-HMAC authenticated (same auth as the send API). Returns internal bot transactions for a given Telegram user ID, filtered by sender or recipient, newest first, with limit/offset pagination and a per-tx direction (incoming/outgoing) relative to the queried user.
📝 WalkthroughWalkthroughAdds a new ChangesUser Transactions Endpoint
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant Client
participant Service as Service.UserTransactions
participant Telegram as telegram.GetUserByTelegramID
participant DB as Database
Client->>Service: POST /api/v1/usertransactions
Service->>Service: decode JSON, validate telegram_id, apply limit/offset
Service->>Telegram: GetUserByTelegramID(telegram_id)
Telegram-->>Service: user or error
alt user not found
Service-->>Client: success=false, empty transactions
else user found
Service->>DB: query transactions by from_id/to_id with pagination
DB-->>Service: transaction rows
Service->>Service: map rows to UserTransactionData
Service-->>Client: success=true, transactions list
end
Possibly related PRs
Suggested labels: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (2)
internal/api/user_transactions.go (2)
65-71: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueHardcoded default limit not tied to a named constant.
limitdefaults to a bare100, while the cap uses the namedmaxAnalyticsLimitconstant. Consider a named constant (e.g.defaultTransactionsLimit) for consistency and to make the default/cap relationship self-documenting.♻️ Suggested tweak
+const defaultUserTransactionsLimit = 100 + limit := req.Limit if limit <= 0 { - limit = 100 + limit = defaultUserTransactionsLimit }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@internal/api/user_transactions.go` around lines 65 - 71, The transaction limit fallback in the request handling logic uses a bare 100, while the upper bound already relies on maxAnalyticsLimit. Introduce a named constant for the default in the same area as the limit normalization in the user transaction handler, and use it when limit <= 0 so the default and cap are both self-documenting and consistent.
99-103: 🚀 Performance & Scalability | 🔵 TrivialConsider indexing
from_id/to_idfor this query pattern.An
OR-based filter across two columns generally can't be satisfied efficiently by a single composite index and often forces a full scan as the transactions table grows. If this table doesn't already have indexes onfrom_idandto_id, this endpoint could become a slow query under load.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@internal/api/user_transactions.go` around lines 99 - 103, The query in the transactions lookup uses an OR filter on from_id and to_id, so add dedicated indexes for both columns in the Transactions model/migration rather than changing the query logic. Update the schema definition associated with s.Bot.DB.Transactions, ensuring from_id and to_id are individually indexed so the Where("from_id = ? OR to_id = ?") pattern can use them efficiently.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@internal/api/user_transactions.go`:
- Around line 65-71: The transaction limit fallback in the request handling
logic uses a bare 100, while the upper bound already relies on
maxAnalyticsLimit. Introduce a named constant for the default in the same area
as the limit normalization in the user transaction handler, and use it when
limit <= 0 so the default and cap are both self-documenting and consistent.
- Around line 99-103: The query in the transactions lookup uses an OR filter on
from_id and to_id, so add dedicated indexes for both columns in the Transactions
model/migration rather than changing the query logic. Update the schema
definition associated with s.Bot.DB.Transactions, ensuring from_id and to_id are
individually indexed so the Where("from_id = ? OR to_id = ?") pattern can use
them efficiently.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: ddcd8a3c-deae-4fec-8617-f5309fcee553
📒 Files selected for processing (2)
internal/api/user_transactions.gomain.go
Summary
Adds a new wallet-HMAC-authenticated endpoint so Send-API users can fetch a Telegram user's transaction history.
POST /api/v1/usertransactions— registered alongside the other send-API routes (gated behindIsAPISendEnabled()), using the sameWalletHMACMiddlewareauth as/api/v1/sendand/api/v1/userbalance.Request
{ "telegram_id": 123456789, "limit": 100, "offset": 0 }limitdefaults to 100, capped at 250 (reusesmaxAnalyticsLimit)offsetcapped atmaxAnalyticsOffsetResponse
{ "success": true, "telegram_id": 123456789, "count": 1, "limit": 100, "offset": 0, "transactions": [ { "id": 42, "time": "2026-07-06T12:00:00Z", "direction": "outgoing", "from_id": 123456789, "to_id": 987654321, "from_user": "@alice", "to_user": "@bob", "type": "api_send", "amount": 1000, "amount_lkr": "...", "memo": "...", "success": true } ], "message": "Transactions retrieved successfully" }Behavior
from_id = ? OR to_id = ?), newest first.directionfield (incoming/outgoing) relative to the queried user.200withsuccess:falseand an empty array — same pattern as/api/v1/userbalance— so callers can distinguish "no user" from "no transactions".GetUserTransactionHistory.HMAC signing
Same scheme as the rest of the send API:
POST/api/v1/usertransactions{timestamp}{body}.Test plan
go build ./...passesgo vet ./internal/api/...passesSummary by CodeRabbit
New Features
Bug Fixes