Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Work/roman #12

Merged
merged 44 commits into from
May 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
cc21089
Add new parameter for event in config 'StartAt'. Add opener in reopen…
Zaptoss Mar 7, 2024
5f15087
Change Render to RenderErr in AuthMiddleware
Zaptoss Mar 7, 2024
366f9c5
rename initOpener -> runStartingWachers; add function startingWatcher…
Zaptoss Mar 8, 2024
73e29e9
Add /events/{id} endpoint. Add fields 'ShortDescription' and 'Actiona…
Zaptoss Mar 8, 2024
3fb0797
Typos fixes and tiny improvements
violog Mar 11, 2024
e0773a8
Merge branch 'fix/endpoint-routes' into work/Roman
violog Mar 11, 2024
b7cd17d
Filter inactive types on getting event too
violog Mar 11, 2024
fc55153
Add check if passport_hash already in use
Zaptoss Mar 11, 2024
ddb2510
If user try to set own passport and passport_hash already set, return…
Zaptoss Mar 11, 2024
d556432
Drop unnecessary utility function from passport handler
violog Mar 11, 2024
3d478ca
Change passport expiration logic
Zaptoss Mar 11, 2024
6353f4b
Remove unnecessary request in DB in verify_passport
Zaptoss Mar 11, 2024
2c6a4c6
verify_passport handler refactoring
Zaptoss Mar 12, 2024
622c18d
Add field is_withdrawal_allowed
Zaptoss Mar 12, 2024
50c2b07
Create endpoint for activate balance. Now CreateBalance endpoint only…
Zaptoss Mar 12, 2024
7d7fc31
Add resource type update_balance
Zaptoss Mar 12, 2024
bdb2963
Fix syntax error in migration
violog Mar 13, 2024
952c0b2
Add func fulFillPassportScanEvent. Code refactoring
Zaptoss Mar 13, 2024
c27948f
Change SetPassport function. Remove Update func for balances
Zaptoss Mar 13, 2024
19278ee
Add handle sql.ErrNoRows in Get - referrals
Zaptoss Mar 13, 2024
4eaf414
Change cursor pagination to offset pagination in list events. Order b…
Zaptoss Mar 14, 2024
3e6d9be
Add logo field of type url.URL in event type config. Add disabled fie…
Zaptoss Mar 14, 2024
370163b
Add logging if points connector disabled
Zaptoss Mar 15, 2024
93af134
Add event types for generate proof
Zaptoss Mar 15, 2024
996998e
Add private endpoint /proofs for fulfillevents for proof verification…
Zaptoss Mar 18, 2024
b61dbcb
Add event types verify_proof_* and verified_proof_*
Zaptoss Mar 18, 2024
5c71003
Add logic for creating balance for verifier if balance absent
Zaptoss Mar 18, 2024
62dbcc4
reduce count of loggin
Zaptoss Mar 18, 2024
719069a
Change logic verify proof endpoint. One request can contain many proofs
Zaptoss Mar 20, 2024
0a7304e
Add consumed referral codes in response
violog Mar 20, 2024
98acc41
Return added codes in response from edit referrals
violog Mar 20, 2024
c161324
Merge branch 'main' into fix/used-referrals
violog Mar 21, 2024
9ed2343
Fix edit referrals endpoint, add docs for it in README.md
violog Mar 4, 2024
62868b0
Fix text wraps in readme
violog Mar 4, 2024
458e67f
Small fixes in referrals and proof event
violog Mar 21, 2024
08f0785
Fix count-index logic in edit referrals handler
violog Mar 22, 2024
e4669df
Fix URL JSON marshalling by replacing it with string
violog Mar 22, 2024
0b205b5
Fix dynamic passport scan reward
Zaptoss Mar 25, 2024
aca4035
Fix event opener
Zaptoss Mar 25, 2024
86b291b
Fix json unmarshal
Zaptoss Mar 25, 2024
2519bed
Fix fulfill verified proof event
Zaptoss Mar 25, 2024
427ee9e
Change error message in jsonb
Zaptoss Mar 25, 2024
ae058c9
Add support StartAt logic to PoH event in sbtcheck
Zaptoss Mar 26, 2024
b1b3967
VerifyPassport connector become deprecated. Change private endpoint f…
Zaptoss Mar 27, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,34 @@ functionality to interact with these endpoints.

