update api
This commit is contained in:
@@ -1,9 +1,13 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"go-backend-template/config"
|
||||
"go-backend-template/internal/constants"
|
||||
"go-backend-template/internal/contract"
|
||||
"go-backend-template/internal/logger"
|
||||
@@ -14,39 +18,61 @@ import (
|
||||
|
||||
type DukcapilHandler struct {
|
||||
dukcapilService DukcapilService
|
||||
config *config.Config
|
||||
}
|
||||
|
||||
func NewDukcapilHandler(dukcapilService DukcapilService) *DukcapilHandler {
|
||||
return &DukcapilHandler{dukcapilService: dukcapilService}
|
||||
func NewDukcapilHandler(dukcapilService DukcapilService, cfg *config.Config) *DukcapilHandler {
|
||||
return &DukcapilHandler{
|
||||
dukcapilService: dukcapilService,
|
||||
config: cfg,
|
||||
}
|
||||
}
|
||||
|
||||
// FaceMatch handles POST /api/v1/dukcapil/face-match (1:N face recognition).
|
||||
// Accepts only an image file via multipart form. All other parameters are
|
||||
// generated or retrieved from configuration.
|
||||
func (h *DukcapilHandler) FaceMatch(c *gin.Context) {
|
||||
var req contract.FaceMatchRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
logger.FromContext(c.Request.Context()).WithError(err).Error("DukcapilHandler::FaceMatch -> request binding failed")
|
||||
h.sendValidationError(c, "Invalid request body", constants.MalformedFieldErrorCode)
|
||||
// Parse multipart form
|
||||
file, err := c.FormFile("image")
|
||||
if err != nil {
|
||||
logger.FromContext(c.Request.Context()).WithError(err).Error("DukcapilHandler::FaceMatch -> failed to get image file")
|
||||
h.sendValidationError(c, "image file is required", constants.MissingFieldErrorCode)
|
||||
return
|
||||
}
|
||||
|
||||
if strings.TrimSpace(req.TransactionID) == "" {
|
||||
h.sendValidationError(c, "transaction_id is required", constants.MissingFieldErrorCode)
|
||||
// Open the uploaded file
|
||||
src, err := file.Open()
|
||||
if err != nil {
|
||||
logger.FromContext(c.Request.Context()).WithError(err).Error("DukcapilHandler::FaceMatch -> failed to open image file")
|
||||
h.sendValidationError(c, "failed to read image file", constants.MalformedFieldErrorCode)
|
||||
return
|
||||
}
|
||||
if strings.TrimSpace(req.TransactionSource) == "" {
|
||||
h.sendValidationError(c, "transaction_source is required", constants.MissingFieldErrorCode)
|
||||
return
|
||||
}
|
||||
if strings.TrimSpace(req.Threshold) == "" {
|
||||
h.sendValidationError(c, "threshold is required", constants.MissingFieldErrorCode)
|
||||
return
|
||||
}
|
||||
if strings.TrimSpace(req.Image) == "" {
|
||||
h.sendValidationError(c, "image is required (base64-encoded)", constants.MissingFieldErrorCode)
|
||||
defer src.Close()
|
||||
|
||||
// Read file content
|
||||
imageBytes, err := io.ReadAll(src)
|
||||
if err != nil {
|
||||
logger.FromContext(c.Request.Context()).WithError(err).Error("DukcapilHandler::FaceMatch -> failed to read image bytes")
|
||||
h.sendValidationError(c, "failed to read image file", constants.MalformedFieldErrorCode)
|
||||
return
|
||||
}
|
||||
|
||||
res, err := h.dukcapilService.FaceMatch(c.Request.Context(), &req)
|
||||
// Convert to base64
|
||||
imageBase64 := base64.StdEncoding.EncodeToString(imageBytes)
|
||||
|
||||
// Generate transaction_id (timestamp-based random ID)
|
||||
transactionID := fmt.Sprintf("TXN%d", time.Now().UnixNano())
|
||||
|
||||
// Build request with config values
|
||||
req := &contract.FaceMatchRequest{
|
||||
TransactionID: transactionID,
|
||||
TransactionSource: h.config.Dukcapil.TransactionSource,
|
||||
Threshold: h.config.Dukcapil.Threshold,
|
||||
Image: imageBase64,
|
||||
IP: h.config.Dukcapil.DefaultIP,
|
||||
}
|
||||
|
||||
res, err := h.dukcapilService.FaceMatch(c.Request.Context(), req)
|
||||
if err != nil {
|
||||
logger.FromContext(c.Request.Context()).WithError(err).Error("DukcapilHandler::FaceMatch -> upstream call failed")
|
||||
c.JSON(http.StatusBadGateway, &contract.ErrorResponse{
|
||||
|
||||
Reference in New Issue
Block a user