Thanks! I think I got it except for one concern - my AdminService interface is not even being used (see below).
Also, can you look at NewAdminService
and let me know if it looks ok? I am instantiating my db inside it and returning a new struct.

cmd/web/server.go
type AdminController struct {
// by not exporting this, it is only available to methods on the AdminController
adminService *bolt.AdminService
}
// TODO: is it possible to get rid of this global?
var configuration config.Configuration
func init() {
// initialize the db
configPath := flag.String("config", "", "Path to config.json")
flag.Parse()
if *configPath == "" {
*configPath = config.GetPathOfConfig()
}
configuration = config.ReadConf(*configPath)
}
func main() {
adminService, err := bolt.NewAdminService(configuration.DbPath)
if err != nil {
log.Fatal(err)
}
ac := AdminController{
adminService: adminService,
}
r := mux.NewRouter()
r.HandleFunc("/adminlogin", ac.adminLogin).Methods("POST")
defer adminService.Store.Close()
h := c.Handler(r)
log.Fatal(http.ListenAndServe(":"+configuration.WebPort, h))
}
bolt/main.go
// AdminService represents a BoltDB implementation of admin.UserService.
type AdminService struct {
Store *cayley.Handle
}
// open a db connection and store it's handle inside AdminService instance
func NewAdminService(dbFile string) (*AdminService, error) {
graph.InitQuadStore("bolt", dbFile, nil)
// Open and use the database
db, err := cayley.NewGraph("bolt", dbFile, nil)
if err != nil {
log.Fatalln(err)
}
adminService := &AdminService{Store: db}
return adminService, nil
}
The only concern I have is this: in the root folder I have all my domain related structures that are needed both by the CLI and the Web executables. (This idea is based on the standard package layout blog post) And currently this interface is not even being used:
admin.go
type AdminService interface {
CreateAdmin(a *Admin, password string) error
Login(password string) (string, error)
Authenticate(jwt string) (MyCustomClaims, error)
AddClinic(c *Clinic, email string) error
All() ([]Admin, error)
AllClinics() ([]Clinic, error)
GetClinic(clinicId string) (Clinic, error)
AddEmployee(e *NewEmployee, clinicId string, email string) error
AllEmployees() ([]Employee, error)
// Admin(id int) (*Admin, error)
// Admins() ([]*Admin, error)
// DeleteAdmin(id int) error
}
Here my project’s folders:
.
├── admin.go
├── bolt
│ ├── add-clinic.go
│ ├── add-employee.go
│ ├── authenticate.go
│ ├── create-admin.go
│ ├── delete-clinic.go
│ ├── get-clinic.go
│ ├── list-admins.go
│ ├── list-clinics.go
│ ├── list-employees.go
│ ├── login.go
│ ├── main.go
│ └── quads.go
├── cmd
│ ├── cli
│ │ ├── add-admin.go
│ │ ├── add-clinic.go
│ │ ├── add-employee.go
│ │ ├── cli
│ │ ├── config.json.sample
│ │ ├── delete-clinic.go
│ │ ├── get-clinic.go
│ │ ├── list-admins.go
│ │ ├── list-clinics.go
│ │ ├── list-employees.go
│ │ ├── list-quads.go
│ │ ├── login-admin.go
│ │ ├── main.go
│ │ ├── README.md
│ │ └── test.sh
│ └── web
│ ├── add_clinic_test.go
│ ├── admin-login.go
│ ├── config.json.sample
│ ├── location
│ ├── login_test.go
│ ├── README.md
│ ├── server.go
│ ├── tmp
│ └── web
├── config
│ ├── getdatadir_unix.go
│ ├── getdatadir_windows.go
│ └── main.go