Premier League Predictor: FastAPI & PostgreSQL — Chapter 5, Exercise 3 ==================================================== TASK Record a user, an expert, an AI, and two separately-named guest predictions against a single real fixture, then call GET /api/fixtures/{id}/predictions and confirm all five rows come back with the correct source and guest_name values. SOLUTION Using a real fixture_id from a fixture already created in Chapter 4 (43, for this example), five POST requests to /api/fixtures/43/predictions: 1. {"source": "user", "guest_name": null, "predicted_home_score": 2, "predicted_away_score": 1} 2. {"source": "expert", "guest_name": null, "predicted_home_score": 1, "predicted_away_score": 1} 3. {"source": "ai", "guest_name": null, "predicted_home_score": 2, "predicted_away_score": 0} 4. {"source": "guest", "guest_name": "Micah Richards", "predicted_home_score": 3, "predicted_away_score": 0} 5. {"source": "guest", "guest_name": "Jamie Carragher", "predicted_home_score": 1, "predicted_away_score": 0} Each of these returns a 200 with the newly created row, since none of them collides with an existing prediction for that source (and, for the guest rows, that specific guest_name). Calling GET /api/fixtures/43/predictions afterward returns a JSON array of exactly five objects. Checking it against what was submitted: - One row with source "user", guest_name null, 2-1 — matches submission 1. - One row with source "expert", guest_name null, 1-1 — matches submission 2. - One row with source "ai", guest_name null, 2-0 — matches submission 3. - One row with source "guest", guest_name "Micah Richards", 3-0 — matches submission 4. - One row with source "guest", guest_name "Jamie Carragher", 1-0 — matches submission 5. All five rows are present because only the "guest" rows shared a source with each other, and they're distinguished by their own different guest_name values — exactly the partial-unique-index behavior from Exercise 1, confirmed by actually running it against a real fixture rather than only reasoning about it. WHY THIS WORKS AS AN ANSWER ---------------------------- It provides five real, concrete request bodies covering all four sources (with two distinctly-named guests), then verifies the GET response against each individual submission by source and guest_name, directly confirming in practice that the partial unique index and the upsert route behave exactly as Exercises 1 and 2 explained.