init
This commit is contained in:
82
api/auction_handler.go
Normal file
82
api/auction_handler.go
Normal 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
90
api/card_handler.go
Normal 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
37
api/lookup_handler.go
Normal 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
29
api/router.go
Normal 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
106
api/value_handler.go
Normal 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
|
||||
}
|
||||
Reference in New Issue
Block a user