Skip to content

Commit 97d3ab3

Browse files
feat: add support for Org KYC (#873)
* feat: update protobuf files * fix: update protobuf files * fix: update protobuf files * feat: add dummy impl * feat: register endpoints on auth middleware * feat: wip service and repository of org kyc * feat: service and repository of org kyc * fix: error scenarios * fix: auto update timestamp * test: add unit test for get KYC from repository * test: add unit test for upsert KYC * test: add more tests * test: add service test * test: add handler test * fix: lint * fix: update proton commit ref
1 parent 8ae5439 commit 97d3ab3

33 files changed

+10067
-7421
lines changed

.mockery.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ packages:
5959
config:
6060
dir: "core/organization/mocks"
6161
all: true
62+
github.com/raystack/frontier/core/kyc:
63+
config:
64+
dir: "core/kyc/mocks"
65+
all: true
6266
github.com/raystack/frontier/core/invitation:
6367
config:
6468
dir: "core/invitation/mocks"

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ TAG := $(shell git rev-list --tags --max-count=1)
44
VERSION := $(shell git describe --tags ${TAG})
55
.PHONY: build check fmt lint test test-race vet test-cover-html help install proto ui compose-up-dev
66
.DEFAULT_GOAL := build
7-
PROTON_COMMIT := "2750c7e5fe37ace10c463068089b57244d6245b9"
7+
PROTON_COMMIT := "698f57c206bb5377f5aead5c509393ff92bf58ce"
88

99
ui:
1010
@echo " > generating ui build"
@@ -13,7 +13,7 @@ ui:
1313
install:
1414
@echo "Clean up imports..."
1515
@go mod download
16-
@go install github.com/vektra/mockery/v2@v2.32.4
16+
@go install github.com/vektra/mockery/v2@v2.40.2
1717

1818
build:
1919
CGO_ENABLED=0 go build -ldflags "-X ${NAME}/config.Version=${VERSION}" -o frontier .

cmd/serve.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import (
1212
"syscall"
1313
"time"
1414

15+
"github.com/raystack/frontier/core/kyc"
16+
1517
"golang.org/x/exp/slices"
1618

1719
"github.com/jackc/pgx/v4"
@@ -400,6 +402,9 @@ func buildAPIDependencies(
400402
organizationService := organization.NewService(organizationRepository, relationService, userService,
401403
authnService, policyService, preferenceService)
402404

405+
orgKycRepository := postgres.NewOrgKycRepository(dbc)
406+
orgKycService := kyc.NewService(orgKycRepository)
407+
403408
domainRepository := postgres.NewDomainRepository(logger, dbc)
404409
domainService := domain.NewService(logger, domainRepository, userService, organizationService)
405410

@@ -506,6 +511,7 @@ func buildAPIDependencies(
506511

507512
dependencies := api.Deps{
508513
OrgService: organizationService,
514+
OrgKycService: orgKycService,
509515
ProjectService: projectService,
510516
GroupService: groupService,
511517
RoleService: roleService,

core/kyc/errors.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package kyc
2+
3+
import "errors"
4+
5+
var (
6+
ErrNotExist = errors.New("org kyc doesn't exist")
7+
ErrKycLinkNotSet = errors.New("link cannot be empty")
8+
ErrInvalidUUID = errors.New("invalid syntax of uuid")
9+
ErrOrgDoesntExist = errors.New("org doesn't exist")
10+
)

core/kyc/kyc.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package kyc
2+
3+
import "time"
4+
5+
type KYC struct {
6+
OrgID string
7+
Status bool
8+
Link string
9+
10+
CreatedAt time.Time
11+
UpdatedAt time.Time
12+
}

core/kyc/mocks/repository.go

Lines changed: 151 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

core/kyc/service.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package kyc
2+
3+
import "context"
4+
5+
type Repository interface {
6+
GetByOrgID(context.Context, string) (KYC, error)
7+
Upsert(context.Context, KYC) (KYC, error)
8+
}
9+
10+
type Service struct {
11+
repository Repository
12+
}
13+
14+
func NewService(repository Repository) *Service {
15+
return &Service{
16+
repository: repository,
17+
}
18+
}
19+
20+
func (s Service) GetKyc(ctx context.Context, orgID string) (KYC, error) {
21+
return s.repository.GetByOrgID(ctx, orgID)
22+
}
23+
24+
func (s Service) SetKyc(ctx context.Context, kyc KYC) (KYC, error) {
25+
return s.repository.Upsert(ctx, kyc)
26+
}

core/kyc/service_test.go

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
package kyc_test
2+
3+
import (
4+
"context"
5+
"errors"
6+
"testing"
7+
8+
"github.com/stretchr/testify/assert"
9+
10+
"github.com/raystack/frontier/core/kyc"
11+
"github.com/raystack/frontier/core/kyc/mocks"
12+
)
13+
14+
func TestService_GetKyc(t *testing.T) {
15+
tests := []struct {
16+
name string
17+
orgID string
18+
mockReturn kyc.KYC
19+
mockError error
20+
expectError bool
21+
}{
22+
{
23+
name: "successful fetch",
24+
orgID: "org-123",
25+
mockReturn: kyc.KYC{
26+
OrgID: "org-123",
27+
Status: true,
28+
Link: "abcd",
29+
},
30+
mockError: nil,
31+
expectError: false,
32+
},
33+
{
34+
name: "error fetching",
35+
orgID: "org-123",
36+
mockReturn: kyc.KYC{},
37+
mockError: errors.New("some error"),
38+
expectError: true,
39+
},
40+
}
41+
42+
for _, tt := range tests {
43+
t.Run(tt.name, func(t *testing.T) {
44+
mockRepo := mocks.NewRepository(t)
45+
svc := kyc.NewService(mockRepo)
46+
ctx := context.Background()
47+
48+
mockRepo.On("GetByOrgID", ctx, tt.orgID).Return(tt.mockReturn, tt.mockError)
49+
50+
result, err := svc.GetKyc(ctx, tt.orgID)
51+
52+
if tt.expectError {
53+
assert.Error(t, err)
54+
assert.Equal(t, tt.mockError, err)
55+
} else {
56+
assert.NoError(t, err)
57+
assert.Equal(t, tt.mockReturn, result)
58+
}
59+
mockRepo.AssertExpectations(t)
60+
})
61+
}
62+
}
63+
64+
func TestService_SetKyc(t *testing.T) {
65+
tests := []struct {
66+
name string
67+
input kyc.KYC
68+
mockReturn kyc.KYC
69+
mockError error
70+
expectError bool
71+
}{
72+
{
73+
name: "successful upsert",
74+
input: kyc.KYC{
75+
OrgID: "org-123",
76+
Status: true,
77+
Link: "abcd",
78+
},
79+
mockReturn: kyc.KYC{
80+
OrgID: "org-123",
81+
Status: true,
82+
Link: "abcd",
83+
},
84+
mockError: nil,
85+
expectError: false,
86+
},
87+
{
88+
name: "error upserting",
89+
input: kyc.KYC{
90+
OrgID: "org-123",
91+
Status: true,
92+
Link: "abcd",
93+
},
94+
mockReturn: kyc.KYC{},
95+
mockError: errors.New("some error"),
96+
expectError: true,
97+
},
98+
}
99+
100+
for _, tt := range tests {
101+
t.Run(tt.name, func(t *testing.T) {
102+
mockRepo := mocks.NewRepository(t)
103+
svc := kyc.NewService(mockRepo)
104+
ctx := context.Background()
105+
106+
mockRepo.On("Upsert", ctx, tt.input).Return(tt.mockReturn, tt.mockError)
107+
108+
result, err := svc.SetKyc(ctx, tt.input)
109+
110+
if tt.expectError {
111+
assert.Error(t, err)
112+
assert.Equal(t, tt.mockError, err)
113+
} else {
114+
assert.NoError(t, err)
115+
assert.Equal(t, tt.mockReturn, result)
116+
}
117+
mockRepo.AssertExpectations(t)
118+
})
119+
}
120+
}

internal/api/api.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"github.com/raystack/frontier/core/event"
1919
"github.com/raystack/frontier/core/group"
2020
"github.com/raystack/frontier/core/invitation"
21+
"github.com/raystack/frontier/core/kyc"
2122
"github.com/raystack/frontier/core/metaschema"
2223
"github.com/raystack/frontier/core/namespace"
2324
"github.com/raystack/frontier/core/organization"
@@ -36,6 +37,7 @@ import (
3637

3738
type Deps struct {
3839
OrgService *organization.Service
40+
OrgKycService *kyc.Service
3941
ProjectService *project.Service
4042
GroupService *group.Service
4143
RoleService *role.Service

0 commit comments

Comments
 (0)