Reactions tweaks
This commit is contained in:
parent
a6c7834b3b
commit
2cc8cfb1d0
223
sojorn_docs/reactions-implementation-troubleshooting.md
Normal file
223
sojorn_docs/reactions-implementation-troubleshooting.md
Normal file
|
|
@ -0,0 +1,223 @@
|
|||
# Reactions Feature Implementation & Troubleshooting
|
||||
|
||||
## Overview
|
||||
This document covers the complete implementation and troubleshooting of the reactions feature in the Sojorn application, including both backend (Go) and frontend (Flutter) components.
|
||||
|
||||
## Problem Statement
|
||||
The reactions feature had multiple issues:
|
||||
1. **Backend 500 errors** when toggling reactions
|
||||
2. **Frontend not showing reactions** on initial load (showing `null`)
|
||||
3. **UI not updating immediately** after toggling reactions
|
||||
4. **Need to refresh page** to see reaction changes
|
||||
|
||||
## Backend Issues & Solutions
|
||||
|
||||
### Issue 1: pgx.ErrNoRows vs sql.ErrNoRows
|
||||
**Problem**: The Go backend was using `sql.ErrNoRows` to check for no rows in database queries, but pgx returns `pgx.ErrNoRows`.
|
||||
|
||||
**Error**:
|
||||
```
|
||||
ERR DEBUG: Failed to check existing reaction - unexpected error error="no rows in result set"
|
||||
```
|
||||
|
||||
**Solution**: Update error handling in `internal/repository/post_repository.go`:
|
||||
```go
|
||||
import (
|
||||
"github.com/jackc/pgx/v5" // Add this import
|
||||
)
|
||||
|
||||
// Change from:
|
||||
} else if err != sql.ErrNoRows {
|
||||
|
||||
// To:
|
||||
} else if err != pgx.ErrNoRows {
|
||||
```
|
||||
|
||||
### Issue 2: JSON Serialization Omitting Empty Fields
|
||||
**Problem**: The `Post` model had `omitempty` tags on reaction fields, causing them to be omitted from JSON responses when empty.
|
||||
|
||||
**Solution**: Remove `omitempty` from reaction JSON tags in `internal/models/post.go`:
|
||||
```go
|
||||
// Before:
|
||||
Reactions map[string]int `json:"reactions,omitempty"`
|
||||
MyReactions []string `json:"my_reactions,omitempty"`
|
||||
ReactionUsers map[string][]string `json:"reaction_users,omitempty"`
|
||||
|
||||
// After:
|
||||
Reactions map[string]int `json:"reactions"`
|
||||
MyReactions []string `json:"my_reactions"`
|
||||
ReactionUsers map[string][]string `json:"reaction_users"`
|
||||
```
|
||||
|
||||
## Frontend Issues & Solutions
|
||||
|
||||
### Issue 1: UI Not Updating Immediately
|
||||
**Problem**: The `_reactionCountsFor` and `_myReactionsFor` methods prioritized `post.reactions` over local state, but after toggle reactions, local state had updated data while `post.reactions` still had old data.
|
||||
|
||||
**Solution**: Change priority to prefer local state for immediate updates in `lib/screens/post/threaded_conversation_screen.dart`:
|
||||
|
||||
```dart
|
||||
Map<String, int> _reactionCountsFor(Post post) {
|
||||
// Prefer local state for immediate updates after toggle reactions
|
||||
final localState = _reactionCountsByPost[post.id];
|
||||
if (localState != null) {
|
||||
return localState;
|
||||
}
|
||||
// Fall back to post model if no local state
|
||||
return post.reactions ?? {};
|
||||
}
|
||||
|
||||
Set<String> _myReactionsFor(Post post) {
|
||||
// Prefer local state for immediate updates after toggle reactions
|
||||
final localState = _myReactionsByPost[post.id];
|
||||
if (localState != null) {
|
||||
return localState;
|
||||
}
|
||||
// Fall back to post model if no local state
|
||||
return post.myReactions?.toSet() ?? <String>{};
|
||||
}
|
||||
```
|
||||
|
||||
## Implementation Steps
|
||||
|
||||
### Backend Implementation
|
||||
1. **Fix Error Handling**:
|
||||
```bash
|
||||
cd go-backend
|
||||
# Edit internal/repository/post_repository.go
|
||||
# Add pgx import and change error handling
|
||||
git add . && git commit -m "Fix ToggleReaction error handling - use pgx.ErrNoRows"
|
||||
```
|
||||
|
||||
2. **Fix JSON Serialization**:
|
||||
```bash
|
||||
# Edit internal/models/post.go
|
||||
# Remove omitempty from reaction fields
|
||||
git add . && git commit -m "Remove omitempty from reaction JSON fields"
|
||||
```
|
||||
|
||||
3. **Deploy Backend**:
|
||||
```bash
|
||||
cd /opt/sojorn/go-backend
|
||||
git pull origin ThreadRestoration
|
||||
sudo systemctl stop sojorn-api
|
||||
go build -o ../bin/api ./cmd/api
|
||||
sudo systemctl start sojorn-api
|
||||
```
|
||||
|
||||
### Frontend Implementation
|
||||
1. **Fix UI Update Priority**:
|
||||
```bash
|
||||
cd sojorn_app
|
||||
# Edit lib/screens/post/threaded_conversation_screen.dart
|
||||
# Update _reactionCountsFor and _myReactionsFor methods
|
||||
git add . && git commit -m "Fix reaction UI updates - prioritize local state"
|
||||
```
|
||||
|
||||
## Debugging Techniques
|
||||
|
||||
### Backend Debugging
|
||||
1. **Add Debug Logging**:
|
||||
```go
|
||||
log.Info().Str("postID", postID).Str("userID", userID).Msg("DEBUG: No existing reaction found (expected)")
|
||||
log.Error().Err(err).Str("postID", postID).Str("userID", userID).Msg("DEBUG: Failed to check existing reaction - unexpected error")
|
||||
```
|
||||
|
||||
2. **Monitor Logs**:
|
||||
```bash
|
||||
sudo tail -f /var/log/syslog | grep api
|
||||
```
|
||||
|
||||
### Frontend Debugging
|
||||
1. **Add Debug Logging**:
|
||||
```dart
|
||||
print('DEBUG: Toggle reaction response: $response');
|
||||
print('DEBUG: Updated local reaction counts: ${_reactionCountsByPost[postId]}');
|
||||
print('DEBUG: Using local state: ${localState}');
|
||||
```
|
||||
|
||||
2. **Check API Response**:
|
||||
```dart
|
||||
final response = await api.toggleReaction(postId, emoji);
|
||||
print('DEBUG: API response: $response');
|
||||
```
|
||||
|
||||
## Testing Checklist
|
||||
|
||||
### Backend Tests
|
||||
- [ ] Toggle reaction returns 200 (not 500)
|
||||
- [ ] Reaction is saved to database
|
||||
- [ ] API response includes updated counts and user reactions
|
||||
- [ ] Empty reaction fields return `{}` and `[]` instead of `null`
|
||||
|
||||
### Frontend Tests
|
||||
- [ ] Reactions show on initial load
|
||||
- [ ] Toggle reaction updates UI immediately
|
||||
- [ ] No refresh needed to see changes
|
||||
- [ ] Selected emoji shows as selected
|
||||
- [ ] Reaction count updates correctly
|
||||
|
||||
## Common Issues & Solutions
|
||||
|
||||
### Issue: "no rows in result set" Error
|
||||
**Cause**: Using `sql.ErrNoRows` instead of `pgx.ErrNoRows`
|
||||
**Fix**: Update error handling to use `pgx.ErrNoRows`
|
||||
|
||||
### Issue: Frontend Shows `null` for Reactions
|
||||
**Cause**: `omitempty` in JSON tags omits empty fields
|
||||
**Fix**: Remove `omitempty` from reaction field JSON tags
|
||||
|
||||
### Issue: UI Not Updating After Toggle
|
||||
**Cause**: UI prioritizes old post data over updated local state
|
||||
**Fix**: Change priority to prefer local state for immediate updates
|
||||
|
||||
### Issue: Need to Refresh to See Changes
|
||||
**Cause**: Same as above - UI not using updated local state
|
||||
**Fix**: Same solution - prioritize local state
|
||||
|
||||
## Key Files Modified
|
||||
|
||||
### Backend
|
||||
- `internal/repository/post_repository.go` - Error handling fix
|
||||
- `internal/models/post.go` - JSON serialization fix
|
||||
|
||||
### Frontend
|
||||
- `lib/screens/post/threaded_conversation_screen.dart` - UI update priority fix
|
||||
|
||||
## Verification Commands
|
||||
|
||||
### Backend Verification
|
||||
```bash
|
||||
# Check if service is running
|
||||
sudo systemctl status sojorn-api
|
||||
|
||||
# Check logs for errors
|
||||
sudo tail -f /var/log/syslog | grep api
|
||||
|
||||
# Test API endpoint
|
||||
curl -X POST "http://194.238.28.122:8080/api/v1/posts/{post-id}/reactions/toggle" \
|
||||
-H "Authorization: Bearer {jwt-token}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"emoji": "❤️"}'
|
||||
```
|
||||
|
||||
### Frontend Verification
|
||||
```bash
|
||||
# Check Flutter logs
|
||||
flutter run --verbose
|
||||
|
||||
# Look for debug messages
|
||||
grep "DEBUG:" flutter_logs.txt
|
||||
```
|
||||
|
||||
## Success Criteria
|
||||
✅ **Backend**: Toggle reactions return 200, no 500 errors
|
||||
✅ **Frontend**: Reactions show immediately, no refresh needed
|
||||
✅ **UI**: Selected emojis display correctly
|
||||
✅ **Data**: Empty reactions show as empty, not null
|
||||
|
||||
## Future Improvements
|
||||
1. **Optimistic Updates**: Implement proper optimistic UI updates
|
||||
2. **Error Handling**: Better error messages for failed reactions
|
||||
3. **Performance**: Cache reaction data to reduce API calls
|
||||
4. **Real-time**: WebSocket updates for live reaction changes
|
||||
Loading…
Reference in a new issue