alert service

This commit is contained in:
yash 2026-02-25 23:52:21 +03:00
parent 0e73841b3e
commit 608561ab38
8 changed files with 283 additions and 8 deletions

View file

@ -9,14 +9,14 @@ import (
)
const saveAlertQuery = `
insert into alert(user_id, instrument_id, price)
values ($1, $2, $3)
insert into alert(user_id, instrument_id, price, condition)
values ($1, $2, $3, $4)
returning id`
func (p *Postgresql) SaveAlert(ctx context.Context, alert *entities.Alert) (entities.AlertID, error) {
var id entities.AlertID
err := p.db.QueryRow(ctx, saveAlertQuery, alert.UserID, alert.Instrument.ID, alert.Price).Scan(&id)
err := p.db.QueryRow(ctx, saveAlertQuery, alert.UserID, alert.Instrument.ID, alert.Price.String(), alert.Condition).Scan(&id)
if err != nil {
return "", fmt.Errorf("failed to exec saveAlertQuery: %w", err)
}
@ -24,8 +24,47 @@ func (p *Postgresql) SaveAlert(ctx context.Context, alert *entities.Alert) (enti
return id, nil
}
const allActiveAlertsQuery = `
select a.id, a.user_id, a.price, a.condition, i.id, c_base.symbol, c_quote.symbol
from alert a
join instrument i on i.id = a.instrument_id
join currency c_base on c_base.id = i.base_currency_id
join currency c_quote on c_quote.id = i.quoted_currency_id
where a.active = true
order by a.id`
func (p *Postgresql) AllActiveAlerts(ctx context.Context) ([]entities.Alert, error) {
rows, err := p.db.Query(ctx, allActiveAlertsQuery)
if err != nil {
return nil, fmt.Errorf("failed to exec allActiveAlertsQuery: %w", err)
}
defer rows.Close()
var alerts []entities.Alert
for rows.Next() {
var alert entities.Alert
var priceStr string
if err := rows.Scan(
&alert.ID, &alert.UserID, &priceStr, &alert.Condition,
&alert.Instrument.ID, &alert.Instrument.BaseCurrency, &alert.Instrument.QuoteCurrency,
); err != nil {
return nil, fmt.Errorf("failed to scan alert row: %w", err)
}
alert.Price, err = decimal.NewFromString(priceStr)
if err != nil {
return nil, fmt.Errorf("failed to parse alert price: %w", err)
}
alerts = append(alerts, alert)
}
return alerts, nil
}
const alertByIDQuery = `
select a.id, a.user_id, a.price, i.id, c_base.symbol, c_quote.symbol
select a.id, a.user_id, a.price, a.condition, i.id, c_base.symbol, c_quote.symbol
from alert a
join instrument i on i.id = a.instrument_id
join currency c_base on c_base.id = i.base_currency_id
@ -37,7 +76,7 @@ func (p *Postgresql) AlertByID(ctx context.Context, id entities.AlertID) (*entit
var priceStr string
err := p.db.QueryRow(ctx, alertByIDQuery, id).Scan(
&alert.ID, &alert.UserID, &priceStr,
&alert.ID, &alert.UserID, &priceStr, &alert.Condition,
&alert.Instrument.ID, &alert.Instrument.BaseCurrency, &alert.Instrument.QuoteCurrency,
)
if err != nil {
@ -53,7 +92,7 @@ func (p *Postgresql) AlertByID(ctx context.Context, id entities.AlertID) (*entit
}
const alertsByUserIDQuery = `
select a.id, a.user_id, a.price, i.id, c_base.symbol, c_quote.symbol
select a.id, a.user_id, a.price, a.condition, i.id, c_base.symbol, c_quote.symbol
from alert a
join instrument i on i.id = a.instrument_id
join currency c_base on c_base.id = i.base_currency_id
@ -75,7 +114,7 @@ func (p *Postgresql) AlertsByUserID(ctx context.Context, userID entities.UserID,
var priceStr string
if err := rows.Scan(
&alert.ID, &alert.UserID, &priceStr,
&alert.ID, &alert.UserID, &priceStr, &alert.Condition,
&alert.Instrument.ID, &alert.Instrument.BaseCurrency, &alert.Instrument.QuoteCurrency,
); err != nil {
return nil, fmt.Errorf("failed to scan alert row: %w", err)
@ -103,6 +142,17 @@ func (p *Postgresql) DeleteAlert(ctx context.Context, id entities.AlertID) error
return nil
}
const disableAlertQuery = "update alert set active = false where id = $1"
func (p *Postgresql) DisableAlert(ctx context.Context, id entities.AlertID) error {
_, err := p.db.Exec(ctx, disableAlertQuery, id)
if err != nil {
return fmt.Errorf("failed to exec disableAlertQuery: %w", err)
}
return nil
}
const updateAlertPriceQuery = "update alert set price = $2 where id = $1"
func (p *Postgresql) UpdateAlertPrice(ctx context.Context, id entities.AlertID, price decimal.Decimal) error {

View file

@ -1,4 +1,5 @@
drop table if exists alert;
drop type alert_condition;
drop table if exists instrument;
drop table if exists currency;
drop table if exists users;

View file

@ -17,12 +17,15 @@ create table if not exists instrument (
UNIQUE (base_currency_id, quoted_currency_id)
);
create type alert_condition as enum ('above', 'below');
create table if not exists alert (
id uuid primary key not null default gen_random_uuid(),
user_id uuid references users(id) not null,
instrument_id uuid references instrument(id) not null,
price text not null,
active bool not null default true
active bool not null default true,
condition alert_condition not null
);
insert into currency(symbol) values ('USDT'), ('BTC'), ('ETH'), ('SOL');