Skip to content

Commit

Permalink
Merge pull request #10 from rarimo/fix/endpoint-routes
Browse files Browse the repository at this point in the history
Fix/endpoint routes
  • Loading branch information
olegfomenko authored Mar 14, 2024
2 parents 38b030e + e4e230d commit 5cd89e3
Show file tree
Hide file tree
Showing 53 changed files with 882 additions and 225 deletions.
19 changes: 10 additions & 9 deletions config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,18 @@ db:
url: postgres://points:points@localhost:5432/points?sslmode=disable

listener:
addr: :8000

cop:
disabled: true
endpoint: "http://..."
upstream: "http://..."
service_name: rarime-points-svc
service_port: 80
addr: localhost:8000

event_types:
passport_rewards:
age: 20
nationality: 50
types:
- name: passport_scan
title: Points for passport scan
reward: 200
description: Get points for scan passport and share data
frequency: one-time
- name: get_poh
title: Get PoH credential
reward: 50
Expand Down Expand Up @@ -56,7 +57,7 @@ auth:
addr: http://rarime-auth

broadcaster:
addr: "http://broadcaster"
addr: broadcaster
sender_account: "rarimo15hcd6tv7pe8hk2re7hu0zg0aphqdm2dtjrs0ds"

withdrawal:
Expand Down
19 changes: 14 additions & 5 deletions docs/spec/components/schemas/Balance.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ allOf:
type: object
required:
- amount
- referral_id
- is_verified
- is_disabled
- created_at
- updated_at
properties:
Expand All @@ -18,14 +18,17 @@ allOf:
format: int64
description: Amount of points
example: 580
referral_id:
type: string
description: Referral ID used to build a referral link and send it to friends
example: "zgsScguZ"
is_verified:
type: boolean
description: Whether the user has scanned passport
example: true
is_disabled:
type: boolean
description: |
Whether the user was not referred by anybody, but the balance with some
events was reserved. It happens when the user fulfills some event
before the balance creation.
example: false
created_at:
type: integer
description: Unix timestamp of balance creation
Expand All @@ -39,3 +42,9 @@ allOf:
format: int
description: Rank of the user in the full leaderboard. Returned only for the single user.
example: 294
referral_codes:
type: array
description: Referral codes used to build a referral link and send it to friends. Required if a balance is created
example: ["zgsScguZ", "jerUsmac"]
items:
type: string
5 changes: 4 additions & 1 deletion docs/spec/components/schemas/CreateBalance.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ allOf:
- $ref: '#/components/schemas/CreateBalanceKey'
- type: object
x-go-is-request: true
required:
- attributes
properties:
attributes:
type: object
Expand All @@ -10,5 +12,6 @@ allOf:
properties:
referred_by:
type: string
description: ID of the referrer from the link
description: referrer code from the link
example: "rCx18MZ4"