The path for internal endpoints is `/integrations/rarime-points-svc/v1/private/*`.

### Add referrals

Private endpoint to set number of available referral codes or create a new
_System user_ with referrals. _System user_ is unable to claim events or
withdraw, it has `is_disabled` attribute set to `true`, so the client app should
not allow it interactions with the system, although it is technically possible
to do other actions.

Path: `/integrations/rarime-points-svc/v1/private/referrals`
Query parameters:
- `did` - user DID to create or edit referrals for
- `count` - number of referrals to set

Example to set 200 referrals for user `did:example:123`:
```shell
curl -X POST "http://localhost/integrations/rarime-points-svc/v1/private/referrals?did=did:example:123&count=200"
```

Behavior:
a) User does not exist -> create a _System user_ with the specified number of
referrals (if count == 0, do not create)
b) User exists, `N` > `count` -> add `N - count` active referrals
c) User exists, `N` < `count` -> consume `count - N` active referrals (not delete!)
d) User exists, `N` = `count` -> do nothing

Where `N` is the current number of active referrals for the user, `count` is
query parameter value.

### Local build

We do use openapi:json standard for API. We use swagger for documenting our API.
Expand Down
52 changes: 52 additions & 0 deletions config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,41 +17,93 @@ event_types:
title: Points for passport scan
reward: 200
description: Get points for scan passport and share data
short_description: Short description
frequency: one-time
action_url: https://...
logo: https://...
- name: get_poh
title: Get PoH credential
reward: 50
description: Prove that you are human
short_description: Short description
frequency: one-time
expires_at: 2020-01-01T00:00:00Z
- name: free_weekly
title: Free weekly points
reward: 100
frequency: weekly
description: Get free points every week by visiting the platform and claiming your reward
short_description: Short description
- name: daily_login
title: Daily login
reward: 5
frequency: daily
description: Login every day
short_description: Short description
disabled: true
- name: be_referred
title: Referral welcome bonus
reward: 5
frequency: one-time
description: Be referred by a friend and get a welcome bonus
short_description: Short description
no_auto_open: true
- name: referral_common
title: Refer new users
reward: 25
frequency: one-time
description: Refer friends and get a reward for each friend who verifies the passport
short_description: Short description
- name: referral_specific
title: Refer user {:did}
reward: 25
frequency: unlimited
description: The user {:did} has verified the passport. Claim the reward!
short_description: Short description
no_auto_open: true
- name: planned
title: Planned event
reward: 25
frequency: unlimited
description: Event that start at specified time
short_description: Short description
starts_at: 2020-01-01T00:00:00Z
- name: generate_proof_age
title: Generate proof age
reward: 25
frequency: one-time
description: Event that become fulfilled when user create proof that prove age
short_description: Short description
- name: generate_proof_nationality
title: Generate proof nationality
reward: 50
frequency: one-time
description: Event that become fulfilled when user create proof that prove nationality
short_description: Short description
- name: verify_proof_age
title: Verify proof age
reward: 25
frequency: one-time
description: Event that become fulfilled when user verify someone else's proof age
short_description: Short description
- name: verify_proof_nationality
title: Verify proof nationality
reward: 50
frequency: one-time
description: Event that become fulfilled when user verify someone else's proof nationality
short_description: Short description
- name: verified_proof_age
title: Have proof age verified
reward: 25
frequency: one-time
description: Event that become fulfilled when another user verify you proof age (user that verify must have verified passport)
short_description: Short description
- name: verified_proof_nationality
title: Have proof nationality verified
reward: 50
frequency: one-time
description: Event that become fulfilled when another user verify you proof nationality (user that verify must have verified passport)
short_description: Short description

