From 9c47618b5824787a50110f13561089f480233061 Mon Sep 17 00:00:00 2001
From: Ophestra Umiker <cat@ophivana.moe>
Date: Wed, 16 Oct 2024 22:07:06 +0900
Subject: [PATCH] feat(api): add registration count API endpoint

This adds /api/count which returns a value initialised on startup and incremented each successful registration.

Signed-off-by: Ophestra Umiker <cat@ophivana.moe>
---
 app.go      |  9 ++++++++-
 count.go    | 32 ++++++++++++++++++++++++++++++++
 register.go |  4 +++-
 3 files changed, 43 insertions(+), 2 deletions(-)
 create mode 100644 count.go

diff --git a/app.go b/app.go
index 08cd160..2b73e58 100644
--- a/app.go
+++ b/app.go
@@ -4,6 +4,7 @@ import (
 	"fmt"
 	"log"
 	"os"
+	"sync/atomic"
 	"time"
 
 	"github.com/gofiber/contrib/hcaptcha"
@@ -54,8 +55,14 @@ func serve(sig chan os.Signal, db *leveldb.DB) error {
 			confEnv[hCaptchaSiteKey][0], confEnv[hCaptchaSecretKey][0])
 	}
 
+	count := new(atomic.Uint64)
+
 	routeHCaptchaSiteKey(app, "/api", !hCaptchaEnable, conf[hCaptchaSiteKey])
-	routeRegister(app, "/api/register", db, captcha)
+	routeRegister(app, "/api/register", db, count, captcha)
+
+	if err := routeCount(app, "/api/count", db, count); err != nil {
+		return err
+	}
 
 	// graceful shutdown
 	go func() {
diff --git a/count.go b/count.go
new file mode 100644
index 0000000..bff029a
--- /dev/null
+++ b/count.go
@@ -0,0 +1,32 @@
+package main
+
+import (
+	"log"
+	"strconv"
+	"sync/atomic"
+
+	"github.com/gofiber/fiber/v3"
+	"github.com/syndtr/goleveldb/leveldb"
+)
+
+func routeCount(app *fiber.App, p string, db *leveldb.DB, count *atomic.Uint64) error {
+	var c uint64
+	iter := db.NewIterator(nil, nil)
+	for iter.Next() {
+		c++
+	}
+	iter.Release()
+	if err := iter.Error(); err != nil {
+		return err
+	}
+	count.Store(c)
+
+	log.Printf("registration count is %d on startup", c)
+
+	app.Get(p, func(c fiber.Ctx) error {
+		c.Set("Content-Type", "text/plain")
+		return c.SendString(strconv.FormatUint(count.Load(), 10))
+	})
+
+	return nil
+}
diff --git a/register.go b/register.go
index a27fb24..5ad3d00 100644
--- a/register.go
+++ b/register.go
@@ -3,6 +3,7 @@ package main
 import (
 	"log"
 	"regexp"
+	"sync/atomic"
 
 	"github.com/gofiber/fiber/v3"
 	"github.com/syndtr/goleveldb/leveldb"
@@ -15,7 +16,7 @@ type registration struct {
 }
 
 // Waitlist registration route
-func routeRegister(app *fiber.App, p string, db *leveldb.DB, captcha fiber.Handler) {
+func routeRegister(app *fiber.App, p string, db *leveldb.DB, count *atomic.Uint64, captcha fiber.Handler) {
 	app.Post(p, func(c fiber.Ctx) error {
 		req := new(registration)
 
@@ -53,6 +54,7 @@ func routeRegister(app *fiber.App, p string, db *leveldb.DB, captcha fiber.Handl
 		}
 
 		log.Printf("registered email %q", req.Email)
+		count.Add(1)
 		return c.JSON(newMessage(true, "Email registered successfully"))
 	}, captcha)
 }
-- 
GitLab