4 changes: 4 additions & 0 deletions docs/spec/components/schemas/WithdrawKey.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ required:
- id
- type
properties:
id:
type: string
description: DID of the points owner
example: "did:iden3:readonly:tUDjWxnVJNi7t3FudukqrUcNwF5KVGoWgim5pp2jV"
type:
type: string
enum: [ withdraw ]
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,14 @@ post:
- Points balance
summary: Create points balance
description: |
Create an empty balance for authorized user who makes the request. Rank is included.
Create an empty balance for authorized user who makes the request. Rank is included
in response.
This operation might be time-consuming, because `open` events should be added for
the new account synchronously (to display them right after the request).
If balance already exists, but it is disabled (it was not referred by another user,
but has fulfilled some event), you should use this endpoint as well.
operationId: createPointsBalance
requestBody:
content:
Expand Down Expand Up @@ -68,5 +73,11 @@ get:
$ref: '#/components/schemas/Balance'
400:
$ref: '#/components/responses/invalidParameter'
409:
description: Balance already exists and it is not disabled
content:
application/vnd.api+json:
schema:
$ref: '#/components/schemas/Errors'
500:
$ref: '#/components/responses/internalError'
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,20 @@ get:
operationId: getPointsBalance
parameters:
- $ref: '#/components/parameters/pathDID'
- in: query
name: 'rank'
description: 'Specifies whether to return the rank'
required: false
schema:
type: boolean
example: true
- in: query
name: 'referral_codes'
description: 'Specifies whether to return the referral codes'
required: false
schema:
type: booleand
example: true
responses:
200:
description: Success
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ require (
github.com/go-chi/chi v4.1.2+incompatible
github.com/go-co-op/gocron/v2 v2.2.2
github.com/go-ozzo/ozzo-validation/v4 v4.3.0
github.com/google/jsonapi v1.0.0
github.com/iden3/go-iden3-core/v2 v2.0.4
github.com/rarimo/auth-svc v1.0.0-rc2
github.com/rarimo/auth-svc v1.0.0-rc2.0.20240311143312-de1e2258f175
github.com/rarimo/saver-grpc-lib v1.0.0
github.com/rubenv/sql-migrate v1.6.1
gitlab.com/distributed_lab/ape v1.7.1
Expand Down Expand Up @@ -79,7 +80,6 @@ require (
github.com/golang/protobuf v1.5.3 // indirect
github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect
github.com/google/btree v1.1.2 // indirect
github.com/google/jsonapi v1.0.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1217,8 +1217,8 @@ github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJf
github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY=
github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ=
github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc=
github.com/rarimo/auth-svc v1.0.0-rc2 h1:6w+T8xFZwi5gc2x8FlObnfMEij2zlNQZDNSdaBLY2iw=
github.com/rarimo/auth-svc v1.0.0-rc2/go.mod h1:XtPIuJABJ3QNmhcpmJRlQrxuagPfpIWwFbY0j5SakFg=
github.com/rarimo/auth-svc v1.0.0-rc2.0.20240311143312-de1e2258f175 h1:LWfw+633hf9J0unWMA528CEf+taYdzhhoqJVFj3po6Y=
github.com/rarimo/auth-svc v1.0.0-rc2.0.20240311143312-de1e2258f175/go.mod h1:XtPIuJABJ3QNmhcpmJRlQrxuagPfpIWwFbY0j5SakFg=
github.com/rarimo/broadcaster-svc v1.0.2 h1:ExQcjjWCRP5+POLDlZHrTD1ffUsBH+Dgv5FAgcP3BXc=
github.com/rarimo/broadcaster-svc v1.0.2/go.mod h1:lYIHy+X4IqQt4eBdtMN/V352H3EV0/gO8G+32SFwUWI=
github.com/rarimo/cosmos-sdk v0.46.7 h1:jU2PiWzc+19SF02cXM0O0puKPeH1C6Q6t2lzJ9s1ejc=
Expand Down
24 changes: 17 additions & 7 deletions internal/assets/migrations/001_initial.sql
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,29 @@ CREATE TABLE IF NOT EXISTS balances
amount bigint NOT NULL default 0,
created_at integer NOT NULL default EXTRACT('EPOCH' FROM NOW()),
updated_at integer NOT NULL default EXTRACT('EPOCH' FROM NOW()),
referral_id text UNIQUE NOT NULL,
referred_by text REFERENCES balances (referral_id),
referred_by text UNIQUE,
passport_hash text UNIQUE,
passport_expires timestamp without time zone
);

CREATE INDEX IF NOT EXISTS balances_amount_index ON balances using btree (amount);
CREATE INDEX IF NOT EXISTS balances_page_index ON balances (amount, updated_at) WHERE referred_by IS NOT NULL;

CREATE TRIGGER set_updated_at
BEFORE UPDATE
ON balances
FOR EACH ROW
EXECUTE FUNCTION trigger_set_updated_at();

CREATE TABLE IF NOT EXISTS referrals
(
id text PRIMARY KEY,
user_did text NOT NULL REFERENCES balances (did),
is_consumed boolean NOT NULL default false
);

ALTER TABLE balances ADD CONSTRAINT referred_by_fk FOREIGN KEY (referred_by) REFERENCES referrals (id);
CREATE INDEX IF NOT EXISTS referrals_user_did_index ON referrals (user_did);

CREATE TYPE event_status AS ENUM ('open', 'fulfilled', 'claimed');

CREATE TABLE IF NOT EXISTS events
Expand All @@ -39,9 +48,7 @@ CREATE TABLE IF NOT EXISTS events
CONSTRAINT unique_external_id UNIQUE (user_did, type, external_id)
);

CREATE INDEX IF NOT EXISTS events_user_did_index ON events using btree (user_did);
CREATE INDEX IF NOT EXISTS events_type_index ON events using btree (type);
CREATE INDEX IF NOT EXISTS events_updated_at_index ON events using btree (updated_at);
CREATE INDEX IF NOT EXISTS events_page_index ON events (user_did, updated_at);

CREATE TRIGGER set_updated_at
BEFORE UPDATE
Expand All @@ -58,11 +65,14 @@ CREATE TABLE IF NOT EXISTS withdrawals
created_at integer NOT NULL default EXTRACT('EPOCH' FROM NOW())
);