auth:
addr: http://rarime-auth
Expand Down
16 changes: 14 additions & 2 deletions docs/spec/components/schemas/Balance.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,21 @@ allOf:
format: int
description: Rank of the user in the full leaderboard. Returned only for the single user.
example: 294
referral_codes:
active_referral_codes:
type: array
description: Referral codes used to build a referral link and send it to friends. Required if a balance is created
description: |
Referral codes which can be used to build a referral link and send it
to friends. Returned only for the single user.
example: ["zgsScguZ", "jerUsmac"]
items:
type: string
consumed_referral_codes:
type: array
description: Referral codes used by invited users. Returned only for the single user.
example: ["73k3bdYaFWM", "9csIL7dW65m"]
items:
type: string
is_withdrawal_allowed:
type: boolean
description: Whether the user can withdraw tokens. Returned only for the single user.
example: true
2 changes: 1 addition & 1 deletion docs/spec/components/schemas/CreateBalanceKey.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ properties:
example: "did:iden3:readonly:tUDjWxnVJNi7t3FudukqrUcNwF5KVGoWgim5pp2jV"
type:
type: string
enum: [ create_balance ]
enum: [ create_balance, update_balance ]
17 changes: 17 additions & 0 deletions docs/spec/components/schemas/EventStaticMeta.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ required:
- reward
- title
- description
- short_description
- frequency
- no_auto_open
properties:
Expand All @@ -25,14 +26,30 @@ properties:
description:
type: string
example: Lorem ipsum dolor sit amet
short_description:
type: string
example: Short description
frequency:
type: string
description: |
Event frequency, which means how often you can fulfill
certain task and claim the reward.
enum: [one-time, daily, weekly, unlimited]
starts_at:
type: string
format: time.Time
description: General event starting date (UTC RFC3339)
example: 2020-01-01T00:00:00Z
expires_at:
type: string
format: time.Time
description: General event expiration date (UTC RFC3339)
example: 2020-01-01T00:00:00Z
action_url:
type: string
description: Page where you can fulfill the event
example: https://robotornot.rarimo.com
logo:
type: string
description: Event logo
example: https://logo.com/some_logo.svg
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ post:
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.
but has fulfilled some event), you should use PATCH balances/{did} endpoint as well.
operationId: createPointsBalance
requestBody:
content:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,51 @@ get:
$ref: '#/components/responses/invalidAuth'
500:
$ref: '#/components/responses/internalError'

patch:
tags:
- Points balance
summary: Activate points balance
description: |
Activate inactive balance. Balance is inactive when referred_by field is null.
did in query must match with id in request body
operationId: activatePointsBalance
parameters:
- $ref: '#/components/parameters/pathDID'
requestBody:
content:
application/vnd.api+json:
schema:
type: object
required:
- data
properties:
data:
$ref: '#/components/schemas/CreateBalance'

responses:
200:
description: Success
content:
application/vnd.api+json:
schema:
type: object
required:
- data
properties:
data:
$ref: '#/components/schemas/Balance'
400:
$ref: '#/components/responses/invalidParameter'
401:
$ref: '#/components/responses/invalidAuth'
404:
$ref: '#/components/responses/notFound'
409:
description: Balance already activated
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 @@ -35,8 +35,8 @@ get:
schema:
type: boolean
example: true
- $ref: '#/components/parameters/pageCursor'
- $ref: '#/components/parameters/pageLimit'
- $ref: '#/components/parameters/pageNumber'
- $ref: '#/components/parameters/pageOrder'
responses:
200:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,30 @@
get:
tags:
- Events
summary: Get event
description: Returns a single event by ID.
operationId: getEvent
responses:
200:
description: Success
content:
application/vnd.api+json:
schema:
type: object
required:
- data
properties:
data:
$ref: '#/components/schemas/Event'
400:
$ref: '#/components/responses/invalidParameter'
401:
$ref: '#/components/responses/invalidAuth'
404:
$ref: '#/components/responses/notFound'
500:
$ref: '#/components/responses/internalError'

