Skip to content

Commit

Permalink
first test version
Browse files Browse the repository at this point in the history
  • Loading branch information
kish1n committed Aug 16, 2024
1 parent a4cf7ea commit a4c6f56
Show file tree
Hide file tree
Showing 28 changed files with 588 additions and 444 deletions.
10 changes: 2 additions & 8 deletions docs/spec/components/schemas/DailyQuestion.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ allOf:
- time_for_answer
- reward
- answer_options
- active
- starts_at
- created_at
properties:
Expand All @@ -28,7 +27,7 @@ allOf:
example: Georgian capital
time_for_answer:
type: integer
format: int
format: int64
description: Time for answer
example: 86400
reward:
Expand All @@ -39,15 +38,10 @@ allOf:
answer_options:
$ref: '#/components/schemas/DailyQuestionAnswers'
description: answer options
Active:
type: boolean
description: Status activity event
example: true
starts_at:
type: time.Time
format: int
format: int64
description: Event start date, after which the event becomes active
created_at:
type: time.Time
format: int
description: Event add date
5 changes: 0 additions & 5 deletions docs/spec/components/schemas/DailyQuestionAnswer.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,6 @@ allOf:
type: integer
format: int
description: ID in table daily_question
nullifier:
type: string
description: Nullifier of the user who gave the answer
example: "0x123...abc"
pattern: '^0x[0-9a-fA-F]{64}$'
answer:
type: string
example: "That day is May 26, 2025"
9 changes: 8 additions & 1 deletion internal/assets/migrations/004_daily_questions_tabel.sql
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,17 @@ CREATE TABLE IF NOT EXISTS daily_questions (
time_for_answer INTEGER NOT NULL,
reward INTEGER NOT NULL,
answer_options JSONB NOT NULL,
active BOOLEAN DEFAULT TRUE,
starts_at TIMESTAMP NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT (NOW() AT TIME ZONE 'utc')
);

CREATE TABLE IF NOT EXISTS daily_question_responses (
id SERIAL PRIMARY KEY,
daily_question_id INTEGER REFERENCES daily_questions (id),
nullifier TEXT REFERENCES balances (nullifier),
created_at TIMESTAMP NOT NULL DEFAULT (NOW() AT TIME ZONE 'utc')
);

-- +migrate Down 2024-08-14 11:42:56.462615
DROP TABLE IF EXISTS daily_question_responses;
DROP TABLE IF EXISTS daily_questions;
13 changes: 0 additions & 13 deletions internal/config/main.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
package config

