package main import ( "log" "net/http" "encoding/json" "os" "github.com/golang-jwt/jwt" "time" "database/sql" _ "github.com/lib/pq" ) func GenerateJwt(username string) (string, error) { token := jwt.New(jwt.SigningMethodEdDSA) claims := token.Claims.(jwt.MapClaims) claims["exp"] = time.Now().Add(10 * time.Minute) claims["authorized"] = true claims["user"] = username tokenString, err := token.SignedString(os.Getenv("GREPFOOD_JWT_SECRET")) if err != nil { return "", err } return tokenString, nil } func WriteJson(w http.ResponseWriter, v any) { w.Header().Set("Content-Type", "application/json") jsonData, err := json.Marshal(v) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } w.Write(jsonData) } func handleVersion(w http.ResponseWriter, r *http.Request) { version := struct {Version string `json:version`} { Version: "0.1.0-demo", } WriteJson(w, version) } func InitDatabase(db *sql.DB) { _, err := db.Exec( `CREATE TABLE IF NOT EXISTS ingredient ( id SERIAL, name VARCHAR(64) UNIQUE NOT NULL, icon VARCHAR(64), price INT, PRIMARY KEY(id) )`) if err != nil { log.Fatal(err) } log.Print("created table for ingredients") _, err = db.Exec( `CREATE TABLE IF NOT EXISTS recipe ( id SERIAL, name VARCHAR(64) UNIQUE NOT NULL, icon VARCHAR(64), PRIMARY KEY(id) )`) if err != nil { log.Fatal(err) } log.Print("created table for receipts") _, err = db.Exec( `CREATE TABLE IF NOT EXISTS recipe_ingredient ( recipe_id INT NOT NULL, ingredient_d INT NOT NULL, amount INT, FOREIGN KEY (recipe_id) REFERENCES recipe(id), FOREIGN KEY (ingredient_d) REFERENCES ingredient(id) )`) if err != nil { log.Fatal(err) } log.Print("created table for recipe ingredients") } type Ingredient struct { Name string `json:name` Icon string `json:icon` Price int `json:price` } type Recipe struct { Name string `json:name` Icon string `json:icon` } type RecipeIngredient struct { Recipe int `json:recipe` Ingredient int `json:ingredient` Amount int `json:amount` } func main() { dbconn := os.Getenv("GREPFOOD_DATABASE_CONNECTION") db, err := sql.Open("postgres", dbconn) if err != nil { log.Fatal(err) } log.Print("connected to database: ", dbconn) InitDatabase(db) http.HandleFunc("/version", handleVersion) http.HandleFunc("/api/recipes", func(w http.ResponseWriter, r *http.Request) { rows, err := db.Query("SELECT name, icon FROM recipe") if err != nil { http.Error(w, "Internal server error", http.StatusInternalServerError) return } recipes := struct { Recipes []Recipe `json:recipes`} { Recipes: []Recipe{}, } for rows.Next() { recipe := Recipe{} rows.Scan(&recipe.Name, &recipe.Icon) recipes.Recipes = append(recipes.Recipes, recipe) } WriteJson(w, recipes) }) log.Fatal(http.ListenAndServe(os.Getenv("GREPFOOD_SYNCSERVER_PORT"), nil)) }