{"id":20744665,"url":"https://github.com/opplieam/bb-admin-api","last_synced_at":"2026-05-06T09:34:14.759Z","repository":{"id":248713058,"uuid":"829482317","full_name":"opplieam/bb-admin-api","owner":"opplieam","description":"A stateless REST API developed in Go, utilizing a PostgreSQL database, and designed for production in a Kubernetes environment.","archived":false,"fork":false,"pushed_at":"2024-12-27T09:51:09.000Z","size":192,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-11T12:51:36.128Z","etag":null,"topics":["gin","go-jet","go-migrate","golang","kubernetes","mockery","rest","sql","testify"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/opplieam.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-07-16T14:13:00.000Z","updated_at":"2024-12-27T09:51:13.000Z","dependencies_parsed_at":"2024-11-12T17:19:30.372Z","dependency_job_id":"368fb7ca-29c5-4bfb-a577-872768b321bb","html_url":"https://github.com/opplieam/bb-admin-api","commit_stats":null,"previous_names":["opplieam/bb-admin-api"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/opplieam/bb-admin-api","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/opplieam%2Fbb-admin-api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/opplieam%2Fbb-admin-api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/opplieam%2Fbb-admin-api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/opplieam%2Fbb-admin-api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/opplieam","download_url":"https://codeload.github.com/opplieam/bb-admin-api/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/opplieam%2Fbb-admin-api/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32687067,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-06T08:33:17.875Z","status":"ssl_error","status_checked_at":"2026-05-06T08:33:17.221Z","response_time":117,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["gin","go-jet","go-migrate","golang","kubernetes","mockery","rest","sql","testify"],"created_at":"2024-11-17T07:16:47.280Z","updated_at":"2026-05-06T09:34:14.744Z","avatar_url":"https://github.com/opplieam.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Buy-Better Admin API\n![workflow](https://github.com/opplieam/bb-admin-api/actions/workflows/unittest.yml/badge.svg)\n## Table of contents\n- [Overview](#overview)\n- [Project structure](#project-structure)\n- [Dependencies](#dependencies)\n- [Developer Setup](#developer-setup)\n- [Running Test](#running-test)\n- [Starting server and swagger openapi for Frontend development](#starting-server-and-swagger-openapi-for-frontend-development)\n- [Running in local cluster minikube](#running-in-local-cluster-minikube)\n- [Useful Command/Makefile](#useful-commandmakefile)\n- [Database Schema](#database-schema)\n- [Design choice](#design-choice)\n\n## Overview\nBuy Better Admin API is an admin backend to handle the admin task like `category matching`, `product matching`, \n`user managment` etc. including a helper for web scraping part.\n\nCurrently, only `category matching` is available.\n\n`NOTE: This project is for learning purpose and not fully complete yet`\n\n## Project structure\n```\n├── .gen                # auto generated by jet-db\n│   ├── buy-better-admin\n├── .github\n│   ├── workflows\n├── bin                 # go binary\n├── cmd\n│   ├── api             # main package for api server\n│   ├── dbhelper        # a dev tool for database helper \n│   └── tokengen        # a dev tool for paseto generator\n├── data                # the sql file using for seed or test db\n├── internal\n│   ├── middleware      # api middleware\n│   ├── store           # database logic\n│   ├── utils           # global utilities\n│   └── v1\n│       ├── category    # category handler\n│       ├── probe       # liveness \u0026 readiness handler\n│       └── user        # user handler\n├── k8s\n│   ├── base            # kustomize base\n│   │   └── admin-api\n│   ├── dev             # patch kustomize\n│   │   └── admin-api\n│   └── secret          # bitnami sealed secrets\n│       └── dev\n├── migrations          # generated by migrate tool\n└── spec                # openapi v3 spec\n```\n\n## Dependencies\n#### Infrastructure\n- docker / docker-compose\n- minikube\n- kubectl / kustomize\n- helm\n- kubeseal\n#### Database tools\n- CLI go [migrate](https://github.com/golang-migrate/migrate/tree/master/cmd/migrate)\n- CLI [jet-db](https://github.com/go-jet/jet?tab=readme-ov-file#installation)\n#### Testing tools\n- CLI [mockery](https://vektra.github.io/mockery/latest/installation/)\n\n## Developer Setup\n1. Create environment variable store in `.env` file at root directory\n```\nWEB_SERVICE_ENV=\"dev\"\nWEB_ADDR=\":3000\"\nWEB_READ_TIMEOUT=5\nWEB_WRITE_TIMEOUT=40\nWEB_IDLE_TIMEOUT=120\nWEB_SHUTDOWN_TIMEOUT=20\n\nDB_DRIVER=\"postgres\"\nDB_DSN=\"postgresql://postgres:admin1234@localhost:5432/buy-better-admin?sslmode=disable\"\nDB_MAX_OPEN_CONNS=25\nDB_MAX_IDLE_CONNS=25\nDB_MAX_IDLE_TIME=\"15m\"\n\nTOKEN_ENCODED=\"1c0021bc344fa16c72fc522c53bfe9f77a2a597507374e56e3a275759c4c1562\"\n```\n\u003e For `TOKEN_ENCODED`, you can random generate using [this](https://www.browserling.com/tools/random-hex) and use 64 digits\n\n2. Create postgres environment variable in `.postgres.env` file at root directory. This will be used by `docker-compose`. \n\n```\nPOSTGRES_USER=\"postgres\"\nPOSTGRES_PASSWORD=\"admin1234\"\nPOSTGRES_DB=\"buy-better-admin\"\n```\n\u003e postgres environment variables must be match with Makefile\n\n3. Visit `Makefile` There are 4 important variables for local development. Feel free to edit. \n```\nDB_DSN\nDB_NAME\nDB_USERNAME\nCONTAINER_NAME\t\t\n```\n\n4. Start the development postgres db `make dev-db-up` this command does follow \n   * docker-compose with postgres image\n   * sleep for 3 seconds\n   * migrate up\n   * seed the fake data with `dbhelper` tool\n\n5. `go run cmd/api` start the server with port `:3000`\n\n## Running Test\n- Run only unit test `make test-unit-v`\n- Run only integration test `make test-integr-v`\n- Run all test `make test-all-v`\n\n## Starting server and swagger openapi for Frontend development\n![swagger](https://github.com/opplieam/buy-better/blob/main/swagger.png?raw=true)\n- `make server up` starting postgres db, swagger and buy better admin server\n  * `localhost:3000` - buy better admin server\n  * `localhost:8081` - swagger openapi\n- `make server down` shutting postgres db and swagger down\n\n## Running in local cluster minikube\n1.  create `encoded-secret.yaml` under k8s/secret/dev\n```\napiVersion: v1\nkind: Secret\nmetadata:\n  name: admin-api-secret\n  namespace: buy-better\n\ntype: Opaque\ndata:\n  TOKEN_ENCODED: \"your base64 encode to TOKEN_ENCODED\"\n```\n2. `make dev-up-all`\n    * starting postgres db -\u003e migration -\u003e seed fake data\n    * starting minikube \n    * apply `bitnami-sealed-secrets` controller\n\n3. `minikbue tunnel` to expose load balancer\n4. `make dev-apply`\n    * go mod tidy\n    * building an image with docker\n    * kustomize apply resources\n    * generate and apply bitnami secret\n    * restart deployment (due to bitnami seal secret controller changing certificate everytime when starting a new cluster)\n     \n## Useful Command/Makefile\n\nPlease visit `Makefile` for the full command.\n- `make token-gen-build` build a binary of paseto token generator for testing\n   * `make token-gen-valid` generate a valid token with 1 hour expiration and user_id 1\n   * `make token-gen-expire` generate an expired token with user_id 1\n- `make jet-gen` generate a type safe from database. run this command everytime there is a change in database schema.\n- `mockery` generate a mock file. please visit `.mockery.yaml` for the setting\n- `make dev-db-reset` restart the postgres container. run when you want to reset the database\n\n## Database Schema\n\n![db](https://github.com/opplieam/bb-admin-api/blob/main/Buy-Better-Admin.png?raw=true)\n\n## Design choice\n\nMost of the tools and 3rd party libraries are for learning purpose and convenience. I will try to explain some libraries.\n\n- `go migrate` a go native migration tool with go SDK So it can run programmatic migration. \nIt's useful when run integration test with `dockertest` \n- `gin` it has many useful features like `validator` and middleware. Yes, I can use `chi` router but eventually I will\nuse `validator` package. So I picked `gin` which already had built-in `validator`.\n- `testify` a test suite feature is the reason. I planned to separate a unit and integration test with test suite.\n- `jet-db` a type safe sql builder. very good dx for dynamic queries from my research.\nwhich is the best match for this project. I also prefer SQL style rather than ORM\n- `paseto` instead of jwt. This is related to the frontend development. I planned to store token for both localstorage\nand cookies (token and refresh token). both storage have pros and cons. So I spread the risk into 2 storage \n(cookies and localstorage). Since paseto is an encrypted token. It made it very difficult to encrypted \nif the token is leaked.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopplieam%2Fbb-admin-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopplieam%2Fbb-admin-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopplieam%2Fbb-admin-api/lists"}