package main import ( "context" "flag" "fmt" "fuj-management/go/internal/config" "fuj-management/go/internal/logging" "fuj-management/go/internal/services/membership" "fuj-management/go/internal/web" "os" "time" ) // Injected at build time via -ldflags "-X main.version=... -X main.commit=... -X main.buildDate=..." var ( version = "dev" commit = "unknown" buildDate = "unknown" ) func main() { if len(os.Args) < 2 { usage() os.Exit(2) } cmd, args := os.Args[1], os.Args[2:] switch cmd { case "server": serverCmd(args) case "version": versionCmd() case "fees": feesCmd(args) case "reconcile": reconcileCmd(args) case "sync", "infer": fmt.Fprintf(os.Stderr, "fuj %s: not implemented yet (lands in M4)\n", cmd) os.Exit(2) case "-h", "--help", "help": usage() default: fmt.Fprintf(os.Stderr, "fuj: unknown command %q\n\n", cmd) usage() os.Exit(2) } } func serverCmd(args []string) { fs := flag.NewFlagSet("server", flag.ExitOnError) addr := fs.String("addr", "", "listen address (default from SERVER_ADDR env or :8080)") fs.Usage = func() { fmt.Fprintln(os.Stderr, "usage: fuj server [--addr :8080]") fs.PrintDefaults() } if err := fs.Parse(args); err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(2) } cfg := config.Load() if *addr != "" { cfg.ServerAddr = *addr } logger := logging.New(cfg.LogLevel) build := web.BuildInfo{Version: version, Commit: commit, BuildDate: buildDate} if err := web.Run(logger, cfg.ServerAddr, build); err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } } func feesCmd(args []string) { fs := flag.NewFlagSet("fees", flag.ExitOnError) fs.Usage = func() { fmt.Fprintln(os.Stderr, "usage: fuj fees") } if err := fs.Parse(args); err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(2) } sources := membership.NewStubSources() if err := membership.FeesReport(context.Background(), sources, os.Stdout); err != nil { fmt.Fprintf(os.Stderr, "fuj fees: %v\n", err) os.Exit(1) } } func reconcileCmd(args []string) { fs := flag.NewFlagSet("reconcile", flag.ExitOnError) fs.Usage = func() { fmt.Fprintln(os.Stderr, "usage: fuj reconcile") } if err := fs.Parse(args); err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(2) } sources := membership.NewStubSources() if err := membership.ReconcileReport(context.Background(), sources, time.Now().Year(), os.Stdout); err != nil { fmt.Fprintf(os.Stderr, "fuj reconcile: %v\n", err) os.Exit(1) } } func versionCmd() { fmt.Printf("fuj %s (%s) built %s\n", version, commit, buildDate) } func usage() { fmt.Fprintln(os.Stderr, `usage: fuj [flags] Commands: server Start HTTP server (default :8080) version Print version information fees Calculate monthly fees reconcile Show balance report sync Sync Fio transactions [M4] infer Infer payment details [M4]`) }