CREATE INDEX IF NOT EXISTS withdrawals_user_did_index ON withdrawals using btree (user_did);
CREATE INDEX IF NOT EXISTS withdrawals_page_index ON withdrawals (user_did, created_at);

-- +migrate Down
DROP TABLE IF EXISTS withdrawals;
DROP TABLE IF EXISTS events;

ALTER TABLE balances DROP CONSTRAINT referred_by_fk;
DROP TABLE IF EXISTS referrals;
DROP TABLE IF EXISTS balances;

DROP TYPE IF EXISTS event_status;
Expand Down
7 changes: 4 additions & 3 deletions internal/data/balances.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ type Balance struct {
Amount int64 `db:"amount"`
CreatedAt int32 `db:"created_at"`
UpdatedAt int32 `db:"updated_at"`
ReferralID string `db:"referral_id"`
ReferredBy sql.NullString `db:"referred_by"`
PassportHash sql.NullString `db:"passport_hash"`
PassportExpires sql.NullTime `db:"passport_expires"`
Expand All @@ -24,12 +23,14 @@ type BalancesQ interface {
Insert(Balance) error
UpdateAmountBy(points int64) error
SetPassport(hash string, exp time.Time) error
SetReferredBy(referralCode string) error

Page(*pgdb.OffsetPageParams) BalancesQ
Select() ([]Balance, error)
Get() (*Balance, error)
// GetWithRank returns balance with rank, filtered by DID. No other filters can be applied.
GetWithRank(did string) (*Balance, error)

WithRank() BalancesQ
FilterByDID(string) BalancesQ
FilterByReferralID(string) BalancesQ
FilterDisabled() BalancesQ
}
1 change: 1 addition & 0 deletions internal/data/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,5 @@ type EventsQ interface {
FilterByType(...string) EventsQ
FilterByUpdatedAtBefore(int64) EventsQ
FilterByExternalID(string) EventsQ
FilterInactiveNotClaimed(types ...string) EventsQ
}
19 changes: 17 additions & 2 deletions internal/data/evtypes/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ func NewConfig(getter kv.Getter) EventTypeser {
func (c *config) EventTypes() Types {
return c.once.Do(func() interface{} {
var raw struct {
Types []EventConfig `fig:"types,required"`
Types []EventConfig `fig:"types,required"`
PassportRewards map[string]int `fig:"passport_rewards"`
}

err := figure.Out(&raw).
Expand All @@ -42,7 +43,21 @@ func (c *config) EventTypes() Types {
m[t.Name] = t
}

return Types{m, raw.Types}
if _, ok := m[TypePassportScan]; !ok {
if len(raw.PassportRewards) != 0 {
panic(fmt.Errorf("rewards exists, but event PassportScan not exists"))
}
return Types{m, raw.Types, raw.PassportRewards}
}

if _, ok := raw.PassportRewards[PassportRewardAge]; !ok {
panic(fmt.Errorf("absent required field: %s", PassportRewardAge))
}
if _, ok := raw.PassportRewards[PassportRewardNationality]; !ok {
panic(fmt.Errorf("absent required field: %s", PassportRewardNationality))
}

return Types{m, raw.Types, raw.PassportRewards}
}).(Types)
}

Expand Down
22 changes: 20 additions & 2 deletions internal/data/evtypes/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ const (
TypeFreeWeekly = "free_weekly"
TypeBeReferred = "be_referred"
TypeReferralSpecific = "referral_specific"
TypePassportScan = "passport_scan"
)

const (
PassportRewardAge = "age"
PassportRewardNationality = "nationality"
)

type EventConfig struct {
Expand All @@ -50,8 +56,9 @@ func (e EventConfig) Resource() resources.EventStaticMeta {
}

type Types struct {
m map[string]EventConfig
list []EventConfig
m map[string]EventConfig
list []EventConfig
passportRewards map[string]int
}

func (t Types) Get(name string, filters ...filter) *EventConfig {
Expand Down Expand Up @@ -118,3 +125,14 @@ func (t Types) ensureInitialized() {
panic("event types are not correctly initialized")
}
}

func (t Types) CalculatePassportScanReward(sharedFields ...string) (reward int64, success bool) {
for _, field := range sharedFields {
val, ok := t.passportRewards[field]
if !ok {
return 0, false
}
reward += int64(val)
}
return reward, true
}
Loading

0 comments on commit 5cd89e3

Please sign in to comment.