import (
"log"
"time"

"github.com/rarimo/geo-auth-svc/pkg/auth"
"github.com/rarimo/geo-auth-svc/pkg/hmacsig"
"github.com/rarimo/geo-points-svc/internal/data/evtypes"
Expand All @@ -14,8 +11,6 @@ import (
"gitlab.com/distributed_lab/kit/pgdb"
)

const locationName = "Asia/Tbilisi"

type Config interface {
comfig.Logger
pgdb.Databaser
Expand All @@ -25,7 +20,6 @@ type Config interface {
evtypes.EventTypeser
hmacsig.SigCalculatorProvider
PollVerifierer
TimeZoneProvider

Levels() *Levels
Verifiers() Verifiers
Expand All @@ -41,8 +35,6 @@ type config struct {
hmacsig.SigCalculatorProvider
PollVerifierer

timeZone *time.Location

passport root.VerifierProvider

levels comfig.Once
Expand All @@ -51,10 +43,6 @@ type config struct {
}

func New(getter kv.Getter) Config {
location, err := time.LoadLocation(locationName)
if err != nil {
log.Fatalf("error loading location: %v", err)
}
return &config{
getter: getter,
Databaser: pgdb.NewDatabaser(getter),
Expand All @@ -66,6 +54,5 @@ func New(getter kv.Getter) Config {
passport: root.NewVerifierProvider(getter, root.PoseidonSMT),
EventTypeser: evtypes.NewConfig(getter),
SigCalculatorProvider: hmacsig.NewCalculatorProvider(getter),
timeZone: location,
}
}
16 changes: 0 additions & 16 deletions internal/config/utcTimeZone.go

This file was deleted.

27 changes: 27 additions & 0 deletions internal/data/daily_question_responses.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package data

import "time"

type DailyQuestionsResponses struct {
ID int `db:"id"`
DailyQuestionId int `db:"daily_question_id"`
Nullifier string `db:"nullifier"`
CreatedAt time.Time `db:"created_at"`
}

type DailyQuestionsResponsesQ interface {
New() DailyQuestionsResponsesQ
Insert(DailyQuestionsResponses) error
Update(map[string]any) error
Transaction(func() error) error

Count() (int64, error)
Select() ([]DailyQuestionsResponses, error)
Get() (*DailyQuestionsResponses, error)

FilterByQuestionID(ID int) DailyQuestionsResponsesQ
FilterByNullifier(nullifier string) DailyQuestionsResponsesQ
FilterByCreatedBefore(before int64) DailyQuestionsResponsesQ
FilterByCreatedAfter(after int64) DailyQuestionsResponsesQ
FilterByCreatedAt(date time.Time) DailyQuestionsResponsesQ
}
5 changes: 2 additions & 3 deletions internal/data/daily_questions.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@ import "time"
type DailyQuestion struct {
ID int `db:"id"`
Title string `db:"title"`
TimeForAnswer int `db:"time_for_answer"`
TimeForAnswer int64 `db:"time_for_answer"`
Reward int `db:"reward"`
AnswerOptions Jsonb `db:"answer_options"`
Active bool `db:"active"`
StartsAt time.Time `db:"starts_at"`
CreatedAt time.Time `db:"created_at"`
}
Expand All @@ -22,7 +21,7 @@ type DailyQuestionQ interface {
Select() ([]DailyQuestion, error)
Get() (*DailyQuestion, error)

FilterByActive(status bool) DailyQuestionQ
FilterActive() DailyQuestionQ
FilterByStartAt(date time.Time) DailyQuestionQ
FilterByCreatedAt(date time.Time) DailyQuestionQ
FilterByID(ID int) DailyQuestionQ
Expand Down
2 changes: 2 additions & 0 deletions internal/data/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ type EventsQ interface {
FilterByType(...string) EventsQ
FilterByNotType(types ...string) EventsQ
FilterByUpdatedAtBefore(int64) EventsQ
FilterByCreatedAtAfter(int64) EventsQ
FilterByCreatedAtBefore(int64) EventsQ
FilterByExternalID(string) EventsQ
FilterInactiveNotClaimed(types ...string) EventsQ
}
1 change: 0 additions & 1 deletion internal/data/evtypes/models/extra.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ const (
TypePollParticipation = "poll_participation"
TypeEarlyTest = "early_test"
TypeDailyQuestion = "daily_question"
TypeDailyQuestionPost = "daily_question_post"
)

const (
Expand Down
119 changes: 119 additions & 0 deletions internal/data/pg/daily_question_responses.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
package pg

import (
"database/sql"
"errors"
"fmt"
"time"

"github.com/Masterminds/squirrel"
"github.com/rarimo/geo-points-svc/internal/data"
"gitlab.com/distributed_lab/kit/pgdb"
)

const dailyQuestionAnswerTable = "daily_question_responses"

type DailyQuestionsAnswerQ struct {
db *pgdb.DB
selector squirrel.SelectBuilder
updater squirrel.UpdateBuilder
counter squirrel.SelectBuilder
}

func NewDailyQuestionsAnswerQ(db *pgdb.DB) data.DailyQuestionsResponsesQ {
return &DailyQuestionsAnswerQ{
db: db,
selector: squirrel.Select("*").From(dailyQuestionAnswerTable),
updater: squirrel.Update(dailyQuestionAnswerTable),
counter: squirrel.Select("COUNT(*) as count").From(dailyQuestionAnswerTable),
}
}

func (q *DailyQuestionsAnswerQ) New() data.DailyQuestionsResponsesQ {
return NewDailyQuestionsAnswerQ(q.db)
}

func (q *DailyQuestionsAnswerQ) Insert(answer data.DailyQuestionsResponses) error {
stmt := squirrel.Insert(dailyQuestionAnswerTable).SetMap(map[string]interface{}{
"daily_question_id": answer.DailyQuestionId,
"nullifier": answer.Nullifier,
"created_at": answer.CreatedAt,
})

if err := q.db.Exec(stmt); err != nil {
return fmt.Errorf("insert daily_questions_answer %+v: %w", answer, err)
}

return nil
}

func (q *DailyQuestionsAnswerQ) Update(fields map[string]any) error {
if err := q.db.Exec(q.updater.SetMap(fields)); err != nil {
return fmt.Errorf("update daily_question_responses: %w", err)
}

return nil
}

func (q *DailyQuestionsAnswerQ) Count() (int64, error) {
res := struct {
Count int64 `db:"count"`
}{}

if err := q.db.Get(&res, q.counter); err != nil {
return 0, fmt.Errorf("get daily_question_responses: %w", err)
}

return res.Count, nil
}

func (q *DailyQuestionsAnswerQ) Select() ([]data.DailyQuestionsResponses, error) {
var res []data.DailyQuestionsResponses
if err := q.db.Select(&res, q.selector); err != nil {
return res, fmt.Errorf("select daily_question_responses: %w", err)
}
return res, nil
}

func (q *DailyQuestionsAnswerQ) Get() (*data.DailyQuestionsResponses, error) {
var res data.DailyQuestionsResponses
if err := q.db.Get(&res, q.selector); err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil, nil
}
return nil, fmt.Errorf("get daily_question_responses: %w", err)
}

return &res, nil
}

func (q *DailyQuestionsAnswerQ) Transaction(f func() error) error {
return q.db.Transaction(f)
}

func (q *DailyQuestionsAnswerQ) FilterByQuestionID(ID int) data.DailyQuestionsResponsesQ {
return q.applyCondition(squirrel.Eq{"daily_question_id": ID})
}

func (q *DailyQuestionsAnswerQ) FilterByNullifier(nullifier string) data.DailyQuestionsResponsesQ {
return q.applyCondition(squirrel.Eq{"nullifier": nullifier})
}

func (q *DailyQuestionsAnswerQ) FilterByCreatedAt(date time.Time) data.DailyQuestionsResponsesQ {
return q.applyCondition(squirrel.Eq{"created_at": date})
}

func (q *DailyQuestionsAnswerQ) FilterByCreatedAfter(after int64) data.DailyQuestionsResponsesQ {
return q.applyCondition(squirrel.Expr("created_at > TO_TIMESTAMP(?)", after))
}

func (q *DailyQuestionsAnswerQ) FilterByCreatedBefore(before int64) data.DailyQuestionsResponsesQ {
return q.applyCondition(squirrel.Expr("created_at < TO_TIMESTAMP(?)", before))
}

func (q *DailyQuestionsAnswerQ) applyCondition(cond squirrel.Sqlizer) data.DailyQuestionsResponsesQ {
q.selector = q.selector.Where(cond)
q.updater = q.updater.Where(cond)
q.counter = q.counter.Where(cond)
return q
}
6 changes: 3 additions & 3 deletions internal/data/pg/daily_questions.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ func (q *dailyQuestionsQ) Insert(quest data.DailyQuestion) error {
"time_for_answer": quest.TimeForAnswer,
"reward": quest.Reward,
"answer_options": quest.AnswerOptions,
"active": quest.Active,
"starts_at": quest.StartsAt,
})

Expand Down Expand Up @@ -91,8 +90,9 @@ func (q *dailyQuestionsQ) Get() (*data.DailyQuestion, error) {
return &res, nil
}

func (q *dailyQuestionsQ) FilterByActive(status bool) data.DailyQuestionQ {
return q.applyCondition(squirrel.Eq{"active": status})
func (q *dailyQuestionsQ) FilterActive() data.DailyQuestionQ {
now := time.Now().Unix()
return q.applyCondition(squirrel.Expr("EXTRACT(EPOCH FROM starts_at) + time_for_answer > ? AND EXTRACT(EPOCH FROM starts_at) < ?", now, now))
}

func (q *dailyQuestionsQ) FilterByStartAt(date time.Time) data.DailyQuestionQ {
Expand Down
8 changes: 8 additions & 0 deletions internal/data/pg/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,14 @@ func (q *events) FilterByUpdatedAtBefore(unix int64) data.EventsQ {
return q.applyCondition(squirrel.Lt{"updated_at": unix})
}

func (q *events) FilterByCreatedAtAfter(unix int64) data.EventsQ {
return q.applyCondition(squirrel.Gt{"created_at": unix})
}

func (q *events) FilterByCreatedAtBefore(unix int64) data.EventsQ {
return q.applyCondition(squirrel.Lt{"created_at": unix})
}

func (q *events) FilterInactiveNotClaimed(types ...string) data.EventsQ {
if len(types) == 0 {
return q
Expand Down
17 changes: 14 additions & 3 deletions internal/service/handlers/ctx.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ const (
verifiersCtxKey
sigCalculatorCtxKey
voteVerifierCtxKey
dailyQuestionsQCtxKey
dailyQuestionsCtxKey
dailyResponsesCtxKey
)

func CtxLog(entry *logan.Entry) func(context.Context) context.Context {
Expand Down Expand Up @@ -57,7 +58,13 @@ func CtxBalancesQ(q data.BalancesQ) func(context.Context) context.Context {

func CtxDailyQuestionsQ(q data.DailyQuestionQ) func(context.Context) context.Context {
return func(ctx context.Context) context.Context {
return context.WithValue(ctx, dailyQuestionsQCtxKey, q)
return context.WithValue(ctx, dailyQuestionsCtxKey, q)
}
}

func CtxDailyQuestionsResponsesQ(q data.DailyQuestionsResponsesQ) func(context.Context) context.Context {
return func(ctx context.Context) context.Context {
return context.WithValue(ctx, dailyResponsesCtxKey, q)
}
}

Expand All @@ -66,7 +73,11 @@ func BalancesQ(r *http.Request) data.BalancesQ {
}

func DailyQuestionsQ(r *http.Request) data.DailyQuestionQ {
return r.Context().Value(dailyQuestionsQCtxKey).(data.DailyQuestionQ).New()
return r.Context().Value(dailyQuestionsCtxKey).(data.DailyQuestionQ).New()
}

func DailyQuestionsResponsesQ(r *http.Request) data.DailyQuestionsResponsesQ {
return r.Context().Value(dailyResponsesCtxKey).(data.DailyQuestionsResponsesQ).New()
}

func CtxReferralsQ(q data.ReferralsQ) func(context.Context) context.Context {
Expand Down
Loading

0 comments on commit a4c6f56

Please sign in to comment.