Skip to content

Commit

Permalink
DCS-52: user notification preferences (#15)
Browse files Browse the repository at this point in the history
* remove outdated entry

* add notification tables

* add notification types

* add notification targets

* add notification preferences

* add notification preferences table

* add create and update

* change package name for oss

* add default preferences handling

* add audit log handling

* add notification-preferences routes

* add authenticated user notifications routes

* add notification types client

* fix error notification types or targets empty

* fix linter errors

* add notification type client

* add notification targets client

* rebase main

* add notification preferences client

* add tests

* refactor per suggestions

* use bool pointer to ensure value is provided

* Update pkg/api/v1alpha1/authenticated_user.go

Co-authored-by: E Camden Fisher <fish@fishnix.net>

* validate notification preference len before update

* update per review

* simplify indices

* update per review

---------

Co-authored-by: E Camden Fisher <fish@fishnix.net>
  • Loading branch information
bailinhe and fishnix authored Aug 9, 2023
1 parent cded768 commit 439cf33
Show file tree
Hide file tree
Showing 29 changed files with 8,219 additions and 134 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@ coverage.txt
audit.log
.devcontainer/nats/resolver.conf
.devcontainer/nsc

tmp/**
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ dev-hydra: |
echo "strategies:\n access_token: jwt\n" >> ./hydra/hydra.yml; \
echo "oidc:\n subject_identifiers:\n supported_types:\n - public\n" >> ./hydra/hydra.yml; \
fi;
@docker-compose up -d hydra-migrate hydra consent
@docker-compose up -d hydra-migrate hydra
@sleep 10
@echo creating hydra client-id governor and client-secret ${SECRET}
@docker-compose exec hydra hydra clients create \
Expand Down Expand Up @@ -145,4 +145,4 @@ test-local-init:
@cockroach sql --database defaultdb --insecure -f testing/local_init.sql

dev-serve:
go run . serve --config .governor-dev.yaml --audit-log-path audit.log
go run . serve --config .governor-dev.yaml --audit-log-path audit.log
2 changes: 1 addition & 1 deletion db/migrations/00012_orgs_deleted_at.sql
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
ALTER TABLE organizations ADD COLUMN deleted_at TIMESTAMPTZ NULL;
ALTER TABLE organizations ALTER COLUMN slug SET NOT NULL;
-- +goose StatementEnd

-- +goose Down
-- +goose StatementBegin
ALTER TABLE organizations DROP COLUMN deleted_at TIMESTAMPTZ NULL;
Expand Down
76 changes: 76 additions & 0 deletions db/migrations/00031_notification_preferences.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
-- +goose Up
-- +goose StatementBegin
CREATE TABLE notification_types (
id UUID PRIMARY KEY NOT NULL DEFAULT gen_random_uuid(),
name STRING NOT NULL,
slug STRING NOT NULL,
description STRING NOT NULL,
default_enabled BOOL NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
deleted_at TIMESTAMPTZ NULL,

CONSTRAINT notification_types_slug_key UNIQUE (slug) WHERE deleted_at IS NULL,
INDEX (deleted_at) STORING (slug, default_enabled)
);

CREATE TABLE notification_targets (
id UUID PRIMARY KEY NOT NULL DEFAULT gen_random_uuid(),
name STRING NOT NULL,
slug STRING NOT NULL,
description STRING NOT NULL,
default_enabled BOOL NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
deleted_at TIMESTAMPTZ NULL,

CONSTRAINT notification_targets_slug_key UNIQUE (slug) WHERE deleted_at IS NULL,
INDEX (deleted_at) STORING (slug, default_enabled)
);

CREATE TABLE notification_preferences (
id UUID PRIMARY KEY NOT NULL DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE ON UPDATE CASCADE,
notification_type_id UUID NOT NULL REFERENCES notification_types(id) ON DELETE CASCADE ON UPDATE CASCADE,
notification_target_id UUID NULL REFERENCES notification_targets(id) ON DELETE CASCADE ON UPDATE CASCADE,
notification_target_id_null_string UUID AS (IFNULL(notification_target_id, '00000000-0000-0000-0000-000000000000')) STORED,
enabled BOOL NOT NULL DEFAULT false,

CONSTRAINT unique_user_type_target UNIQUE (user_id, notification_type_id, notification_target_id_null_string),
INDEX (user_id, notification_target_id, notification_type_id) STORING (enabled, notification_target_id_null_string)
);

CREATE MATERIALIZED VIEW notification_defaults AS
SELECT
targets.id AS target_id,
targets.slug AS target_slug,
types.id AS type_id,
types.slug AS type_slug,
targets.default_enabled AS default_enabled
FROM
notification_types AS types
CROSS JOIN notification_targets AS targets
WHERE types.deleted_at IS NULL AND targets.deleted_at IS NULL
UNION (
SELECT
'00000000-0000-0000-0000-000000000000' AS target_id,
'' AS target_slug,
types.id AS type_id,
types.slug AS type_slug,
types.default_enabled AS default_enabled
FROM
notification_types AS types
WHERE types.deleted_at IS NULL
);

CREATE INDEX ON notification_defaults (target_id, type_id) STORING (target_slug, type_slug, default_enabled);

-- +goose StatementEnd

-- +goose Down
-- +goose StatementBegin
DROP MATERIALIZED VIEW notification_defaults;
DROP TABLE notification_preferences;
DROP TABLE notification_targets;
DROP TABLE notification_types;
-- +goose StatementEnd
54 changes: 28 additions & 26 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ go 1.20
require (
github.com/XSAM/otelsql v0.23.0
github.com/cockroachdb/cockroach-go/v2 v2.3.5
github.com/coreos/go-oidc/v3 v3.5.0
github.com/coreos/go-oidc/v3 v3.6.0
github.com/friendsofgo/errors v0.9.2
github.com/gin-contrib/cors v1.4.0
github.com/gin-contrib/zap v0.1.0
Expand All @@ -15,20 +15,20 @@ require (
github.com/gosimple/slug v1.13.1
github.com/jmoiron/sqlx v1.3.5
github.com/lib/pq v1.10.9
github.com/metal-toolbox/auditevent v0.7.0
github.com/metal-toolbox/auditevent v0.8.0
github.com/mitchellh/go-homedir v1.1.0
github.com/nats-io/nats.go v1.25.0
github.com/pressly/goose/v3 v3.10.0
github.com/nats-io/nats.go v1.28.0
github.com/pressly/goose/v3 v3.14.0
github.com/spf13/cobra v1.7.0
github.com/spf13/pflag v1.0.5
github.com/spf13/viper v1.15.0
github.com/spf13/viper v1.16.0
github.com/stretchr/testify v1.8.4
github.com/volatiletech/null/v8 v8.1.2
github.com/volatiletech/sqlboiler/v4 v4.14.2
github.com/volatiletech/strmangle v0.0.5
github.com/zsais/go-gin-prometheus v0.1.0
go.hollow.sh/toolbox v0.5.1
go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.40.0
go.hollow.sh/toolbox v0.6.1
go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.42.0
go.opentelemetry.io/otel v1.16.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.16.0
go.opentelemetry.io/otel/sdk v1.16.0
Expand All @@ -39,19 +39,22 @@ require (

require (
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
github.com/chenzhuoyu/iasm v0.9.0 // indirect
github.com/gofrs/flock v0.8.1 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.2 // indirect
github.com/klauspost/compress v1.16.7 // indirect
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0 // indirect
go.opentelemetry.io/proto/otlp v0.19.0 // indirect
google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect
google.golang.org/grpc v1.55.0 // indirect
go.opentelemetry.io/proto/otlp v1.0.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20230731193218-e0aa005b6bdf // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230731193218-e0aa005b6bdf // indirect
google.golang.org/grpc v1.57.0 // indirect
)

require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/bytedance/sonic v1.9.1 // indirect
github.com/bytedance/sonic v1.10.0-rc3 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/ericlagergren/decimal v0.0.0-20221120152707-495c53812d05 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
Expand All @@ -60,25 +63,25 @@ require (
github.com/go-jose/go-jose/v3 v3.0.0 // indirect
github.com/go-logr/logr v1.2.4 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-logr/zapr v1.2.3 // indirect
github.com/go-logr/zapr v1.2.4 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.14.0 // indirect
github.com/go-playground/validator/v10 v10.14.1 // indirect
github.com/gofrs/uuid v4.4.0+incompatible // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/gosimple/unidecode v1.0.1 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jackc/chunkreader/v2 v2.0.1 // indirect
github.com/jackc/pgconn v1.14.0 // indirect
github.com/jackc/pgconn v1.14.1 // indirect
github.com/jackc/pgio v1.0.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgproto3/v2 v2.3.2 // indirect
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
github.com/jackc/pgtype v1.14.0 // indirect
github.com/jackc/pgx/v4 v4.18.1 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
github.com/klauspost/cpuid/v2 v2.2.5 // indirect
github.com/leodido/go-urn v1.2.4 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
Expand All @@ -87,16 +90,15 @@ require (
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/nats-io/nats-server/v2 v2.8.4 // indirect
github.com/nats-io/nkeys v0.4.4 // indirect
github.com/nats-io/nuid v1.0.1 // indirect
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
github.com/pelletier/go-toml/v2 v2.0.9 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_golang v1.14.0
github.com/prometheus/client_model v0.3.0 // indirect
github.com/prometheus/common v0.42.0 // indirect
github.com/prometheus/procfs v0.9.0 // indirect
github.com/sirupsen/logrus v1.9.0 // indirect
github.com/prometheus/client_golang v1.16.0
github.com/prometheus/client_model v0.4.0 // indirect
github.com/prometheus/common v0.44.0 // indirect
github.com/prometheus/procfs v0.11.1 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/spf13/afero v1.9.5 // indirect
github.com/spf13/cast v1.5.1 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
Expand All @@ -108,9 +110,9 @@ require (
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.16.0
go.opentelemetry.io/otel/metric v1.16.0 // indirect
go.opentelemetry.io/otel/trace v1.16.0 // indirect
go.uber.org/atomic v1.10.0 // indirect
go.uber.org/atomic v1.11.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/arch v0.3.0 // indirect
golang.org/x/arch v0.4.0 // indirect
golang.org/x/crypto v0.11.0 // indirect
golang.org/x/net v0.12.0 // indirect
golang.org/x/sys v0.10.0 // indirect
Expand Down
Loading

0 comments on commit 439cf33

Please sign in to comment.