Repository: moov-io/customers
Pull request #54 (2019-11-06 19:19:11)

cmd/server: include CreatedAt timestamp on ofac search results
Kinda need to know when the search was performed.. 

Issue: https://github.com/moov-io/customers/issues/50 


Patch:
diff --git a/client/api/openapi.yaml b/client/api/openapi.yaml
index a4a1780..75262d8 100644
--- a/client/api/openapi.yaml
+++ b/client/api/openapi.yaml
@@ -1101,6 +1101,7 @@ components:
     OFACSearch:
       example:
         sdnType: Individual
+        createdAt: 2016-08-29T09:12:33.001Z
         match: 0.91
         entityId: "2141"
         sdnName: John Smith
@@ -1122,4 +1123,8 @@ components:
             OFAC entity
           example: 0.91
           type: number
+        createdAt:
+          example: 2016-08-29T09:12:33.001Z
+          format: date-time
+          type: string
       type: object
diff --git a/client/docs/OfacSearch.md b/client/docs/OfacSearch.md
index a041606..4d4d911 100644
--- a/client/docs/OfacSearch.md
+++ b/client/docs/OfacSearch.md
@@ -8,6 +8,7 @@ Name | Type | Description | Notes
 **SdnName** | **string** | Name of the SDN entity | [optional] 
 **SdnType** | **string** | SDN entity type | [optional] 
 **Match** | **float32** | Percentage of similarity between the Customer name and this OFAC entity | [optional] 
