E-Auc an online auction.
E-Auc is a platform for sellers to post there products with a valid ask price and buyers to bid on the give product. the functionality involves.
Sellers to upload product with a valid ask price.
Buyers to bid on the product up-to set bid rate by seller.
With products image and description sellers will also add the address/google map link. for buyers to get an idea of product location.
Once bidding is completed a Chat room for some time will be available for seller and buyer to finally close the deal.
Project layout
The E-Auc is an opensource project uploaded in github. the project is made in golang (go) and react (javascript).
Below is the folder structure i am thinking to go forward with.
/NotWork/e-auc/server/
▾ cmd/
handler.go
main.go
▾ internal/services/users/
users.go
go.mod
go.sum
Makefile
As we'll build this application I'll be adding more files and folder however for now basic idea is to have server (handler) related code in cmd folder and all the business related code in internal folder. for now I have only created a user service in this I'll add different functions that are related to a user.
Database is a container (pod) I would be using podman in this series as an alternative to docker but it is easily switchable. below are the commands in Makefile for database.
# server/Makefile
# Database configuration
DB_HOST ?= localhost
DB_PORT ?= 5432
DB_USER ?= dbadmin
DB_PASSWORD ?= dbadminpw
DB_NAME ?= e-auc
DB_URL ?= postgres://\((DB_USER):\)(DB_PASSWORD)@\((DB_HOST):\)(DB_PORT)/$(DB_NAME)?sslmode=disable
# Migration configuration
MIGRATIONS_DIR ?= $(shell pwd)/migrations
.PHONY: run migrate-create migrate-up migrate-down
run:
go run cmd/*.go
## Usage: make migrate-create name=<migration_name>
migrate-create:
podman run --rm \
-v $(MIGRATIONS_DIR):/migrations \
--network host \
migrate/migrate \
create -ext sql -dir /migrations -seq -digits 3 $(name)
migrate-up:
podman run --rm \
-v $(MIGRATIONS_DIR):/migrations \
--network host \
migrate/migrate \
-path=/migrations/ -database "$(DB_URL)" up
migrate-down:
podman run --rm \
-v $(MIGRATIONS_DIR):/migrations \
--network host \
migrate/migrate \
-path=/migrations/ -database "$(DB_URL)" down 1
For database migration I am using migrate tool. (that too container image)
Note: I have also added a run command to start the go server
We'll now look at sqlc setup, for sqlc we only have to setup one yaml config file and then we mostly have to add the sql queries for now I'll only setup the sqlc.yaml file
version: "2"
sql:
- engine: "postgresql"
queries: "internal/db/queries/"
schema: "migrations/"
gen:
go:
package: "db"
out: "internal/db/generated"
sql_package: "pgx/v5"
overrides:
- db_type: "uuid"
go_type: "github.com/google/uuid.UUID"
- db_type: "timestamptz"
go_type: "time.Time"
- db_type: "citext"
go_type: "string"
- db_type: "text"
go_type: "string"
- db_type: "bool"
go_type: "bool"
Note: We have used pgx/v5 driver.
Note: We have to create a folder `internal/db/queries/`
I also update the makefile to add a command to generate the sqlc code.
sqlc-generate:
podman run --rm \
-v $(PWD):/src \
-w /src \
sqlc/sqlc generate
We'll try to implement TDD on service layer. and for testing we'll be using test containers. below is the setup for test container to create, migrate and run the postgres (database) container
package services
import (
"context"
"log"
"os"
"testing"
"github.com/golang-migrate/migrate/v4"
_ "github.com/golang-migrate/migrate/v4/database/postgres"
_ "github.com/golang-migrate/migrate/v4/source/file"
"github.com/jackc/pgx/v5/pgxpool"
"github.com/testcontainers/testcontainers-go/modules/postgres"
db "github.com/itsdrac/e-auc/internal/db/generated"
)
func TestMain(m *testing.M) {
ctx := context.Background()
// 1. Start PostgreSQL container.
// Note: testcontainers-go uses the Docker socket by default.
// With Podman on macOS, set DOCKER_HOST to your Podman socket path, e.g.:
// export DOCKER_HOST=unix:///var/run/docker.sock
pgContainer, err := postgres.Run(ctx, "postgres:latest",
postgres.WithDatabase("testdb"),
postgres.WithUsername("test"),
postgres.WithPassword("test"),
)
if err != nil {
log.Fatal("failed to start postgres container:", err)
}
// 2. Run migrations.
// Connection string format: postgres://test:test@localhost:PORT/testdb?sslmode=disable
connStr, err := pgContainer.ConnectionString(ctx, "sslmode=disable")
if err != nil {
log.Fatal("failed to get connection string:", err)
}
mig, err := migrate.New("file://../../../migrations", connStr)
if err != nil {
log.Fatal("failed to create migrator:", err)
}
if err := mig.Up(); err != nil && err != migrate.ErrNoChange {
log.Fatal("failed to run migrations:", err)
}
// 3. Build service.
pool, err := pgxpool.New(ctx, connStr)
if err != nil {
log.Fatal("failed to create connection pool:", err)
}
queries := db.New(pool)
svc = NewUserService(queries)
// 4. Run tests.
code := m.Run()
// 5. Teardown — container deletion removes all data.
pool.Close()
if err := pgContainer.Terminate(ctx); err != nil {
log.Printf("warning: failed to terminate container: %v", err)
}
os.Exit(code)
}
In next chapter we'll implement user create/login functionality.
Thanks.