feat: social graph features

This commit is contained in:
Krispire Admin
2026-06-04 19:29:48 +05:30
parent d9678ebb3b
commit efa1eaf23b
28 changed files with 1882 additions and 78 deletions
+30
View File
@@ -1,13 +1,16 @@
package handler
import (
"context"
"encoding/json"
"errors"
"net/http"
"time"
"github.com/prabhupadasays/spsays-bff/internal/middleware"
"github.com/prabhupadasays/spsays-bff/internal/service"
"github.com/prabhupadasays/spsays-bff/pkg/auth"
"github.com/prabhupadasays/spsays-bff/pkg/geoip"
"github.com/prabhupadasays/spsays-bff/pkg/response"
"github.com/prabhupadasays/spsays-bff/pkg/validator"
)
@@ -94,10 +97,37 @@ func (h *AuthHandler) SignUp(w http.ResponseWriter, r *http.Request) {
h.renderAuthErr(w, err)
return
}
h.captureCountry(r, res.User.ID)
auth.Set(w, res.Token, res.Expires, h.cookies)
response.JSON(w, http.StatusCreated, res.User)
}
// captureCountry records the new account's country off the critical path.
// Cloudflare's CF-IPCountry header is preferred (no network); when absent
// — as in the current DNS-only setup — we fall back to a GeoIP lookup on
// the client IP. The header read + IP extraction happen synchronously
// (they need the live request), then the network lookup + DB write run in
// a goroutine so signup latency is untouched. Any failure is silent: the
// account simply keeps country = NULL until the user sets it themselves.
func (h *AuthHandler) captureCountry(r *http.Request, userID string) {
cfCountry := geoip.CountryFromCloudflare(r)
ip := geoip.ClientIP(r)
go func() {
cc := cfCountry
if cc == "" {
lookupCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
cc = geoip.LookupCountryByIP(lookupCtx, ip)
cancel()
}
if cc == "" {
return
}
writeCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
h.svc.CaptureCountry(writeCtx, userID, cc)
}()
}
// LogIn authenticates an existing user. The response is one of:
//
// - 200 OK with the User JSON — credentials verified, session cookie set,