Files
MyClub/ARTICLE_CACHE_MATCH_DATA_FIX.md
T
Tomas Dvorak 63700eedb2 dev day #67
2025-10-21 15:02:05 +02:00

6.4 KiB

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:

{"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:

// 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:

// 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:

// Trigger full prefetch cache update if article is published
if art.Published {
    go func() {
        base := getPrefetchBaseURL()
        services.PrefetchOnce(base)
    }()
}

Helper function added:

// 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:
    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:

{
  "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:

# 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:

# 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

# 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
  • 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