patch:
tags:
- Events
Expand Down
15 changes: 8 additions & 7 deletions internal/assets/migrations/001_initial.sql
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ AS $$ BEGIN NEW.updated_at = EXTRACT('EPOCH' FROM NOW()); RETURN NEW; END; $$;

CREATE TABLE IF NOT EXISTS balances
(
did text PRIMARY KEY,
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()),
referred_by text UNIQUE,
passport_hash text UNIQUE,
passport_expires timestamp without time zone
did text PRIMARY KEY,
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()),
referred_by text UNIQUE,
passport_hash text UNIQUE,
passport_expires timestamp without time zone,
is_withdrawal_allowed boolean NOT NULL default false
);

CREATE INDEX IF NOT EXISTS balances_page_index ON balances (amount, updated_at) WHERE referred_by IS NOT NULL;
Expand Down
20 changes: 11 additions & 9 deletions internal/data/balances.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,22 @@ import (
)

type Balance struct {
DID string `db:"did"`
Amount int64 `db:"amount"`
CreatedAt int32 `db:"created_at"`
UpdatedAt int32 `db:"updated_at"`
ReferredBy sql.NullString `db:"referred_by"`
PassportHash sql.NullString `db:"passport_hash"`
PassportExpires sql.NullTime `db:"passport_expires"`
Rank *int `db:"rank"`
DID string `db:"did"`
Amount int64 `db:"amount"`
CreatedAt int32 `db:"created_at"`
UpdatedAt int32 `db:"updated_at"`
ReferredBy sql.NullString `db:"referred_by"`
PassportHash sql.NullString `db:"passport_hash"`
PassportExpires sql.NullTime `db:"passport_expires"`
Rank *int `db:"rank"`
IsWithdrawalAllowed bool `db:"is_withdrawal_allowed"`
}

type BalancesQ interface {
New() BalancesQ
Insert(Balance) error
UpdateAmountBy(points int64) error
SetPassport(hash string, exp time.Time) error
SetPassport(hash string, exp time.Time, isWithdrawalAllowed bool) error
SetReferredBy(referralCode string) error

Page(*pgdb.OffsetPageParams) BalancesQ
Expand All @@ -32,5 +33,6 @@ type BalancesQ interface {
GetWithRank(did string) (*Balance, error)

FilterByDID(string) BalancesQ
FilterByPassportHash(string) BalancesQ
FilterDisabled() BalancesQ
}
2 changes: 1 addition & 1 deletion internal/data/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ type EventsQ interface {
Delete() (rowsAffected int64, err error)
Transaction(func() error) error

Page(*pgdb.CursorPageParams) EventsQ
Page(*pgdb.OffsetPageParams) EventsQ
Select() ([]Event, error)
Get() (*Event, error)
// Count returns the total number of events that match filters. Page is not
Expand Down
6 changes: 6 additions & 0 deletions internal/data/evtypes/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ func (c *config) EventTypes() Types {
if !checkFreqValue(t.Frequency) {
panic(fmt.Errorf("invalid frequency: %s", t.Frequency))
}

if t.ExpiresAt != nil && t.StartsAt != nil && !t.StartsAt.Before(*t.ExpiresAt) {
panic(fmt.Errorf("starts_at must be before expires_at: %s > %s",
t.StartsAt, t.ExpiresAt))
}

m[t.Name] = t
}

Expand Down
6 changes: 5 additions & 1 deletion internal/data/evtypes/filters.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,12 @@ func FilterExpired(ev EventConfig) bool {
return ev.ExpiresAt != nil && ev.ExpiresAt.Before(time.Now().UTC())
}

func FilterNotStarted(ev EventConfig) bool {
return ev.StartsAt != nil && ev.StartsAt.After(time.Now().UTC())
}

func FilterInactive(ev EventConfig) bool {
return ev.Disabled || FilterExpired(ev)
return ev.Disabled || FilterExpired(ev) || FilterNotStarted(ev)
}

func FilterNotOpenable(ev EventConfig) bool {
Expand Down
Loading
Loading