refactor: redesign notification table design
This commit is contained in:
parent
d5d85c5e30
commit
54553cfbdd
@ -25,19 +25,19 @@ type LabelColor struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Notification struct {
|
type Notification struct {
|
||||||
NotificationID uuid.UUID `json:"notification_id"`
|
NotificationID uuid.UUID `json:"notification_id"`
|
||||||
NotificationObjectID uuid.UUID `json:"notification_object_id"`
|
CausedBy uuid.UUID `json:"caused_by"`
|
||||||
NotifierID uuid.UUID `json:"notifier_id"`
|
ActionType string `json:"action_type"`
|
||||||
Read bool `json:"read"`
|
Data json.RawMessage `json:"data"`
|
||||||
|
CreatedOn time.Time `json:"created_on"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type NotificationObject struct {
|
type NotificationNotified struct {
|
||||||
NotificationObjectID uuid.UUID `json:"notification_object_id"`
|
NotifiedID uuid.UUID `json:"notified_id"`
|
||||||
EntityID uuid.UUID `json:"entity_id"`
|
NotificationID uuid.UUID `json:"notification_id"`
|
||||||
ActionType int32 `json:"action_type"`
|
UserID uuid.UUID `json:"user_id"`
|
||||||
ActorID uuid.UUID `json:"actor_id"`
|
Read bool `json:"read"`
|
||||||
EntityType int32 `json:"entity_type"`
|
ReadAt sql.NullTime `json:"read_at"`
|
||||||
CreatedOn time.Time `json:"created_on"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Organization struct {
|
type Organization struct {
|
||||||
|
@ -5,86 +5,129 @@ package db
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"database/sql"
|
||||||
|
"encoding/json"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
const createNotification = `-- name: CreateNotification :one
|
const createNotification = `-- name: CreateNotification :one
|
||||||
INSERT INTO notification(notification_object_id, notifier_id)
|
INSERT INTO notification (caused_by, data, action_type, created_on)
|
||||||
VALUES ($1, $2) RETURNING notification_id, notification_object_id, notifier_id, read
|
VALUES ($1, $2, $3, $4) RETURNING notification_id, caused_by, action_type, data, created_on
|
||||||
`
|
`
|
||||||
|
|
||||||
type CreateNotificationParams struct {
|
type CreateNotificationParams struct {
|
||||||
NotificationObjectID uuid.UUID `json:"notification_object_id"`
|
CausedBy uuid.UUID `json:"caused_by"`
|
||||||
NotifierID uuid.UUID `json:"notifier_id"`
|
Data json.RawMessage `json:"data"`
|
||||||
|
ActionType string `json:"action_type"`
|
||||||
|
CreatedOn time.Time `json:"created_on"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) CreateNotification(ctx context.Context, arg CreateNotificationParams) (Notification, error) {
|
func (q *Queries) CreateNotification(ctx context.Context, arg CreateNotificationParams) (Notification, error) {
|
||||||
row := q.db.QueryRowContext(ctx, createNotification, arg.NotificationObjectID, arg.NotifierID)
|
row := q.db.QueryRowContext(ctx, createNotification,
|
||||||
|
arg.CausedBy,
|
||||||
|
arg.Data,
|
||||||
|
arg.ActionType,
|
||||||
|
arg.CreatedOn,
|
||||||
|
)
|
||||||
var i Notification
|
var i Notification
|
||||||
err := row.Scan(
|
err := row.Scan(
|
||||||
&i.NotificationID,
|
&i.NotificationID,
|
||||||
&i.NotificationObjectID,
|
&i.CausedBy,
|
||||||
&i.NotifierID,
|
|
||||||
&i.Read,
|
|
||||||
)
|
|
||||||
return i, err
|
|
||||||
}
|
|
||||||
|
|
||||||
const createNotificationObject = `-- name: CreateNotificationObject :one
|
|
||||||
INSERT INTO notification_object(entity_type, action_type, entity_id, created_on, actor_id)
|
|
||||||
VALUES ($1, $2, $3, $4, $5) RETURNING notification_object_id, entity_id, action_type, actor_id, entity_type, created_on
|
|
||||||
`
|
|
||||||
|
|
||||||
type CreateNotificationObjectParams struct {
|
|
||||||
EntityType int32 `json:"entity_type"`
|
|
||||||
ActionType int32 `json:"action_type"`
|
|
||||||
EntityID uuid.UUID `json:"entity_id"`
|
|
||||||
CreatedOn time.Time `json:"created_on"`
|
|
||||||
ActorID uuid.UUID `json:"actor_id"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (q *Queries) CreateNotificationObject(ctx context.Context, arg CreateNotificationObjectParams) (NotificationObject, error) {
|
|
||||||
row := q.db.QueryRowContext(ctx, createNotificationObject,
|
|
||||||
arg.EntityType,
|
|
||||||
arg.ActionType,
|
|
||||||
arg.EntityID,
|
|
||||||
arg.CreatedOn,
|
|
||||||
arg.ActorID,
|
|
||||||
)
|
|
||||||
var i NotificationObject
|
|
||||||
err := row.Scan(
|
|
||||||
&i.NotificationObjectID,
|
|
||||||
&i.EntityID,
|
|
||||||
&i.ActionType,
|
&i.ActionType,
|
||||||
&i.ActorID,
|
&i.Data,
|
||||||
&i.EntityType,
|
|
||||||
&i.CreatedOn,
|
&i.CreatedOn,
|
||||||
)
|
)
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
|
|
||||||
const getAllNotificationsForUserID = `-- name: GetAllNotificationsForUserID :many
|
const createNotificationNotifed = `-- name: CreateNotificationNotifed :one
|
||||||
SELECT n.notification_id, n.notification_object_id, n.notifier_id, n.read FROM notification as n
|
INSERT INTO notification_notified (notification_id, user_id) VALUES ($1, $2) RETURNING notified_id, notification_id, user_id, read, read_at
|
||||||
INNER JOIN notification_object as no ON no.notification_object_id = n.notification_object_id
|
|
||||||
WHERE n.notifier_id = $1 ORDER BY no.created_on DESC
|
|
||||||
`
|
`
|
||||||
|
|
||||||
func (q *Queries) GetAllNotificationsForUserID(ctx context.Context, notifierID uuid.UUID) ([]Notification, error) {
|
type CreateNotificationNotifedParams struct {
|
||||||
rows, err := q.db.QueryContext(ctx, getAllNotificationsForUserID, notifierID)
|
NotificationID uuid.UUID `json:"notification_id"`
|
||||||
|
UserID uuid.UUID `json:"user_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) CreateNotificationNotifed(ctx context.Context, arg CreateNotificationNotifedParams) (NotificationNotified, error) {
|
||||||
|
row := q.db.QueryRowContext(ctx, createNotificationNotifed, arg.NotificationID, arg.UserID)
|
||||||
|
var i NotificationNotified
|
||||||
|
err := row.Scan(
|
||||||
|
&i.NotifiedID,
|
||||||
|
&i.NotificationID,
|
||||||
|
&i.UserID,
|
||||||
|
&i.Read,
|
||||||
|
&i.ReadAt,
|
||||||
|
)
|
||||||
|
return i, err
|
||||||
|
}
|
||||||
|
|
||||||
|
const getAllNotificationsForUserID = `-- name: GetAllNotificationsForUserID :many
|
||||||
|
SELECT notified_id, nn.notification_id, nn.user_id, read, read_at, n.notification_id, caused_by, action_type, data, created_on, user_account.user_id, created_at, email, username, password_hash, profile_bg_color, full_name, initials, profile_avatar_url, role_code, bio, active FROM notification_notified AS nn
|
||||||
|
INNER JOIN notification AS n ON n.notification_id = nn.notification_id
|
||||||
|
LEFT JOIN user_account ON user_account.user_id = n.caused_by
|
||||||
|
WHERE nn.user_id = $1
|
||||||
|
`
|
||||||
|
|
||||||
|
type GetAllNotificationsForUserIDRow struct {
|
||||||
|
NotifiedID uuid.UUID `json:"notified_id"`
|
||||||
|
NotificationID uuid.UUID `json:"notification_id"`
|
||||||
|
UserID uuid.UUID `json:"user_id"`
|
||||||
|
Read bool `json:"read"`
|
||||||
|
ReadAt sql.NullTime `json:"read_at"`
|
||||||
|
NotificationID_2 uuid.UUID `json:"notification_id_2"`
|
||||||
|
CausedBy uuid.UUID `json:"caused_by"`
|
||||||
|
ActionType string `json:"action_type"`
|
||||||
|
Data json.RawMessage `json:"data"`
|
||||||
|
CreatedOn time.Time `json:"created_on"`
|
||||||
|
UserID_2 uuid.UUID `json:"user_id_2"`
|
||||||
|
CreatedAt time.Time `json:"created_at"`
|
||||||
|
Email string `json:"email"`
|
||||||
|
Username string `json:"username"`
|
||||||
|
PasswordHash string `json:"password_hash"`
|
||||||
|
ProfileBgColor string `json:"profile_bg_color"`
|
||||||
|
FullName string `json:"full_name"`
|
||||||
|
Initials string `json:"initials"`
|
||||||
|
ProfileAvatarUrl sql.NullString `json:"profile_avatar_url"`
|
||||||
|
RoleCode string `json:"role_code"`
|
||||||
|
Bio string `json:"bio"`
|
||||||
|
Active bool `json:"active"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) GetAllNotificationsForUserID(ctx context.Context, userID uuid.UUID) ([]GetAllNotificationsForUserIDRow, error) {
|
||||||
|
rows, err := q.db.QueryContext(ctx, getAllNotificationsForUserID, userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
var items []Notification
|
var items []GetAllNotificationsForUserIDRow
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var i Notification
|
var i GetAllNotificationsForUserIDRow
|
||||||
if err := rows.Scan(
|
if err := rows.Scan(
|
||||||
|
&i.NotifiedID,
|
||||||
&i.NotificationID,
|
&i.NotificationID,
|
||||||
&i.NotificationObjectID,
|
&i.UserID,
|
||||||
&i.NotifierID,
|
|
||||||
&i.Read,
|
&i.Read,
|
||||||
|
&i.ReadAt,
|
||||||
|
&i.NotificationID_2,
|
||||||
|
&i.CausedBy,
|
||||||
|
&i.ActionType,
|
||||||
|
&i.Data,
|
||||||
|
&i.CreatedOn,
|
||||||
|
&i.UserID_2,
|
||||||
|
&i.CreatedAt,
|
||||||
|
&i.Email,
|
||||||
|
&i.Username,
|
||||||
|
&i.PasswordHash,
|
||||||
|
&i.ProfileBgColor,
|
||||||
|
&i.FullName,
|
||||||
|
&i.Initials,
|
||||||
|
&i.ProfileAvatarUrl,
|
||||||
|
&i.RoleCode,
|
||||||
|
&i.Bio,
|
||||||
|
&i.Active,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -99,79 +142,16 @@ func (q *Queries) GetAllNotificationsForUserID(ctx context.Context, notifierID u
|
|||||||
return items, nil
|
return items, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
const getEntityForNotificationID = `-- name: GetEntityForNotificationID :one
|
const markNotificationAsRead = `-- name: MarkNotificationAsRead :exec
|
||||||
SELECT no.created_on, no.entity_id, no.entity_type, no.action_type, no.actor_id FROM notification as n
|
UPDATE notification_notified SET read = true, read_at = $2 WHERE user_id = $1
|
||||||
INNER JOIN notification_object as no ON no.notification_object_id = n.notification_object_id
|
|
||||||
WHERE n.notification_id = $1
|
|
||||||
`
|
`
|
||||||
|
|
||||||
type GetEntityForNotificationIDRow struct {
|
type MarkNotificationAsReadParams struct {
|
||||||
CreatedOn time.Time `json:"created_on"`
|
UserID uuid.UUID `json:"user_id"`
|
||||||
EntityID uuid.UUID `json:"entity_id"`
|
ReadAt sql.NullTime `json:"read_at"`
|
||||||
EntityType int32 `json:"entity_type"`
|
|
||||||
ActionType int32 `json:"action_type"`
|
|
||||||
ActorID uuid.UUID `json:"actor_id"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) GetEntityForNotificationID(ctx context.Context, notificationID uuid.UUID) (GetEntityForNotificationIDRow, error) {
|
func (q *Queries) MarkNotificationAsRead(ctx context.Context, arg MarkNotificationAsReadParams) error {
|
||||||
row := q.db.QueryRowContext(ctx, getEntityForNotificationID, notificationID)
|
_, err := q.db.ExecContext(ctx, markNotificationAsRead, arg.UserID, arg.ReadAt)
|
||||||
var i GetEntityForNotificationIDRow
|
return err
|
||||||
err := row.Scan(
|
|
||||||
&i.CreatedOn,
|
|
||||||
&i.EntityID,
|
|
||||||
&i.EntityType,
|
|
||||||
&i.ActionType,
|
|
||||||
&i.ActorID,
|
|
||||||
)
|
|
||||||
return i, err
|
|
||||||
}
|
|
||||||
|
|
||||||
const getEntityIDForNotificationID = `-- name: GetEntityIDForNotificationID :one
|
|
||||||
SELECT no.entity_id FROM notification as n
|
|
||||||
INNER JOIN notification_object as no ON no.notification_object_id = n.notification_object_id
|
|
||||||
WHERE n.notification_id = $1
|
|
||||||
`
|
|
||||||
|
|
||||||
func (q *Queries) GetEntityIDForNotificationID(ctx context.Context, notificationID uuid.UUID) (uuid.UUID, error) {
|
|
||||||
row := q.db.QueryRowContext(ctx, getEntityIDForNotificationID, notificationID)
|
|
||||||
var entity_id uuid.UUID
|
|
||||||
err := row.Scan(&entity_id)
|
|
||||||
return entity_id, err
|
|
||||||
}
|
|
||||||
|
|
||||||
const getNotificationForNotificationID = `-- name: GetNotificationForNotificationID :one
|
|
||||||
SELECT n.notification_id, n.notification_object_id, n.notifier_id, n.read, no.notification_object_id, no.entity_id, no.action_type, no.actor_id, no.entity_type, no.created_on FROM notification as n
|
|
||||||
INNER JOIN notification_object as no ON no.notification_object_id = n.notification_object_id
|
|
||||||
WHERE n.notification_id = $1
|
|
||||||
`
|
|
||||||
|
|
||||||
type GetNotificationForNotificationIDRow struct {
|
|
||||||
NotificationID uuid.UUID `json:"notification_id"`
|
|
||||||
NotificationObjectID uuid.UUID `json:"notification_object_id"`
|
|
||||||
NotifierID uuid.UUID `json:"notifier_id"`
|
|
||||||
Read bool `json:"read"`
|
|
||||||
NotificationObjectID_2 uuid.UUID `json:"notification_object_id_2"`
|
|
||||||
EntityID uuid.UUID `json:"entity_id"`
|
|
||||||
ActionType int32 `json:"action_type"`
|
|
||||||
ActorID uuid.UUID `json:"actor_id"`
|
|
||||||
EntityType int32 `json:"entity_type"`
|
|
||||||
CreatedOn time.Time `json:"created_on"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (q *Queries) GetNotificationForNotificationID(ctx context.Context, notificationID uuid.UUID) (GetNotificationForNotificationIDRow, error) {
|
|
||||||
row := q.db.QueryRowContext(ctx, getNotificationForNotificationID, notificationID)
|
|
||||||
var i GetNotificationForNotificationIDRow
|
|
||||||
err := row.Scan(
|
|
||||||
&i.NotificationID,
|
|
||||||
&i.NotificationObjectID,
|
|
||||||
&i.NotifierID,
|
|
||||||
&i.Read,
|
|
||||||
&i.NotificationObjectID_2,
|
|
||||||
&i.EntityID,
|
|
||||||
&i.ActionType,
|
|
||||||
&i.ActorID,
|
|
||||||
&i.EntityType,
|
|
||||||
&i.CreatedOn,
|
|
||||||
)
|
|
||||||
return i, err
|
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ type Querier interface {
|
|||||||
CreateInvitedUser(ctx context.Context, email string) (UserAccountInvited, error)
|
CreateInvitedUser(ctx context.Context, email string) (UserAccountInvited, error)
|
||||||
CreateLabelColor(ctx context.Context, arg CreateLabelColorParams) (LabelColor, error)
|
CreateLabelColor(ctx context.Context, arg CreateLabelColorParams) (LabelColor, error)
|
||||||
CreateNotification(ctx context.Context, arg CreateNotificationParams) (Notification, error)
|
CreateNotification(ctx context.Context, arg CreateNotificationParams) (Notification, error)
|
||||||
CreateNotificationObject(ctx context.Context, arg CreateNotificationObjectParams) (NotificationObject, error)
|
CreateNotificationNotifed(ctx context.Context, arg CreateNotificationNotifedParams) (NotificationNotified, error)
|
||||||
CreateOrganization(ctx context.Context, arg CreateOrganizationParams) (Organization, error)
|
CreateOrganization(ctx context.Context, arg CreateOrganizationParams) (Organization, error)
|
||||||
CreatePersonalProject(ctx context.Context, arg CreatePersonalProjectParams) (Project, error)
|
CreatePersonalProject(ctx context.Context, arg CreatePersonalProjectParams) (Project, error)
|
||||||
CreatePersonalProjectLink(ctx context.Context, arg CreatePersonalProjectLinkParams) (PersonalProject, error)
|
CreatePersonalProjectLink(ctx context.Context, arg CreatePersonalProjectLinkParams) (PersonalProject, error)
|
||||||
@ -61,7 +61,7 @@ type Querier interface {
|
|||||||
DeleteUserAccountInvitedForEmail(ctx context.Context, email string) error
|
DeleteUserAccountInvitedForEmail(ctx context.Context, email string) error
|
||||||
DoesUserExist(ctx context.Context, arg DoesUserExistParams) (bool, error)
|
DoesUserExist(ctx context.Context, arg DoesUserExistParams) (bool, error)
|
||||||
GetActivityForTaskID(ctx context.Context, taskID uuid.UUID) ([]TaskActivity, error)
|
GetActivityForTaskID(ctx context.Context, taskID uuid.UUID) ([]TaskActivity, error)
|
||||||
GetAllNotificationsForUserID(ctx context.Context, notifierID uuid.UUID) ([]Notification, error)
|
GetAllNotificationsForUserID(ctx context.Context, userID uuid.UUID) ([]GetAllNotificationsForUserIDRow, error)
|
||||||
GetAllOrganizations(ctx context.Context) ([]Organization, error)
|
GetAllOrganizations(ctx context.Context) ([]Organization, error)
|
||||||
GetAllProjectsForTeam(ctx context.Context, teamID uuid.UUID) ([]Project, error)
|
GetAllProjectsForTeam(ctx context.Context, teamID uuid.UUID) ([]Project, error)
|
||||||
GetAllTaskGroups(ctx context.Context) ([]TaskGroup, error)
|
GetAllTaskGroups(ctx context.Context) ([]TaskGroup, error)
|
||||||
@ -78,8 +78,6 @@ type Querier interface {
|
|||||||
GetCommentsForTaskID(ctx context.Context, taskID uuid.UUID) ([]TaskComment, error)
|
GetCommentsForTaskID(ctx context.Context, taskID uuid.UUID) ([]TaskComment, error)
|
||||||
GetConfirmTokenByEmail(ctx context.Context, email string) (UserAccountConfirmToken, error)
|
GetConfirmTokenByEmail(ctx context.Context, email string) (UserAccountConfirmToken, error)
|
||||||
GetConfirmTokenByID(ctx context.Context, confirmTokenID uuid.UUID) (UserAccountConfirmToken, error)
|
GetConfirmTokenByID(ctx context.Context, confirmTokenID uuid.UUID) (UserAccountConfirmToken, error)
|
||||||
GetEntityForNotificationID(ctx context.Context, notificationID uuid.UUID) (GetEntityForNotificationIDRow, error)
|
|
||||||
GetEntityIDForNotificationID(ctx context.Context, notificationID uuid.UUID) (uuid.UUID, error)
|
|
||||||
GetInvitedMembersForProjectID(ctx context.Context, projectID uuid.UUID) ([]GetInvitedMembersForProjectIDRow, error)
|
GetInvitedMembersForProjectID(ctx context.Context, projectID uuid.UUID) ([]GetInvitedMembersForProjectIDRow, error)
|
||||||
GetInvitedUserAccounts(ctx context.Context) ([]UserAccountInvited, error)
|
GetInvitedUserAccounts(ctx context.Context) ([]UserAccountInvited, error)
|
||||||
GetInvitedUserByEmail(ctx context.Context, email string) (UserAccountInvited, error)
|
GetInvitedUserByEmail(ctx context.Context, email string) (UserAccountInvited, error)
|
||||||
@ -89,7 +87,6 @@ type Querier interface {
|
|||||||
GetMemberData(ctx context.Context, projectID uuid.UUID) ([]UserAccount, error)
|
GetMemberData(ctx context.Context, projectID uuid.UUID) ([]UserAccount, error)
|
||||||
GetMemberProjectIDsForUserID(ctx context.Context, userID uuid.UUID) ([]uuid.UUID, error)
|
GetMemberProjectIDsForUserID(ctx context.Context, userID uuid.UUID) ([]uuid.UUID, error)
|
||||||
GetMemberTeamIDsForUserID(ctx context.Context, userID uuid.UUID) ([]uuid.UUID, error)
|
GetMemberTeamIDsForUserID(ctx context.Context, userID uuid.UUID) ([]uuid.UUID, error)
|
||||||
GetNotificationForNotificationID(ctx context.Context, notificationID uuid.UUID) (GetNotificationForNotificationIDRow, error)
|
|
||||||
GetPersonalProjectsForUserID(ctx context.Context, userID uuid.UUID) ([]Project, error)
|
GetPersonalProjectsForUserID(ctx context.Context, userID uuid.UUID) ([]Project, error)
|
||||||
GetProjectByID(ctx context.Context, projectID uuid.UUID) (Project, error)
|
GetProjectByID(ctx context.Context, projectID uuid.UUID) (Project, error)
|
||||||
GetProjectIDForTask(ctx context.Context, taskID uuid.UUID) (uuid.UUID, error)
|
GetProjectIDForTask(ctx context.Context, taskID uuid.UUID) (uuid.UUID, error)
|
||||||
@ -134,6 +131,7 @@ type Querier interface {
|
|||||||
GetUserRolesForProject(ctx context.Context, arg GetUserRolesForProjectParams) (GetUserRolesForProjectRow, error)
|
GetUserRolesForProject(ctx context.Context, arg GetUserRolesForProjectParams) (GetUserRolesForProjectRow, error)
|
||||||
HasActiveUser(ctx context.Context) (bool, error)
|
HasActiveUser(ctx context.Context) (bool, error)
|
||||||
HasAnyUser(ctx context.Context) (bool, error)
|
HasAnyUser(ctx context.Context) (bool, error)
|
||||||
|
MarkNotificationAsRead(ctx context.Context, arg MarkNotificationAsReadParams) error
|
||||||
SetFirstUserActive(ctx context.Context) (UserAccount, error)
|
SetFirstUserActive(ctx context.Context) (UserAccount, error)
|
||||||
SetInactiveLastMoveForTaskID(ctx context.Context, taskID uuid.UUID) error
|
SetInactiveLastMoveForTaskID(ctx context.Context, taskID uuid.UUID) error
|
||||||
SetPublicOn(ctx context.Context, arg SetPublicOnParams) (Project, error)
|
SetPublicOn(ctx context.Context, arg SetPublicOnParams) (Project, error)
|
||||||
|
@ -1,27 +1,15 @@
|
|||||||
-- name: GetAllNotificationsForUserID :many
|
-- name: GetAllNotificationsForUserID :many
|
||||||
SELECT n.* FROM notification as n
|
SELECT * FROM notification_notified AS nn
|
||||||
INNER JOIN notification_object as no ON no.notification_object_id = n.notification_object_id
|
INNER JOIN notification AS n ON n.notification_id = nn.notification_id
|
||||||
WHERE n.notifier_id = $1 ORDER BY no.created_on DESC;
|
LEFT JOIN user_account ON user_account.user_id = n.caused_by
|
||||||
|
WHERE nn.user_id = $1;
|
||||||
|
|
||||||
-- name: GetNotificationForNotificationID :one
|
-- name: MarkNotificationAsRead :exec
|
||||||
SELECT n.*, no.* FROM notification as n
|
UPDATE notification_notified SET read = true, read_at = $2 WHERE user_id = $1;
|
||||||
INNER JOIN notification_object as no ON no.notification_object_id = n.notification_object_id
|
|
||||||
WHERE n.notification_id = $1;
|
|
||||||
|
|
||||||
-- name: CreateNotificationObject :one
|
|
||||||
INSERT INTO notification_object(entity_type, action_type, entity_id, created_on, actor_id)
|
|
||||||
VALUES ($1, $2, $3, $4, $5) RETURNING *;
|
|
||||||
|
|
||||||
-- name: GetEntityIDForNotificationID :one
|
|
||||||
SELECT no.entity_id FROM notification as n
|
|
||||||
INNER JOIN notification_object as no ON no.notification_object_id = n.notification_object_id
|
|
||||||
WHERE n.notification_id = $1;
|
|
||||||
|
|
||||||
-- name: GetEntityForNotificationID :one
|
|
||||||
SELECT no.created_on, no.entity_id, no.entity_type, no.action_type, no.actor_id FROM notification as n
|
|
||||||
INNER JOIN notification_object as no ON no.notification_object_id = n.notification_object_id
|
|
||||||
WHERE n.notification_id = $1;
|
|
||||||
|
|
||||||
-- name: CreateNotification :one
|
-- name: CreateNotification :one
|
||||||
INSERT INTO notification(notification_object_id, notifier_id)
|
INSERT INTO notification (caused_by, data, action_type, created_on)
|
||||||
VALUES ($1, $2) RETURNING *;
|
VALUES ($1, $2, $3, $4) RETURNING *;
|
||||||
|
|
||||||
|
-- name: CreateNotificationNotifed :one
|
||||||
|
INSERT INTO notification_notified (notification_id, user_id) VALUES ($1, $2) RETURNING *;
|
||||||
|
@ -222,16 +222,6 @@ func ConvertToRoleCode(r string) RoleCode {
|
|||||||
return RoleCodeObserver
|
return RoleCodeObserver
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetEntityType converts integer to EntityType enum
|
|
||||||
func GetEntityType(entityType int32) EntityType {
|
|
||||||
switch entityType {
|
|
||||||
case 1:
|
|
||||||
return EntityTypeTask
|
|
||||||
default:
|
|
||||||
panic("Not a valid entity type!")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetActionType converts integer to ActionType enum
|
// GetActionType converts integer to ActionType enum
|
||||||
func GetActionType(actionType int32) ActionType {
|
func GetActionType(actionType int32) ActionType {
|
||||||
switch actionType {
|
switch actionType {
|
||||||
|
@ -6,14 +6,12 @@ package graph
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/jordanknott/taskcafe/internal/db"
|
"github.com/jordanknott/taskcafe/internal/db"
|
||||||
"github.com/jordanknott/taskcafe/internal/logger"
|
"github.com/jordanknott/taskcafe/internal/logger"
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *notificationResolver) ID(ctx context.Context, obj *db.Notification) (uuid.UUID, error) {
|
func (r *notificationResolver) ID(ctx context.Context, obj *db.Notification) (uuid.UUID, error) {
|
||||||
@ -21,12 +19,7 @@ func (r *notificationResolver) ID(ctx context.Context, obj *db.Notification) (uu
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *notificationResolver) ActionType(ctx context.Context, obj *db.Notification) (ActionType, error) {
|
func (r *notificationResolver) ActionType(ctx context.Context, obj *db.Notification) (ActionType, error) {
|
||||||
entity, err := r.Repository.GetEntityForNotificationID(ctx, obj.NotificationID)
|
return ActionTypeTaskMemberAdded, nil // TODO
|
||||||
if err != nil {
|
|
||||||
return ActionTypeTaskMemberAdded, err
|
|
||||||
}
|
|
||||||
actionType := GetActionType(entity.ActionType)
|
|
||||||
return actionType, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *notificationResolver) CausedBy(ctx context.Context, obj *db.Notification) (*NotificationCausedBy, error) {
|
func (r *notificationResolver) CausedBy(ctx context.Context, obj *db.Notification) (*NotificationCausedBy, error) {
|
||||||
@ -38,26 +31,42 @@ func (r *notificationResolver) Data(ctx context.Context, obj *db.Notification) (
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *notificationResolver) CreatedAt(ctx context.Context, obj *db.Notification) (*time.Time, error) {
|
func (r *notificationResolver) CreatedAt(ctx context.Context, obj *db.Notification) (*time.Time, error) {
|
||||||
entity, err := r.Repository.GetEntityForNotificationID(ctx, obj.NotificationID)
|
return &obj.CreatedOn, nil
|
||||||
if err != nil {
|
|
||||||
return &time.Time{}, err
|
|
||||||
}
|
|
||||||
return &entity.CreatedOn, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *queryResolver) Notifications(ctx context.Context) ([]Notified, error) {
|
func (r *queryResolver) Notifications(ctx context.Context) ([]Notified, error) {
|
||||||
userID, ok := GetUserID(ctx)
|
userID, ok := GetUserID(ctx)
|
||||||
logger.New(ctx).Info("fetching notifications")
|
logger.New(ctx).Info("fetching notifications")
|
||||||
if !ok {
|
if !ok {
|
||||||
return []db.Notification{}, errors.New("user id is missing")
|
return []Notified{}, nil
|
||||||
}
|
}
|
||||||
notifications, err := r.Repository.GetAllNotificationsForUserID(ctx, userID)
|
notifications, err := r.Repository.GetAllNotificationsForUserID(ctx, userID)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return []db.Notification{}, nil
|
return []Notified{}, nil
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return []db.Notification{}, err
|
return []Notified{}, err
|
||||||
}
|
}
|
||||||
return notifications, nil
|
userNotifications := []Notified{}
|
||||||
|
for _, notified := range notifications {
|
||||||
|
var readAt *time.Time
|
||||||
|
if notified.ReadAt.Valid {
|
||||||
|
readAt = ¬ified.ReadAt.Time
|
||||||
|
}
|
||||||
|
n := Notified{
|
||||||
|
ID: notified.NotifiedID,
|
||||||
|
Read: notified.Read,
|
||||||
|
ReadAt: readAt,
|
||||||
|
Notification: &db.Notification{
|
||||||
|
NotificationID: notified.NotificationID,
|
||||||
|
CausedBy: notified.CausedBy,
|
||||||
|
ActionType: notified.ActionType,
|
||||||
|
Data: notified.Data,
|
||||||
|
CreatedOn: notified.CreatedOn,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
userNotifications = append(userNotifications, n)
|
||||||
|
}
|
||||||
|
return userNotifications, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *subscriptionResolver) NotificationAdded(ctx context.Context) (<-chan *Notified, error) {
|
func (r *subscriptionResolver) NotificationAdded(ctx context.Context) (<-chan *Notified, error) {
|
||||||
@ -68,42 +77,3 @@ func (r *subscriptionResolver) NotificationAdded(ctx context.Context) (<-chan *N
|
|||||||
func (r *Resolver) Notification() NotificationResolver { return ¬ificationResolver{r} }
|
func (r *Resolver) Notification() NotificationResolver { return ¬ificationResolver{r} }
|
||||||
|
|
||||||
type notificationResolver struct{ *Resolver }
|
type notificationResolver struct{ *Resolver }
|
||||||
|
|
||||||
// !!! WARNING !!!
|
|
||||||
// The code below was going to be deleted when updating resolvers. It has been copied here so you have
|
|
||||||
// one last chance to move it out of harms way if you want. There are two reasons this happens:
|
|
||||||
// - When renaming or deleting a resolver the old code will be put in here. You can safely delete
|
|
||||||
// it when you're done.
|
|
||||||
// - You have helper methods in this file. Move them out to keep these resolver files clean.
|
|
||||||
func (r *notificationResolver) Entity(ctx context.Context, obj *db.Notification) (*NotificationEntity, error) {
|
|
||||||
logger.New(ctx).WithFields(log.Fields{"notificationID": obj.NotificationID}).Info("fetching entity for notification")
|
|
||||||
entity, err := r.Repository.GetEntityForNotificationID(ctx, obj.NotificationID)
|
|
||||||
logger.New(ctx).WithFields(log.Fields{"entityID": entity.EntityID}).Info("fetched entity")
|
|
||||||
if err != nil {
|
|
||||||
return &NotificationEntity{}, err
|
|
||||||
}
|
|
||||||
entityType := GetEntityType(entity.EntityType)
|
|
||||||
switch entityType {
|
|
||||||
case EntityTypeTask:
|
|
||||||
task, err := r.Repository.GetTaskByID(ctx, entity.EntityID)
|
|
||||||
if err != nil {
|
|
||||||
return &NotificationEntity{}, err
|
|
||||||
}
|
|
||||||
return &NotificationEntity{Type: entityType, ID: entity.EntityID, Name: task.Name}, err
|
|
||||||
|
|
||||||
default:
|
|
||||||
panic(fmt.Errorf("not implemented"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
func (r *notificationResolver) Actor(ctx context.Context, obj *db.Notification) (*NotificationActor, error) {
|
|
||||||
entity, err := r.Repository.GetEntityForNotificationID(ctx, obj.NotificationID)
|
|
||||||
if err != nil {
|
|
||||||
return &NotificationActor{}, err
|
|
||||||
}
|
|
||||||
logger.New(ctx).WithFields(log.Fields{"entityID": entity.ActorID}).Info("fetching actor")
|
|
||||||
user, err := r.Repository.GetUserAccountByID(ctx, entity.ActorID)
|
|
||||||
if err != nil {
|
|
||||||
return &NotificationActor{}, err
|
|
||||||
}
|
|
||||||
return &NotificationActor{ID: entity.ActorID, Name: user.FullName, Type: ActorTypeUser}, nil
|
|
||||||
}
|
|
||||||
|
@ -1,15 +1,10 @@
|
|||||||
package notification
|
package notification
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/RichardKnop/machinery/v1"
|
"github.com/RichardKnop/machinery/v1"
|
||||||
"github.com/RichardKnop/machinery/v1/tasks"
|
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/jordanknott/taskcafe/internal/db"
|
"github.com/jordanknott/taskcafe/internal/db"
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func RegisterTasks(server *machinery.Server, repo db.Repository) {
|
func RegisterTasks(server *machinery.Server, repo db.Repository) {
|
||||||
@ -24,23 +19,6 @@ type NotificationTasks struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *NotificationTasks) TaskMemberWasAdded(taskID, notifierID, notifiedID string) (bool, error) {
|
func (m *NotificationTasks) TaskMemberWasAdded(taskID, notifierID, notifiedID string) (bool, error) {
|
||||||
tid := uuid.MustParse(taskID)
|
|
||||||
notifier := uuid.MustParse(notifierID)
|
|
||||||
notified := uuid.MustParse(notifiedID)
|
|
||||||
if notifier == notified {
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
ctx := context.Background()
|
|
||||||
now := time.Now().UTC()
|
|
||||||
notificationObject, err := m.Repository.CreateNotificationObject(ctx, db.CreateNotificationObjectParams{EntityType: 1, EntityID: tid, ActionType: 1, ActorID: notifier, CreatedOn: now})
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
notification, err := m.Repository.CreateNotification(ctx, db.CreateNotificationParams{NotificationObjectID: notificationObject.NotificationObjectID, NotifierID: notified})
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
log.WithFields(log.Fields{"notificationID": notification.NotificationID}).Info("created new notification")
|
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,30 +27,5 @@ type NotificationQueue struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (n *NotificationQueue) TaskMemberWasAdded(taskID, notifier, notified uuid.UUID) error {
|
func (n *NotificationQueue) TaskMemberWasAdded(taskID, notifier, notified uuid.UUID) error {
|
||||||
task := tasks.Signature{
|
|
||||||
Name: "taskMemberWasAdded",
|
|
||||||
Args: []tasks.Arg{
|
|
||||||
{
|
|
||||||
Name: "taskID",
|
|
||||||
Type: "string",
|
|
||||||
Value: taskID.String(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "notifierID",
|
|
||||||
Type: "string",
|
|
||||||
Value: notifier.String(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "notifiedID",
|
|
||||||
Type: "string",
|
|
||||||
Value: notified.String(),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err := n.Server.SendTask(&task)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,8 @@ DROP TABLE notification CASCADE;
|
|||||||
|
|
||||||
CREATE TABLE notification (
|
CREATE TABLE notification (
|
||||||
notification_id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
|
notification_id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||||
actor_id uuid,
|
caused_by uuid NOT NULL,
|
||||||
action_type int NOT NULL,
|
action_type text NOT NULL,
|
||||||
data jsonb,
|
data jsonb,
|
||||||
created_on timestamptz NOT NULL
|
created_on timestamptz NOT NULL
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user