# Blog Creation Testing Guide ## What I Fixed After your 15+ hours of debugging, I've created a **bulletproof blog creation handler** with: 1. **Comprehensive error handling** - Every step is logged and validated 2. **Detailed logging** - You can see exactly where it fails if there's an issue 3. **Input validation** - All fields are properly validated before processing 4. **Automatic slug generation** - Handles Czech/Slovak diacritics correctly 5. **Category auto-creation** - Creates categories if they don't exist 6. **SEO metadata generation** - Auto-fills SEO fields with sensible defaults 7. **Read time estimation** - Calculates estimated reading time 8. **File tracking** - Tracks uploaded images for later management ## Files Created/Modified ### New Files: - `internal/controllers/article_controller.go` - New dedicated article controller with comprehensive error handling ### Modified Files: - `internal/routes/routes.go` - Updated to use the new article controller ## How to Test ### 1. Start Your Server ```bash cd /home/tdvorak/Desktop/PROG+HTML/Fotbal/fotbal-club go run cmd/server/main.go ``` ### 2. Get Authentication Token First, log in to get a token: ```bash curl -X POST http://localhost:8080/api/v1/auth/login \ -H "Content-Type: application/json" \ -d '{ "email": "your-email@example.com", "password": "your-password" }' ``` Save the token from the response. ### 3. Create a Blog Article #### Minimal Example (Title + Content only): ```bash curl -X POST http://localhost:8080/api/v1/articles \ -H "Content-Type: application/json" \ -H "Authorization: Bearer YOUR_TOKEN_HERE" \ -d '{ "title": "Testovací článek", "content": "
Toto je testovací článek s HTML obsahem.
", "category_name": "Aktuality" }' ``` #### Full Example (All fields): ```bash curl -X POST http://localhost:8080/api/v1/articles \ -H "Content-Type: application/json" \ -H "Authorization: Bearer YOUR_TOKEN_HERE" \ -d '{ "title": "Vítězství našeho týmu", "content": "Náš tým dnes zvítězil 3:1 nad soupeřem. Jana Nováková vstřelila dva góly a celý tým podal skvělý výkon.
", "category_name": "Výsledky zápasů", "image_url": "/uploads/2025/01/team-photo.jpg", "published": true, "featured": false, "slug": "vitezstvi-naseho-tymu", "seo_title": "Vítězství našeho týmu 3:1 | Fotbalový klub", "seo_description": "Náš tým dnes zvítězil 3:1. Přečtěte si o skvělém výkonu a gólu Jany Novákové.", "youtube_video_id": "dQw4w9WgXcQ", "youtube_video_title": "Sestřih ze zápasu", "youtube_video_url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ" }' ``` ### 4. Test from Frontend Your existing frontend code in `ArticlesAdminPage.tsx` should work without any changes! The API endpoint is already configured correctly at `/api/v1/articles`. ## What Happens Behind the Scenes When you create an article, the handler: 1. ✅ **Authenticates** the user (checks JWT token) 2. ✅ **Validates** required fields (title, content) 3. ✅ **Generates slug** from title if not provided (handles Czech characters) 4. ✅ **Ensures unique slug** (adds numbers if collision detected) 5. ✅ **Resolves/creates category** by name or ID 6. ✅ **Sets published status** and timestamp 7. ✅ **Calculates read time** from word count 8. ✅ **Generates SEO metadata** with fallbacks 9. ✅ **Sets default image** if none provided 10. ✅ **Saves all optional fields** (YouTube, gallery, attachments) 11. ✅ **Tracks file usage** (async, won't slow down response) 12. ✅ **Returns complete article** with associations loaded ## Logging All actions are logged to help you debug. Look for lines like: ``` [INFO] CreateArticle: Request from user 1 (admin@example.com) [INFO] CreateArticle: Creating article 'Test Article' by user 1 [INFO] CreateArticle: Generated slug 'test-article' from title [INFO] CreateArticle: Using category ID 5 [INFO] CreateArticle: Estimated read time: 2 minutes [INFO] CreateArticle: Successfully created article ID=42, slug=test-article ``` ## Error Handling If something goes wrong, you'll get detailed error messages: - **401 Unauthorized** - Not logged in or invalid token - **400 Bad Request** - Missing required fields or invalid JSON - **500 Internal Server Error** - Database error (check logs) Each error includes: - Clear Czech error message (`error` field) - Technical details (`details` field) for debugging ## Common Issues and Solutions ### Issue: "Uživatel není přihlášen" **Solution:** Make sure you're sending the Authorization header with Bearer token ### Issue: "Neplatná data požadavku" **Solution:** Check that title and content are provided and JSON is valid ### Issue: Slug already exists **Solution:** The handler automatically adds numbers (-1, -2, etc.) to make it unique ### Issue: Database connection error **Solution:** Check that PostgreSQL is running and connection string is correct ## Development Mode Bypass For testing, you can use the dev bypass header (non-production only): ```bash curl -X POST http://localhost:8080/api/v1/articles \ -H "Content-Type: application/json" \ -H "X-Dev-Admin: true" \ -d '{ "title": "Test Article", "content": "Test content
", "category_name": "Test Category" }' ``` This works because your frontend sends `X-Dev-Admin: true` in development (see `frontend/src/services/api.ts`). ## Next Steps 1. **Test basic creation** with minimal fields 2. **Test with all fields** including YouTube and gallery 3. **Test category creation** - use a new category name 4. **Test slug generation** - use Czech characters in title 5. **Test duplicate detection** - create two articles with same title 6. **Check frontend** - Open the admin panel and create articles through UI ## Need Help? Check the server logs for detailed information: ```bash # If using systemd journalctl -u fotbal-club -f # Or if running directly # Look at console output where you started the server ``` The logs will show you exactly what's happening at each step!