mirror of
https://github.com/Dvorinka/MyClubServer.git
synced 2026-06-04 10:42:57 +00:00
224 lines
6.4 KiB
Markdown
224 lines
6.4 KiB
Markdown
# Article Cache & Match Data Not Saving - FIXED
|
|
|
|
## Problem
|
|
|
|
The `cache/prefetch/articles.json` file was empty or not updating with newly created articles and their match link data:
|
|
|
|
```json
|
|
{"items":[],"page":1,"page_size":10,"total":0}
|
|
```
|
|
|
|
**Root Causes:**
|
|
1. **Prefetch runs every 30 minutes** - New articles weren't appearing in cache immediately
|
|
2. **No automatic cache refresh** - Creating/updating articles didn't trigger prefetch
|
|
3. **Match link data is loaded separately** - The `GetArticles` endpoint loads match links via batch query, but this wasn't being captured in cache files
|
|
|
|
## Console Logs Analysis
|
|
|
|
From your console logs, the article WAS created successfully:
|
|
```
|
|
Article created successfully in mutation callback: Object { ID: 1, ... }
|
|
Linking new article 1 with match 89d23bfd-5be6-416a-96d0-35ec694aa22c
|
|
Match link created for new article
|
|
```
|
|
|
|
The article exists in the database with:
|
|
- **Article ID**: 1
|
|
- **Match Link**: `89d23bfd-5be6-416a-96d0-35ec694aa22c`
|
|
- **Category**: "KALMAN TRADE Krajský přebor mladší dorost"
|
|
|
|
The cache was just stale - it hadn't updated yet since prefetch runs every 30 minutes.
|
|
|
|
## Solution Implemented
|
|
|
|
### 1. Automatic Prefetch Trigger on Article Create
|
|
|
|
**File**: `internal/controllers/article_controller.go`
|
|
|
|
Added automatic prefetch cache refresh when a published article is created:
|
|
|
|
```go
|
|
// 18. Trigger prefetch cache update (async)
|
|
if published {
|
|
go func() {
|
|
base := getBaseURL()
|
|
logger.Info("CreateArticle: Triggering prefetch cache update for published article")
|
|
services.PrefetchOnce(base)
|
|
}()
|
|
}
|
|
```
|
|
|
|
**Helper function added:**
|
|
```go
|
|
// getBaseURL returns the base URL for internal API calls (used for prefetch trigger)
|
|
func getBaseURL() string {
|
|
base := strings.TrimSpace(os.Getenv("PREFETCH_TARGET"))
|
|
if base == "" {
|
|
port := strings.TrimSpace(os.Getenv("PORT"))
|
|
if port == "" {
|
|
port = "8080"
|
|
}
|
|
base = "http://127.0.0.1:" + port + "/api/v1"
|
|
}
|
|
return base
|
|
}
|
|
```
|
|
|
|
### 2. Automatic Prefetch Trigger on Article Update
|
|
|
|
**File**: `internal/controllers/base_controller.go`
|
|
|
|
Added automatic prefetch cache refresh when an article is updated and published:
|
|
|
|
```go
|
|
// Trigger full prefetch cache update if article is published
|
|
if art.Published {
|
|
go func() {
|
|
base := getPrefetchBaseURL()
|
|
services.PrefetchOnce(base)
|
|
}()
|
|
}
|
|
```
|
|
|
|
**Helper function added:**
|
|
```go
|
|
// getPrefetchBaseURL returns the base URL for internal API calls (used for prefetch trigger)
|
|
func getPrefetchBaseURL() string {
|
|
base := strings.TrimSpace(os.Getenv("PREFETCH_TARGET"))
|
|
if base == "" {
|
|
port := strings.TrimSpace(os.Getenv("PORT"))
|
|
if port == "" {
|
|
port = "8080"
|
|
}
|
|
base = "http://127.0.0.1:" + port + "/api/v1"
|
|
}
|
|
return base
|
|
}
|
|
```
|
|
|
|
## How Match Data Gets Cached
|
|
|
|
The prefetch service fetches `/api/v1/articles?page=1&page_size=10&published=true` which:
|
|
|
|
1. Queries articles from database with `Preload("Author").Preload("Category")`
|
|
2. **Batch loads match links** for all articles:
|
|
```go
|
|
var matchLinks []models.ArticleMatchLink
|
|
bc.DB.Where("article_id IN ?", articleIDs).Find(&matchLinks)
|
|
```
|
|
3. Assigns match links to each article in the response
|
|
4. Returns JSON with full article data including `match_link` object
|
|
|
|
The JSON response structure includes:
|
|
```json
|
|
{
|
|
"items": [
|
|
{
|
|
"ID": 1,
|
|
"title": "...",
|
|
"category": { "ID": 1, "name": "..." },
|
|
"match_link": {
|
|
"ID": 1,
|
|
"article_id": 1,
|
|
"external_match_id": "89d23bfd-5be6-416a-96d0-35ec694aa22c",
|
|
"title": "Match Title"
|
|
}
|
|
}
|
|
],
|
|
"total": 1,
|
|
"page": 1,
|
|
"page_size": 10
|
|
}
|
|
```
|
|
|
|
## Testing
|
|
|
|
### 1. Create a New Published Article
|
|
1. Go to `/admin/articles`
|
|
2. Create a new article with "Publikovat" checked
|
|
3. Optionally link to a match via the match selector
|
|
4. Click "Vytvořit článek"
|
|
5. **Wait ~2 seconds** for prefetch to complete
|
|
6. Check `cache/prefetch/articles.json` - it should now contain your article with full data including match link
|
|
|
|
### 2. Update an Existing Article
|
|
1. Edit an existing article
|
|
2. Change content or publish status
|
|
3. Save changes
|
|
4. **Wait ~2 seconds** for prefetch to complete
|
|
5. Check cache file - it should be updated
|
|
|
|
### 3. Manual Trigger (Admin)
|
|
You can also manually trigger prefetch:
|
|
```bash
|
|
# Via admin endpoint
|
|
curl -X POST http://localhost:8080/api/v1/admin/prefetch/trigger \
|
|
-H "Authorization: Bearer YOUR_JWT_TOKEN"
|
|
```
|
|
|
|
Or from admin panel: Visit `/admin/tools` and click "Refresh Cache"
|
|
|
|
## Environment Variables
|
|
|
|
You can configure the base URL for prefetch if needed:
|
|
|
|
```bash
|
|
# Default (uses internal localhost)
|
|
# No config needed
|
|
|
|
# Custom target (e.g., behind nginx proxy)
|
|
PREFETCH_TARGET="http://your-domain.com/api/v1"
|
|
|
|
# Custom port
|
|
PORT="3000"
|
|
|
|
# Prefetch interval (default 30 minutes)
|
|
PREFETCH_INTERVAL_MINUTES="15"
|
|
```
|
|
|
|
## Verification Commands
|
|
|
|
```bash
|
|
# Check if articles are in cache
|
|
cat cache/prefetch/articles.json | jq '.items | length'
|
|
|
|
# See full article data with match links
|
|
cat cache/prefetch/articles.json | jq '.items[0]'
|
|
|
|
# Check prefetch status
|
|
cat cache/prefetch/prefetch_status.json | jq '.'
|
|
|
|
# Check last update time
|
|
cat cache/prefetch/meta.json | jq '.'
|
|
```
|
|
|
|
## Benefits
|
|
|
|
✅ **Immediate cache updates** - Articles appear in cache within seconds of creation
|
|
✅ **Match data preserved** - Full match link information is cached correctly
|
|
✅ **Category data included** - Complete category objects in cached response
|
|
✅ **Non-blocking** - Prefetch runs asynchronously (doesn't slow down API responses)
|
|
✅ **Existing behavior maintained** - 30-minute background refresh still runs
|
|
✅ **Smart triggers** - Only triggers for published articles (drafts don't waste resources)
|
|
|
|
## Files Modified
|
|
|
|
1. `internal/controllers/article_controller.go` - Added prefetch trigger on create
|
|
2. `internal/controllers/base_controller.go` - Added prefetch trigger on update
|
|
3. `ARTICLE_CACHE_MATCH_DATA_FIX.md` (this file) - Documentation
|
|
|
|
## Related Systems
|
|
|
|
- **Prefetch Service**: `internal/services/prefetch_service.go`
|
|
- **Prefetch Controller**: `internal/controllers/prefetch_controller.go`
|
|
- **Article Match Links**: `internal/models/models.go` (ArticleMatchLink)
|
|
- **Cache Directory**: `cache/prefetch/`
|
|
|
|
## Future Enhancements
|
|
|
|
Consider adding prefetch triggers for:
|
|
- Article deletion (to remove from cache)
|
|
- Match link creation/updates
|
|
- Category changes
|
|
- Featured article toggles
|