This commit is contained in:
2025-04-28 00:04:14 +02:00
parent 39a80829c9
commit 8858578f84
16 changed files with 758 additions and 1 deletions

82
api/auction_handler.go Normal file
View File

@@ -0,0 +1,82 @@
package api
import (
"encoding/json"
"net/http"
"pokeval/db"
"strconv"
"github.com/gorilla/mux"
)
// GET /api/v1/auctions/{id}
func GetAuction(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
id, _ := strconv.Atoi(vars["id"])
row := db.DB.QueryRow("SELECT id, card_id, price, date_sold FROM auctions WHERE id = ?", id)
var auctionID, cardID int
var price float64
var dateSold string
err := row.Scan(&auctionID, &cardID, &price, &dateSold)
if err != nil {
http.Error(w, "Auktion nicht gefunden", http.StatusNotFound)
return
}
resp := map[string]interface{}{
"id": auctionID,
"card_id": cardID,
"price": price,
"date_sold": dateSold,
}
json.NewEncoder(w).Encode(resp)
}
// POST /api/v1/auctions
func CreateAuction(w http.ResponseWriter, r *http.Request) {
var input struct {
CardID int `json:"card_id"`
PlatformID int `json:"platform_id"`
Price float64 `json:"price"`
Currency int `json:"currency"`
DateSold string `json:"date_sold"`
}
json.NewDecoder(r.Body).Decode(&input)
_, err := db.DB.Exec("INSERT INTO auctions (card_id, platform_id, price, currency, date_sold) VALUES (?, ?, ?, ?, ?)",
input.CardID, input.PlatformID, input.Price, input.Currency, input.DateSold)
if err != nil {
http.Error(w, "Fehler beim Erstellen der Auktion", http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusCreated)
json.NewEncoder(w).Encode(map[string]string{"message": "Auktion erfolgreich erstellt"})
}
// GET /api/v1/auctions
func ListAuctions(w http.ResponseWriter, r *http.Request) {
rows, err := db.DB.Query("SELECT id, card_id, price FROM auctions LIMIT 50")
if err != nil {
http.Error(w, "Fehler beim Laden der Auktionen", http.StatusInternalServerError)
return
}
defer rows.Close()
var auctions []map[string]interface{}
for rows.Next() {
var id, cardID int
var price float64
rows.Scan(&id, &cardID, &price)
auctions = append(auctions, map[string]interface{}{
"id": id,
"card_id": cardID,
"price": price,
})
}
json.NewEncoder(w).Encode(auctions)
}

90
api/card_handler.go Normal file
View File

@@ -0,0 +1,90 @@
package api
import (
"encoding/json"
"net/http"
"pokeval/db"
"pokeval/models"
"strconv"
"github.com/gorilla/mux"
)
// GET /api/v1/cards/{id}
func GetCard(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
cardID, _ := strconv.Atoi(vars["id"])
var card models.Card
err := db.DB.QueryRow("SELECT cards_id, cards_number, cards_name FROM cards WHERE cards_id = ?", cardID).
Scan(&card.ID, &card.Number, &card.Name)
if err != nil {
http.Error(w, "{}", 404)
return
}
// Attribute laden
rows, _ := db.DB.Query(`
SELECT ak.attributekeys_name, a.attributes_value
FROM attributes a
JOIN attributekeys ak ON ak.attributekeys_id = a.attributes_key
WHERE a.attributes_card = ?`, cardID)
attrs := make(map[string]interface{})
for rows.Next() {
var key string
var value []byte
rows.Scan(&key, &value)
var parsed interface{}
json.Unmarshal(value, &parsed)
attrs[key] = parsed
}
card.Attributes = attrs
json.NewEncoder(w).Encode(card)
}
// GET /api/v1/cards/{id}
/*func GetCard(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
id, _ := strconv.Atoi(vars["id"])
row := db.DB.QueryRow("SELECT id, name, number FROM cards WHERE id = ?", id)
var cardID int
var name, number string
err := row.Scan(&cardID, &name, &number)
if err != nil {
http.Error(w, "Karte nicht gefunden", http.StatusNotFound)
return
}
resp := map[string]interface{}{
"id": cardID,
"name": name,
"number": number,
}
json.NewEncoder(w).Encode(resp)
}*/
// POST /api/v1/cards
func CreateCard(w http.ResponseWriter, r *http.Request) {
var input struct {
Name string `json:"name"`
Number string `json:"number"`
SeriesID int `json:"series_id"`
}
json.NewDecoder(r.Body).Decode(&input)
_, err := db.DB.Exec("INSERT INTO cards (name, number, series_id) VALUES (?, ?, ?)",
input.Name, input.Number, input.SeriesID)
if err != nil {
http.Error(w, "Fehler beim Erstellen der Karte", http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusCreated)
json.NewEncoder(w).Encode(map[string]string{"message": "Karte erfolgreich erstellt"})
}

37
api/lookup_handler.go Normal file
View File

@@ -0,0 +1,37 @@
package api
import (
"encoding/json"
"net/http"
"pokeval/db"
)
// GET /api/v1/platforms
func GetPlatforms(w http.ResponseWriter, r *http.Request) {
rows, _ := db.DB.Query("SELECT id, platform_name FROM auction_platform")
defer rows.Close()
var platforms []map[string]interface{}
for rows.Next() {
var id int
var name string
rows.Scan(&id, &name)
platforms = append(platforms, map[string]interface{}{"id": id, "name": name})
}
json.NewEncoder(w).Encode(platforms)
}
// GET /api/v1/currencies
func GetCurrencies(w http.ResponseWriter, r *http.Request) {
rows, _ := db.DB.Query("SELECT id, currency_code FROM currency")
defer rows.Close()
var currencies []map[string]interface{}
for rows.Next() {
var id int
var code string
rows.Scan(&id, &code)
currencies = append(currencies, map[string]interface{}{"id": id, "code": code})
}
json.NewEncoder(w).Encode(currencies)
}

29
api/router.go Normal file
View File

@@ -0,0 +1,29 @@
package api
import (
"github.com/gorilla/mux"
)
func NewRouter() *mux.Router {
router := mux.NewRouter().StrictSlash(true)
// Auktionen
router.HandleFunc("/api/v1/auctions/{id}", GetAuction).Methods("GET")
router.HandleFunc("/api/v1/auctions", CreateAuction).Methods("POST")
router.HandleFunc("/api/v1/auctions", ListAuctions).Methods("GET")
// Karten
router.HandleFunc("/api/v1/cards/{id}", GetCard).Methods("GET")
router.HandleFunc("/api/v1/cards", CreateCard).Methods("POST")
// Bewertung
router.HandleFunc("/api/v1/value/{auction_id}", GetCardValue).Methods("GET")
// Lookup-Tabellen
router.HandleFunc("/api/v1/platforms", GetPlatforms).Methods("GET")
router.HandleFunc("/api/v1/currencies", GetCurrencies).Methods("GET")
/*router.HandleFunc("/api/v1/autograph-types", GetAutographTypes).Methods("GET")
router.HandleFunc("/api/v1/misprint-types", GetMisprintTypes).Methods("GET")*/
return router
}

106
api/value_handler.go Normal file
View File

@@ -0,0 +1,106 @@
package api
import (
"encoding/json"
"net/http"
"pokeval/db"
"pokeval/logic"
"strconv"
"github.com/gorilla/mux"
)
// GET /api/v1/value/{auction_id}
func GetCardValue(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
auctionID, err := strconv.Atoi(vars["auction_id"])
if err != nil {
http.Error(w, "Ungültige Auktions-ID", http.StatusBadRequest)
return
}
// 1⃣ Hole die Basis-Auktionsdaten
var cardID int
query := `SELECT card_id FROM auctions WHERE id = ?`
err = db.DB.QueryRow(query, auctionID).Scan(&cardID)
if err != nil {
http.Error(w, "Auktion nicht gefunden", http.StatusNotFound)
return
}
// 2⃣ Base Sales: Alle Verkäufe dieser Karte
baseSales := fetchBaseSales(cardID)
// 3⃣ Exact Match Sales: Verkäufe mit gleichem Grading, Autograph, Misprint
exactSales := fetchExactMatchSales(auctionID)
// 4⃣ Bewertungsfaktoren (Dummy-Werte oder aus DB/Logik ableiten)
factors := map[string]float64{
"GF": 1.6,
"RF": 2.0,
"EF": 2.0,
"ST": 3.5,
"DF": 1.4,
"AF": 2.0,
"MF": 1.5,
"TAF": 200,
}
// 5⃣ Wert berechnen
value := logic.CalculateCardValue(baseSales, exactSales, factors)
// 6⃣ Response
resp := map[string]interface{}{
"auction_id": auctionID,
"calculated_value": value,
"currency": "EUR",
"factors": factors,
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(resp)
}
// Holt alle Preise der Basisverkäufe (gleiche Karte)
func fetchBaseSales(cardID int) []float64 {
rows, err := db.DB.Query("SELECT price FROM auctions WHERE card_id = ?", cardID)
if err != nil {
return []float64{}
}
defer rows.Close()
var prices []float64
for rows.Next() {
var price float64
rows.Scan(&price)
prices = append(prices, price)
}
return prices
}
// Holt alle Exact Match Verkäufe (vereinfachte Logik)
func fetchExactMatchSales(auctionID int) []float64 {
// Beispielhafte Logik: Verkäufe mit gleichem Grading, Autograph & Misprint
query := `
SELECT a.price
FROM auctions a
JOIN auction_gradings ag ON ag.auction_id = a.id
WHERE a.id != ? AND ag.grading_id IN (
SELECT grading_id FROM auction_gradings WHERE auction_id = ?
)
`
rows, err := db.DB.Query(query, auctionID, auctionID)
if err != nil {
return []float64{}
}
defer rows.Close()
var prices []float64
for rows.Next() {
var price float64
rows.Scan(&price)
prices = append(prices, price)
}
return prices
}