+**CreatedAt** | [**time.Time**](time.Time.md) |  | [optional] 
 
 [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
 
diff --git a/client/model_ofac_search.go b/client/model_ofac_search.go
index b5aaed5..b8cbdda 100644
--- a/client/model_ofac_search.go
+++ b/client/model_ofac_search.go
@@ -9,6 +9,10 @@
 
 package openapi
 
+import (
+	"time"
+)
+
 // OfacSearch struct for OfacSearch
 type OfacSearch struct {
 	// SDN EntityID of the Entity
@@ -18,5 +22,6 @@ type OfacSearch struct {
 	// SDN entity type
 	SdnType string `json:"sdnType,omitempty"`
 	// Percentage of similarity between the Customer name and this OFAC entity
-	Match float32 `json:"match,omitempty"`
+	Match     float32   `json:"match,omitempty"`
+	CreatedAt time.Time `json:"createdAt,omitempty"`
 }
diff --git a/cmd/server/approval_ofac.go b/cmd/server/approval_ofac.go
index 718aee7..8f0bd59 100644
--- a/cmd/server/approval_ofac.go
+++ b/cmd/server/approval_ofac.go
@@ -22,10 +22,11 @@ import (
 )
 
 type ofacSearchResult struct {
-	EntityId string  `json:"entityId"`
-	SDNName  string  `json:"sdnName"`
-	SDNType  string  `json:"sdnType"`
-	Match    float32 `json:"match"`
+	EntityId  string    `json:"entityId"`
+	SDNName   string    `json:"sdnName"`
+	SDNType   string    `json:"sdnType"`
+	Match     float32   `json:"match"`
+	CreatedAt time.Time `json:"createdAt"`
 }
 
 type ofacSearcher struct {
@@ -58,17 +59,19 @@ func (s *ofacSearcher) storeCustomerOFACSearch(cust *client.Customer, requestID
 	switch {
 	case nickSDN != nil && nickSDN.Match > sdn.Match:
 		err = s.repo.saveCustomerOFACSearch(cust.ID, ofacSearchResult{
-			EntityId: nickSDN.EntityID,
-			SDNName:  nickSDN.SdnName,
-			SDNType:  nickSDN.SdnType,
-			Match:    nickSDN.Match,
+			EntityId:  nickSDN.EntityID,
+			SDNName:   nickSDN.SdnName,
+			SDNType:   nickSDN.SdnType,
+			Match:     nickSDN.Match,
+			CreatedAt: time.Now(),
 		})
 	case sdn != nil:
 		err = s.repo.saveCustomerOFACSearch(cust.ID, ofacSearchResult{
-			EntityId: sdn.EntityID,
-			SDNName:  sdn.SdnName,
-			SDNType:  sdn.SdnType,
-			Match:    sdn.Match,
+			EntityId:  sdn.EntityID,
+			SDNName:   sdn.SdnName,
+			SDNType:   sdn.SdnType,
+			Match:     sdn.Match,
+			CreatedAt: time.Now(),
 		})
 	}
 	if err != nil {
diff --git a/cmd/server/customers.go b/cmd/server/customers.go
index be249f4..4672451 100644
--- a/cmd/server/customers.go
+++ b/cmd/server/customers.go
@@ -582,7 +582,7 @@ func (r *sqlCustomerRepository) updateCustomerAddress(customerID, addressID stri
 }
 
 func (r *sqlCustomerRepository) getLatestCustomerOFACSearch(customerID string) (*ofacSearchResult, error) {
-	query := `select entity_id, sdn_name, sdn_type, match from customer_ofac_searches where customer_id = ? order by created_at desc limit 1;`
+	query := `select entity_id, sdn_name, sdn_type, match, created_at from customer_ofac_searches where customer_id = ? order by created_at desc limit 1;`
 	stmt, err := r.db.Prepare(query)
 	if err != nil {
 		return nil, fmt.Errorf("getLatestCustomerOFACSearch: prepare: %v", err)
@@ -591,7 +591,7 @@ func (r *sqlCustomerRepository) getLatestCustomerOFACSearch(customerID string) (
 
 	row := stmt.QueryRow(customerID)
 	var res ofacSearchResult
-	if err := row.Scan(&res.EntityId, &res.SDNName, &res.SDNType, &res.Match); err != nil {
+	if err := row.Scan(&res.EntityId, &res.SDNName, &res.SDNType, &res.Match, &res.CreatedAt); err != nil {
 		if err == sql.ErrNoRows {
 			return nil, nil // nothing found
 		}
@@ -608,7 +608,11 @@ func (r *sqlCustomerRepository) saveCustomerOFACSearch(customerID string, result
 	}
 	defer stmt.Close()
 
-	if _, err := stmt.Exec(customerID, result.EntityId, result.SDNName, result.SDNType, result.Match, time.Now()); err != nil {
+	if result.CreatedAt.IsZero() {
+		result.CreatedAt = time.Now()
+	}
+
+	if _, err := stmt.Exec(customerID, result.EntityId, result.SDNName, result.SDNType, result.Match, result.CreatedAt); err != nil {
 		return fmt.Errorf("saveCustomerOFACSearch: exec: %v", err)
 	}
 	return nil
diff --git a/openapi.yaml b/openapi.yaml
index b77c809..fcab5e4 100644
--- a/openapi.yaml
+++ b/openapi.yaml
@@ -876,3 +876,7 @@ components:
           type: number
           example: 0.91
           description: Percentage of similarity between the Customer name and this OFAC entity
+        createdAt:
+          type: string
+          format: date-time
+          example: '2016-08-29T09:12:33.001Z'


Test patch:
diff --git a/cmd/server/approval_ofac_test.go b/cmd/server/approval_ofac_test.go
index 5fd524e..116be7c 100644
--- a/cmd/server/approval_ofac_test.go
+++ b/cmd/server/approval_ofac_test.go
@@ -64,6 +64,9 @@ func TestOFACSearcher__storeCustomerOFACSearch(t *testing.T) {
 	if res.EntityId != "1241421" {
 		t.Errorf("ofacSearchResult: %#v", res)
 	}
+	if res.CreatedAt.IsZero() {
+		t.Errorf("res.CreatedAt=%v", res.CreatedAt)
+	}
 
 	// retry but with NickName set (test coverage)
 	customerID = base.ID()