From 863a0ea2f664025f419c841be8687d784b09e50d Mon Sep 17 00:00:00 2001 From: claude Date: Sun, 29 Mar 2026 15:47:09 +0000 Subject: [PATCH] feat: add notification events handling and MQTT integration - Implemented notification event publishing with a new NotificationEventPublisher interface. - Created a noopNotificationEventPublisher for testing purposes. - Added functionality to publish notification created events via MQTT. - Introduced a new stream event publisher for handling job logs and updates. - Added database migration for popup_ads table. - Created tests for notification events and popup ads functionality. - Established MQTT connection and publishing helpers for event messages. --- go.mod | 23 +- go.sum | 65 +- internal/api/proto/app/v1/admin.pb.go | 1086 +++++++++++++---- internal/api/proto/app/v1/admin_grpc.pb.go | 190 +++ internal/api/proto/app/v1/catalog.pb.go | 730 +++++++++-- internal/api/proto/app/v1/catalog_grpc.pb.go | 254 ++++ internal/api/proto/app/v1/common.pb.go | 512 ++++++-- internal/database/model/player_configs.gen.go | 2 +- internal/database/model/popup_ads.gen.go | 30 + internal/database/query/gen.go | 8 + internal/database/query/popup_ads.gen.go | 427 +++++++ internal/middleware/authenticator.go | 27 +- internal/middleware/authenticator_test.go | 12 +- internal/repository/popup_ad_repository.go | 105 ++ .../service_notification_mqtt_test.go | 96 ++ .../__test__/service_popup_ads_test.go | 177 +++ .../service/__test__/testdb_setup_test.go | 62 +- internal/service/admin_helpers.go | 43 + internal/service/catalog_mapper.go | 22 +- internal/service/interface.go | 16 + internal/service/notification_events.go | 57 + internal/service/notification_events_test.go | 175 +++ internal/service/payment_helpers.go | 3 + .../service/payment_notification_helpers.go | 31 + internal/service/referral_helpers.go | 4 +- internal/service/register.go | 1 + .../service/service_admin_finance_catalog.go | 144 +++ internal/service/service_core.go | 12 +- internal/service/service_payments.go | 1 + internal/service/service_popup_ads_test.go | 354 ++++++ internal/service/service_user_features.go | 144 +++ internal/service/value_helpers.go | 8 + internal/transport/grpc/server.go | 4 +- internal/transport/mqtt/bootstrap.go | 41 + internal/transport/mqtt/constants.go | 14 + .../transport/mqtt/notification_publisher.go | 44 + .../{paho_helpers.go => publish_helpers.go} | 19 +- ...publisher.go => stream_event_publisher.go} | 87 +- migrations/004_create_popup_ads_table.sql | 15 + proto/app/v1/admin.proto | 58 + proto/app/v1/catalog.proto | 55 + proto/app/v1/common.proto | 24 + 42 files changed, 4606 insertions(+), 576 deletions(-) create mode 100644 internal/database/model/popup_ads.gen.go create mode 100644 internal/database/query/popup_ads.gen.go create mode 100644 internal/repository/popup_ad_repository.go create mode 100644 internal/service/__test__/service_notification_mqtt_test.go create mode 100644 internal/service/__test__/service_popup_ads_test.go create mode 100644 internal/service/notification_events.go create mode 100644 internal/service/notification_events_test.go create mode 100644 internal/service/payment_notification_helpers.go create mode 100644 internal/service/service_popup_ads_test.go create mode 100644 internal/transport/mqtt/bootstrap.go create mode 100644 internal/transport/mqtt/constants.go create mode 100644 internal/transport/mqtt/notification_publisher.go rename internal/transport/mqtt/{paho_helpers.go => publish_helpers.go} (80%) rename internal/transport/mqtt/{mqtt_publisher.go => stream_event_publisher.go} (61%) create mode 100644 migrations/004_create_popup_ads_table.sql diff --git a/go.mod b/go.mod index 98f3c79..8c29700 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/redis/go-redis/v9 v9.17.2 github.com/spf13/viper v1.21.0 go.uber.org/zap v1.27.1 - golang.org/x/crypto v0.47.0 + golang.org/x/crypto v0.48.0 golang.org/x/oauth2 v0.34.0 google.golang.org/grpc v1.79.2 google.golang.org/protobuf v1.36.11 @@ -22,6 +22,17 @@ require ( gorm.io/gen v0.3.27 gorm.io/gorm v1.31.1 gorm.io/plugin/dbresolver v1.6.2 + modernc.org/sqlite v1.47.0 +) + +require ( + github.com/dustin/go-humanize v1.0.1 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/ncruces/go-strftime v1.0.0 // indirect + github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect + modernc.org/libc v1.70.0 // indirect + modernc.org/mathutil v1.7.1 // indirect + modernc.org/memory v1.11.0 // indirect ) require ( @@ -66,12 +77,12 @@ require ( github.com/subosito/gotenv v1.6.0 // indirect go.uber.org/multierr v1.10.0 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/mod v0.32.0 // indirect - golang.org/x/net v0.49.0 // indirect + golang.org/x/mod v0.33.0 // indirect + golang.org/x/net v0.50.0 // indirect golang.org/x/sync v0.19.0 // indirect - golang.org/x/sys v0.40.0 // indirect - golang.org/x/text v0.33.0 // indirect - golang.org/x/tools v0.41.0 // indirect + golang.org/x/sys v0.42.0 // indirect + golang.org/x/text v0.34.0 // indirect + golang.org/x/tools v0.42.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect gorm.io/datatypes v1.2.4 gorm.io/driver/mysql v1.5.7 // indirect diff --git a/go.sum b/go.sum index 673dd9b..b12b890 100644 --- a/go.sum +++ b/go.sum @@ -51,6 +51,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= +github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/eclipse/paho.mqtt.golang v1.5.1 h1:/VSOv3oDLlpqR2Epjn1Q7b2bSTplJIeV2ISgCl2W7nE= github.com/eclipse/paho.mqtt.golang v1.5.1/go.mod h1:1/yJCneuyOoCOzKSsOTUc0AJfpsItBGWvYpBLimhArU= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= @@ -74,10 +76,14 @@ github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e h1:ijClszYn+mADRFY17kjQEVQ1XRhq2/JR1M3sGqeJoxs= +github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= +github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo= @@ -97,17 +103,23 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/lib/pq v1.11.2 h1:x6gxUeu39V0BHZiugWe8LXZYZ+Utk7hSJGThs8sdzfs= github.com/lib/pq v1.11.2/go.mod h1:/p+8NSbOcwzAEI7wiMXFlgydTwcgTr3OSKMsD2BitpA= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-sqlite3 v1.14.8/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/microsoft/go-mssqldb v0.17.0 h1:Fto83dMZPnYv1Zwx5vHHxpNraeEaUlQ/hhHLgZiaenE= github.com/microsoft/go-mssqldb v0.17.0/go.mod h1:OkoNGhGEs8EZqchVTtochlXruEhEOaO4S0d2sB5aeGQ= +github.com/ncruces/go-strftime v1.0.0 h1:HMFp8mLCTPp341M/ZnA4qaf7ZlsbTc+miZjCLOFAw7w= +github.com/ncruces/go-strftime v1.0.0/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/redis/go-redis/v9 v9.17.2 h1:P2EGsA4qVIM3Pp+aPocCJ7DguDHhqrXNhVcEp4ViluI= github.com/redis/go-redis/v9 v9.17.2/go.mod h1:u410H11HMLoB+TP67dz8rL9s6QW2j76l0//kSOd3370= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDcg+AAIFXc= @@ -151,22 +163,23 @@ go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8= -golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A= -golang.org/x/mod v0.32.0 h1:9F4d3PHLljb6x//jOyokMv3eX+YDeepZSEo3mFJy93c= -golang.org/x/mod v0.32.0/go.mod h1:SgipZ/3h2Ci89DlEtEXWUk/HteuRin+HHhN+WbNhguU= -golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o= -golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8= +golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= +golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= +golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= +golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= +golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60= +golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM= golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw= golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE= -golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= -golang.org/x/tools v0.41.0 h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc= -golang.org/x/tools v0.41.0/go.mod h1:XSY6eDqxVNiYgezAVqqCeihT4j1U2CCsqvH3WhQpnlg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= +golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= +golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k= +golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww= @@ -203,3 +216,31 @@ gorm.io/hints v1.1.0 h1:Lp4z3rxREufSdxn4qmkK3TLDltrM10FLTHiuqwDPvXw= gorm.io/hints v1.1.0/go.mod h1:lKQ0JjySsPBj3uslFzY3JhYDtqEwzm+G1hv8rWujB6Y= gorm.io/plugin/dbresolver v1.6.2 h1:F4b85TenghUeITqe3+epPSUtHH7RIk3fXr5l83DF8Pc= gorm.io/plugin/dbresolver v1.6.2/go.mod h1:tctw63jdrOezFR9HmrKnPkmig3m5Edem9fdxk9bQSzM= +modernc.org/cc/v4 v4.27.1 h1:9W30zRlYrefrDV2JE2O8VDtJ1yPGownxciz5rrbQZis= +modernc.org/cc/v4 v4.27.1/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0= +modernc.org/ccgo/v4 v4.32.0 h1:hjG66bI/kqIPX1b2yT6fr/jt+QedtP2fqojG2VrFuVw= +modernc.org/ccgo/v4 v4.32.0/go.mod h1:6F08EBCx5uQc38kMGl+0Nm0oWczoo1c7cgpzEry7Uc0= +modernc.org/fileutil v1.4.0 h1:j6ZzNTftVS054gi281TyLjHPp6CPHr2KCxEXjEbD6SM= +modernc.org/fileutil v1.4.0/go.mod h1:EqdKFDxiByqxLk8ozOxObDSfcVOv/54xDs/DUHdvCUU= +modernc.org/gc/v2 v2.6.5 h1:nyqdV8q46KvTpZlsw66kWqwXRHdjIlJOhG6kxiV/9xI= +modernc.org/gc/v2 v2.6.5/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito= +modernc.org/gc/v3 v3.1.2 h1:ZtDCnhonXSZexk/AYsegNRV1lJGgaNZJuKjJSWKyEqo= +modernc.org/gc/v3 v3.1.2/go.mod h1:HFK/6AGESC7Ex+EZJhJ2Gni6cTaYpSMmU/cT9RmlfYY= +modernc.org/goabi0 v0.2.0 h1:HvEowk7LxcPd0eq6mVOAEMai46V+i7Jrj13t4AzuNks= +modernc.org/goabi0 v0.2.0/go.mod h1:CEFRnnJhKvWT1c1JTI3Avm+tgOWbkOu5oPA8eH8LnMI= +modernc.org/libc v1.70.0 h1:U58NawXqXbgpZ/dcdS9kMshu08aiA6b7gusEusqzNkw= +modernc.org/libc v1.70.0/go.mod h1:OVmxFGP1CI/Z4L3E0Q3Mf1PDE0BucwMkcXjjLntvHJo= +modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU= +modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg= +modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI= +modernc.org/memory v1.11.0/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw= +modernc.org/opt v0.1.4 h1:2kNGMRiUjrp4LcaPuLY2PzUfqM/w9N23quVwhKt5Qm8= +modernc.org/opt v0.1.4/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns= +modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w= +modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE= +modernc.org/sqlite v1.47.0 h1:R1XyaNpoW4Et9yly+I2EeX7pBza/w+pmYee/0HJDyKk= +modernc.org/sqlite v1.47.0/go.mod h1:hWjRO6Tj/5Ik8ieqxQybiEOUXy0NJFNp2tpvVpKlvig= +modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0= +modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A= +modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= +modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= diff --git a/internal/api/proto/app/v1/admin.pb.go b/internal/api/proto/app/v1/admin.pb.go index 16eb26f..9dd0f57 100644 --- a/internal/api/proto/app/v1/admin.pb.go +++ b/internal/api/proto/app/v1/admin.pb.go @@ -2937,6 +2937,538 @@ func (x *DeleteAdminAdTemplateRequest) GetId() string { return "" } +type ListAdminPopupAdsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Page int32 `protobuf:"varint,1,opt,name=page,proto3" json:"page,omitempty"` + Limit int32 `protobuf:"varint,2,opt,name=limit,proto3" json:"limit,omitempty"` + UserId *string `protobuf:"bytes,3,opt,name=user_id,json=userId,proto3,oneof" json:"user_id,omitempty"` + Search *string `protobuf:"bytes,4,opt,name=search,proto3,oneof" json:"search,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListAdminPopupAdsRequest) Reset() { + *x = ListAdminPopupAdsRequest{} + mi := &file_app_v1_admin_proto_msgTypes[49] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListAdminPopupAdsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListAdminPopupAdsRequest) ProtoMessage() {} + +func (x *ListAdminPopupAdsRequest) ProtoReflect() protoreflect.Message { + mi := &file_app_v1_admin_proto_msgTypes[49] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListAdminPopupAdsRequest.ProtoReflect.Descriptor instead. +func (*ListAdminPopupAdsRequest) Descriptor() ([]byte, []int) { + return file_app_v1_admin_proto_rawDescGZIP(), []int{49} +} + +func (x *ListAdminPopupAdsRequest) GetPage() int32 { + if x != nil { + return x.Page + } + return 0 +} + +func (x *ListAdminPopupAdsRequest) GetLimit() int32 { + if x != nil { + return x.Limit + } + return 0 +} + +func (x *ListAdminPopupAdsRequest) GetUserId() string { + if x != nil && x.UserId != nil { + return *x.UserId + } + return "" +} + +func (x *ListAdminPopupAdsRequest) GetSearch() string { + if x != nil && x.Search != nil { + return *x.Search + } + return "" +} + +type ListAdminPopupAdsResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Items []*AdminPopupAd `protobuf:"bytes,1,rep,name=items,proto3" json:"items,omitempty"` + Total int64 `protobuf:"varint,2,opt,name=total,proto3" json:"total,omitempty"` + Page int32 `protobuf:"varint,3,opt,name=page,proto3" json:"page,omitempty"` + Limit int32 `protobuf:"varint,4,opt,name=limit,proto3" json:"limit,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListAdminPopupAdsResponse) Reset() { + *x = ListAdminPopupAdsResponse{} + mi := &file_app_v1_admin_proto_msgTypes[50] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListAdminPopupAdsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListAdminPopupAdsResponse) ProtoMessage() {} + +func (x *ListAdminPopupAdsResponse) ProtoReflect() protoreflect.Message { + mi := &file_app_v1_admin_proto_msgTypes[50] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListAdminPopupAdsResponse.ProtoReflect.Descriptor instead. +func (*ListAdminPopupAdsResponse) Descriptor() ([]byte, []int) { + return file_app_v1_admin_proto_rawDescGZIP(), []int{50} +} + +func (x *ListAdminPopupAdsResponse) GetItems() []*AdminPopupAd { + if x != nil { + return x.Items + } + return nil +} + +func (x *ListAdminPopupAdsResponse) GetTotal() int64 { + if x != nil { + return x.Total + } + return 0 +} + +func (x *ListAdminPopupAdsResponse) GetPage() int32 { + if x != nil { + return x.Page + } + return 0 +} + +func (x *ListAdminPopupAdsResponse) GetLimit() int32 { + if x != nil { + return x.Limit + } + return 0 +} + +type GetAdminPopupAdRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetAdminPopupAdRequest) Reset() { + *x = GetAdminPopupAdRequest{} + mi := &file_app_v1_admin_proto_msgTypes[51] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetAdminPopupAdRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetAdminPopupAdRequest) ProtoMessage() {} + +func (x *GetAdminPopupAdRequest) ProtoReflect() protoreflect.Message { + mi := &file_app_v1_admin_proto_msgTypes[51] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetAdminPopupAdRequest.ProtoReflect.Descriptor instead. +func (*GetAdminPopupAdRequest) Descriptor() ([]byte, []int) { + return file_app_v1_admin_proto_rawDescGZIP(), []int{51} +} + +func (x *GetAdminPopupAdRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +type GetAdminPopupAdResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Item *AdminPopupAd `protobuf:"bytes,1,opt,name=item,proto3" json:"item,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetAdminPopupAdResponse) Reset() { + *x = GetAdminPopupAdResponse{} + mi := &file_app_v1_admin_proto_msgTypes[52] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetAdminPopupAdResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetAdminPopupAdResponse) ProtoMessage() {} + +func (x *GetAdminPopupAdResponse) ProtoReflect() protoreflect.Message { + mi := &file_app_v1_admin_proto_msgTypes[52] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetAdminPopupAdResponse.ProtoReflect.Descriptor instead. +func (*GetAdminPopupAdResponse) Descriptor() ([]byte, []int) { + return file_app_v1_admin_proto_rawDescGZIP(), []int{52} +} + +func (x *GetAdminPopupAdResponse) GetItem() *AdminPopupAd { + if x != nil { + return x.Item + } + return nil +} + +type CreateAdminPopupAdRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` + Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"` + Label string `protobuf:"bytes,3,opt,name=label,proto3" json:"label,omitempty"` + Value string `protobuf:"bytes,4,opt,name=value,proto3" json:"value,omitempty"` + IsActive *bool `protobuf:"varint,5,opt,name=is_active,json=isActive,proto3,oneof" json:"is_active,omitempty"` + MaxTriggersPerSession *int32 `protobuf:"varint,6,opt,name=max_triggers_per_session,json=maxTriggersPerSession,proto3,oneof" json:"max_triggers_per_session,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CreateAdminPopupAdRequest) Reset() { + *x = CreateAdminPopupAdRequest{} + mi := &file_app_v1_admin_proto_msgTypes[53] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CreateAdminPopupAdRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateAdminPopupAdRequest) ProtoMessage() {} + +func (x *CreateAdminPopupAdRequest) ProtoReflect() protoreflect.Message { + mi := &file_app_v1_admin_proto_msgTypes[53] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateAdminPopupAdRequest.ProtoReflect.Descriptor instead. +func (*CreateAdminPopupAdRequest) Descriptor() ([]byte, []int) { + return file_app_v1_admin_proto_rawDescGZIP(), []int{53} +} + +func (x *CreateAdminPopupAdRequest) GetUserId() string { + if x != nil { + return x.UserId + } + return "" +} + +func (x *CreateAdminPopupAdRequest) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *CreateAdminPopupAdRequest) GetLabel() string { + if x != nil { + return x.Label + } + return "" +} + +func (x *CreateAdminPopupAdRequest) GetValue() string { + if x != nil { + return x.Value + } + return "" +} + +func (x *CreateAdminPopupAdRequest) GetIsActive() bool { + if x != nil && x.IsActive != nil { + return *x.IsActive + } + return false +} + +func (x *CreateAdminPopupAdRequest) GetMaxTriggersPerSession() int32 { + if x != nil && x.MaxTriggersPerSession != nil { + return *x.MaxTriggersPerSession + } + return 0 +} + +type CreateAdminPopupAdResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Item *AdminPopupAd `protobuf:"bytes,1,opt,name=item,proto3" json:"item,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CreateAdminPopupAdResponse) Reset() { + *x = CreateAdminPopupAdResponse{} + mi := &file_app_v1_admin_proto_msgTypes[54] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CreateAdminPopupAdResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateAdminPopupAdResponse) ProtoMessage() {} + +func (x *CreateAdminPopupAdResponse) ProtoReflect() protoreflect.Message { + mi := &file_app_v1_admin_proto_msgTypes[54] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateAdminPopupAdResponse.ProtoReflect.Descriptor instead. +func (*CreateAdminPopupAdResponse) Descriptor() ([]byte, []int) { + return file_app_v1_admin_proto_rawDescGZIP(), []int{54} +} + +func (x *CreateAdminPopupAdResponse) GetItem() *AdminPopupAd { + if x != nil { + return x.Item + } + return nil +} + +type UpdateAdminPopupAdRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + UserId string `protobuf:"bytes,2,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` + Type string `protobuf:"bytes,3,opt,name=type,proto3" json:"type,omitempty"` + Label string `protobuf:"bytes,4,opt,name=label,proto3" json:"label,omitempty"` + Value string `protobuf:"bytes,5,opt,name=value,proto3" json:"value,omitempty"` + IsActive *bool `protobuf:"varint,6,opt,name=is_active,json=isActive,proto3,oneof" json:"is_active,omitempty"` + MaxTriggersPerSession *int32 `protobuf:"varint,7,opt,name=max_triggers_per_session,json=maxTriggersPerSession,proto3,oneof" json:"max_triggers_per_session,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UpdateAdminPopupAdRequest) Reset() { + *x = UpdateAdminPopupAdRequest{} + mi := &file_app_v1_admin_proto_msgTypes[55] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UpdateAdminPopupAdRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateAdminPopupAdRequest) ProtoMessage() {} + +func (x *UpdateAdminPopupAdRequest) ProtoReflect() protoreflect.Message { + mi := &file_app_v1_admin_proto_msgTypes[55] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateAdminPopupAdRequest.ProtoReflect.Descriptor instead. +func (*UpdateAdminPopupAdRequest) Descriptor() ([]byte, []int) { + return file_app_v1_admin_proto_rawDescGZIP(), []int{55} +} + +func (x *UpdateAdminPopupAdRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *UpdateAdminPopupAdRequest) GetUserId() string { + if x != nil { + return x.UserId + } + return "" +} + +func (x *UpdateAdminPopupAdRequest) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *UpdateAdminPopupAdRequest) GetLabel() string { + if x != nil { + return x.Label + } + return "" +} + +func (x *UpdateAdminPopupAdRequest) GetValue() string { + if x != nil { + return x.Value + } + return "" +} + +func (x *UpdateAdminPopupAdRequest) GetIsActive() bool { + if x != nil && x.IsActive != nil { + return *x.IsActive + } + return false +} + +func (x *UpdateAdminPopupAdRequest) GetMaxTriggersPerSession() int32 { + if x != nil && x.MaxTriggersPerSession != nil { + return *x.MaxTriggersPerSession + } + return 0 +} + +type UpdateAdminPopupAdResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Item *AdminPopupAd `protobuf:"bytes,1,opt,name=item,proto3" json:"item,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UpdateAdminPopupAdResponse) Reset() { + *x = UpdateAdminPopupAdResponse{} + mi := &file_app_v1_admin_proto_msgTypes[56] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UpdateAdminPopupAdResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateAdminPopupAdResponse) ProtoMessage() {} + +func (x *UpdateAdminPopupAdResponse) ProtoReflect() protoreflect.Message { + mi := &file_app_v1_admin_proto_msgTypes[56] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateAdminPopupAdResponse.ProtoReflect.Descriptor instead. +func (*UpdateAdminPopupAdResponse) Descriptor() ([]byte, []int) { + return file_app_v1_admin_proto_rawDescGZIP(), []int{56} +} + +func (x *UpdateAdminPopupAdResponse) GetItem() *AdminPopupAd { + if x != nil { + return x.Item + } + return nil +} + +type DeleteAdminPopupAdRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DeleteAdminPopupAdRequest) Reset() { + *x = DeleteAdminPopupAdRequest{} + mi := &file_app_v1_admin_proto_msgTypes[57] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DeleteAdminPopupAdRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteAdminPopupAdRequest) ProtoMessage() {} + +func (x *DeleteAdminPopupAdRequest) ProtoReflect() protoreflect.Message { + mi := &file_app_v1_admin_proto_msgTypes[57] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteAdminPopupAdRequest.ProtoReflect.Descriptor instead. +func (*DeleteAdminPopupAdRequest) Descriptor() ([]byte, []int) { + return file_app_v1_admin_proto_rawDescGZIP(), []int{57} +} + +func (x *DeleteAdminPopupAdRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + type ListAdminPlayerConfigsRequest struct { state protoimpl.MessageState `protogen:"open.v1"` Page int32 `protobuf:"varint,1,opt,name=page,proto3" json:"page,omitempty"` @@ -2949,7 +3481,7 @@ type ListAdminPlayerConfigsRequest struct { func (x *ListAdminPlayerConfigsRequest) Reset() { *x = ListAdminPlayerConfigsRequest{} - mi := &file_app_v1_admin_proto_msgTypes[49] + mi := &file_app_v1_admin_proto_msgTypes[58] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2961,7 +3493,7 @@ func (x *ListAdminPlayerConfigsRequest) String() string { func (*ListAdminPlayerConfigsRequest) ProtoMessage() {} func (x *ListAdminPlayerConfigsRequest) ProtoReflect() protoreflect.Message { - mi := &file_app_v1_admin_proto_msgTypes[49] + mi := &file_app_v1_admin_proto_msgTypes[58] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2974,7 +3506,7 @@ func (x *ListAdminPlayerConfigsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListAdminPlayerConfigsRequest.ProtoReflect.Descriptor instead. func (*ListAdminPlayerConfigsRequest) Descriptor() ([]byte, []int) { - return file_app_v1_admin_proto_rawDescGZIP(), []int{49} + return file_app_v1_admin_proto_rawDescGZIP(), []int{58} } func (x *ListAdminPlayerConfigsRequest) GetPage() int32 { @@ -3017,7 +3549,7 @@ type ListAdminPlayerConfigsResponse struct { func (x *ListAdminPlayerConfigsResponse) Reset() { *x = ListAdminPlayerConfigsResponse{} - mi := &file_app_v1_admin_proto_msgTypes[50] + mi := &file_app_v1_admin_proto_msgTypes[59] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3029,7 +3561,7 @@ func (x *ListAdminPlayerConfigsResponse) String() string { func (*ListAdminPlayerConfigsResponse) ProtoMessage() {} func (x *ListAdminPlayerConfigsResponse) ProtoReflect() protoreflect.Message { - mi := &file_app_v1_admin_proto_msgTypes[50] + mi := &file_app_v1_admin_proto_msgTypes[59] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3042,7 +3574,7 @@ func (x *ListAdminPlayerConfigsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListAdminPlayerConfigsResponse.ProtoReflect.Descriptor instead. func (*ListAdminPlayerConfigsResponse) Descriptor() ([]byte, []int) { - return file_app_v1_admin_proto_rawDescGZIP(), []int{50} + return file_app_v1_admin_proto_rawDescGZIP(), []int{59} } func (x *ListAdminPlayerConfigsResponse) GetConfigs() []*AdminPlayerConfig { @@ -3082,7 +3614,7 @@ type GetAdminPlayerConfigRequest struct { func (x *GetAdminPlayerConfigRequest) Reset() { *x = GetAdminPlayerConfigRequest{} - mi := &file_app_v1_admin_proto_msgTypes[51] + mi := &file_app_v1_admin_proto_msgTypes[60] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3094,7 +3626,7 @@ func (x *GetAdminPlayerConfigRequest) String() string { func (*GetAdminPlayerConfigRequest) ProtoMessage() {} func (x *GetAdminPlayerConfigRequest) ProtoReflect() protoreflect.Message { - mi := &file_app_v1_admin_proto_msgTypes[51] + mi := &file_app_v1_admin_proto_msgTypes[60] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3107,7 +3639,7 @@ func (x *GetAdminPlayerConfigRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetAdminPlayerConfigRequest.ProtoReflect.Descriptor instead. func (*GetAdminPlayerConfigRequest) Descriptor() ([]byte, []int) { - return file_app_v1_admin_proto_rawDescGZIP(), []int{51} + return file_app_v1_admin_proto_rawDescGZIP(), []int{60} } func (x *GetAdminPlayerConfigRequest) GetId() string { @@ -3126,7 +3658,7 @@ type GetAdminPlayerConfigResponse struct { func (x *GetAdminPlayerConfigResponse) Reset() { *x = GetAdminPlayerConfigResponse{} - mi := &file_app_v1_admin_proto_msgTypes[52] + mi := &file_app_v1_admin_proto_msgTypes[61] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3138,7 +3670,7 @@ func (x *GetAdminPlayerConfigResponse) String() string { func (*GetAdminPlayerConfigResponse) ProtoMessage() {} func (x *GetAdminPlayerConfigResponse) ProtoReflect() protoreflect.Message { - mi := &file_app_v1_admin_proto_msgTypes[52] + mi := &file_app_v1_admin_proto_msgTypes[61] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3151,7 +3683,7 @@ func (x *GetAdminPlayerConfigResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetAdminPlayerConfigResponse.ProtoReflect.Descriptor instead. func (*GetAdminPlayerConfigResponse) Descriptor() ([]byte, []int) { - return file_app_v1_admin_proto_rawDescGZIP(), []int{52} + return file_app_v1_admin_proto_rawDescGZIP(), []int{61} } func (x *GetAdminPlayerConfigResponse) GetConfig() *AdminPlayerConfig { @@ -3183,7 +3715,7 @@ type CreateAdminPlayerConfigRequest struct { func (x *CreateAdminPlayerConfigRequest) Reset() { *x = CreateAdminPlayerConfigRequest{} - mi := &file_app_v1_admin_proto_msgTypes[53] + mi := &file_app_v1_admin_proto_msgTypes[62] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3195,7 +3727,7 @@ func (x *CreateAdminPlayerConfigRequest) String() string { func (*CreateAdminPlayerConfigRequest) ProtoMessage() {} func (x *CreateAdminPlayerConfigRequest) ProtoReflect() protoreflect.Message { - mi := &file_app_v1_admin_proto_msgTypes[53] + mi := &file_app_v1_admin_proto_msgTypes[62] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3208,7 +3740,7 @@ func (x *CreateAdminPlayerConfigRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateAdminPlayerConfigRequest.ProtoReflect.Descriptor instead. func (*CreateAdminPlayerConfigRequest) Descriptor() ([]byte, []int) { - return file_app_v1_admin_proto_rawDescGZIP(), []int{53} + return file_app_v1_admin_proto_rawDescGZIP(), []int{62} } func (x *CreateAdminPlayerConfigRequest) GetUserId() string { @@ -3318,7 +3850,7 @@ type CreateAdminPlayerConfigResponse struct { func (x *CreateAdminPlayerConfigResponse) Reset() { *x = CreateAdminPlayerConfigResponse{} - mi := &file_app_v1_admin_proto_msgTypes[54] + mi := &file_app_v1_admin_proto_msgTypes[63] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3330,7 +3862,7 @@ func (x *CreateAdminPlayerConfigResponse) String() string { func (*CreateAdminPlayerConfigResponse) ProtoMessage() {} func (x *CreateAdminPlayerConfigResponse) ProtoReflect() protoreflect.Message { - mi := &file_app_v1_admin_proto_msgTypes[54] + mi := &file_app_v1_admin_proto_msgTypes[63] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3343,7 +3875,7 @@ func (x *CreateAdminPlayerConfigResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateAdminPlayerConfigResponse.ProtoReflect.Descriptor instead. func (*CreateAdminPlayerConfigResponse) Descriptor() ([]byte, []int) { - return file_app_v1_admin_proto_rawDescGZIP(), []int{54} + return file_app_v1_admin_proto_rawDescGZIP(), []int{63} } func (x *CreateAdminPlayerConfigResponse) GetConfig() *AdminPlayerConfig { @@ -3376,7 +3908,7 @@ type UpdateAdminPlayerConfigRequest struct { func (x *UpdateAdminPlayerConfigRequest) Reset() { *x = UpdateAdminPlayerConfigRequest{} - mi := &file_app_v1_admin_proto_msgTypes[55] + mi := &file_app_v1_admin_proto_msgTypes[64] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3388,7 +3920,7 @@ func (x *UpdateAdminPlayerConfigRequest) String() string { func (*UpdateAdminPlayerConfigRequest) ProtoMessage() {} func (x *UpdateAdminPlayerConfigRequest) ProtoReflect() protoreflect.Message { - mi := &file_app_v1_admin_proto_msgTypes[55] + mi := &file_app_v1_admin_proto_msgTypes[64] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3401,7 +3933,7 @@ func (x *UpdateAdminPlayerConfigRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateAdminPlayerConfigRequest.ProtoReflect.Descriptor instead. func (*UpdateAdminPlayerConfigRequest) Descriptor() ([]byte, []int) { - return file_app_v1_admin_proto_rawDescGZIP(), []int{55} + return file_app_v1_admin_proto_rawDescGZIP(), []int{64} } func (x *UpdateAdminPlayerConfigRequest) GetId() string { @@ -3518,7 +4050,7 @@ type UpdateAdminPlayerConfigResponse struct { func (x *UpdateAdminPlayerConfigResponse) Reset() { *x = UpdateAdminPlayerConfigResponse{} - mi := &file_app_v1_admin_proto_msgTypes[56] + mi := &file_app_v1_admin_proto_msgTypes[65] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3530,7 +4062,7 @@ func (x *UpdateAdminPlayerConfigResponse) String() string { func (*UpdateAdminPlayerConfigResponse) ProtoMessage() {} func (x *UpdateAdminPlayerConfigResponse) ProtoReflect() protoreflect.Message { - mi := &file_app_v1_admin_proto_msgTypes[56] + mi := &file_app_v1_admin_proto_msgTypes[65] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3543,7 +4075,7 @@ func (x *UpdateAdminPlayerConfigResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateAdminPlayerConfigResponse.ProtoReflect.Descriptor instead. func (*UpdateAdminPlayerConfigResponse) Descriptor() ([]byte, []int) { - return file_app_v1_admin_proto_rawDescGZIP(), []int{56} + return file_app_v1_admin_proto_rawDescGZIP(), []int{65} } func (x *UpdateAdminPlayerConfigResponse) GetConfig() *AdminPlayerConfig { @@ -3562,7 +4094,7 @@ type DeleteAdminPlayerConfigRequest struct { func (x *DeleteAdminPlayerConfigRequest) Reset() { *x = DeleteAdminPlayerConfigRequest{} - mi := &file_app_v1_admin_proto_msgTypes[57] + mi := &file_app_v1_admin_proto_msgTypes[66] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3574,7 +4106,7 @@ func (x *DeleteAdminPlayerConfigRequest) String() string { func (*DeleteAdminPlayerConfigRequest) ProtoMessage() {} func (x *DeleteAdminPlayerConfigRequest) ProtoReflect() protoreflect.Message { - mi := &file_app_v1_admin_proto_msgTypes[57] + mi := &file_app_v1_admin_proto_msgTypes[66] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3587,7 +4119,7 @@ func (x *DeleteAdminPlayerConfigRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteAdminPlayerConfigRequest.ProtoReflect.Descriptor instead. func (*DeleteAdminPlayerConfigRequest) Descriptor() ([]byte, []int) { - return file_app_v1_admin_proto_rawDescGZIP(), []int{57} + return file_app_v1_admin_proto_rawDescGZIP(), []int{66} } func (x *DeleteAdminPlayerConfigRequest) GetId() string { @@ -3612,7 +4144,7 @@ type ListAdminJobsRequest struct { func (x *ListAdminJobsRequest) Reset() { *x = ListAdminJobsRequest{} - mi := &file_app_v1_admin_proto_msgTypes[58] + mi := &file_app_v1_admin_proto_msgTypes[67] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3624,7 +4156,7 @@ func (x *ListAdminJobsRequest) String() string { func (*ListAdminJobsRequest) ProtoMessage() {} func (x *ListAdminJobsRequest) ProtoReflect() protoreflect.Message { - mi := &file_app_v1_admin_proto_msgTypes[58] + mi := &file_app_v1_admin_proto_msgTypes[67] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3637,7 +4169,7 @@ func (x *ListAdminJobsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListAdminJobsRequest.ProtoReflect.Descriptor instead. func (*ListAdminJobsRequest) Descriptor() ([]byte, []int) { - return file_app_v1_admin_proto_rawDescGZIP(), []int{58} + return file_app_v1_admin_proto_rawDescGZIP(), []int{67} } func (x *ListAdminJobsRequest) GetCursor() string { @@ -3690,7 +4222,7 @@ type ListAdminJobsResponse struct { func (x *ListAdminJobsResponse) Reset() { *x = ListAdminJobsResponse{} - mi := &file_app_v1_admin_proto_msgTypes[59] + mi := &file_app_v1_admin_proto_msgTypes[68] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3702,7 +4234,7 @@ func (x *ListAdminJobsResponse) String() string { func (*ListAdminJobsResponse) ProtoMessage() {} func (x *ListAdminJobsResponse) ProtoReflect() protoreflect.Message { - mi := &file_app_v1_admin_proto_msgTypes[59] + mi := &file_app_v1_admin_proto_msgTypes[68] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3715,7 +4247,7 @@ func (x *ListAdminJobsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListAdminJobsResponse.ProtoReflect.Descriptor instead. func (*ListAdminJobsResponse) Descriptor() ([]byte, []int) { - return file_app_v1_admin_proto_rawDescGZIP(), []int{59} + return file_app_v1_admin_proto_rawDescGZIP(), []int{68} } func (x *ListAdminJobsResponse) GetJobs() []*AdminJob { @@ -3776,7 +4308,7 @@ type GetAdminJobRequest struct { func (x *GetAdminJobRequest) Reset() { *x = GetAdminJobRequest{} - mi := &file_app_v1_admin_proto_msgTypes[60] + mi := &file_app_v1_admin_proto_msgTypes[69] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3788,7 +4320,7 @@ func (x *GetAdminJobRequest) String() string { func (*GetAdminJobRequest) ProtoMessage() {} func (x *GetAdminJobRequest) ProtoReflect() protoreflect.Message { - mi := &file_app_v1_admin_proto_msgTypes[60] + mi := &file_app_v1_admin_proto_msgTypes[69] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3801,7 +4333,7 @@ func (x *GetAdminJobRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetAdminJobRequest.ProtoReflect.Descriptor instead. func (*GetAdminJobRequest) Descriptor() ([]byte, []int) { - return file_app_v1_admin_proto_rawDescGZIP(), []int{60} + return file_app_v1_admin_proto_rawDescGZIP(), []int{69} } func (x *GetAdminJobRequest) GetId() string { @@ -3820,7 +4352,7 @@ type GetAdminJobResponse struct { func (x *GetAdminJobResponse) Reset() { *x = GetAdminJobResponse{} - mi := &file_app_v1_admin_proto_msgTypes[61] + mi := &file_app_v1_admin_proto_msgTypes[70] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3832,7 +4364,7 @@ func (x *GetAdminJobResponse) String() string { func (*GetAdminJobResponse) ProtoMessage() {} func (x *GetAdminJobResponse) ProtoReflect() protoreflect.Message { - mi := &file_app_v1_admin_proto_msgTypes[61] + mi := &file_app_v1_admin_proto_msgTypes[70] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3845,7 +4377,7 @@ func (x *GetAdminJobResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetAdminJobResponse.ProtoReflect.Descriptor instead. func (*GetAdminJobResponse) Descriptor() ([]byte, []int) { - return file_app_v1_admin_proto_rawDescGZIP(), []int{61} + return file_app_v1_admin_proto_rawDescGZIP(), []int{70} } func (x *GetAdminJobResponse) GetJob() *AdminJob { @@ -3864,7 +4396,7 @@ type GetAdminJobLogsRequest struct { func (x *GetAdminJobLogsRequest) Reset() { *x = GetAdminJobLogsRequest{} - mi := &file_app_v1_admin_proto_msgTypes[62] + mi := &file_app_v1_admin_proto_msgTypes[71] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3876,7 +4408,7 @@ func (x *GetAdminJobLogsRequest) String() string { func (*GetAdminJobLogsRequest) ProtoMessage() {} func (x *GetAdminJobLogsRequest) ProtoReflect() protoreflect.Message { - mi := &file_app_v1_admin_proto_msgTypes[62] + mi := &file_app_v1_admin_proto_msgTypes[71] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3889,7 +4421,7 @@ func (x *GetAdminJobLogsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetAdminJobLogsRequest.ProtoReflect.Descriptor instead. func (*GetAdminJobLogsRequest) Descriptor() ([]byte, []int) { - return file_app_v1_admin_proto_rawDescGZIP(), []int{62} + return file_app_v1_admin_proto_rawDescGZIP(), []int{71} } func (x *GetAdminJobLogsRequest) GetId() string { @@ -3908,7 +4440,7 @@ type GetAdminJobLogsResponse struct { func (x *GetAdminJobLogsResponse) Reset() { *x = GetAdminJobLogsResponse{} - mi := &file_app_v1_admin_proto_msgTypes[63] + mi := &file_app_v1_admin_proto_msgTypes[72] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3920,7 +4452,7 @@ func (x *GetAdminJobLogsResponse) String() string { func (*GetAdminJobLogsResponse) ProtoMessage() {} func (x *GetAdminJobLogsResponse) ProtoReflect() protoreflect.Message { - mi := &file_app_v1_admin_proto_msgTypes[63] + mi := &file_app_v1_admin_proto_msgTypes[72] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3933,7 +4465,7 @@ func (x *GetAdminJobLogsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetAdminJobLogsResponse.ProtoReflect.Descriptor instead. func (*GetAdminJobLogsResponse) Descriptor() ([]byte, []int) { - return file_app_v1_admin_proto_rawDescGZIP(), []int{63} + return file_app_v1_admin_proto_rawDescGZIP(), []int{72} } func (x *GetAdminJobLogsResponse) GetLogs() string { @@ -3959,7 +4491,7 @@ type CreateAdminJobRequest struct { func (x *CreateAdminJobRequest) Reset() { *x = CreateAdminJobRequest{} - mi := &file_app_v1_admin_proto_msgTypes[64] + mi := &file_app_v1_admin_proto_msgTypes[73] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3971,7 +4503,7 @@ func (x *CreateAdminJobRequest) String() string { func (*CreateAdminJobRequest) ProtoMessage() {} func (x *CreateAdminJobRequest) ProtoReflect() protoreflect.Message { - mi := &file_app_v1_admin_proto_msgTypes[64] + mi := &file_app_v1_admin_proto_msgTypes[73] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3984,7 +4516,7 @@ func (x *CreateAdminJobRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateAdminJobRequest.ProtoReflect.Descriptor instead. func (*CreateAdminJobRequest) Descriptor() ([]byte, []int) { - return file_app_v1_admin_proto_rawDescGZIP(), []int{64} + return file_app_v1_admin_proto_rawDescGZIP(), []int{73} } func (x *CreateAdminJobRequest) GetCommand() string { @@ -4052,7 +4584,7 @@ type CreateAdminJobResponse struct { func (x *CreateAdminJobResponse) Reset() { *x = CreateAdminJobResponse{} - mi := &file_app_v1_admin_proto_msgTypes[65] + mi := &file_app_v1_admin_proto_msgTypes[74] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4064,7 +4596,7 @@ func (x *CreateAdminJobResponse) String() string { func (*CreateAdminJobResponse) ProtoMessage() {} func (x *CreateAdminJobResponse) ProtoReflect() protoreflect.Message { - mi := &file_app_v1_admin_proto_msgTypes[65] + mi := &file_app_v1_admin_proto_msgTypes[74] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4077,7 +4609,7 @@ func (x *CreateAdminJobResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateAdminJobResponse.ProtoReflect.Descriptor instead. func (*CreateAdminJobResponse) Descriptor() ([]byte, []int) { - return file_app_v1_admin_proto_rawDescGZIP(), []int{65} + return file_app_v1_admin_proto_rawDescGZIP(), []int{74} } func (x *CreateAdminJobResponse) GetJob() *AdminJob { @@ -4096,7 +4628,7 @@ type CancelAdminJobRequest struct { func (x *CancelAdminJobRequest) Reset() { *x = CancelAdminJobRequest{} - mi := &file_app_v1_admin_proto_msgTypes[66] + mi := &file_app_v1_admin_proto_msgTypes[75] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4108,7 +4640,7 @@ func (x *CancelAdminJobRequest) String() string { func (*CancelAdminJobRequest) ProtoMessage() {} func (x *CancelAdminJobRequest) ProtoReflect() protoreflect.Message { - mi := &file_app_v1_admin_proto_msgTypes[66] + mi := &file_app_v1_admin_proto_msgTypes[75] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4121,7 +4653,7 @@ func (x *CancelAdminJobRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CancelAdminJobRequest.ProtoReflect.Descriptor instead. func (*CancelAdminJobRequest) Descriptor() ([]byte, []int) { - return file_app_v1_admin_proto_rawDescGZIP(), []int{66} + return file_app_v1_admin_proto_rawDescGZIP(), []int{75} } func (x *CancelAdminJobRequest) GetId() string { @@ -4141,7 +4673,7 @@ type CancelAdminJobResponse struct { func (x *CancelAdminJobResponse) Reset() { *x = CancelAdminJobResponse{} - mi := &file_app_v1_admin_proto_msgTypes[67] + mi := &file_app_v1_admin_proto_msgTypes[76] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4153,7 +4685,7 @@ func (x *CancelAdminJobResponse) String() string { func (*CancelAdminJobResponse) ProtoMessage() {} func (x *CancelAdminJobResponse) ProtoReflect() protoreflect.Message { - mi := &file_app_v1_admin_proto_msgTypes[67] + mi := &file_app_v1_admin_proto_msgTypes[76] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4166,7 +4698,7 @@ func (x *CancelAdminJobResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CancelAdminJobResponse.ProtoReflect.Descriptor instead. func (*CancelAdminJobResponse) Descriptor() ([]byte, []int) { - return file_app_v1_admin_proto_rawDescGZIP(), []int{67} + return file_app_v1_admin_proto_rawDescGZIP(), []int{76} } func (x *CancelAdminJobResponse) GetStatus() string { @@ -4192,7 +4724,7 @@ type RetryAdminJobRequest struct { func (x *RetryAdminJobRequest) Reset() { *x = RetryAdminJobRequest{} - mi := &file_app_v1_admin_proto_msgTypes[68] + mi := &file_app_v1_admin_proto_msgTypes[77] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4204,7 +4736,7 @@ func (x *RetryAdminJobRequest) String() string { func (*RetryAdminJobRequest) ProtoMessage() {} func (x *RetryAdminJobRequest) ProtoReflect() protoreflect.Message { - mi := &file_app_v1_admin_proto_msgTypes[68] + mi := &file_app_v1_admin_proto_msgTypes[77] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4217,7 +4749,7 @@ func (x *RetryAdminJobRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RetryAdminJobRequest.ProtoReflect.Descriptor instead. func (*RetryAdminJobRequest) Descriptor() ([]byte, []int) { - return file_app_v1_admin_proto_rawDescGZIP(), []int{68} + return file_app_v1_admin_proto_rawDescGZIP(), []int{77} } func (x *RetryAdminJobRequest) GetId() string { @@ -4236,7 +4768,7 @@ type RetryAdminJobResponse struct { func (x *RetryAdminJobResponse) Reset() { *x = RetryAdminJobResponse{} - mi := &file_app_v1_admin_proto_msgTypes[69] + mi := &file_app_v1_admin_proto_msgTypes[78] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4248,7 +4780,7 @@ func (x *RetryAdminJobResponse) String() string { func (*RetryAdminJobResponse) ProtoMessage() {} func (x *RetryAdminJobResponse) ProtoReflect() protoreflect.Message { - mi := &file_app_v1_admin_proto_msgTypes[69] + mi := &file_app_v1_admin_proto_msgTypes[78] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4261,7 +4793,7 @@ func (x *RetryAdminJobResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RetryAdminJobResponse.ProtoReflect.Descriptor instead. func (*RetryAdminJobResponse) Descriptor() ([]byte, []int) { - return file_app_v1_admin_proto_rawDescGZIP(), []int{69} + return file_app_v1_admin_proto_rawDescGZIP(), []int{78} } func (x *RetryAdminJobResponse) GetJob() *AdminJob { @@ -4279,7 +4811,7 @@ type ListAdminAgentsRequest struct { func (x *ListAdminAgentsRequest) Reset() { *x = ListAdminAgentsRequest{} - mi := &file_app_v1_admin_proto_msgTypes[70] + mi := &file_app_v1_admin_proto_msgTypes[79] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4291,7 +4823,7 @@ func (x *ListAdminAgentsRequest) String() string { func (*ListAdminAgentsRequest) ProtoMessage() {} func (x *ListAdminAgentsRequest) ProtoReflect() protoreflect.Message { - mi := &file_app_v1_admin_proto_msgTypes[70] + mi := &file_app_v1_admin_proto_msgTypes[79] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4304,7 +4836,7 @@ func (x *ListAdminAgentsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListAdminAgentsRequest.ProtoReflect.Descriptor instead. func (*ListAdminAgentsRequest) Descriptor() ([]byte, []int) { - return file_app_v1_admin_proto_rawDescGZIP(), []int{70} + return file_app_v1_admin_proto_rawDescGZIP(), []int{79} } type ListAdminAgentsResponse struct { @@ -4316,7 +4848,7 @@ type ListAdminAgentsResponse struct { func (x *ListAdminAgentsResponse) Reset() { *x = ListAdminAgentsResponse{} - mi := &file_app_v1_admin_proto_msgTypes[71] + mi := &file_app_v1_admin_proto_msgTypes[80] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4328,7 +4860,7 @@ func (x *ListAdminAgentsResponse) String() string { func (*ListAdminAgentsResponse) ProtoMessage() {} func (x *ListAdminAgentsResponse) ProtoReflect() protoreflect.Message { - mi := &file_app_v1_admin_proto_msgTypes[71] + mi := &file_app_v1_admin_proto_msgTypes[80] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4341,7 +4873,7 @@ func (x *ListAdminAgentsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListAdminAgentsResponse.ProtoReflect.Descriptor instead. func (*ListAdminAgentsResponse) Descriptor() ([]byte, []int) { - return file_app_v1_admin_proto_rawDescGZIP(), []int{71} + return file_app_v1_admin_proto_rawDescGZIP(), []int{80} } func (x *ListAdminAgentsResponse) GetAgents() []*AdminAgent { @@ -4360,7 +4892,7 @@ type RestartAdminAgentRequest struct { func (x *RestartAdminAgentRequest) Reset() { *x = RestartAdminAgentRequest{} - mi := &file_app_v1_admin_proto_msgTypes[72] + mi := &file_app_v1_admin_proto_msgTypes[81] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4372,7 +4904,7 @@ func (x *RestartAdminAgentRequest) String() string { func (*RestartAdminAgentRequest) ProtoMessage() {} func (x *RestartAdminAgentRequest) ProtoReflect() protoreflect.Message { - mi := &file_app_v1_admin_proto_msgTypes[72] + mi := &file_app_v1_admin_proto_msgTypes[81] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4385,7 +4917,7 @@ func (x *RestartAdminAgentRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RestartAdminAgentRequest.ProtoReflect.Descriptor instead. func (*RestartAdminAgentRequest) Descriptor() ([]byte, []int) { - return file_app_v1_admin_proto_rawDescGZIP(), []int{72} + return file_app_v1_admin_proto_rawDescGZIP(), []int{81} } func (x *RestartAdminAgentRequest) GetId() string { @@ -4404,7 +4936,7 @@ type UpdateAdminAgentRequest struct { func (x *UpdateAdminAgentRequest) Reset() { *x = UpdateAdminAgentRequest{} - mi := &file_app_v1_admin_proto_msgTypes[73] + mi := &file_app_v1_admin_proto_msgTypes[82] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4416,7 +4948,7 @@ func (x *UpdateAdminAgentRequest) String() string { func (*UpdateAdminAgentRequest) ProtoMessage() {} func (x *UpdateAdminAgentRequest) ProtoReflect() protoreflect.Message { - mi := &file_app_v1_admin_proto_msgTypes[73] + mi := &file_app_v1_admin_proto_msgTypes[82] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4429,7 +4961,7 @@ func (x *UpdateAdminAgentRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateAdminAgentRequest.ProtoReflect.Descriptor instead. func (*UpdateAdminAgentRequest) Descriptor() ([]byte, []int) { - return file_app_v1_admin_proto_rawDescGZIP(), []int{73} + return file_app_v1_admin_proto_rawDescGZIP(), []int{82} } func (x *UpdateAdminAgentRequest) GetId() string { @@ -4448,7 +4980,7 @@ type AdminAgentCommandResponse struct { func (x *AdminAgentCommandResponse) Reset() { *x = AdminAgentCommandResponse{} - mi := &file_app_v1_admin_proto_msgTypes[74] + mi := &file_app_v1_admin_proto_msgTypes[83] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4460,7 +4992,7 @@ func (x *AdminAgentCommandResponse) String() string { func (*AdminAgentCommandResponse) ProtoMessage() {} func (x *AdminAgentCommandResponse) ProtoReflect() protoreflect.Message { - mi := &file_app_v1_admin_proto_msgTypes[74] + mi := &file_app_v1_admin_proto_msgTypes[83] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4473,7 +5005,7 @@ func (x *AdminAgentCommandResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use AdminAgentCommandResponse.ProtoReflect.Descriptor instead. func (*AdminAgentCommandResponse) Descriptor() ([]byte, []int) { - return file_app_v1_admin_proto_rawDescGZIP(), []int{74} + return file_app_v1_admin_proto_rawDescGZIP(), []int{83} } func (x *AdminAgentCommandResponse) GetStatus() string { @@ -4743,6 +5275,50 @@ const file_app_v1_admin_proto_rawDesc = "" + "\x1dUpdateAdminAdTemplateResponse\x12:\n" + "\btemplate\x18\x01 \x01(\v2\x1e.stream.app.v1.AdminAdTemplateR\btemplate\".\n" + "\x1cDeleteAdminAdTemplateRequest\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\"\x96\x01\n" + + "\x18ListAdminPopupAdsRequest\x12\x12\n" + + "\x04page\x18\x01 \x01(\x05R\x04page\x12\x14\n" + + "\x05limit\x18\x02 \x01(\x05R\x05limit\x12\x1c\n" + + "\auser_id\x18\x03 \x01(\tH\x00R\x06userId\x88\x01\x01\x12\x1b\n" + + "\x06search\x18\x04 \x01(\tH\x01R\x06search\x88\x01\x01B\n" + + "\n" + + "\b_user_idB\t\n" + + "\a_search\"\x8e\x01\n" + + "\x19ListAdminPopupAdsResponse\x121\n" + + "\x05items\x18\x01 \x03(\v2\x1b.stream.app.v1.AdminPopupAdR\x05items\x12\x14\n" + + "\x05total\x18\x02 \x01(\x03R\x05total\x12\x12\n" + + "\x04page\x18\x03 \x01(\x05R\x04page\x12\x14\n" + + "\x05limit\x18\x04 \x01(\x05R\x05limit\"(\n" + + "\x16GetAdminPopupAdRequest\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\"J\n" + + "\x17GetAdminPopupAdResponse\x12/\n" + + "\x04item\x18\x01 \x01(\v2\x1b.stream.app.v1.AdminPopupAdR\x04item\"\xff\x01\n" + + "\x19CreateAdminPopupAdRequest\x12\x17\n" + + "\auser_id\x18\x01 \x01(\tR\x06userId\x12\x12\n" + + "\x04type\x18\x02 \x01(\tR\x04type\x12\x14\n" + + "\x05label\x18\x03 \x01(\tR\x05label\x12\x14\n" + + "\x05value\x18\x04 \x01(\tR\x05value\x12 \n" + + "\tis_active\x18\x05 \x01(\bH\x00R\bisActive\x88\x01\x01\x12<\n" + + "\x18max_triggers_per_session\x18\x06 \x01(\x05H\x01R\x15maxTriggersPerSession\x88\x01\x01B\f\n" + + "\n" + + "_is_activeB\x1b\n" + + "\x19_max_triggers_per_session\"M\n" + + "\x1aCreateAdminPopupAdResponse\x12/\n" + + "\x04item\x18\x01 \x01(\v2\x1b.stream.app.v1.AdminPopupAdR\x04item\"\x8f\x02\n" + + "\x19UpdateAdminPopupAdRequest\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12\x17\n" + + "\auser_id\x18\x02 \x01(\tR\x06userId\x12\x12\n" + + "\x04type\x18\x03 \x01(\tR\x04type\x12\x14\n" + + "\x05label\x18\x04 \x01(\tR\x05label\x12\x14\n" + + "\x05value\x18\x05 \x01(\tR\x05value\x12 \n" + + "\tis_active\x18\x06 \x01(\bH\x00R\bisActive\x88\x01\x01\x12<\n" + + "\x18max_triggers_per_session\x18\a \x01(\x05H\x01R\x15maxTriggersPerSession\x88\x01\x01B\f\n" + + "\n" + + "_is_activeB\x1b\n" + + "\x19_max_triggers_per_session\"M\n" + + "\x1aUpdateAdminPopupAdResponse\x12/\n" + + "\x04item\x18\x01 \x01(\v2\x1b.stream.app.v1.AdminPopupAdR\x04item\"+\n" + + "\x19DeleteAdminPopupAdRequest\x12\x0e\n" + "\x02id\x18\x01 \x01(\tR\x02id\"\x9b\x01\n" + "\x1dListAdminPlayerConfigsRequest\x12\x12\n" + "\x04page\x18\x01 \x01(\x05R\x04page\x12\x14\n" + @@ -4881,7 +5457,7 @@ const file_app_v1_admin_proto_rawDesc = "" + "\x17UpdateAdminAgentRequest\x12\x0e\n" + "\x02id\x18\x01 \x01(\tR\x02id\"3\n" + "\x19AdminAgentCommandResponse\x12\x16\n" + - "\x06status\x18\x01 \x01(\tR\x06status2\x9d \n" + + "\x06status\x18\x01 \x01(\tR\x06status2\x9d$\n" + "\x05Admin\x12f\n" + "\x11GetAdminDashboard\x12'.stream.app.v1.GetAdminDashboardRequest\x1a(.stream.app.v1.GetAdminDashboardResponse\x12]\n" + "\x0eListAdminUsers\x12$.stream.app.v1.ListAdminUsersRequest\x1a%.stream.app.v1.ListAdminUsersResponse\x12W\n" + @@ -4908,7 +5484,12 @@ const file_app_v1_admin_proto_rawDesc = "" + "\x12GetAdminAdTemplate\x12(.stream.app.v1.GetAdminAdTemplateRequest\x1a).stream.app.v1.GetAdminAdTemplateResponse\x12r\n" + "\x15CreateAdminAdTemplate\x12+.stream.app.v1.CreateAdminAdTemplateRequest\x1a,.stream.app.v1.CreateAdminAdTemplateResponse\x12r\n" + "\x15UpdateAdminAdTemplate\x12+.stream.app.v1.UpdateAdminAdTemplateRequest\x1a,.stream.app.v1.UpdateAdminAdTemplateResponse\x12d\n" + - "\x15DeleteAdminAdTemplate\x12+.stream.app.v1.DeleteAdminAdTemplateRequest\x1a\x1e.stream.app.v1.MessageResponse\x12u\n" + + "\x15DeleteAdminAdTemplate\x12+.stream.app.v1.DeleteAdminAdTemplateRequest\x1a\x1e.stream.app.v1.MessageResponse\x12f\n" + + "\x11ListAdminPopupAds\x12'.stream.app.v1.ListAdminPopupAdsRequest\x1a(.stream.app.v1.ListAdminPopupAdsResponse\x12`\n" + + "\x0fGetAdminPopupAd\x12%.stream.app.v1.GetAdminPopupAdRequest\x1a&.stream.app.v1.GetAdminPopupAdResponse\x12i\n" + + "\x12CreateAdminPopupAd\x12(.stream.app.v1.CreateAdminPopupAdRequest\x1a).stream.app.v1.CreateAdminPopupAdResponse\x12i\n" + + "\x12UpdateAdminPopupAd\x12(.stream.app.v1.UpdateAdminPopupAdRequest\x1a).stream.app.v1.UpdateAdminPopupAdResponse\x12^\n" + + "\x12DeleteAdminPopupAd\x12(.stream.app.v1.DeleteAdminPopupAdRequest\x1a\x1e.stream.app.v1.MessageResponse\x12u\n" + "\x16ListAdminPlayerConfigs\x12,.stream.app.v1.ListAdminPlayerConfigsRequest\x1a-.stream.app.v1.ListAdminPlayerConfigsResponse\x12o\n" + "\x14GetAdminPlayerConfig\x12*.stream.app.v1.GetAdminPlayerConfigRequest\x1a+.stream.app.v1.GetAdminPlayerConfigResponse\x12x\n" + "\x17CreateAdminPlayerConfig\x12-.stream.app.v1.CreateAdminPlayerConfigRequest\x1a..stream.app.v1.CreateAdminPlayerConfigResponse\x12x\n" + @@ -4936,7 +5517,7 @@ func file_app_v1_admin_proto_rawDescGZIP() []byte { return file_app_v1_admin_proto_rawDescData } -var file_app_v1_admin_proto_msgTypes = make([]protoimpl.MessageInfo, 76) +var file_app_v1_admin_proto_msgTypes = make([]protoimpl.MessageInfo, 85) var file_app_v1_admin_proto_goTypes = []any{ (*GetAdminDashboardRequest)(nil), // 0: stream.app.v1.GetAdminDashboardRequest (*GetAdminDashboardResponse)(nil), // 1: stream.app.v1.GetAdminDashboardResponse @@ -4987,164 +5568,188 @@ var file_app_v1_admin_proto_goTypes = []any{ (*UpdateAdminAdTemplateRequest)(nil), // 46: stream.app.v1.UpdateAdminAdTemplateRequest (*UpdateAdminAdTemplateResponse)(nil), // 47: stream.app.v1.UpdateAdminAdTemplateResponse (*DeleteAdminAdTemplateRequest)(nil), // 48: stream.app.v1.DeleteAdminAdTemplateRequest - (*ListAdminPlayerConfigsRequest)(nil), // 49: stream.app.v1.ListAdminPlayerConfigsRequest - (*ListAdminPlayerConfigsResponse)(nil), // 50: stream.app.v1.ListAdminPlayerConfigsResponse - (*GetAdminPlayerConfigRequest)(nil), // 51: stream.app.v1.GetAdminPlayerConfigRequest - (*GetAdminPlayerConfigResponse)(nil), // 52: stream.app.v1.GetAdminPlayerConfigResponse - (*CreateAdminPlayerConfigRequest)(nil), // 53: stream.app.v1.CreateAdminPlayerConfigRequest - (*CreateAdminPlayerConfigResponse)(nil), // 54: stream.app.v1.CreateAdminPlayerConfigResponse - (*UpdateAdminPlayerConfigRequest)(nil), // 55: stream.app.v1.UpdateAdminPlayerConfigRequest - (*UpdateAdminPlayerConfigResponse)(nil), // 56: stream.app.v1.UpdateAdminPlayerConfigResponse - (*DeleteAdminPlayerConfigRequest)(nil), // 57: stream.app.v1.DeleteAdminPlayerConfigRequest - (*ListAdminJobsRequest)(nil), // 58: stream.app.v1.ListAdminJobsRequest - (*ListAdminJobsResponse)(nil), // 59: stream.app.v1.ListAdminJobsResponse - (*GetAdminJobRequest)(nil), // 60: stream.app.v1.GetAdminJobRequest - (*GetAdminJobResponse)(nil), // 61: stream.app.v1.GetAdminJobResponse - (*GetAdminJobLogsRequest)(nil), // 62: stream.app.v1.GetAdminJobLogsRequest - (*GetAdminJobLogsResponse)(nil), // 63: stream.app.v1.GetAdminJobLogsResponse - (*CreateAdminJobRequest)(nil), // 64: stream.app.v1.CreateAdminJobRequest - (*CreateAdminJobResponse)(nil), // 65: stream.app.v1.CreateAdminJobResponse - (*CancelAdminJobRequest)(nil), // 66: stream.app.v1.CancelAdminJobRequest - (*CancelAdminJobResponse)(nil), // 67: stream.app.v1.CancelAdminJobResponse - (*RetryAdminJobRequest)(nil), // 68: stream.app.v1.RetryAdminJobRequest - (*RetryAdminJobResponse)(nil), // 69: stream.app.v1.RetryAdminJobResponse - (*ListAdminAgentsRequest)(nil), // 70: stream.app.v1.ListAdminAgentsRequest - (*ListAdminAgentsResponse)(nil), // 71: stream.app.v1.ListAdminAgentsResponse - (*RestartAdminAgentRequest)(nil), // 72: stream.app.v1.RestartAdminAgentRequest - (*UpdateAdminAgentRequest)(nil), // 73: stream.app.v1.UpdateAdminAgentRequest - (*AdminAgentCommandResponse)(nil), // 74: stream.app.v1.AdminAgentCommandResponse - nil, // 75: stream.app.v1.CreateAdminJobRequest.EnvEntry - (*AdminDashboard)(nil), // 76: stream.app.v1.AdminDashboard - (*AdminUser)(nil), // 77: stream.app.v1.AdminUser - (*AdminUserDetail)(nil), // 78: stream.app.v1.AdminUserDetail - (*AdminVideo)(nil), // 79: stream.app.v1.AdminVideo - (*AdminPayment)(nil), // 80: stream.app.v1.AdminPayment - (*PlanSubscription)(nil), // 81: stream.app.v1.PlanSubscription - (*AdminPlan)(nil), // 82: stream.app.v1.AdminPlan - (*AdminAdTemplate)(nil), // 83: stream.app.v1.AdminAdTemplate - (*AdminPlayerConfig)(nil), // 84: stream.app.v1.AdminPlayerConfig - (*AdminJob)(nil), // 85: stream.app.v1.AdminJob - (*AdminAgent)(nil), // 86: stream.app.v1.AdminAgent - (*MessageResponse)(nil), // 87: stream.app.v1.MessageResponse + (*ListAdminPopupAdsRequest)(nil), // 49: stream.app.v1.ListAdminPopupAdsRequest + (*ListAdminPopupAdsResponse)(nil), // 50: stream.app.v1.ListAdminPopupAdsResponse + (*GetAdminPopupAdRequest)(nil), // 51: stream.app.v1.GetAdminPopupAdRequest + (*GetAdminPopupAdResponse)(nil), // 52: stream.app.v1.GetAdminPopupAdResponse + (*CreateAdminPopupAdRequest)(nil), // 53: stream.app.v1.CreateAdminPopupAdRequest + (*CreateAdminPopupAdResponse)(nil), // 54: stream.app.v1.CreateAdminPopupAdResponse + (*UpdateAdminPopupAdRequest)(nil), // 55: stream.app.v1.UpdateAdminPopupAdRequest + (*UpdateAdminPopupAdResponse)(nil), // 56: stream.app.v1.UpdateAdminPopupAdResponse + (*DeleteAdminPopupAdRequest)(nil), // 57: stream.app.v1.DeleteAdminPopupAdRequest + (*ListAdminPlayerConfigsRequest)(nil), // 58: stream.app.v1.ListAdminPlayerConfigsRequest + (*ListAdminPlayerConfigsResponse)(nil), // 59: stream.app.v1.ListAdminPlayerConfigsResponse + (*GetAdminPlayerConfigRequest)(nil), // 60: stream.app.v1.GetAdminPlayerConfigRequest + (*GetAdminPlayerConfigResponse)(nil), // 61: stream.app.v1.GetAdminPlayerConfigResponse + (*CreateAdminPlayerConfigRequest)(nil), // 62: stream.app.v1.CreateAdminPlayerConfigRequest + (*CreateAdminPlayerConfigResponse)(nil), // 63: stream.app.v1.CreateAdminPlayerConfigResponse + (*UpdateAdminPlayerConfigRequest)(nil), // 64: stream.app.v1.UpdateAdminPlayerConfigRequest + (*UpdateAdminPlayerConfigResponse)(nil), // 65: stream.app.v1.UpdateAdminPlayerConfigResponse + (*DeleteAdminPlayerConfigRequest)(nil), // 66: stream.app.v1.DeleteAdminPlayerConfigRequest + (*ListAdminJobsRequest)(nil), // 67: stream.app.v1.ListAdminJobsRequest + (*ListAdminJobsResponse)(nil), // 68: stream.app.v1.ListAdminJobsResponse + (*GetAdminJobRequest)(nil), // 69: stream.app.v1.GetAdminJobRequest + (*GetAdminJobResponse)(nil), // 70: stream.app.v1.GetAdminJobResponse + (*GetAdminJobLogsRequest)(nil), // 71: stream.app.v1.GetAdminJobLogsRequest + (*GetAdminJobLogsResponse)(nil), // 72: stream.app.v1.GetAdminJobLogsResponse + (*CreateAdminJobRequest)(nil), // 73: stream.app.v1.CreateAdminJobRequest + (*CreateAdminJobResponse)(nil), // 74: stream.app.v1.CreateAdminJobResponse + (*CancelAdminJobRequest)(nil), // 75: stream.app.v1.CancelAdminJobRequest + (*CancelAdminJobResponse)(nil), // 76: stream.app.v1.CancelAdminJobResponse + (*RetryAdminJobRequest)(nil), // 77: stream.app.v1.RetryAdminJobRequest + (*RetryAdminJobResponse)(nil), // 78: stream.app.v1.RetryAdminJobResponse + (*ListAdminAgentsRequest)(nil), // 79: stream.app.v1.ListAdminAgentsRequest + (*ListAdminAgentsResponse)(nil), // 80: stream.app.v1.ListAdminAgentsResponse + (*RestartAdminAgentRequest)(nil), // 81: stream.app.v1.RestartAdminAgentRequest + (*UpdateAdminAgentRequest)(nil), // 82: stream.app.v1.UpdateAdminAgentRequest + (*AdminAgentCommandResponse)(nil), // 83: stream.app.v1.AdminAgentCommandResponse + nil, // 84: stream.app.v1.CreateAdminJobRequest.EnvEntry + (*AdminDashboard)(nil), // 85: stream.app.v1.AdminDashboard + (*AdminUser)(nil), // 86: stream.app.v1.AdminUser + (*AdminUserDetail)(nil), // 87: stream.app.v1.AdminUserDetail + (*AdminVideo)(nil), // 88: stream.app.v1.AdminVideo + (*AdminPayment)(nil), // 89: stream.app.v1.AdminPayment + (*PlanSubscription)(nil), // 90: stream.app.v1.PlanSubscription + (*AdminPlan)(nil), // 91: stream.app.v1.AdminPlan + (*AdminAdTemplate)(nil), // 92: stream.app.v1.AdminAdTemplate + (*AdminPopupAd)(nil), // 93: stream.app.v1.AdminPopupAd + (*AdminPlayerConfig)(nil), // 94: stream.app.v1.AdminPlayerConfig + (*AdminJob)(nil), // 95: stream.app.v1.AdminJob + (*AdminAgent)(nil), // 96: stream.app.v1.AdminAgent + (*MessageResponse)(nil), // 97: stream.app.v1.MessageResponse } var file_app_v1_admin_proto_depIdxs = []int32{ - 76, // 0: stream.app.v1.GetAdminDashboardResponse.dashboard:type_name -> stream.app.v1.AdminDashboard - 77, // 1: stream.app.v1.ListAdminUsersResponse.users:type_name -> stream.app.v1.AdminUser - 78, // 2: stream.app.v1.GetAdminUserResponse.user:type_name -> stream.app.v1.AdminUserDetail - 77, // 3: stream.app.v1.CreateAdminUserResponse.user:type_name -> stream.app.v1.AdminUser - 77, // 4: stream.app.v1.UpdateAdminUserResponse.user:type_name -> stream.app.v1.AdminUser - 78, // 5: stream.app.v1.UpdateAdminUserReferralSettingsResponse.user:type_name -> stream.app.v1.AdminUserDetail - 79, // 6: stream.app.v1.ListAdminVideosResponse.videos:type_name -> stream.app.v1.AdminVideo - 79, // 7: stream.app.v1.GetAdminVideoResponse.video:type_name -> stream.app.v1.AdminVideo - 79, // 8: stream.app.v1.CreateAdminVideoResponse.video:type_name -> stream.app.v1.AdminVideo - 79, // 9: stream.app.v1.UpdateAdminVideoResponse.video:type_name -> stream.app.v1.AdminVideo - 80, // 10: stream.app.v1.ListAdminPaymentsResponse.payments:type_name -> stream.app.v1.AdminPayment - 80, // 11: stream.app.v1.GetAdminPaymentResponse.payment:type_name -> stream.app.v1.AdminPayment - 80, // 12: stream.app.v1.CreateAdminPaymentResponse.payment:type_name -> stream.app.v1.AdminPayment - 81, // 13: stream.app.v1.CreateAdminPaymentResponse.subscription:type_name -> stream.app.v1.PlanSubscription - 80, // 14: stream.app.v1.UpdateAdminPaymentResponse.payment:type_name -> stream.app.v1.AdminPayment - 82, // 15: stream.app.v1.ListAdminPlansResponse.plans:type_name -> stream.app.v1.AdminPlan - 82, // 16: stream.app.v1.CreateAdminPlanResponse.plan:type_name -> stream.app.v1.AdminPlan - 82, // 17: stream.app.v1.UpdateAdminPlanResponse.plan:type_name -> stream.app.v1.AdminPlan - 83, // 18: stream.app.v1.ListAdminAdTemplatesResponse.templates:type_name -> stream.app.v1.AdminAdTemplate - 83, // 19: stream.app.v1.GetAdminAdTemplateResponse.template:type_name -> stream.app.v1.AdminAdTemplate - 83, // 20: stream.app.v1.CreateAdminAdTemplateResponse.template:type_name -> stream.app.v1.AdminAdTemplate - 83, // 21: stream.app.v1.UpdateAdminAdTemplateResponse.template:type_name -> stream.app.v1.AdminAdTemplate - 84, // 22: stream.app.v1.ListAdminPlayerConfigsResponse.configs:type_name -> stream.app.v1.AdminPlayerConfig - 84, // 23: stream.app.v1.GetAdminPlayerConfigResponse.config:type_name -> stream.app.v1.AdminPlayerConfig - 84, // 24: stream.app.v1.CreateAdminPlayerConfigResponse.config:type_name -> stream.app.v1.AdminPlayerConfig - 84, // 25: stream.app.v1.UpdateAdminPlayerConfigResponse.config:type_name -> stream.app.v1.AdminPlayerConfig - 85, // 26: stream.app.v1.ListAdminJobsResponse.jobs:type_name -> stream.app.v1.AdminJob - 85, // 27: stream.app.v1.GetAdminJobResponse.job:type_name -> stream.app.v1.AdminJob - 75, // 28: stream.app.v1.CreateAdminJobRequest.env:type_name -> stream.app.v1.CreateAdminJobRequest.EnvEntry - 85, // 29: stream.app.v1.CreateAdminJobResponse.job:type_name -> stream.app.v1.AdminJob - 85, // 30: stream.app.v1.RetryAdminJobResponse.job:type_name -> stream.app.v1.AdminJob - 86, // 31: stream.app.v1.ListAdminAgentsResponse.agents:type_name -> stream.app.v1.AdminAgent - 0, // 32: stream.app.v1.Admin.GetAdminDashboard:input_type -> stream.app.v1.GetAdminDashboardRequest - 2, // 33: stream.app.v1.Admin.ListAdminUsers:input_type -> stream.app.v1.ListAdminUsersRequest - 4, // 34: stream.app.v1.Admin.GetAdminUser:input_type -> stream.app.v1.GetAdminUserRequest - 6, // 35: stream.app.v1.Admin.CreateAdminUser:input_type -> stream.app.v1.CreateAdminUserRequest - 8, // 36: stream.app.v1.Admin.UpdateAdminUser:input_type -> stream.app.v1.UpdateAdminUserRequest - 10, // 37: stream.app.v1.Admin.UpdateAdminUserReferralSettings:input_type -> stream.app.v1.UpdateAdminUserReferralSettingsRequest - 12, // 38: stream.app.v1.Admin.UpdateAdminUserRole:input_type -> stream.app.v1.UpdateAdminUserRoleRequest - 14, // 39: stream.app.v1.Admin.DeleteAdminUser:input_type -> stream.app.v1.DeleteAdminUserRequest - 15, // 40: stream.app.v1.Admin.ListAdminVideos:input_type -> stream.app.v1.ListAdminVideosRequest - 17, // 41: stream.app.v1.Admin.GetAdminVideo:input_type -> stream.app.v1.GetAdminVideoRequest - 19, // 42: stream.app.v1.Admin.CreateAdminVideo:input_type -> stream.app.v1.CreateAdminVideoRequest - 21, // 43: stream.app.v1.Admin.UpdateAdminVideo:input_type -> stream.app.v1.UpdateAdminVideoRequest - 23, // 44: stream.app.v1.Admin.DeleteAdminVideo:input_type -> stream.app.v1.DeleteAdminVideoRequest - 24, // 45: stream.app.v1.Admin.ListAdminPayments:input_type -> stream.app.v1.ListAdminPaymentsRequest - 26, // 46: stream.app.v1.Admin.GetAdminPayment:input_type -> stream.app.v1.GetAdminPaymentRequest - 28, // 47: stream.app.v1.Admin.CreateAdminPayment:input_type -> stream.app.v1.CreateAdminPaymentRequest - 30, // 48: stream.app.v1.Admin.UpdateAdminPayment:input_type -> stream.app.v1.UpdateAdminPaymentRequest - 32, // 49: stream.app.v1.Admin.ListAdminPlans:input_type -> stream.app.v1.ListAdminPlansRequest - 34, // 50: stream.app.v1.Admin.CreateAdminPlan:input_type -> stream.app.v1.CreateAdminPlanRequest - 36, // 51: stream.app.v1.Admin.UpdateAdminPlan:input_type -> stream.app.v1.UpdateAdminPlanRequest - 38, // 52: stream.app.v1.Admin.DeleteAdminPlan:input_type -> stream.app.v1.DeleteAdminPlanRequest - 40, // 53: stream.app.v1.Admin.ListAdminAdTemplates:input_type -> stream.app.v1.ListAdminAdTemplatesRequest - 42, // 54: stream.app.v1.Admin.GetAdminAdTemplate:input_type -> stream.app.v1.GetAdminAdTemplateRequest - 44, // 55: stream.app.v1.Admin.CreateAdminAdTemplate:input_type -> stream.app.v1.CreateAdminAdTemplateRequest - 46, // 56: stream.app.v1.Admin.UpdateAdminAdTemplate:input_type -> stream.app.v1.UpdateAdminAdTemplateRequest - 48, // 57: stream.app.v1.Admin.DeleteAdminAdTemplate:input_type -> stream.app.v1.DeleteAdminAdTemplateRequest - 49, // 58: stream.app.v1.Admin.ListAdminPlayerConfigs:input_type -> stream.app.v1.ListAdminPlayerConfigsRequest - 51, // 59: stream.app.v1.Admin.GetAdminPlayerConfig:input_type -> stream.app.v1.GetAdminPlayerConfigRequest - 53, // 60: stream.app.v1.Admin.CreateAdminPlayerConfig:input_type -> stream.app.v1.CreateAdminPlayerConfigRequest - 55, // 61: stream.app.v1.Admin.UpdateAdminPlayerConfig:input_type -> stream.app.v1.UpdateAdminPlayerConfigRequest - 57, // 62: stream.app.v1.Admin.DeleteAdminPlayerConfig:input_type -> stream.app.v1.DeleteAdminPlayerConfigRequest - 58, // 63: stream.app.v1.Admin.ListAdminJobs:input_type -> stream.app.v1.ListAdminJobsRequest - 60, // 64: stream.app.v1.Admin.GetAdminJob:input_type -> stream.app.v1.GetAdminJobRequest - 62, // 65: stream.app.v1.Admin.GetAdminJobLogs:input_type -> stream.app.v1.GetAdminJobLogsRequest - 64, // 66: stream.app.v1.Admin.CreateAdminJob:input_type -> stream.app.v1.CreateAdminJobRequest - 66, // 67: stream.app.v1.Admin.CancelAdminJob:input_type -> stream.app.v1.CancelAdminJobRequest - 68, // 68: stream.app.v1.Admin.RetryAdminJob:input_type -> stream.app.v1.RetryAdminJobRequest - 70, // 69: stream.app.v1.Admin.ListAdminAgents:input_type -> stream.app.v1.ListAdminAgentsRequest - 72, // 70: stream.app.v1.Admin.RestartAdminAgent:input_type -> stream.app.v1.RestartAdminAgentRequest - 73, // 71: stream.app.v1.Admin.UpdateAdminAgent:input_type -> stream.app.v1.UpdateAdminAgentRequest - 1, // 72: stream.app.v1.Admin.GetAdminDashboard:output_type -> stream.app.v1.GetAdminDashboardResponse - 3, // 73: stream.app.v1.Admin.ListAdminUsers:output_type -> stream.app.v1.ListAdminUsersResponse - 5, // 74: stream.app.v1.Admin.GetAdminUser:output_type -> stream.app.v1.GetAdminUserResponse - 7, // 75: stream.app.v1.Admin.CreateAdminUser:output_type -> stream.app.v1.CreateAdminUserResponse - 9, // 76: stream.app.v1.Admin.UpdateAdminUser:output_type -> stream.app.v1.UpdateAdminUserResponse - 11, // 77: stream.app.v1.Admin.UpdateAdminUserReferralSettings:output_type -> stream.app.v1.UpdateAdminUserReferralSettingsResponse - 13, // 78: stream.app.v1.Admin.UpdateAdminUserRole:output_type -> stream.app.v1.UpdateAdminUserRoleResponse - 87, // 79: stream.app.v1.Admin.DeleteAdminUser:output_type -> stream.app.v1.MessageResponse - 16, // 80: stream.app.v1.Admin.ListAdminVideos:output_type -> stream.app.v1.ListAdminVideosResponse - 18, // 81: stream.app.v1.Admin.GetAdminVideo:output_type -> stream.app.v1.GetAdminVideoResponse - 20, // 82: stream.app.v1.Admin.CreateAdminVideo:output_type -> stream.app.v1.CreateAdminVideoResponse - 22, // 83: stream.app.v1.Admin.UpdateAdminVideo:output_type -> stream.app.v1.UpdateAdminVideoResponse - 87, // 84: stream.app.v1.Admin.DeleteAdminVideo:output_type -> stream.app.v1.MessageResponse - 25, // 85: stream.app.v1.Admin.ListAdminPayments:output_type -> stream.app.v1.ListAdminPaymentsResponse - 27, // 86: stream.app.v1.Admin.GetAdminPayment:output_type -> stream.app.v1.GetAdminPaymentResponse - 29, // 87: stream.app.v1.Admin.CreateAdminPayment:output_type -> stream.app.v1.CreateAdminPaymentResponse - 31, // 88: stream.app.v1.Admin.UpdateAdminPayment:output_type -> stream.app.v1.UpdateAdminPaymentResponse - 33, // 89: stream.app.v1.Admin.ListAdminPlans:output_type -> stream.app.v1.ListAdminPlansResponse - 35, // 90: stream.app.v1.Admin.CreateAdminPlan:output_type -> stream.app.v1.CreateAdminPlanResponse - 37, // 91: stream.app.v1.Admin.UpdateAdminPlan:output_type -> stream.app.v1.UpdateAdminPlanResponse - 39, // 92: stream.app.v1.Admin.DeleteAdminPlan:output_type -> stream.app.v1.DeleteAdminPlanResponse - 41, // 93: stream.app.v1.Admin.ListAdminAdTemplates:output_type -> stream.app.v1.ListAdminAdTemplatesResponse - 43, // 94: stream.app.v1.Admin.GetAdminAdTemplate:output_type -> stream.app.v1.GetAdminAdTemplateResponse - 45, // 95: stream.app.v1.Admin.CreateAdminAdTemplate:output_type -> stream.app.v1.CreateAdminAdTemplateResponse - 47, // 96: stream.app.v1.Admin.UpdateAdminAdTemplate:output_type -> stream.app.v1.UpdateAdminAdTemplateResponse - 87, // 97: stream.app.v1.Admin.DeleteAdminAdTemplate:output_type -> stream.app.v1.MessageResponse - 50, // 98: stream.app.v1.Admin.ListAdminPlayerConfigs:output_type -> stream.app.v1.ListAdminPlayerConfigsResponse - 52, // 99: stream.app.v1.Admin.GetAdminPlayerConfig:output_type -> stream.app.v1.GetAdminPlayerConfigResponse - 54, // 100: stream.app.v1.Admin.CreateAdminPlayerConfig:output_type -> stream.app.v1.CreateAdminPlayerConfigResponse - 56, // 101: stream.app.v1.Admin.UpdateAdminPlayerConfig:output_type -> stream.app.v1.UpdateAdminPlayerConfigResponse - 87, // 102: stream.app.v1.Admin.DeleteAdminPlayerConfig:output_type -> stream.app.v1.MessageResponse - 59, // 103: stream.app.v1.Admin.ListAdminJobs:output_type -> stream.app.v1.ListAdminJobsResponse - 61, // 104: stream.app.v1.Admin.GetAdminJob:output_type -> stream.app.v1.GetAdminJobResponse - 63, // 105: stream.app.v1.Admin.GetAdminJobLogs:output_type -> stream.app.v1.GetAdminJobLogsResponse - 65, // 106: stream.app.v1.Admin.CreateAdminJob:output_type -> stream.app.v1.CreateAdminJobResponse - 67, // 107: stream.app.v1.Admin.CancelAdminJob:output_type -> stream.app.v1.CancelAdminJobResponse - 69, // 108: stream.app.v1.Admin.RetryAdminJob:output_type -> stream.app.v1.RetryAdminJobResponse - 71, // 109: stream.app.v1.Admin.ListAdminAgents:output_type -> stream.app.v1.ListAdminAgentsResponse - 74, // 110: stream.app.v1.Admin.RestartAdminAgent:output_type -> stream.app.v1.AdminAgentCommandResponse - 74, // 111: stream.app.v1.Admin.UpdateAdminAgent:output_type -> stream.app.v1.AdminAgentCommandResponse - 72, // [72:112] is the sub-list for method output_type - 32, // [32:72] is the sub-list for method input_type - 32, // [32:32] is the sub-list for extension type_name - 32, // [32:32] is the sub-list for extension extendee - 0, // [0:32] is the sub-list for field type_name + 85, // 0: stream.app.v1.GetAdminDashboardResponse.dashboard:type_name -> stream.app.v1.AdminDashboard + 86, // 1: stream.app.v1.ListAdminUsersResponse.users:type_name -> stream.app.v1.AdminUser + 87, // 2: stream.app.v1.GetAdminUserResponse.user:type_name -> stream.app.v1.AdminUserDetail + 86, // 3: stream.app.v1.CreateAdminUserResponse.user:type_name -> stream.app.v1.AdminUser + 86, // 4: stream.app.v1.UpdateAdminUserResponse.user:type_name -> stream.app.v1.AdminUser + 87, // 5: stream.app.v1.UpdateAdminUserReferralSettingsResponse.user:type_name -> stream.app.v1.AdminUserDetail + 88, // 6: stream.app.v1.ListAdminVideosResponse.videos:type_name -> stream.app.v1.AdminVideo + 88, // 7: stream.app.v1.GetAdminVideoResponse.video:type_name -> stream.app.v1.AdminVideo + 88, // 8: stream.app.v1.CreateAdminVideoResponse.video:type_name -> stream.app.v1.AdminVideo + 88, // 9: stream.app.v1.UpdateAdminVideoResponse.video:type_name -> stream.app.v1.AdminVideo + 89, // 10: stream.app.v1.ListAdminPaymentsResponse.payments:type_name -> stream.app.v1.AdminPayment + 89, // 11: stream.app.v1.GetAdminPaymentResponse.payment:type_name -> stream.app.v1.AdminPayment + 89, // 12: stream.app.v1.CreateAdminPaymentResponse.payment:type_name -> stream.app.v1.AdminPayment + 90, // 13: stream.app.v1.CreateAdminPaymentResponse.subscription:type_name -> stream.app.v1.PlanSubscription + 89, // 14: stream.app.v1.UpdateAdminPaymentResponse.payment:type_name -> stream.app.v1.AdminPayment + 91, // 15: stream.app.v1.ListAdminPlansResponse.plans:type_name -> stream.app.v1.AdminPlan + 91, // 16: stream.app.v1.CreateAdminPlanResponse.plan:type_name -> stream.app.v1.AdminPlan + 91, // 17: stream.app.v1.UpdateAdminPlanResponse.plan:type_name -> stream.app.v1.AdminPlan + 92, // 18: stream.app.v1.ListAdminAdTemplatesResponse.templates:type_name -> stream.app.v1.AdminAdTemplate + 92, // 19: stream.app.v1.GetAdminAdTemplateResponse.template:type_name -> stream.app.v1.AdminAdTemplate + 92, // 20: stream.app.v1.CreateAdminAdTemplateResponse.template:type_name -> stream.app.v1.AdminAdTemplate + 92, // 21: stream.app.v1.UpdateAdminAdTemplateResponse.template:type_name -> stream.app.v1.AdminAdTemplate + 93, // 22: stream.app.v1.ListAdminPopupAdsResponse.items:type_name -> stream.app.v1.AdminPopupAd + 93, // 23: stream.app.v1.GetAdminPopupAdResponse.item:type_name -> stream.app.v1.AdminPopupAd + 93, // 24: stream.app.v1.CreateAdminPopupAdResponse.item:type_name -> stream.app.v1.AdminPopupAd + 93, // 25: stream.app.v1.UpdateAdminPopupAdResponse.item:type_name -> stream.app.v1.AdminPopupAd + 94, // 26: stream.app.v1.ListAdminPlayerConfigsResponse.configs:type_name -> stream.app.v1.AdminPlayerConfig + 94, // 27: stream.app.v1.GetAdminPlayerConfigResponse.config:type_name -> stream.app.v1.AdminPlayerConfig + 94, // 28: stream.app.v1.CreateAdminPlayerConfigResponse.config:type_name -> stream.app.v1.AdminPlayerConfig + 94, // 29: stream.app.v1.UpdateAdminPlayerConfigResponse.config:type_name -> stream.app.v1.AdminPlayerConfig + 95, // 30: stream.app.v1.ListAdminJobsResponse.jobs:type_name -> stream.app.v1.AdminJob + 95, // 31: stream.app.v1.GetAdminJobResponse.job:type_name -> stream.app.v1.AdminJob + 84, // 32: stream.app.v1.CreateAdminJobRequest.env:type_name -> stream.app.v1.CreateAdminJobRequest.EnvEntry + 95, // 33: stream.app.v1.CreateAdminJobResponse.job:type_name -> stream.app.v1.AdminJob + 95, // 34: stream.app.v1.RetryAdminJobResponse.job:type_name -> stream.app.v1.AdminJob + 96, // 35: stream.app.v1.ListAdminAgentsResponse.agents:type_name -> stream.app.v1.AdminAgent + 0, // 36: stream.app.v1.Admin.GetAdminDashboard:input_type -> stream.app.v1.GetAdminDashboardRequest + 2, // 37: stream.app.v1.Admin.ListAdminUsers:input_type -> stream.app.v1.ListAdminUsersRequest + 4, // 38: stream.app.v1.Admin.GetAdminUser:input_type -> stream.app.v1.GetAdminUserRequest + 6, // 39: stream.app.v1.Admin.CreateAdminUser:input_type -> stream.app.v1.CreateAdminUserRequest + 8, // 40: stream.app.v1.Admin.UpdateAdminUser:input_type -> stream.app.v1.UpdateAdminUserRequest + 10, // 41: stream.app.v1.Admin.UpdateAdminUserReferralSettings:input_type -> stream.app.v1.UpdateAdminUserReferralSettingsRequest + 12, // 42: stream.app.v1.Admin.UpdateAdminUserRole:input_type -> stream.app.v1.UpdateAdminUserRoleRequest + 14, // 43: stream.app.v1.Admin.DeleteAdminUser:input_type -> stream.app.v1.DeleteAdminUserRequest + 15, // 44: stream.app.v1.Admin.ListAdminVideos:input_type -> stream.app.v1.ListAdminVideosRequest + 17, // 45: stream.app.v1.Admin.GetAdminVideo:input_type -> stream.app.v1.GetAdminVideoRequest + 19, // 46: stream.app.v1.Admin.CreateAdminVideo:input_type -> stream.app.v1.CreateAdminVideoRequest + 21, // 47: stream.app.v1.Admin.UpdateAdminVideo:input_type -> stream.app.v1.UpdateAdminVideoRequest + 23, // 48: stream.app.v1.Admin.DeleteAdminVideo:input_type -> stream.app.v1.DeleteAdminVideoRequest + 24, // 49: stream.app.v1.Admin.ListAdminPayments:input_type -> stream.app.v1.ListAdminPaymentsRequest + 26, // 50: stream.app.v1.Admin.GetAdminPayment:input_type -> stream.app.v1.GetAdminPaymentRequest + 28, // 51: stream.app.v1.Admin.CreateAdminPayment:input_type -> stream.app.v1.CreateAdminPaymentRequest + 30, // 52: stream.app.v1.Admin.UpdateAdminPayment:input_type -> stream.app.v1.UpdateAdminPaymentRequest + 32, // 53: stream.app.v1.Admin.ListAdminPlans:input_type -> stream.app.v1.ListAdminPlansRequest + 34, // 54: stream.app.v1.Admin.CreateAdminPlan:input_type -> stream.app.v1.CreateAdminPlanRequest + 36, // 55: stream.app.v1.Admin.UpdateAdminPlan:input_type -> stream.app.v1.UpdateAdminPlanRequest + 38, // 56: stream.app.v1.Admin.DeleteAdminPlan:input_type -> stream.app.v1.DeleteAdminPlanRequest + 40, // 57: stream.app.v1.Admin.ListAdminAdTemplates:input_type -> stream.app.v1.ListAdminAdTemplatesRequest + 42, // 58: stream.app.v1.Admin.GetAdminAdTemplate:input_type -> stream.app.v1.GetAdminAdTemplateRequest + 44, // 59: stream.app.v1.Admin.CreateAdminAdTemplate:input_type -> stream.app.v1.CreateAdminAdTemplateRequest + 46, // 60: stream.app.v1.Admin.UpdateAdminAdTemplate:input_type -> stream.app.v1.UpdateAdminAdTemplateRequest + 48, // 61: stream.app.v1.Admin.DeleteAdminAdTemplate:input_type -> stream.app.v1.DeleteAdminAdTemplateRequest + 49, // 62: stream.app.v1.Admin.ListAdminPopupAds:input_type -> stream.app.v1.ListAdminPopupAdsRequest + 51, // 63: stream.app.v1.Admin.GetAdminPopupAd:input_type -> stream.app.v1.GetAdminPopupAdRequest + 53, // 64: stream.app.v1.Admin.CreateAdminPopupAd:input_type -> stream.app.v1.CreateAdminPopupAdRequest + 55, // 65: stream.app.v1.Admin.UpdateAdminPopupAd:input_type -> stream.app.v1.UpdateAdminPopupAdRequest + 57, // 66: stream.app.v1.Admin.DeleteAdminPopupAd:input_type -> stream.app.v1.DeleteAdminPopupAdRequest + 58, // 67: stream.app.v1.Admin.ListAdminPlayerConfigs:input_type -> stream.app.v1.ListAdminPlayerConfigsRequest + 60, // 68: stream.app.v1.Admin.GetAdminPlayerConfig:input_type -> stream.app.v1.GetAdminPlayerConfigRequest + 62, // 69: stream.app.v1.Admin.CreateAdminPlayerConfig:input_type -> stream.app.v1.CreateAdminPlayerConfigRequest + 64, // 70: stream.app.v1.Admin.UpdateAdminPlayerConfig:input_type -> stream.app.v1.UpdateAdminPlayerConfigRequest + 66, // 71: stream.app.v1.Admin.DeleteAdminPlayerConfig:input_type -> stream.app.v1.DeleteAdminPlayerConfigRequest + 67, // 72: stream.app.v1.Admin.ListAdminJobs:input_type -> stream.app.v1.ListAdminJobsRequest + 69, // 73: stream.app.v1.Admin.GetAdminJob:input_type -> stream.app.v1.GetAdminJobRequest + 71, // 74: stream.app.v1.Admin.GetAdminJobLogs:input_type -> stream.app.v1.GetAdminJobLogsRequest + 73, // 75: stream.app.v1.Admin.CreateAdminJob:input_type -> stream.app.v1.CreateAdminJobRequest + 75, // 76: stream.app.v1.Admin.CancelAdminJob:input_type -> stream.app.v1.CancelAdminJobRequest + 77, // 77: stream.app.v1.Admin.RetryAdminJob:input_type -> stream.app.v1.RetryAdminJobRequest + 79, // 78: stream.app.v1.Admin.ListAdminAgents:input_type -> stream.app.v1.ListAdminAgentsRequest + 81, // 79: stream.app.v1.Admin.RestartAdminAgent:input_type -> stream.app.v1.RestartAdminAgentRequest + 82, // 80: stream.app.v1.Admin.UpdateAdminAgent:input_type -> stream.app.v1.UpdateAdminAgentRequest + 1, // 81: stream.app.v1.Admin.GetAdminDashboard:output_type -> stream.app.v1.GetAdminDashboardResponse + 3, // 82: stream.app.v1.Admin.ListAdminUsers:output_type -> stream.app.v1.ListAdminUsersResponse + 5, // 83: stream.app.v1.Admin.GetAdminUser:output_type -> stream.app.v1.GetAdminUserResponse + 7, // 84: stream.app.v1.Admin.CreateAdminUser:output_type -> stream.app.v1.CreateAdminUserResponse + 9, // 85: stream.app.v1.Admin.UpdateAdminUser:output_type -> stream.app.v1.UpdateAdminUserResponse + 11, // 86: stream.app.v1.Admin.UpdateAdminUserReferralSettings:output_type -> stream.app.v1.UpdateAdminUserReferralSettingsResponse + 13, // 87: stream.app.v1.Admin.UpdateAdminUserRole:output_type -> stream.app.v1.UpdateAdminUserRoleResponse + 97, // 88: stream.app.v1.Admin.DeleteAdminUser:output_type -> stream.app.v1.MessageResponse + 16, // 89: stream.app.v1.Admin.ListAdminVideos:output_type -> stream.app.v1.ListAdminVideosResponse + 18, // 90: stream.app.v1.Admin.GetAdminVideo:output_type -> stream.app.v1.GetAdminVideoResponse + 20, // 91: stream.app.v1.Admin.CreateAdminVideo:output_type -> stream.app.v1.CreateAdminVideoResponse + 22, // 92: stream.app.v1.Admin.UpdateAdminVideo:output_type -> stream.app.v1.UpdateAdminVideoResponse + 97, // 93: stream.app.v1.Admin.DeleteAdminVideo:output_type -> stream.app.v1.MessageResponse + 25, // 94: stream.app.v1.Admin.ListAdminPayments:output_type -> stream.app.v1.ListAdminPaymentsResponse + 27, // 95: stream.app.v1.Admin.GetAdminPayment:output_type -> stream.app.v1.GetAdminPaymentResponse + 29, // 96: stream.app.v1.Admin.CreateAdminPayment:output_type -> stream.app.v1.CreateAdminPaymentResponse + 31, // 97: stream.app.v1.Admin.UpdateAdminPayment:output_type -> stream.app.v1.UpdateAdminPaymentResponse + 33, // 98: stream.app.v1.Admin.ListAdminPlans:output_type -> stream.app.v1.ListAdminPlansResponse + 35, // 99: stream.app.v1.Admin.CreateAdminPlan:output_type -> stream.app.v1.CreateAdminPlanResponse + 37, // 100: stream.app.v1.Admin.UpdateAdminPlan:output_type -> stream.app.v1.UpdateAdminPlanResponse + 39, // 101: stream.app.v1.Admin.DeleteAdminPlan:output_type -> stream.app.v1.DeleteAdminPlanResponse + 41, // 102: stream.app.v1.Admin.ListAdminAdTemplates:output_type -> stream.app.v1.ListAdminAdTemplatesResponse + 43, // 103: stream.app.v1.Admin.GetAdminAdTemplate:output_type -> stream.app.v1.GetAdminAdTemplateResponse + 45, // 104: stream.app.v1.Admin.CreateAdminAdTemplate:output_type -> stream.app.v1.CreateAdminAdTemplateResponse + 47, // 105: stream.app.v1.Admin.UpdateAdminAdTemplate:output_type -> stream.app.v1.UpdateAdminAdTemplateResponse + 97, // 106: stream.app.v1.Admin.DeleteAdminAdTemplate:output_type -> stream.app.v1.MessageResponse + 50, // 107: stream.app.v1.Admin.ListAdminPopupAds:output_type -> stream.app.v1.ListAdminPopupAdsResponse + 52, // 108: stream.app.v1.Admin.GetAdminPopupAd:output_type -> stream.app.v1.GetAdminPopupAdResponse + 54, // 109: stream.app.v1.Admin.CreateAdminPopupAd:output_type -> stream.app.v1.CreateAdminPopupAdResponse + 56, // 110: stream.app.v1.Admin.UpdateAdminPopupAd:output_type -> stream.app.v1.UpdateAdminPopupAdResponse + 97, // 111: stream.app.v1.Admin.DeleteAdminPopupAd:output_type -> stream.app.v1.MessageResponse + 59, // 112: stream.app.v1.Admin.ListAdminPlayerConfigs:output_type -> stream.app.v1.ListAdminPlayerConfigsResponse + 61, // 113: stream.app.v1.Admin.GetAdminPlayerConfig:output_type -> stream.app.v1.GetAdminPlayerConfigResponse + 63, // 114: stream.app.v1.Admin.CreateAdminPlayerConfig:output_type -> stream.app.v1.CreateAdminPlayerConfigResponse + 65, // 115: stream.app.v1.Admin.UpdateAdminPlayerConfig:output_type -> stream.app.v1.UpdateAdminPlayerConfigResponse + 97, // 116: stream.app.v1.Admin.DeleteAdminPlayerConfig:output_type -> stream.app.v1.MessageResponse + 68, // 117: stream.app.v1.Admin.ListAdminJobs:output_type -> stream.app.v1.ListAdminJobsResponse + 70, // 118: stream.app.v1.Admin.GetAdminJob:output_type -> stream.app.v1.GetAdminJobResponse + 72, // 119: stream.app.v1.Admin.GetAdminJobLogs:output_type -> stream.app.v1.GetAdminJobLogsResponse + 74, // 120: stream.app.v1.Admin.CreateAdminJob:output_type -> stream.app.v1.CreateAdminJobResponse + 76, // 121: stream.app.v1.Admin.CancelAdminJob:output_type -> stream.app.v1.CancelAdminJobResponse + 78, // 122: stream.app.v1.Admin.RetryAdminJob:output_type -> stream.app.v1.RetryAdminJobResponse + 80, // 123: stream.app.v1.Admin.ListAdminAgents:output_type -> stream.app.v1.ListAdminAgentsResponse + 83, // 124: stream.app.v1.Admin.RestartAdminAgent:output_type -> stream.app.v1.AdminAgentCommandResponse + 83, // 125: stream.app.v1.Admin.UpdateAdminAgent:output_type -> stream.app.v1.AdminAgentCommandResponse + 81, // [81:126] is the sub-list for method output_type + 36, // [36:81] is the sub-list for method input_type + 36, // [36:36] is the sub-list for extension type_name + 36, // [36:36] is the sub-list for extension extendee + 0, // [0:36] is the sub-list for field type_name } func init() { file_app_v1_admin_proto_init() } @@ -5171,15 +5776,18 @@ func file_app_v1_admin_proto_init() { file_app_v1_admin_proto_msgTypes[53].OneofWrappers = []any{} file_app_v1_admin_proto_msgTypes[55].OneofWrappers = []any{} file_app_v1_admin_proto_msgTypes[58].OneofWrappers = []any{} - file_app_v1_admin_proto_msgTypes[59].OneofWrappers = []any{} + file_app_v1_admin_proto_msgTypes[62].OneofWrappers = []any{} file_app_v1_admin_proto_msgTypes[64].OneofWrappers = []any{} + file_app_v1_admin_proto_msgTypes[67].OneofWrappers = []any{} + file_app_v1_admin_proto_msgTypes[68].OneofWrappers = []any{} + file_app_v1_admin_proto_msgTypes[73].OneofWrappers = []any{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_app_v1_admin_proto_rawDesc), len(file_app_v1_admin_proto_rawDesc)), NumEnums: 0, - NumMessages: 76, + NumMessages: 85, NumExtensions: 0, NumServices: 1, }, diff --git a/internal/api/proto/app/v1/admin_grpc.pb.go b/internal/api/proto/app/v1/admin_grpc.pb.go index 8584bf1..0772c17 100644 --- a/internal/api/proto/app/v1/admin_grpc.pb.go +++ b/internal/api/proto/app/v1/admin_grpc.pb.go @@ -45,6 +45,11 @@ const ( Admin_CreateAdminAdTemplate_FullMethodName = "/stream.app.v1.Admin/CreateAdminAdTemplate" Admin_UpdateAdminAdTemplate_FullMethodName = "/stream.app.v1.Admin/UpdateAdminAdTemplate" Admin_DeleteAdminAdTemplate_FullMethodName = "/stream.app.v1.Admin/DeleteAdminAdTemplate" + Admin_ListAdminPopupAds_FullMethodName = "/stream.app.v1.Admin/ListAdminPopupAds" + Admin_GetAdminPopupAd_FullMethodName = "/stream.app.v1.Admin/GetAdminPopupAd" + Admin_CreateAdminPopupAd_FullMethodName = "/stream.app.v1.Admin/CreateAdminPopupAd" + Admin_UpdateAdminPopupAd_FullMethodName = "/stream.app.v1.Admin/UpdateAdminPopupAd" + Admin_DeleteAdminPopupAd_FullMethodName = "/stream.app.v1.Admin/DeleteAdminPopupAd" Admin_ListAdminPlayerConfigs_FullMethodName = "/stream.app.v1.Admin/ListAdminPlayerConfigs" Admin_GetAdminPlayerConfig_FullMethodName = "/stream.app.v1.Admin/GetAdminPlayerConfig" Admin_CreateAdminPlayerConfig_FullMethodName = "/stream.app.v1.Admin/CreateAdminPlayerConfig" @@ -91,6 +96,11 @@ type AdminClient interface { CreateAdminAdTemplate(ctx context.Context, in *CreateAdminAdTemplateRequest, opts ...grpc.CallOption) (*CreateAdminAdTemplateResponse, error) UpdateAdminAdTemplate(ctx context.Context, in *UpdateAdminAdTemplateRequest, opts ...grpc.CallOption) (*UpdateAdminAdTemplateResponse, error) DeleteAdminAdTemplate(ctx context.Context, in *DeleteAdminAdTemplateRequest, opts ...grpc.CallOption) (*MessageResponse, error) + ListAdminPopupAds(ctx context.Context, in *ListAdminPopupAdsRequest, opts ...grpc.CallOption) (*ListAdminPopupAdsResponse, error) + GetAdminPopupAd(ctx context.Context, in *GetAdminPopupAdRequest, opts ...grpc.CallOption) (*GetAdminPopupAdResponse, error) + CreateAdminPopupAd(ctx context.Context, in *CreateAdminPopupAdRequest, opts ...grpc.CallOption) (*CreateAdminPopupAdResponse, error) + UpdateAdminPopupAd(ctx context.Context, in *UpdateAdminPopupAdRequest, opts ...grpc.CallOption) (*UpdateAdminPopupAdResponse, error) + DeleteAdminPopupAd(ctx context.Context, in *DeleteAdminPopupAdRequest, opts ...grpc.CallOption) (*MessageResponse, error) ListAdminPlayerConfigs(ctx context.Context, in *ListAdminPlayerConfigsRequest, opts ...grpc.CallOption) (*ListAdminPlayerConfigsResponse, error) GetAdminPlayerConfig(ctx context.Context, in *GetAdminPlayerConfigRequest, opts ...grpc.CallOption) (*GetAdminPlayerConfigResponse, error) CreateAdminPlayerConfig(ctx context.Context, in *CreateAdminPlayerConfigRequest, opts ...grpc.CallOption) (*CreateAdminPlayerConfigResponse, error) @@ -375,6 +385,56 @@ func (c *adminClient) DeleteAdminAdTemplate(ctx context.Context, in *DeleteAdmin return out, nil } +func (c *adminClient) ListAdminPopupAds(ctx context.Context, in *ListAdminPopupAdsRequest, opts ...grpc.CallOption) (*ListAdminPopupAdsResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ListAdminPopupAdsResponse) + err := c.cc.Invoke(ctx, Admin_ListAdminPopupAds_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *adminClient) GetAdminPopupAd(ctx context.Context, in *GetAdminPopupAdRequest, opts ...grpc.CallOption) (*GetAdminPopupAdResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(GetAdminPopupAdResponse) + err := c.cc.Invoke(ctx, Admin_GetAdminPopupAd_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *adminClient) CreateAdminPopupAd(ctx context.Context, in *CreateAdminPopupAdRequest, opts ...grpc.CallOption) (*CreateAdminPopupAdResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(CreateAdminPopupAdResponse) + err := c.cc.Invoke(ctx, Admin_CreateAdminPopupAd_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *adminClient) UpdateAdminPopupAd(ctx context.Context, in *UpdateAdminPopupAdRequest, opts ...grpc.CallOption) (*UpdateAdminPopupAdResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(UpdateAdminPopupAdResponse) + err := c.cc.Invoke(ctx, Admin_UpdateAdminPopupAd_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *adminClient) DeleteAdminPopupAd(ctx context.Context, in *DeleteAdminPopupAdRequest, opts ...grpc.CallOption) (*MessageResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(MessageResponse) + err := c.cc.Invoke(ctx, Admin_DeleteAdminPopupAd_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *adminClient) ListAdminPlayerConfigs(ctx context.Context, in *ListAdminPlayerConfigsRequest, opts ...grpc.CallOption) (*ListAdminPlayerConfigsResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(ListAdminPlayerConfigsResponse) @@ -545,6 +605,11 @@ type AdminServer interface { CreateAdminAdTemplate(context.Context, *CreateAdminAdTemplateRequest) (*CreateAdminAdTemplateResponse, error) UpdateAdminAdTemplate(context.Context, *UpdateAdminAdTemplateRequest) (*UpdateAdminAdTemplateResponse, error) DeleteAdminAdTemplate(context.Context, *DeleteAdminAdTemplateRequest) (*MessageResponse, error) + ListAdminPopupAds(context.Context, *ListAdminPopupAdsRequest) (*ListAdminPopupAdsResponse, error) + GetAdminPopupAd(context.Context, *GetAdminPopupAdRequest) (*GetAdminPopupAdResponse, error) + CreateAdminPopupAd(context.Context, *CreateAdminPopupAdRequest) (*CreateAdminPopupAdResponse, error) + UpdateAdminPopupAd(context.Context, *UpdateAdminPopupAdRequest) (*UpdateAdminPopupAdResponse, error) + DeleteAdminPopupAd(context.Context, *DeleteAdminPopupAdRequest) (*MessageResponse, error) ListAdminPlayerConfigs(context.Context, *ListAdminPlayerConfigsRequest) (*ListAdminPlayerConfigsResponse, error) GetAdminPlayerConfig(context.Context, *GetAdminPlayerConfigRequest) (*GetAdminPlayerConfigResponse, error) CreateAdminPlayerConfig(context.Context, *CreateAdminPlayerConfigRequest) (*CreateAdminPlayerConfigResponse, error) @@ -647,6 +712,21 @@ func (UnimplementedAdminServer) UpdateAdminAdTemplate(context.Context, *UpdateAd func (UnimplementedAdminServer) DeleteAdminAdTemplate(context.Context, *DeleteAdminAdTemplateRequest) (*MessageResponse, error) { return nil, status.Error(codes.Unimplemented, "method DeleteAdminAdTemplate not implemented") } +func (UnimplementedAdminServer) ListAdminPopupAds(context.Context, *ListAdminPopupAdsRequest) (*ListAdminPopupAdsResponse, error) { + return nil, status.Error(codes.Unimplemented, "method ListAdminPopupAds not implemented") +} +func (UnimplementedAdminServer) GetAdminPopupAd(context.Context, *GetAdminPopupAdRequest) (*GetAdminPopupAdResponse, error) { + return nil, status.Error(codes.Unimplemented, "method GetAdminPopupAd not implemented") +} +func (UnimplementedAdminServer) CreateAdminPopupAd(context.Context, *CreateAdminPopupAdRequest) (*CreateAdminPopupAdResponse, error) { + return nil, status.Error(codes.Unimplemented, "method CreateAdminPopupAd not implemented") +} +func (UnimplementedAdminServer) UpdateAdminPopupAd(context.Context, *UpdateAdminPopupAdRequest) (*UpdateAdminPopupAdResponse, error) { + return nil, status.Error(codes.Unimplemented, "method UpdateAdminPopupAd not implemented") +} +func (UnimplementedAdminServer) DeleteAdminPopupAd(context.Context, *DeleteAdminPopupAdRequest) (*MessageResponse, error) { + return nil, status.Error(codes.Unimplemented, "method DeleteAdminPopupAd not implemented") +} func (UnimplementedAdminServer) ListAdminPlayerConfigs(context.Context, *ListAdminPlayerConfigsRequest) (*ListAdminPlayerConfigsResponse, error) { return nil, status.Error(codes.Unimplemented, "method ListAdminPlayerConfigs not implemented") } @@ -1178,6 +1258,96 @@ func _Admin_DeleteAdminAdTemplate_Handler(srv interface{}, ctx context.Context, return interceptor(ctx, in, info, handler) } +func _Admin_ListAdminPopupAds_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListAdminPopupAdsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AdminServer).ListAdminPopupAds(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Admin_ListAdminPopupAds_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AdminServer).ListAdminPopupAds(ctx, req.(*ListAdminPopupAdsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Admin_GetAdminPopupAd_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetAdminPopupAdRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AdminServer).GetAdminPopupAd(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Admin_GetAdminPopupAd_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AdminServer).GetAdminPopupAd(ctx, req.(*GetAdminPopupAdRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Admin_CreateAdminPopupAd_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateAdminPopupAdRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AdminServer).CreateAdminPopupAd(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Admin_CreateAdminPopupAd_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AdminServer).CreateAdminPopupAd(ctx, req.(*CreateAdminPopupAdRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Admin_UpdateAdminPopupAd_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateAdminPopupAdRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AdminServer).UpdateAdminPopupAd(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Admin_UpdateAdminPopupAd_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AdminServer).UpdateAdminPopupAd(ctx, req.(*UpdateAdminPopupAdRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Admin_DeleteAdminPopupAd_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteAdminPopupAdRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AdminServer).DeleteAdminPopupAd(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Admin_DeleteAdminPopupAd_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AdminServer).DeleteAdminPopupAd(ctx, req.(*DeleteAdminPopupAdRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _Admin_ListAdminPlayerConfigs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ListAdminPlayerConfigsRequest) if err := dec(in); err != nil { @@ -1541,6 +1711,26 @@ var Admin_ServiceDesc = grpc.ServiceDesc{ MethodName: "DeleteAdminAdTemplate", Handler: _Admin_DeleteAdminAdTemplate_Handler, }, + { + MethodName: "ListAdminPopupAds", + Handler: _Admin_ListAdminPopupAds_Handler, + }, + { + MethodName: "GetAdminPopupAd", + Handler: _Admin_GetAdminPopupAd_Handler, + }, + { + MethodName: "CreateAdminPopupAd", + Handler: _Admin_CreateAdminPopupAd_Handler, + }, + { + MethodName: "UpdateAdminPopupAd", + Handler: _Admin_UpdateAdminPopupAd_Handler, + }, + { + MethodName: "DeleteAdminPopupAd", + Handler: _Admin_DeleteAdminPopupAd_Handler, + }, { MethodName: "ListAdminPlayerConfigs", Handler: _Admin_ListAdminPlayerConfigs_Handler, diff --git a/internal/api/proto/app/v1/catalog.pb.go b/internal/api/proto/app/v1/catalog.pb.go index 29a5325..df581b5 100644 --- a/internal/api/proto/app/v1/catalog.pb.go +++ b/internal/api/proto/app/v1/catalog.pb.go @@ -637,6 +637,498 @@ func (x *DeleteAdTemplateRequest) GetId() string { return "" } +type ListPopupAdsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Page int32 `protobuf:"varint,1,opt,name=page,proto3" json:"page,omitempty"` + Limit int32 `protobuf:"varint,2,opt,name=limit,proto3" json:"limit,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListPopupAdsRequest) Reset() { + *x = ListPopupAdsRequest{} + mi := &file_app_v1_catalog_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListPopupAdsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListPopupAdsRequest) ProtoMessage() {} + +func (x *ListPopupAdsRequest) ProtoReflect() protoreflect.Message { + mi := &file_app_v1_catalog_proto_msgTypes[12] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListPopupAdsRequest.ProtoReflect.Descriptor instead. +func (*ListPopupAdsRequest) Descriptor() ([]byte, []int) { + return file_app_v1_catalog_proto_rawDescGZIP(), []int{12} +} + +func (x *ListPopupAdsRequest) GetPage() int32 { + if x != nil { + return x.Page + } + return 0 +} + +func (x *ListPopupAdsRequest) GetLimit() int32 { + if x != nil { + return x.Limit + } + return 0 +} + +type ListPopupAdsResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Items []*PopupAd `protobuf:"bytes,1,rep,name=items,proto3" json:"items,omitempty"` + Total int64 `protobuf:"varint,2,opt,name=total,proto3" json:"total,omitempty"` + Page int32 `protobuf:"varint,3,opt,name=page,proto3" json:"page,omitempty"` + Limit int32 `protobuf:"varint,4,opt,name=limit,proto3" json:"limit,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListPopupAdsResponse) Reset() { + *x = ListPopupAdsResponse{} + mi := &file_app_v1_catalog_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListPopupAdsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListPopupAdsResponse) ProtoMessage() {} + +func (x *ListPopupAdsResponse) ProtoReflect() protoreflect.Message { + mi := &file_app_v1_catalog_proto_msgTypes[13] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListPopupAdsResponse.ProtoReflect.Descriptor instead. +func (*ListPopupAdsResponse) Descriptor() ([]byte, []int) { + return file_app_v1_catalog_proto_rawDescGZIP(), []int{13} +} + +func (x *ListPopupAdsResponse) GetItems() []*PopupAd { + if x != nil { + return x.Items + } + return nil +} + +func (x *ListPopupAdsResponse) GetTotal() int64 { + if x != nil { + return x.Total + } + return 0 +} + +func (x *ListPopupAdsResponse) GetPage() int32 { + if x != nil { + return x.Page + } + return 0 +} + +func (x *ListPopupAdsResponse) GetLimit() int32 { + if x != nil { + return x.Limit + } + return 0 +} + +type CreatePopupAdRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` + Label string `protobuf:"bytes,2,opt,name=label,proto3" json:"label,omitempty"` + Value string `protobuf:"bytes,3,opt,name=value,proto3" json:"value,omitempty"` + IsActive *bool `protobuf:"varint,4,opt,name=is_active,json=isActive,proto3,oneof" json:"is_active,omitempty"` + MaxTriggersPerSession *int32 `protobuf:"varint,5,opt,name=max_triggers_per_session,json=maxTriggersPerSession,proto3,oneof" json:"max_triggers_per_session,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CreatePopupAdRequest) Reset() { + *x = CreatePopupAdRequest{} + mi := &file_app_v1_catalog_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CreatePopupAdRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreatePopupAdRequest) ProtoMessage() {} + +func (x *CreatePopupAdRequest) ProtoReflect() protoreflect.Message { + mi := &file_app_v1_catalog_proto_msgTypes[14] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreatePopupAdRequest.ProtoReflect.Descriptor instead. +func (*CreatePopupAdRequest) Descriptor() ([]byte, []int) { + return file_app_v1_catalog_proto_rawDescGZIP(), []int{14} +} + +func (x *CreatePopupAdRequest) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *CreatePopupAdRequest) GetLabel() string { + if x != nil { + return x.Label + } + return "" +} + +func (x *CreatePopupAdRequest) GetValue() string { + if x != nil { + return x.Value + } + return "" +} + +func (x *CreatePopupAdRequest) GetIsActive() bool { + if x != nil && x.IsActive != nil { + return *x.IsActive + } + return false +} + +func (x *CreatePopupAdRequest) GetMaxTriggersPerSession() int32 { + if x != nil && x.MaxTriggersPerSession != nil { + return *x.MaxTriggersPerSession + } + return 0 +} + +type CreatePopupAdResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Item *PopupAd `protobuf:"bytes,1,opt,name=item,proto3" json:"item,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CreatePopupAdResponse) Reset() { + *x = CreatePopupAdResponse{} + mi := &file_app_v1_catalog_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CreatePopupAdResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreatePopupAdResponse) ProtoMessage() {} + +func (x *CreatePopupAdResponse) ProtoReflect() protoreflect.Message { + mi := &file_app_v1_catalog_proto_msgTypes[15] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreatePopupAdResponse.ProtoReflect.Descriptor instead. +func (*CreatePopupAdResponse) Descriptor() ([]byte, []int) { + return file_app_v1_catalog_proto_rawDescGZIP(), []int{15} +} + +func (x *CreatePopupAdResponse) GetItem() *PopupAd { + if x != nil { + return x.Item + } + return nil +} + +type UpdatePopupAdRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"` + Label string `protobuf:"bytes,3,opt,name=label,proto3" json:"label,omitempty"` + Value string `protobuf:"bytes,4,opt,name=value,proto3" json:"value,omitempty"` + IsActive *bool `protobuf:"varint,5,opt,name=is_active,json=isActive,proto3,oneof" json:"is_active,omitempty"` + MaxTriggersPerSession *int32 `protobuf:"varint,6,opt,name=max_triggers_per_session,json=maxTriggersPerSession,proto3,oneof" json:"max_triggers_per_session,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UpdatePopupAdRequest) Reset() { + *x = UpdatePopupAdRequest{} + mi := &file_app_v1_catalog_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UpdatePopupAdRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdatePopupAdRequest) ProtoMessage() {} + +func (x *UpdatePopupAdRequest) ProtoReflect() protoreflect.Message { + mi := &file_app_v1_catalog_proto_msgTypes[16] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdatePopupAdRequest.ProtoReflect.Descriptor instead. +func (*UpdatePopupAdRequest) Descriptor() ([]byte, []int) { + return file_app_v1_catalog_proto_rawDescGZIP(), []int{16} +} + +func (x *UpdatePopupAdRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *UpdatePopupAdRequest) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *UpdatePopupAdRequest) GetLabel() string { + if x != nil { + return x.Label + } + return "" +} + +func (x *UpdatePopupAdRequest) GetValue() string { + if x != nil { + return x.Value + } + return "" +} + +func (x *UpdatePopupAdRequest) GetIsActive() bool { + if x != nil && x.IsActive != nil { + return *x.IsActive + } + return false +} + +func (x *UpdatePopupAdRequest) GetMaxTriggersPerSession() int32 { + if x != nil && x.MaxTriggersPerSession != nil { + return *x.MaxTriggersPerSession + } + return 0 +} + +type UpdatePopupAdResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Item *PopupAd `protobuf:"bytes,1,opt,name=item,proto3" json:"item,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UpdatePopupAdResponse) Reset() { + *x = UpdatePopupAdResponse{} + mi := &file_app_v1_catalog_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UpdatePopupAdResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdatePopupAdResponse) ProtoMessage() {} + +func (x *UpdatePopupAdResponse) ProtoReflect() protoreflect.Message { + mi := &file_app_v1_catalog_proto_msgTypes[17] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdatePopupAdResponse.ProtoReflect.Descriptor instead. +func (*UpdatePopupAdResponse) Descriptor() ([]byte, []int) { + return file_app_v1_catalog_proto_rawDescGZIP(), []int{17} +} + +func (x *UpdatePopupAdResponse) GetItem() *PopupAd { + if x != nil { + return x.Item + } + return nil +} + +type DeletePopupAdRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DeletePopupAdRequest) Reset() { + *x = DeletePopupAdRequest{} + mi := &file_app_v1_catalog_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DeletePopupAdRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeletePopupAdRequest) ProtoMessage() {} + +func (x *DeletePopupAdRequest) ProtoReflect() protoreflect.Message { + mi := &file_app_v1_catalog_proto_msgTypes[18] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeletePopupAdRequest.ProtoReflect.Descriptor instead. +func (*DeletePopupAdRequest) Descriptor() ([]byte, []int) { + return file_app_v1_catalog_proto_rawDescGZIP(), []int{18} +} + +func (x *DeletePopupAdRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +type GetActivePopupAdRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetActivePopupAdRequest) Reset() { + *x = GetActivePopupAdRequest{} + mi := &file_app_v1_catalog_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetActivePopupAdRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetActivePopupAdRequest) ProtoMessage() {} + +func (x *GetActivePopupAdRequest) ProtoReflect() protoreflect.Message { + mi := &file_app_v1_catalog_proto_msgTypes[19] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetActivePopupAdRequest.ProtoReflect.Descriptor instead. +func (*GetActivePopupAdRequest) Descriptor() ([]byte, []int) { + return file_app_v1_catalog_proto_rawDescGZIP(), []int{19} +} + +type GetActivePopupAdResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Item *PopupAd `protobuf:"bytes,1,opt,name=item,proto3,oneof" json:"item,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetActivePopupAdResponse) Reset() { + *x = GetActivePopupAdResponse{} + mi := &file_app_v1_catalog_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetActivePopupAdResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetActivePopupAdResponse) ProtoMessage() {} + +func (x *GetActivePopupAdResponse) ProtoReflect() protoreflect.Message { + mi := &file_app_v1_catalog_proto_msgTypes[20] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetActivePopupAdResponse.ProtoReflect.Descriptor instead. +func (*GetActivePopupAdResponse) Descriptor() ([]byte, []int) { + return file_app_v1_catalog_proto_rawDescGZIP(), []int{20} +} + +func (x *GetActivePopupAdResponse) GetItem() *PopupAd { + if x != nil { + return x.Item + } + return nil +} + type ListPlayerConfigsRequest struct { state protoimpl.MessageState `protogen:"open.v1"` unknownFields protoimpl.UnknownFields @@ -645,7 +1137,7 @@ type ListPlayerConfigsRequest struct { func (x *ListPlayerConfigsRequest) Reset() { *x = ListPlayerConfigsRequest{} - mi := &file_app_v1_catalog_proto_msgTypes[12] + mi := &file_app_v1_catalog_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -657,7 +1149,7 @@ func (x *ListPlayerConfigsRequest) String() string { func (*ListPlayerConfigsRequest) ProtoMessage() {} func (x *ListPlayerConfigsRequest) ProtoReflect() protoreflect.Message { - mi := &file_app_v1_catalog_proto_msgTypes[12] + mi := &file_app_v1_catalog_proto_msgTypes[21] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -670,7 +1162,7 @@ func (x *ListPlayerConfigsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListPlayerConfigsRequest.ProtoReflect.Descriptor instead. func (*ListPlayerConfigsRequest) Descriptor() ([]byte, []int) { - return file_app_v1_catalog_proto_rawDescGZIP(), []int{12} + return file_app_v1_catalog_proto_rawDescGZIP(), []int{21} } type ListPlayerConfigsResponse struct { @@ -682,7 +1174,7 @@ type ListPlayerConfigsResponse struct { func (x *ListPlayerConfigsResponse) Reset() { *x = ListPlayerConfigsResponse{} - mi := &file_app_v1_catalog_proto_msgTypes[13] + mi := &file_app_v1_catalog_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -694,7 +1186,7 @@ func (x *ListPlayerConfigsResponse) String() string { func (*ListPlayerConfigsResponse) ProtoMessage() {} func (x *ListPlayerConfigsResponse) ProtoReflect() protoreflect.Message { - mi := &file_app_v1_catalog_proto_msgTypes[13] + mi := &file_app_v1_catalog_proto_msgTypes[22] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -707,7 +1199,7 @@ func (x *ListPlayerConfigsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListPlayerConfigsResponse.ProtoReflect.Descriptor instead. func (*ListPlayerConfigsResponse) Descriptor() ([]byte, []int) { - return file_app_v1_catalog_proto_rawDescGZIP(), []int{13} + return file_app_v1_catalog_proto_rawDescGZIP(), []int{22} } func (x *ListPlayerConfigsResponse) GetConfigs() []*PlayerConfig { @@ -738,7 +1230,7 @@ type CreatePlayerConfigRequest struct { func (x *CreatePlayerConfigRequest) Reset() { *x = CreatePlayerConfigRequest{} - mi := &file_app_v1_catalog_proto_msgTypes[14] + mi := &file_app_v1_catalog_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -750,7 +1242,7 @@ func (x *CreatePlayerConfigRequest) String() string { func (*CreatePlayerConfigRequest) ProtoMessage() {} func (x *CreatePlayerConfigRequest) ProtoReflect() protoreflect.Message { - mi := &file_app_v1_catalog_proto_msgTypes[14] + mi := &file_app_v1_catalog_proto_msgTypes[23] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -763,7 +1255,7 @@ func (x *CreatePlayerConfigRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreatePlayerConfigRequest.ProtoReflect.Descriptor instead. func (*CreatePlayerConfigRequest) Descriptor() ([]byte, []int) { - return file_app_v1_catalog_proto_rawDescGZIP(), []int{14} + return file_app_v1_catalog_proto_rawDescGZIP(), []int{23} } func (x *CreatePlayerConfigRequest) GetName() string { @@ -866,7 +1358,7 @@ type CreatePlayerConfigResponse struct { func (x *CreatePlayerConfigResponse) Reset() { *x = CreatePlayerConfigResponse{} - mi := &file_app_v1_catalog_proto_msgTypes[15] + mi := &file_app_v1_catalog_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -878,7 +1370,7 @@ func (x *CreatePlayerConfigResponse) String() string { func (*CreatePlayerConfigResponse) ProtoMessage() {} func (x *CreatePlayerConfigResponse) ProtoReflect() protoreflect.Message { - mi := &file_app_v1_catalog_proto_msgTypes[15] + mi := &file_app_v1_catalog_proto_msgTypes[24] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -891,7 +1383,7 @@ func (x *CreatePlayerConfigResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CreatePlayerConfigResponse.ProtoReflect.Descriptor instead. func (*CreatePlayerConfigResponse) Descriptor() ([]byte, []int) { - return file_app_v1_catalog_proto_rawDescGZIP(), []int{15} + return file_app_v1_catalog_proto_rawDescGZIP(), []int{24} } func (x *CreatePlayerConfigResponse) GetConfig() *PlayerConfig { @@ -923,7 +1415,7 @@ type UpdatePlayerConfigRequest struct { func (x *UpdatePlayerConfigRequest) Reset() { *x = UpdatePlayerConfigRequest{} - mi := &file_app_v1_catalog_proto_msgTypes[16] + mi := &file_app_v1_catalog_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -935,7 +1427,7 @@ func (x *UpdatePlayerConfigRequest) String() string { func (*UpdatePlayerConfigRequest) ProtoMessage() {} func (x *UpdatePlayerConfigRequest) ProtoReflect() protoreflect.Message { - mi := &file_app_v1_catalog_proto_msgTypes[16] + mi := &file_app_v1_catalog_proto_msgTypes[25] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -948,7 +1440,7 @@ func (x *UpdatePlayerConfigRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdatePlayerConfigRequest.ProtoReflect.Descriptor instead. func (*UpdatePlayerConfigRequest) Descriptor() ([]byte, []int) { - return file_app_v1_catalog_proto_rawDescGZIP(), []int{16} + return file_app_v1_catalog_proto_rawDescGZIP(), []int{25} } func (x *UpdatePlayerConfigRequest) GetId() string { @@ -1058,7 +1550,7 @@ type UpdatePlayerConfigResponse struct { func (x *UpdatePlayerConfigResponse) Reset() { *x = UpdatePlayerConfigResponse{} - mi := &file_app_v1_catalog_proto_msgTypes[17] + mi := &file_app_v1_catalog_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1070,7 +1562,7 @@ func (x *UpdatePlayerConfigResponse) String() string { func (*UpdatePlayerConfigResponse) ProtoMessage() {} func (x *UpdatePlayerConfigResponse) ProtoReflect() protoreflect.Message { - mi := &file_app_v1_catalog_proto_msgTypes[17] + mi := &file_app_v1_catalog_proto_msgTypes[26] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1083,7 +1575,7 @@ func (x *UpdatePlayerConfigResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdatePlayerConfigResponse.ProtoReflect.Descriptor instead. func (*UpdatePlayerConfigResponse) Descriptor() ([]byte, []int) { - return file_app_v1_catalog_proto_rawDescGZIP(), []int{17} + return file_app_v1_catalog_proto_rawDescGZIP(), []int{26} } func (x *UpdatePlayerConfigResponse) GetConfig() *PlayerConfig { @@ -1102,7 +1594,7 @@ type DeletePlayerConfigRequest struct { func (x *DeletePlayerConfigRequest) Reset() { *x = DeletePlayerConfigRequest{} - mi := &file_app_v1_catalog_proto_msgTypes[18] + mi := &file_app_v1_catalog_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1114,7 +1606,7 @@ func (x *DeletePlayerConfigRequest) String() string { func (*DeletePlayerConfigRequest) ProtoMessage() {} func (x *DeletePlayerConfigRequest) ProtoReflect() protoreflect.Message { - mi := &file_app_v1_catalog_proto_msgTypes[18] + mi := &file_app_v1_catalog_proto_msgTypes[27] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1127,7 +1619,7 @@ func (x *DeletePlayerConfigRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeletePlayerConfigRequest.ProtoReflect.Descriptor instead. func (*DeletePlayerConfigRequest) Descriptor() ([]byte, []int) { - return file_app_v1_catalog_proto_rawDescGZIP(), []int{18} + return file_app_v1_catalog_proto_rawDescGZIP(), []int{27} } func (x *DeletePlayerConfigRequest) GetId() string { @@ -1145,7 +1637,7 @@ type ListPlansRequest struct { func (x *ListPlansRequest) Reset() { *x = ListPlansRequest{} - mi := &file_app_v1_catalog_proto_msgTypes[19] + mi := &file_app_v1_catalog_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1157,7 +1649,7 @@ func (x *ListPlansRequest) String() string { func (*ListPlansRequest) ProtoMessage() {} func (x *ListPlansRequest) ProtoReflect() protoreflect.Message { - mi := &file_app_v1_catalog_proto_msgTypes[19] + mi := &file_app_v1_catalog_proto_msgTypes[28] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1170,7 +1662,7 @@ func (x *ListPlansRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListPlansRequest.ProtoReflect.Descriptor instead. func (*ListPlansRequest) Descriptor() ([]byte, []int) { - return file_app_v1_catalog_proto_rawDescGZIP(), []int{19} + return file_app_v1_catalog_proto_rawDescGZIP(), []int{28} } type ListPlansResponse struct { @@ -1182,7 +1674,7 @@ type ListPlansResponse struct { func (x *ListPlansResponse) Reset() { *x = ListPlansResponse{} - mi := &file_app_v1_catalog_proto_msgTypes[20] + mi := &file_app_v1_catalog_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1194,7 +1686,7 @@ func (x *ListPlansResponse) String() string { func (*ListPlansResponse) ProtoMessage() {} func (x *ListPlansResponse) ProtoReflect() protoreflect.Message { - mi := &file_app_v1_catalog_proto_msgTypes[20] + mi := &file_app_v1_catalog_proto_msgTypes[29] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1207,7 +1699,7 @@ func (x *ListPlansResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListPlansResponse.ProtoReflect.Descriptor instead. func (*ListPlansResponse) Descriptor() ([]byte, []int) { - return file_app_v1_catalog_proto_rawDescGZIP(), []int{20} + return file_app_v1_catalog_proto_rawDescGZIP(), []int{29} } func (x *ListPlansResponse) GetPlans() []*Plan { @@ -1274,7 +1766,44 @@ const file_app_v1_catalog_proto_rawDesc = "" + "\x18UpdateAdTemplateResponse\x125\n" + "\btemplate\x18\x01 \x01(\v2\x19.stream.app.v1.AdTemplateR\btemplate\")\n" + "\x17DeleteAdTemplateRequest\x12\x0e\n" + - "\x02id\x18\x01 \x01(\tR\x02id\"\x1a\n" + + "\x02id\x18\x01 \x01(\tR\x02id\"?\n" + + "\x13ListPopupAdsRequest\x12\x12\n" + + "\x04page\x18\x01 \x01(\x05R\x04page\x12\x14\n" + + "\x05limit\x18\x02 \x01(\x05R\x05limit\"\x84\x01\n" + + "\x14ListPopupAdsResponse\x12,\n" + + "\x05items\x18\x01 \x03(\v2\x16.stream.app.v1.PopupAdR\x05items\x12\x14\n" + + "\x05total\x18\x02 \x01(\x03R\x05total\x12\x12\n" + + "\x04page\x18\x03 \x01(\x05R\x04page\x12\x14\n" + + "\x05limit\x18\x04 \x01(\x05R\x05limit\"\xe1\x01\n" + + "\x14CreatePopupAdRequest\x12\x12\n" + + "\x04type\x18\x01 \x01(\tR\x04type\x12\x14\n" + + "\x05label\x18\x02 \x01(\tR\x05label\x12\x14\n" + + "\x05value\x18\x03 \x01(\tR\x05value\x12 \n" + + "\tis_active\x18\x04 \x01(\bH\x00R\bisActive\x88\x01\x01\x12<\n" + + "\x18max_triggers_per_session\x18\x05 \x01(\x05H\x01R\x15maxTriggersPerSession\x88\x01\x01B\f\n" + + "\n" + + "_is_activeB\x1b\n" + + "\x19_max_triggers_per_session\"C\n" + + "\x15CreatePopupAdResponse\x12*\n" + + "\x04item\x18\x01 \x01(\v2\x16.stream.app.v1.PopupAdR\x04item\"\xf1\x01\n" + + "\x14UpdatePopupAdRequest\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n" + + "\x04type\x18\x02 \x01(\tR\x04type\x12\x14\n" + + "\x05label\x18\x03 \x01(\tR\x05label\x12\x14\n" + + "\x05value\x18\x04 \x01(\tR\x05value\x12 \n" + + "\tis_active\x18\x05 \x01(\bH\x00R\bisActive\x88\x01\x01\x12<\n" + + "\x18max_triggers_per_session\x18\x06 \x01(\x05H\x01R\x15maxTriggersPerSession\x88\x01\x01B\f\n" + + "\n" + + "_is_activeB\x1b\n" + + "\x19_max_triggers_per_session\"C\n" + + "\x15UpdatePopupAdResponse\x12*\n" + + "\x04item\x18\x01 \x01(\v2\x16.stream.app.v1.PopupAdR\x04item\"&\n" + + "\x14DeletePopupAdRequest\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\"\x19\n" + + "\x17GetActivePopupAdRequest\"T\n" + + "\x18GetActivePopupAdResponse\x12/\n" + + "\x04item\x18\x01 \x01(\v2\x16.stream.app.v1.PopupAdH\x00R\x04item\x88\x01\x01B\a\n" + + "\x05_item\"\x1a\n" + "\x18ListPlayerConfigsRequest\"R\n" + "\x19ListPlayerConfigsResponse\x125\n" + "\aconfigs\x18\x01 \x03(\v2\x1b.stream.app.v1.PlayerConfigR\aconfigs\"\xec\x03\n" + @@ -1344,7 +1873,13 @@ const file_app_v1_catalog_proto_rawDesc = "" + "\x0fListAdTemplates\x12%.stream.app.v1.ListAdTemplatesRequest\x1a&.stream.app.v1.ListAdTemplatesResponse\x12c\n" + "\x10CreateAdTemplate\x12&.stream.app.v1.CreateAdTemplateRequest\x1a'.stream.app.v1.CreateAdTemplateResponse\x12c\n" + "\x10UpdateAdTemplate\x12&.stream.app.v1.UpdateAdTemplateRequest\x1a'.stream.app.v1.UpdateAdTemplateResponse\x12Z\n" + - "\x10DeleteAdTemplate\x12&.stream.app.v1.DeleteAdTemplateRequest\x1a\x1e.stream.app.v1.MessageResponse2\xad\x03\n" + + "\x10DeleteAdTemplate\x12&.stream.app.v1.DeleteAdTemplateRequest\x1a\x1e.stream.app.v1.MessageResponse2\xd6\x03\n" + + "\bPopupAds\x12W\n" + + "\fListPopupAds\x12\".stream.app.v1.ListPopupAdsRequest\x1a#.stream.app.v1.ListPopupAdsResponse\x12Z\n" + + "\rCreatePopupAd\x12#.stream.app.v1.CreatePopupAdRequest\x1a$.stream.app.v1.CreatePopupAdResponse\x12Z\n" + + "\rUpdatePopupAd\x12#.stream.app.v1.UpdatePopupAdRequest\x1a$.stream.app.v1.UpdatePopupAdResponse\x12T\n" + + "\rDeletePopupAd\x12#.stream.app.v1.DeletePopupAdRequest\x1a\x1e.stream.app.v1.MessageResponse\x12c\n" + + "\x10GetActivePopupAd\x12&.stream.app.v1.GetActivePopupAdRequest\x1a'.stream.app.v1.GetActivePopupAdResponse2\xad\x03\n" + "\rPlayerConfigs\x12f\n" + "\x11ListPlayerConfigs\x12'.stream.app.v1.ListPlayerConfigsRequest\x1a(.stream.app.v1.ListPlayerConfigsResponse\x12i\n" + "\x12CreatePlayerConfig\x12(.stream.app.v1.CreatePlayerConfigRequest\x1a).stream.app.v1.CreatePlayerConfigResponse\x12i\n" + @@ -1365,7 +1900,7 @@ func file_app_v1_catalog_proto_rawDescGZIP() []byte { return file_app_v1_catalog_proto_rawDescData } -var file_app_v1_catalog_proto_msgTypes = make([]protoimpl.MessageInfo, 21) +var file_app_v1_catalog_proto_msgTypes = make([]protoimpl.MessageInfo, 30) var file_app_v1_catalog_proto_goTypes = []any{ (*ListDomainsRequest)(nil), // 0: stream.app.v1.ListDomainsRequest (*ListDomainsResponse)(nil), // 1: stream.app.v1.ListDomainsResponse @@ -1379,60 +1914,84 @@ var file_app_v1_catalog_proto_goTypes = []any{ (*UpdateAdTemplateRequest)(nil), // 9: stream.app.v1.UpdateAdTemplateRequest (*UpdateAdTemplateResponse)(nil), // 10: stream.app.v1.UpdateAdTemplateResponse (*DeleteAdTemplateRequest)(nil), // 11: stream.app.v1.DeleteAdTemplateRequest - (*ListPlayerConfigsRequest)(nil), // 12: stream.app.v1.ListPlayerConfigsRequest - (*ListPlayerConfigsResponse)(nil), // 13: stream.app.v1.ListPlayerConfigsResponse - (*CreatePlayerConfigRequest)(nil), // 14: stream.app.v1.CreatePlayerConfigRequest - (*CreatePlayerConfigResponse)(nil), // 15: stream.app.v1.CreatePlayerConfigResponse - (*UpdatePlayerConfigRequest)(nil), // 16: stream.app.v1.UpdatePlayerConfigRequest - (*UpdatePlayerConfigResponse)(nil), // 17: stream.app.v1.UpdatePlayerConfigResponse - (*DeletePlayerConfigRequest)(nil), // 18: stream.app.v1.DeletePlayerConfigRequest - (*ListPlansRequest)(nil), // 19: stream.app.v1.ListPlansRequest - (*ListPlansResponse)(nil), // 20: stream.app.v1.ListPlansResponse - (*Domain)(nil), // 21: stream.app.v1.Domain - (*AdTemplate)(nil), // 22: stream.app.v1.AdTemplate - (*PlayerConfig)(nil), // 23: stream.app.v1.PlayerConfig - (*Plan)(nil), // 24: stream.app.v1.Plan - (*MessageResponse)(nil), // 25: stream.app.v1.MessageResponse + (*ListPopupAdsRequest)(nil), // 12: stream.app.v1.ListPopupAdsRequest + (*ListPopupAdsResponse)(nil), // 13: stream.app.v1.ListPopupAdsResponse + (*CreatePopupAdRequest)(nil), // 14: stream.app.v1.CreatePopupAdRequest + (*CreatePopupAdResponse)(nil), // 15: stream.app.v1.CreatePopupAdResponse + (*UpdatePopupAdRequest)(nil), // 16: stream.app.v1.UpdatePopupAdRequest + (*UpdatePopupAdResponse)(nil), // 17: stream.app.v1.UpdatePopupAdResponse + (*DeletePopupAdRequest)(nil), // 18: stream.app.v1.DeletePopupAdRequest + (*GetActivePopupAdRequest)(nil), // 19: stream.app.v1.GetActivePopupAdRequest + (*GetActivePopupAdResponse)(nil), // 20: stream.app.v1.GetActivePopupAdResponse + (*ListPlayerConfigsRequest)(nil), // 21: stream.app.v1.ListPlayerConfigsRequest + (*ListPlayerConfigsResponse)(nil), // 22: stream.app.v1.ListPlayerConfigsResponse + (*CreatePlayerConfigRequest)(nil), // 23: stream.app.v1.CreatePlayerConfigRequest + (*CreatePlayerConfigResponse)(nil), // 24: stream.app.v1.CreatePlayerConfigResponse + (*UpdatePlayerConfigRequest)(nil), // 25: stream.app.v1.UpdatePlayerConfigRequest + (*UpdatePlayerConfigResponse)(nil), // 26: stream.app.v1.UpdatePlayerConfigResponse + (*DeletePlayerConfigRequest)(nil), // 27: stream.app.v1.DeletePlayerConfigRequest + (*ListPlansRequest)(nil), // 28: stream.app.v1.ListPlansRequest + (*ListPlansResponse)(nil), // 29: stream.app.v1.ListPlansResponse + (*Domain)(nil), // 30: stream.app.v1.Domain + (*AdTemplate)(nil), // 31: stream.app.v1.AdTemplate + (*PopupAd)(nil), // 32: stream.app.v1.PopupAd + (*PlayerConfig)(nil), // 33: stream.app.v1.PlayerConfig + (*Plan)(nil), // 34: stream.app.v1.Plan + (*MessageResponse)(nil), // 35: stream.app.v1.MessageResponse } var file_app_v1_catalog_proto_depIdxs = []int32{ - 21, // 0: stream.app.v1.ListDomainsResponse.domains:type_name -> stream.app.v1.Domain - 21, // 1: stream.app.v1.CreateDomainResponse.domain:type_name -> stream.app.v1.Domain - 22, // 2: stream.app.v1.ListAdTemplatesResponse.templates:type_name -> stream.app.v1.AdTemplate - 22, // 3: stream.app.v1.CreateAdTemplateResponse.template:type_name -> stream.app.v1.AdTemplate - 22, // 4: stream.app.v1.UpdateAdTemplateResponse.template:type_name -> stream.app.v1.AdTemplate - 23, // 5: stream.app.v1.ListPlayerConfigsResponse.configs:type_name -> stream.app.v1.PlayerConfig - 23, // 6: stream.app.v1.CreatePlayerConfigResponse.config:type_name -> stream.app.v1.PlayerConfig - 23, // 7: stream.app.v1.UpdatePlayerConfigResponse.config:type_name -> stream.app.v1.PlayerConfig - 24, // 8: stream.app.v1.ListPlansResponse.plans:type_name -> stream.app.v1.Plan - 0, // 9: stream.app.v1.Domains.ListDomains:input_type -> stream.app.v1.ListDomainsRequest - 2, // 10: stream.app.v1.Domains.CreateDomain:input_type -> stream.app.v1.CreateDomainRequest - 4, // 11: stream.app.v1.Domains.DeleteDomain:input_type -> stream.app.v1.DeleteDomainRequest - 5, // 12: stream.app.v1.AdTemplates.ListAdTemplates:input_type -> stream.app.v1.ListAdTemplatesRequest - 7, // 13: stream.app.v1.AdTemplates.CreateAdTemplate:input_type -> stream.app.v1.CreateAdTemplateRequest - 9, // 14: stream.app.v1.AdTemplates.UpdateAdTemplate:input_type -> stream.app.v1.UpdateAdTemplateRequest - 11, // 15: stream.app.v1.AdTemplates.DeleteAdTemplate:input_type -> stream.app.v1.DeleteAdTemplateRequest - 12, // 16: stream.app.v1.PlayerConfigs.ListPlayerConfigs:input_type -> stream.app.v1.ListPlayerConfigsRequest - 14, // 17: stream.app.v1.PlayerConfigs.CreatePlayerConfig:input_type -> stream.app.v1.CreatePlayerConfigRequest - 16, // 18: stream.app.v1.PlayerConfigs.UpdatePlayerConfig:input_type -> stream.app.v1.UpdatePlayerConfigRequest - 18, // 19: stream.app.v1.PlayerConfigs.DeletePlayerConfig:input_type -> stream.app.v1.DeletePlayerConfigRequest - 19, // 20: stream.app.v1.Plans.ListPlans:input_type -> stream.app.v1.ListPlansRequest - 1, // 21: stream.app.v1.Domains.ListDomains:output_type -> stream.app.v1.ListDomainsResponse - 3, // 22: stream.app.v1.Domains.CreateDomain:output_type -> stream.app.v1.CreateDomainResponse - 25, // 23: stream.app.v1.Domains.DeleteDomain:output_type -> stream.app.v1.MessageResponse - 6, // 24: stream.app.v1.AdTemplates.ListAdTemplates:output_type -> stream.app.v1.ListAdTemplatesResponse - 8, // 25: stream.app.v1.AdTemplates.CreateAdTemplate:output_type -> stream.app.v1.CreateAdTemplateResponse - 10, // 26: stream.app.v1.AdTemplates.UpdateAdTemplate:output_type -> stream.app.v1.UpdateAdTemplateResponse - 25, // 27: stream.app.v1.AdTemplates.DeleteAdTemplate:output_type -> stream.app.v1.MessageResponse - 13, // 28: stream.app.v1.PlayerConfigs.ListPlayerConfigs:output_type -> stream.app.v1.ListPlayerConfigsResponse - 15, // 29: stream.app.v1.PlayerConfigs.CreatePlayerConfig:output_type -> stream.app.v1.CreatePlayerConfigResponse - 17, // 30: stream.app.v1.PlayerConfigs.UpdatePlayerConfig:output_type -> stream.app.v1.UpdatePlayerConfigResponse - 25, // 31: stream.app.v1.PlayerConfigs.DeletePlayerConfig:output_type -> stream.app.v1.MessageResponse - 20, // 32: stream.app.v1.Plans.ListPlans:output_type -> stream.app.v1.ListPlansResponse - 21, // [21:33] is the sub-list for method output_type - 9, // [9:21] is the sub-list for method input_type - 9, // [9:9] is the sub-list for extension type_name - 9, // [9:9] is the sub-list for extension extendee - 0, // [0:9] is the sub-list for field type_name + 30, // 0: stream.app.v1.ListDomainsResponse.domains:type_name -> stream.app.v1.Domain + 30, // 1: stream.app.v1.CreateDomainResponse.domain:type_name -> stream.app.v1.Domain + 31, // 2: stream.app.v1.ListAdTemplatesResponse.templates:type_name -> stream.app.v1.AdTemplate + 31, // 3: stream.app.v1.CreateAdTemplateResponse.template:type_name -> stream.app.v1.AdTemplate + 31, // 4: stream.app.v1.UpdateAdTemplateResponse.template:type_name -> stream.app.v1.AdTemplate + 32, // 5: stream.app.v1.ListPopupAdsResponse.items:type_name -> stream.app.v1.PopupAd + 32, // 6: stream.app.v1.CreatePopupAdResponse.item:type_name -> stream.app.v1.PopupAd + 32, // 7: stream.app.v1.UpdatePopupAdResponse.item:type_name -> stream.app.v1.PopupAd + 32, // 8: stream.app.v1.GetActivePopupAdResponse.item:type_name -> stream.app.v1.PopupAd + 33, // 9: stream.app.v1.ListPlayerConfigsResponse.configs:type_name -> stream.app.v1.PlayerConfig + 33, // 10: stream.app.v1.CreatePlayerConfigResponse.config:type_name -> stream.app.v1.PlayerConfig + 33, // 11: stream.app.v1.UpdatePlayerConfigResponse.config:type_name -> stream.app.v1.PlayerConfig + 34, // 12: stream.app.v1.ListPlansResponse.plans:type_name -> stream.app.v1.Plan + 0, // 13: stream.app.v1.Domains.ListDomains:input_type -> stream.app.v1.ListDomainsRequest + 2, // 14: stream.app.v1.Domains.CreateDomain:input_type -> stream.app.v1.CreateDomainRequest + 4, // 15: stream.app.v1.Domains.DeleteDomain:input_type -> stream.app.v1.DeleteDomainRequest + 5, // 16: stream.app.v1.AdTemplates.ListAdTemplates:input_type -> stream.app.v1.ListAdTemplatesRequest + 7, // 17: stream.app.v1.AdTemplates.CreateAdTemplate:input_type -> stream.app.v1.CreateAdTemplateRequest + 9, // 18: stream.app.v1.AdTemplates.UpdateAdTemplate:input_type -> stream.app.v1.UpdateAdTemplateRequest + 11, // 19: stream.app.v1.AdTemplates.DeleteAdTemplate:input_type -> stream.app.v1.DeleteAdTemplateRequest + 12, // 20: stream.app.v1.PopupAds.ListPopupAds:input_type -> stream.app.v1.ListPopupAdsRequest + 14, // 21: stream.app.v1.PopupAds.CreatePopupAd:input_type -> stream.app.v1.CreatePopupAdRequest + 16, // 22: stream.app.v1.PopupAds.UpdatePopupAd:input_type -> stream.app.v1.UpdatePopupAdRequest + 18, // 23: stream.app.v1.PopupAds.DeletePopupAd:input_type -> stream.app.v1.DeletePopupAdRequest + 19, // 24: stream.app.v1.PopupAds.GetActivePopupAd:input_type -> stream.app.v1.GetActivePopupAdRequest + 21, // 25: stream.app.v1.PlayerConfigs.ListPlayerConfigs:input_type -> stream.app.v1.ListPlayerConfigsRequest + 23, // 26: stream.app.v1.PlayerConfigs.CreatePlayerConfig:input_type -> stream.app.v1.CreatePlayerConfigRequest + 25, // 27: stream.app.v1.PlayerConfigs.UpdatePlayerConfig:input_type -> stream.app.v1.UpdatePlayerConfigRequest + 27, // 28: stream.app.v1.PlayerConfigs.DeletePlayerConfig:input_type -> stream.app.v1.DeletePlayerConfigRequest + 28, // 29: stream.app.v1.Plans.ListPlans:input_type -> stream.app.v1.ListPlansRequest + 1, // 30: stream.app.v1.Domains.ListDomains:output_type -> stream.app.v1.ListDomainsResponse + 3, // 31: stream.app.v1.Domains.CreateDomain:output_type -> stream.app.v1.CreateDomainResponse + 35, // 32: stream.app.v1.Domains.DeleteDomain:output_type -> stream.app.v1.MessageResponse + 6, // 33: stream.app.v1.AdTemplates.ListAdTemplates:output_type -> stream.app.v1.ListAdTemplatesResponse + 8, // 34: stream.app.v1.AdTemplates.CreateAdTemplate:output_type -> stream.app.v1.CreateAdTemplateResponse + 10, // 35: stream.app.v1.AdTemplates.UpdateAdTemplate:output_type -> stream.app.v1.UpdateAdTemplateResponse + 35, // 36: stream.app.v1.AdTemplates.DeleteAdTemplate:output_type -> stream.app.v1.MessageResponse + 13, // 37: stream.app.v1.PopupAds.ListPopupAds:output_type -> stream.app.v1.ListPopupAdsResponse + 15, // 38: stream.app.v1.PopupAds.CreatePopupAd:output_type -> stream.app.v1.CreatePopupAdResponse + 17, // 39: stream.app.v1.PopupAds.UpdatePopupAd:output_type -> stream.app.v1.UpdatePopupAdResponse + 35, // 40: stream.app.v1.PopupAds.DeletePopupAd:output_type -> stream.app.v1.MessageResponse + 20, // 41: stream.app.v1.PopupAds.GetActivePopupAd:output_type -> stream.app.v1.GetActivePopupAdResponse + 22, // 42: stream.app.v1.PlayerConfigs.ListPlayerConfigs:output_type -> stream.app.v1.ListPlayerConfigsResponse + 24, // 43: stream.app.v1.PlayerConfigs.CreatePlayerConfig:output_type -> stream.app.v1.CreatePlayerConfigResponse + 26, // 44: stream.app.v1.PlayerConfigs.UpdatePlayerConfig:output_type -> stream.app.v1.UpdatePlayerConfigResponse + 35, // 45: stream.app.v1.PlayerConfigs.DeletePlayerConfig:output_type -> stream.app.v1.MessageResponse + 29, // 46: stream.app.v1.Plans.ListPlans:output_type -> stream.app.v1.ListPlansResponse + 30, // [30:47] is the sub-list for method output_type + 13, // [13:30] is the sub-list for method input_type + 13, // [13:13] is the sub-list for extension type_name + 13, // [13:13] is the sub-list for extension extendee + 0, // [0:13] is the sub-list for field type_name } func init() { file_app_v1_catalog_proto_init() } @@ -1445,15 +2004,18 @@ func file_app_v1_catalog_proto_init() { file_app_v1_catalog_proto_msgTypes[9].OneofWrappers = []any{} file_app_v1_catalog_proto_msgTypes[14].OneofWrappers = []any{} file_app_v1_catalog_proto_msgTypes[16].OneofWrappers = []any{} + file_app_v1_catalog_proto_msgTypes[20].OneofWrappers = []any{} + file_app_v1_catalog_proto_msgTypes[23].OneofWrappers = []any{} + file_app_v1_catalog_proto_msgTypes[25].OneofWrappers = []any{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_app_v1_catalog_proto_rawDesc), len(file_app_v1_catalog_proto_rawDesc)), NumEnums: 0, - NumMessages: 21, + NumMessages: 30, NumExtensions: 0, - NumServices: 4, + NumServices: 5, }, GoTypes: file_app_v1_catalog_proto_goTypes, DependencyIndexes: file_app_v1_catalog_proto_depIdxs, diff --git a/internal/api/proto/app/v1/catalog_grpc.pb.go b/internal/api/proto/app/v1/catalog_grpc.pb.go index fca27ca..efcdd41 100644 --- a/internal/api/proto/app/v1/catalog_grpc.pb.go +++ b/internal/api/proto/app/v1/catalog_grpc.pb.go @@ -412,6 +412,260 @@ var AdTemplates_ServiceDesc = grpc.ServiceDesc{ Metadata: "app/v1/catalog.proto", } +const ( + PopupAds_ListPopupAds_FullMethodName = "/stream.app.v1.PopupAds/ListPopupAds" + PopupAds_CreatePopupAd_FullMethodName = "/stream.app.v1.PopupAds/CreatePopupAd" + PopupAds_UpdatePopupAd_FullMethodName = "/stream.app.v1.PopupAds/UpdatePopupAd" + PopupAds_DeletePopupAd_FullMethodName = "/stream.app.v1.PopupAds/DeletePopupAd" + PopupAds_GetActivePopupAd_FullMethodName = "/stream.app.v1.PopupAds/GetActivePopupAd" +) + +// PopupAdsClient is the client API for PopupAds service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type PopupAdsClient interface { + ListPopupAds(ctx context.Context, in *ListPopupAdsRequest, opts ...grpc.CallOption) (*ListPopupAdsResponse, error) + CreatePopupAd(ctx context.Context, in *CreatePopupAdRequest, opts ...grpc.CallOption) (*CreatePopupAdResponse, error) + UpdatePopupAd(ctx context.Context, in *UpdatePopupAdRequest, opts ...grpc.CallOption) (*UpdatePopupAdResponse, error) + DeletePopupAd(ctx context.Context, in *DeletePopupAdRequest, opts ...grpc.CallOption) (*MessageResponse, error) + GetActivePopupAd(ctx context.Context, in *GetActivePopupAdRequest, opts ...grpc.CallOption) (*GetActivePopupAdResponse, error) +} + +type popupAdsClient struct { + cc grpc.ClientConnInterface +} + +func NewPopupAdsClient(cc grpc.ClientConnInterface) PopupAdsClient { + return &popupAdsClient{cc} +} + +func (c *popupAdsClient) ListPopupAds(ctx context.Context, in *ListPopupAdsRequest, opts ...grpc.CallOption) (*ListPopupAdsResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ListPopupAdsResponse) + err := c.cc.Invoke(ctx, PopupAds_ListPopupAds_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *popupAdsClient) CreatePopupAd(ctx context.Context, in *CreatePopupAdRequest, opts ...grpc.CallOption) (*CreatePopupAdResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(CreatePopupAdResponse) + err := c.cc.Invoke(ctx, PopupAds_CreatePopupAd_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *popupAdsClient) UpdatePopupAd(ctx context.Context, in *UpdatePopupAdRequest, opts ...grpc.CallOption) (*UpdatePopupAdResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(UpdatePopupAdResponse) + err := c.cc.Invoke(ctx, PopupAds_UpdatePopupAd_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *popupAdsClient) DeletePopupAd(ctx context.Context, in *DeletePopupAdRequest, opts ...grpc.CallOption) (*MessageResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(MessageResponse) + err := c.cc.Invoke(ctx, PopupAds_DeletePopupAd_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *popupAdsClient) GetActivePopupAd(ctx context.Context, in *GetActivePopupAdRequest, opts ...grpc.CallOption) (*GetActivePopupAdResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(GetActivePopupAdResponse) + err := c.cc.Invoke(ctx, PopupAds_GetActivePopupAd_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +// PopupAdsServer is the server API for PopupAds service. +// All implementations must embed UnimplementedPopupAdsServer +// for forward compatibility. +type PopupAdsServer interface { + ListPopupAds(context.Context, *ListPopupAdsRequest) (*ListPopupAdsResponse, error) + CreatePopupAd(context.Context, *CreatePopupAdRequest) (*CreatePopupAdResponse, error) + UpdatePopupAd(context.Context, *UpdatePopupAdRequest) (*UpdatePopupAdResponse, error) + DeletePopupAd(context.Context, *DeletePopupAdRequest) (*MessageResponse, error) + GetActivePopupAd(context.Context, *GetActivePopupAdRequest) (*GetActivePopupAdResponse, error) + mustEmbedUnimplementedPopupAdsServer() +} + +// UnimplementedPopupAdsServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedPopupAdsServer struct{} + +func (UnimplementedPopupAdsServer) ListPopupAds(context.Context, *ListPopupAdsRequest) (*ListPopupAdsResponse, error) { + return nil, status.Error(codes.Unimplemented, "method ListPopupAds not implemented") +} +func (UnimplementedPopupAdsServer) CreatePopupAd(context.Context, *CreatePopupAdRequest) (*CreatePopupAdResponse, error) { + return nil, status.Error(codes.Unimplemented, "method CreatePopupAd not implemented") +} +func (UnimplementedPopupAdsServer) UpdatePopupAd(context.Context, *UpdatePopupAdRequest) (*UpdatePopupAdResponse, error) { + return nil, status.Error(codes.Unimplemented, "method UpdatePopupAd not implemented") +} +func (UnimplementedPopupAdsServer) DeletePopupAd(context.Context, *DeletePopupAdRequest) (*MessageResponse, error) { + return nil, status.Error(codes.Unimplemented, "method DeletePopupAd not implemented") +} +func (UnimplementedPopupAdsServer) GetActivePopupAd(context.Context, *GetActivePopupAdRequest) (*GetActivePopupAdResponse, error) { + return nil, status.Error(codes.Unimplemented, "method GetActivePopupAd not implemented") +} +func (UnimplementedPopupAdsServer) mustEmbedUnimplementedPopupAdsServer() {} +func (UnimplementedPopupAdsServer) testEmbeddedByValue() {} + +// UnsafePopupAdsServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to PopupAdsServer will +// result in compilation errors. +type UnsafePopupAdsServer interface { + mustEmbedUnimplementedPopupAdsServer() +} + +func RegisterPopupAdsServer(s grpc.ServiceRegistrar, srv PopupAdsServer) { + // If the following call panics, it indicates UnimplementedPopupAdsServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } + s.RegisterService(&PopupAds_ServiceDesc, srv) +} + +func _PopupAds_ListPopupAds_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListPopupAdsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PopupAdsServer).ListPopupAds(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: PopupAds_ListPopupAds_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PopupAdsServer).ListPopupAds(ctx, req.(*ListPopupAdsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _PopupAds_CreatePopupAd_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreatePopupAdRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PopupAdsServer).CreatePopupAd(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: PopupAds_CreatePopupAd_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PopupAdsServer).CreatePopupAd(ctx, req.(*CreatePopupAdRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _PopupAds_UpdatePopupAd_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdatePopupAdRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PopupAdsServer).UpdatePopupAd(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: PopupAds_UpdatePopupAd_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PopupAdsServer).UpdatePopupAd(ctx, req.(*UpdatePopupAdRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _PopupAds_DeletePopupAd_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeletePopupAdRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PopupAdsServer).DeletePopupAd(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: PopupAds_DeletePopupAd_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PopupAdsServer).DeletePopupAd(ctx, req.(*DeletePopupAdRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _PopupAds_GetActivePopupAd_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetActivePopupAdRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PopupAdsServer).GetActivePopupAd(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: PopupAds_GetActivePopupAd_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PopupAdsServer).GetActivePopupAd(ctx, req.(*GetActivePopupAdRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// PopupAds_ServiceDesc is the grpc.ServiceDesc for PopupAds service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var PopupAds_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "stream.app.v1.PopupAds", + HandlerType: (*PopupAdsServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "ListPopupAds", + Handler: _PopupAds_ListPopupAds_Handler, + }, + { + MethodName: "CreatePopupAd", + Handler: _PopupAds_CreatePopupAd_Handler, + }, + { + MethodName: "UpdatePopupAd", + Handler: _PopupAds_UpdatePopupAd_Handler, + }, + { + MethodName: "DeletePopupAd", + Handler: _PopupAds_DeletePopupAd_Handler, + }, + { + MethodName: "GetActivePopupAd", + Handler: _PopupAds_GetActivePopupAd_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "app/v1/catalog.proto", +} + const ( PlayerConfigs_ListPlayerConfigs_FullMethodName = "/stream.app.v1.PlayerConfigs/ListPlayerConfigs" PlayerConfigs_CreatePlayerConfig_FullMethodName = "/stream.app.v1.PlayerConfigs/CreatePlayerConfig" diff --git a/internal/api/proto/app/v1/common.pb.go b/internal/api/proto/app/v1/common.pb.go index 684ee67..b14c454 100644 --- a/internal/api/proto/app/v1/common.pb.go +++ b/internal/api/proto/app/v1/common.pb.go @@ -678,6 +678,106 @@ func (x *AdTemplate) GetUpdatedAt() *timestamppb.Timestamp { return nil } +type PopupAd struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"` + Label string `protobuf:"bytes,3,opt,name=label,proto3" json:"label,omitempty"` + Value string `protobuf:"bytes,4,opt,name=value,proto3" json:"value,omitempty"` + IsActive bool `protobuf:"varint,5,opt,name=is_active,json=isActive,proto3" json:"is_active,omitempty"` + MaxTriggersPerSession int32 `protobuf:"varint,6,opt,name=max_triggers_per_session,json=maxTriggersPerSession,proto3" json:"max_triggers_per_session,omitempty"` + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,8,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *PopupAd) Reset() { + *x = PopupAd{} + mi := &file_app_v1_common_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PopupAd) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PopupAd) ProtoMessage() {} + +func (x *PopupAd) ProtoReflect() protoreflect.Message { + mi := &file_app_v1_common_proto_msgTypes[6] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PopupAd.ProtoReflect.Descriptor instead. +func (*PopupAd) Descriptor() ([]byte, []int) { + return file_app_v1_common_proto_rawDescGZIP(), []int{6} +} + +func (x *PopupAd) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *PopupAd) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *PopupAd) GetLabel() string { + if x != nil { + return x.Label + } + return "" +} + +func (x *PopupAd) GetValue() string { + if x != nil { + return x.Value + } + return "" +} + +func (x *PopupAd) GetIsActive() bool { + if x != nil { + return x.IsActive + } + return false +} + +func (x *PopupAd) GetMaxTriggersPerSession() int32 { + if x != nil { + return x.MaxTriggersPerSession + } + return 0 +} + +func (x *PopupAd) GetCreatedAt() *timestamppb.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + +func (x *PopupAd) GetUpdatedAt() *timestamppb.Timestamp { + if x != nil { + return x.UpdatedAt + } + return nil +} + type PlayerConfig struct { state protoimpl.MessageState `protogen:"open.v1"` Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` @@ -702,7 +802,7 @@ type PlayerConfig struct { func (x *PlayerConfig) Reset() { *x = PlayerConfig{} - mi := &file_app_v1_common_proto_msgTypes[6] + mi := &file_app_v1_common_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -714,7 +814,7 @@ func (x *PlayerConfig) String() string { func (*PlayerConfig) ProtoMessage() {} func (x *PlayerConfig) ProtoReflect() protoreflect.Message { - mi := &file_app_v1_common_proto_msgTypes[6] + mi := &file_app_v1_common_proto_msgTypes[7] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -727,7 +827,7 @@ func (x *PlayerConfig) ProtoReflect() protoreflect.Message { // Deprecated: Use PlayerConfig.ProtoReflect.Descriptor instead. func (*PlayerConfig) Descriptor() ([]byte, []int) { - return file_app_v1_common_proto_rawDescGZIP(), []int{6} + return file_app_v1_common_proto_rawDescGZIP(), []int{7} } func (x *PlayerConfig) GetId() string { @@ -868,7 +968,7 @@ type AdminPlayerConfig struct { func (x *AdminPlayerConfig) Reset() { *x = AdminPlayerConfig{} - mi := &file_app_v1_common_proto_msgTypes[7] + mi := &file_app_v1_common_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -880,7 +980,7 @@ func (x *AdminPlayerConfig) String() string { func (*AdminPlayerConfig) ProtoMessage() {} func (x *AdminPlayerConfig) ProtoReflect() protoreflect.Message { - mi := &file_app_v1_common_proto_msgTypes[7] + mi := &file_app_v1_common_proto_msgTypes[8] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -893,7 +993,7 @@ func (x *AdminPlayerConfig) ProtoReflect() protoreflect.Message { // Deprecated: Use AdminPlayerConfig.ProtoReflect.Descriptor instead. func (*AdminPlayerConfig) Descriptor() ([]byte, []int) { - return file_app_v1_common_proto_rawDescGZIP(), []int{7} + return file_app_v1_common_proto_rawDescGZIP(), []int{8} } func (x *AdminPlayerConfig) GetId() string { @@ -1041,7 +1141,7 @@ type Plan struct { func (x *Plan) Reset() { *x = Plan{} - mi := &file_app_v1_common_proto_msgTypes[8] + mi := &file_app_v1_common_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1053,7 +1153,7 @@ func (x *Plan) String() string { func (*Plan) ProtoMessage() {} func (x *Plan) ProtoReflect() protoreflect.Message { - mi := &file_app_v1_common_proto_msgTypes[8] + mi := &file_app_v1_common_proto_msgTypes[9] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1066,7 +1166,7 @@ func (x *Plan) ProtoReflect() protoreflect.Message { // Deprecated: Use Plan.ProtoReflect.Descriptor instead. func (*Plan) Descriptor() ([]byte, []int) { - return file_app_v1_common_proto_rawDescGZIP(), []int{8} + return file_app_v1_common_proto_rawDescGZIP(), []int{9} } func (x *Plan) GetId() string { @@ -1164,7 +1264,7 @@ type Payment struct { func (x *Payment) Reset() { *x = Payment{} - mi := &file_app_v1_common_proto_msgTypes[9] + mi := &file_app_v1_common_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1176,7 +1276,7 @@ func (x *Payment) String() string { func (*Payment) ProtoMessage() {} func (x *Payment) ProtoReflect() protoreflect.Message { - mi := &file_app_v1_common_proto_msgTypes[9] + mi := &file_app_v1_common_proto_msgTypes[10] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1189,7 +1289,7 @@ func (x *Payment) ProtoReflect() protoreflect.Message { // Deprecated: Use Payment.ProtoReflect.Descriptor instead. func (*Payment) Descriptor() ([]byte, []int) { - return file_app_v1_common_proto_rawDescGZIP(), []int{9} + return file_app_v1_common_proto_rawDescGZIP(), []int{10} } func (x *Payment) GetId() string { @@ -1282,7 +1382,7 @@ type PlanSubscription struct { func (x *PlanSubscription) Reset() { *x = PlanSubscription{} - mi := &file_app_v1_common_proto_msgTypes[10] + mi := &file_app_v1_common_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1294,7 +1394,7 @@ func (x *PlanSubscription) String() string { func (*PlanSubscription) ProtoMessage() {} func (x *PlanSubscription) ProtoReflect() protoreflect.Message { - mi := &file_app_v1_common_proto_msgTypes[10] + mi := &file_app_v1_common_proto_msgTypes[11] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1307,7 +1407,7 @@ func (x *PlanSubscription) ProtoReflect() protoreflect.Message { // Deprecated: Use PlanSubscription.ProtoReflect.Descriptor instead. func (*PlanSubscription) Descriptor() ([]byte, []int) { - return file_app_v1_common_proto_rawDescGZIP(), []int{10} + return file_app_v1_common_proto_rawDescGZIP(), []int{11} } func (x *PlanSubscription) GetId() string { @@ -1413,7 +1513,7 @@ type WalletTransaction struct { func (x *WalletTransaction) Reset() { *x = WalletTransaction{} - mi := &file_app_v1_common_proto_msgTypes[11] + mi := &file_app_v1_common_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1425,7 +1525,7 @@ func (x *WalletTransaction) String() string { func (*WalletTransaction) ProtoMessage() {} func (x *WalletTransaction) ProtoReflect() protoreflect.Message { - mi := &file_app_v1_common_proto_msgTypes[11] + mi := &file_app_v1_common_proto_msgTypes[12] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1438,7 +1538,7 @@ func (x *WalletTransaction) ProtoReflect() protoreflect.Message { // Deprecated: Use WalletTransaction.ProtoReflect.Descriptor instead. func (*WalletTransaction) Descriptor() ([]byte, []int) { - return file_app_v1_common_proto_rawDescGZIP(), []int{11} + return file_app_v1_common_proto_rawDescGZIP(), []int{12} } func (x *WalletTransaction) GetId() string { @@ -1538,7 +1638,7 @@ type PaymentHistoryItem struct { func (x *PaymentHistoryItem) Reset() { *x = PaymentHistoryItem{} - mi := &file_app_v1_common_proto_msgTypes[12] + mi := &file_app_v1_common_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1550,7 +1650,7 @@ func (x *PaymentHistoryItem) String() string { func (*PaymentHistoryItem) ProtoMessage() {} func (x *PaymentHistoryItem) ProtoReflect() protoreflect.Message { - mi := &file_app_v1_common_proto_msgTypes[12] + mi := &file_app_v1_common_proto_msgTypes[13] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1563,7 +1663,7 @@ func (x *PaymentHistoryItem) ProtoReflect() protoreflect.Message { // Deprecated: Use PaymentHistoryItem.ProtoReflect.Descriptor instead. func (*PaymentHistoryItem) Descriptor() ([]byte, []int) { - return file_app_v1_common_proto_rawDescGZIP(), []int{12} + return file_app_v1_common_proto_rawDescGZIP(), []int{13} } func (x *PaymentHistoryItem) GetId() string { @@ -1673,7 +1773,7 @@ type Video struct { func (x *Video) Reset() { *x = Video{} - mi := &file_app_v1_common_proto_msgTypes[13] + mi := &file_app_v1_common_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1685,7 +1785,7 @@ func (x *Video) String() string { func (*Video) ProtoMessage() {} func (x *Video) ProtoReflect() protoreflect.Message { - mi := &file_app_v1_common_proto_msgTypes[13] + mi := &file_app_v1_common_proto_msgTypes[14] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1698,7 +1798,7 @@ func (x *Video) ProtoReflect() protoreflect.Message { // Deprecated: Use Video.ProtoReflect.Descriptor instead. func (*Video) Descriptor() ([]byte, []int) { - return file_app_v1_common_proto_rawDescGZIP(), []int{13} + return file_app_v1_common_proto_rawDescGZIP(), []int{14} } func (x *Video) GetId() string { @@ -1823,7 +1923,7 @@ type AdminDashboard struct { func (x *AdminDashboard) Reset() { *x = AdminDashboard{} - mi := &file_app_v1_common_proto_msgTypes[14] + mi := &file_app_v1_common_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1835,7 +1935,7 @@ func (x *AdminDashboard) String() string { func (*AdminDashboard) ProtoMessage() {} func (x *AdminDashboard) ProtoReflect() protoreflect.Message { - mi := &file_app_v1_common_proto_msgTypes[14] + mi := &file_app_v1_common_proto_msgTypes[15] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1848,7 +1948,7 @@ func (x *AdminDashboard) ProtoReflect() protoreflect.Message { // Deprecated: Use AdminDashboard.ProtoReflect.Descriptor instead. func (*AdminDashboard) Descriptor() ([]byte, []int) { - return file_app_v1_common_proto_rawDescGZIP(), []int{14} + return file_app_v1_common_proto_rawDescGZIP(), []int{15} } func (x *AdminDashboard) GetTotalUsers() int64 { @@ -1934,7 +2034,7 @@ type AdminUser struct { func (x *AdminUser) Reset() { *x = AdminUser{} - mi := &file_app_v1_common_proto_msgTypes[15] + mi := &file_app_v1_common_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1946,7 +2046,7 @@ func (x *AdminUser) String() string { func (*AdminUser) ProtoMessage() {} func (x *AdminUser) ProtoReflect() protoreflect.Message { - mi := &file_app_v1_common_proto_msgTypes[15] + mi := &file_app_v1_common_proto_msgTypes[16] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1959,7 +2059,7 @@ func (x *AdminUser) ProtoReflect() protoreflect.Message { // Deprecated: Use AdminUser.ProtoReflect.Descriptor instead. func (*AdminUser) Descriptor() ([]byte, []int) { - return file_app_v1_common_proto_rawDescGZIP(), []int{15} + return file_app_v1_common_proto_rawDescGZIP(), []int{16} } func (x *AdminUser) GetId() string { @@ -2057,7 +2157,7 @@ type ReferralUserSummary struct { func (x *ReferralUserSummary) Reset() { *x = ReferralUserSummary{} - mi := &file_app_v1_common_proto_msgTypes[16] + mi := &file_app_v1_common_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2069,7 +2169,7 @@ func (x *ReferralUserSummary) String() string { func (*ReferralUserSummary) ProtoMessage() {} func (x *ReferralUserSummary) ProtoReflect() protoreflect.Message { - mi := &file_app_v1_common_proto_msgTypes[16] + mi := &file_app_v1_common_proto_msgTypes[17] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2082,7 +2182,7 @@ func (x *ReferralUserSummary) ProtoReflect() protoreflect.Message { // Deprecated: Use ReferralUserSummary.ProtoReflect.Descriptor instead. func (*ReferralUserSummary) Descriptor() ([]byte, []int) { - return file_app_v1_common_proto_rawDescGZIP(), []int{16} + return file_app_v1_common_proto_rawDescGZIP(), []int{17} } func (x *ReferralUserSummary) GetId() string { @@ -2123,7 +2223,7 @@ type AdminUserReferralInfo struct { func (x *AdminUserReferralInfo) Reset() { *x = AdminUserReferralInfo{} - mi := &file_app_v1_common_proto_msgTypes[17] + mi := &file_app_v1_common_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2135,7 +2235,7 @@ func (x *AdminUserReferralInfo) String() string { func (*AdminUserReferralInfo) ProtoMessage() {} func (x *AdminUserReferralInfo) ProtoReflect() protoreflect.Message { - mi := &file_app_v1_common_proto_msgTypes[17] + mi := &file_app_v1_common_proto_msgTypes[18] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2148,7 +2248,7 @@ func (x *AdminUserReferralInfo) ProtoReflect() protoreflect.Message { // Deprecated: Use AdminUserReferralInfo.ProtoReflect.Descriptor instead. func (*AdminUserReferralInfo) Descriptor() ([]byte, []int) { - return file_app_v1_common_proto_rawDescGZIP(), []int{17} + return file_app_v1_common_proto_rawDescGZIP(), []int{18} } func (x *AdminUserReferralInfo) GetReferrer() *ReferralUserSummary { @@ -2225,7 +2325,7 @@ type AdminUserDetail struct { func (x *AdminUserDetail) Reset() { *x = AdminUserDetail{} - mi := &file_app_v1_common_proto_msgTypes[18] + mi := &file_app_v1_common_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2237,7 +2337,7 @@ func (x *AdminUserDetail) String() string { func (*AdminUserDetail) ProtoMessage() {} func (x *AdminUserDetail) ProtoReflect() protoreflect.Message { - mi := &file_app_v1_common_proto_msgTypes[18] + mi := &file_app_v1_common_proto_msgTypes[19] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2250,7 +2350,7 @@ func (x *AdminUserDetail) ProtoReflect() protoreflect.Message { // Deprecated: Use AdminUserDetail.ProtoReflect.Descriptor instead. func (*AdminUserDetail) Descriptor() ([]byte, []int) { - return file_app_v1_common_proto_rawDescGZIP(), []int{18} + return file_app_v1_common_proto_rawDescGZIP(), []int{19} } func (x *AdminUserDetail) GetUser() *AdminUser { @@ -2298,7 +2398,7 @@ type AdminVideo struct { func (x *AdminVideo) Reset() { *x = AdminVideo{} - mi := &file_app_v1_common_proto_msgTypes[19] + mi := &file_app_v1_common_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2310,7 +2410,7 @@ func (x *AdminVideo) String() string { func (*AdminVideo) ProtoMessage() {} func (x *AdminVideo) ProtoReflect() protoreflect.Message { - mi := &file_app_v1_common_proto_msgTypes[19] + mi := &file_app_v1_common_proto_msgTypes[20] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2323,7 +2423,7 @@ func (x *AdminVideo) ProtoReflect() protoreflect.Message { // Deprecated: Use AdminVideo.ProtoReflect.Descriptor instead. func (*AdminVideo) Descriptor() ([]byte, []int) { - return file_app_v1_common_proto_rawDescGZIP(), []int{19} + return file_app_v1_common_proto_rawDescGZIP(), []int{20} } func (x *AdminVideo) GetId() string { @@ -2464,7 +2564,7 @@ type AdminPayment struct { func (x *AdminPayment) Reset() { *x = AdminPayment{} - mi := &file_app_v1_common_proto_msgTypes[20] + mi := &file_app_v1_common_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2476,7 +2576,7 @@ func (x *AdminPayment) String() string { func (*AdminPayment) ProtoMessage() {} func (x *AdminPayment) ProtoReflect() protoreflect.Message { - mi := &file_app_v1_common_proto_msgTypes[20] + mi := &file_app_v1_common_proto_msgTypes[21] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2489,7 +2589,7 @@ func (x *AdminPayment) ProtoReflect() protoreflect.Message { // Deprecated: Use AdminPayment.ProtoReflect.Descriptor instead. func (*AdminPayment) Descriptor() ([]byte, []int) { - return file_app_v1_common_proto_rawDescGZIP(), []int{20} + return file_app_v1_common_proto_rawDescGZIP(), []int{21} } func (x *AdminPayment) GetId() string { @@ -2640,7 +2740,7 @@ type AdminPlan struct { func (x *AdminPlan) Reset() { *x = AdminPlan{} - mi := &file_app_v1_common_proto_msgTypes[21] + mi := &file_app_v1_common_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2652,7 +2752,7 @@ func (x *AdminPlan) String() string { func (*AdminPlan) ProtoMessage() {} func (x *AdminPlan) ProtoReflect() protoreflect.Message { - mi := &file_app_v1_common_proto_msgTypes[21] + mi := &file_app_v1_common_proto_msgTypes[22] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2665,7 +2765,7 @@ func (x *AdminPlan) ProtoReflect() protoreflect.Message { // Deprecated: Use AdminPlan.ProtoReflect.Descriptor instead. func (*AdminPlan) Descriptor() ([]byte, []int) { - return file_app_v1_common_proto_rawDescGZIP(), []int{21} + return file_app_v1_common_proto_rawDescGZIP(), []int{22} } func (x *AdminPlan) GetId() string { @@ -2786,7 +2886,7 @@ type AdminAdTemplate struct { func (x *AdminAdTemplate) Reset() { *x = AdminAdTemplate{} - mi := &file_app_v1_common_proto_msgTypes[22] + mi := &file_app_v1_common_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2798,7 +2898,7 @@ func (x *AdminAdTemplate) String() string { func (*AdminAdTemplate) ProtoMessage() {} func (x *AdminAdTemplate) ProtoReflect() protoreflect.Message { - mi := &file_app_v1_common_proto_msgTypes[22] + mi := &file_app_v1_common_proto_msgTypes[23] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2811,7 +2911,7 @@ func (x *AdminAdTemplate) ProtoReflect() protoreflect.Message { // Deprecated: Use AdminAdTemplate.ProtoReflect.Descriptor instead. func (*AdminAdTemplate) Descriptor() ([]byte, []int) { - return file_app_v1_common_proto_rawDescGZIP(), []int{22} + return file_app_v1_common_proto_rawDescGZIP(), []int{23} } func (x *AdminAdTemplate) GetId() string { @@ -2898,6 +2998,122 @@ func (x *AdminAdTemplate) GetUpdatedAt() *timestamppb.Timestamp { return nil } +type AdminPopupAd struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + UserId string `protobuf:"bytes,2,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` + Type string `protobuf:"bytes,3,opt,name=type,proto3" json:"type,omitempty"` + Label string `protobuf:"bytes,4,opt,name=label,proto3" json:"label,omitempty"` + Value string `protobuf:"bytes,5,opt,name=value,proto3" json:"value,omitempty"` + IsActive bool `protobuf:"varint,6,opt,name=is_active,json=isActive,proto3" json:"is_active,omitempty"` + MaxTriggersPerSession int32 `protobuf:"varint,7,opt,name=max_triggers_per_session,json=maxTriggersPerSession,proto3" json:"max_triggers_per_session,omitempty"` + OwnerEmail *string `protobuf:"bytes,8,opt,name=owner_email,json=ownerEmail,proto3,oneof" json:"owner_email,omitempty"` + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,9,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,10,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AdminPopupAd) Reset() { + *x = AdminPopupAd{} + mi := &file_app_v1_common_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AdminPopupAd) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AdminPopupAd) ProtoMessage() {} + +func (x *AdminPopupAd) ProtoReflect() protoreflect.Message { + mi := &file_app_v1_common_proto_msgTypes[24] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AdminPopupAd.ProtoReflect.Descriptor instead. +func (*AdminPopupAd) Descriptor() ([]byte, []int) { + return file_app_v1_common_proto_rawDescGZIP(), []int{24} +} + +func (x *AdminPopupAd) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *AdminPopupAd) GetUserId() string { + if x != nil { + return x.UserId + } + return "" +} + +func (x *AdminPopupAd) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *AdminPopupAd) GetLabel() string { + if x != nil { + return x.Label + } + return "" +} + +func (x *AdminPopupAd) GetValue() string { + if x != nil { + return x.Value + } + return "" +} + +func (x *AdminPopupAd) GetIsActive() bool { + if x != nil { + return x.IsActive + } + return false +} + +func (x *AdminPopupAd) GetMaxTriggersPerSession() int32 { + if x != nil { + return x.MaxTriggersPerSession + } + return 0 +} + +func (x *AdminPopupAd) GetOwnerEmail() string { + if x != nil && x.OwnerEmail != nil { + return *x.OwnerEmail + } + return "" +} + +func (x *AdminPopupAd) GetCreatedAt() *timestamppb.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + +func (x *AdminPopupAd) GetUpdatedAt() *timestamppb.Timestamp { + if x != nil { + return x.UpdatedAt + } + return nil +} + type AdminJob struct { state protoimpl.MessageState `protogen:"open.v1"` Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` @@ -2926,7 +3142,7 @@ type AdminJob struct { func (x *AdminJob) Reset() { *x = AdminJob{} - mi := &file_app_v1_common_proto_msgTypes[23] + mi := &file_app_v1_common_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2938,7 +3154,7 @@ func (x *AdminJob) String() string { func (*AdminJob) ProtoMessage() {} func (x *AdminJob) ProtoReflect() protoreflect.Message { - mi := &file_app_v1_common_proto_msgTypes[23] + mi := &file_app_v1_common_proto_msgTypes[25] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2951,7 +3167,7 @@ func (x *AdminJob) ProtoReflect() protoreflect.Message { // Deprecated: Use AdminJob.ProtoReflect.Descriptor instead. func (*AdminJob) Descriptor() ([]byte, []int) { - return file_app_v1_common_proto_rawDescGZIP(), []int{23} + return file_app_v1_common_proto_rawDescGZIP(), []int{25} } func (x *AdminJob) GetId() string { @@ -3114,7 +3330,7 @@ type AdminAgent struct { func (x *AdminAgent) Reset() { *x = AdminAgent{} - mi := &file_app_v1_common_proto_msgTypes[24] + mi := &file_app_v1_common_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3126,7 +3342,7 @@ func (x *AdminAgent) String() string { func (*AdminAgent) ProtoMessage() {} func (x *AdminAgent) ProtoReflect() protoreflect.Message { - mi := &file_app_v1_common_proto_msgTypes[24] + mi := &file_app_v1_common_proto_msgTypes[26] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3139,7 +3355,7 @@ func (x *AdminAgent) ProtoReflect() protoreflect.Message { // Deprecated: Use AdminAgent.ProtoReflect.Descriptor instead. func (*AdminAgent) Descriptor() ([]byte, []int) { - return file_app_v1_common_proto_rawDescGZIP(), []int{24} + return file_app_v1_common_proto_rawDescGZIP(), []int{26} } func (x *AdminAgent) GetId() string { @@ -3321,7 +3537,18 @@ const file_app_v1_common_proto_rawDesc = "" + "updated_at\x18\n" + " \x01(\v2\x1a.google.protobuf.TimestampR\tupdatedAtB\x0e\n" + "\f_descriptionB\v\n" + - "\t_duration\"\xa6\x04\n" + + "\t_duration\"\xa5\x02\n" + + "\aPopupAd\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n" + + "\x04type\x18\x02 \x01(\tR\x04type\x12\x14\n" + + "\x05label\x18\x03 \x01(\tR\x05label\x12\x14\n" + + "\x05value\x18\x04 \x01(\tR\x05value\x12\x1b\n" + + "\tis_active\x18\x05 \x01(\bR\bisActive\x127\n" + + "\x18max_triggers_per_session\x18\x06 \x01(\x05R\x15maxTriggersPerSession\x129\n" + + "\n" + + "created_at\x18\a \x01(\v2\x1a.google.protobuf.TimestampR\tcreatedAt\x129\n" + + "\n" + + "updated_at\x18\b \x01(\v2\x1a.google.protobuf.TimestampR\tupdatedAt\"\xa6\x04\n" + "\fPlayerConfig\x12\x0e\n" + "\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n" + "\x04name\x18\x02 \x01(\tR\x04name\x12%\n" + @@ -3664,6 +3891,22 @@ const file_app_v1_common_proto_rawDesc = "" + "updated_at\x18\f \x01(\v2\x1a.google.protobuf.TimestampR\tupdatedAtB\x0e\n" + "\f_descriptionB\v\n" + "\t_durationB\x0e\n" + + "\f_owner_email\"\xf9\x02\n" + + "\fAdminPopupAd\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12\x17\n" + + "\auser_id\x18\x02 \x01(\tR\x06userId\x12\x12\n" + + "\x04type\x18\x03 \x01(\tR\x04type\x12\x14\n" + + "\x05label\x18\x04 \x01(\tR\x05label\x12\x14\n" + + "\x05value\x18\x05 \x01(\tR\x05value\x12\x1b\n" + + "\tis_active\x18\x06 \x01(\bR\bisActive\x127\n" + + "\x18max_triggers_per_session\x18\a \x01(\x05R\x15maxTriggersPerSession\x12$\n" + + "\vowner_email\x18\b \x01(\tH\x00R\n" + + "ownerEmail\x88\x01\x01\x129\n" + + "\n" + + "created_at\x18\t \x01(\v2\x1a.google.protobuf.TimestampR\tcreatedAt\x129\n" + + "\n" + + "updated_at\x18\n" + + " \x01(\v2\x1a.google.protobuf.TimestampR\tupdatedAtB\x0e\n" + "\f_owner_email\"\x98\x05\n" + "\bAdminJob\x12\x0e\n" + "\x02id\x18\x01 \x01(\tR\x02id\x12\x16\n" + @@ -3725,7 +3968,7 @@ func file_app_v1_common_proto_rawDescGZIP() []byte { return file_app_v1_common_proto_rawDescData } -var file_app_v1_common_proto_msgTypes = make([]protoimpl.MessageInfo, 25) +var file_app_v1_common_proto_msgTypes = make([]protoimpl.MessageInfo, 27) var file_app_v1_common_proto_goTypes = []any{ (*MessageResponse)(nil), // 0: stream.app.v1.MessageResponse (*User)(nil), // 1: stream.app.v1.User @@ -3733,76 +3976,82 @@ var file_app_v1_common_proto_goTypes = []any{ (*Notification)(nil), // 3: stream.app.v1.Notification (*Domain)(nil), // 4: stream.app.v1.Domain (*AdTemplate)(nil), // 5: stream.app.v1.AdTemplate - (*PlayerConfig)(nil), // 6: stream.app.v1.PlayerConfig - (*AdminPlayerConfig)(nil), // 7: stream.app.v1.AdminPlayerConfig - (*Plan)(nil), // 8: stream.app.v1.Plan - (*Payment)(nil), // 9: stream.app.v1.Payment - (*PlanSubscription)(nil), // 10: stream.app.v1.PlanSubscription - (*WalletTransaction)(nil), // 11: stream.app.v1.WalletTransaction - (*PaymentHistoryItem)(nil), // 12: stream.app.v1.PaymentHistoryItem - (*Video)(nil), // 13: stream.app.v1.Video - (*AdminDashboard)(nil), // 14: stream.app.v1.AdminDashboard - (*AdminUser)(nil), // 15: stream.app.v1.AdminUser - (*ReferralUserSummary)(nil), // 16: stream.app.v1.ReferralUserSummary - (*AdminUserReferralInfo)(nil), // 17: stream.app.v1.AdminUserReferralInfo - (*AdminUserDetail)(nil), // 18: stream.app.v1.AdminUserDetail - (*AdminVideo)(nil), // 19: stream.app.v1.AdminVideo - (*AdminPayment)(nil), // 20: stream.app.v1.AdminPayment - (*AdminPlan)(nil), // 21: stream.app.v1.AdminPlan - (*AdminAdTemplate)(nil), // 22: stream.app.v1.AdminAdTemplate - (*AdminJob)(nil), // 23: stream.app.v1.AdminJob - (*AdminAgent)(nil), // 24: stream.app.v1.AdminAgent - (*timestamppb.Timestamp)(nil), // 25: google.protobuf.Timestamp + (*PopupAd)(nil), // 6: stream.app.v1.PopupAd + (*PlayerConfig)(nil), // 7: stream.app.v1.PlayerConfig + (*AdminPlayerConfig)(nil), // 8: stream.app.v1.AdminPlayerConfig + (*Plan)(nil), // 9: stream.app.v1.Plan + (*Payment)(nil), // 10: stream.app.v1.Payment + (*PlanSubscription)(nil), // 11: stream.app.v1.PlanSubscription + (*WalletTransaction)(nil), // 12: stream.app.v1.WalletTransaction + (*PaymentHistoryItem)(nil), // 13: stream.app.v1.PaymentHistoryItem + (*Video)(nil), // 14: stream.app.v1.Video + (*AdminDashboard)(nil), // 15: stream.app.v1.AdminDashboard + (*AdminUser)(nil), // 16: stream.app.v1.AdminUser + (*ReferralUserSummary)(nil), // 17: stream.app.v1.ReferralUserSummary + (*AdminUserReferralInfo)(nil), // 18: stream.app.v1.AdminUserReferralInfo + (*AdminUserDetail)(nil), // 19: stream.app.v1.AdminUserDetail + (*AdminVideo)(nil), // 20: stream.app.v1.AdminVideo + (*AdminPayment)(nil), // 21: stream.app.v1.AdminPayment + (*AdminPlan)(nil), // 22: stream.app.v1.AdminPlan + (*AdminAdTemplate)(nil), // 23: stream.app.v1.AdminAdTemplate + (*AdminPopupAd)(nil), // 24: stream.app.v1.AdminPopupAd + (*AdminJob)(nil), // 25: stream.app.v1.AdminJob + (*AdminAgent)(nil), // 26: stream.app.v1.AdminAgent + (*timestamppb.Timestamp)(nil), // 27: google.protobuf.Timestamp } var file_app_v1_common_proto_depIdxs = []int32{ - 25, // 0: stream.app.v1.User.plan_started_at:type_name -> google.protobuf.Timestamp - 25, // 1: stream.app.v1.User.plan_expires_at:type_name -> google.protobuf.Timestamp - 25, // 2: stream.app.v1.User.created_at:type_name -> google.protobuf.Timestamp - 25, // 3: stream.app.v1.User.updated_at:type_name -> google.protobuf.Timestamp - 25, // 4: stream.app.v1.Notification.created_at:type_name -> google.protobuf.Timestamp - 25, // 5: stream.app.v1.Domain.created_at:type_name -> google.protobuf.Timestamp - 25, // 6: stream.app.v1.Domain.updated_at:type_name -> google.protobuf.Timestamp - 25, // 7: stream.app.v1.AdTemplate.created_at:type_name -> google.protobuf.Timestamp - 25, // 8: stream.app.v1.AdTemplate.updated_at:type_name -> google.protobuf.Timestamp - 25, // 9: stream.app.v1.PlayerConfig.created_at:type_name -> google.protobuf.Timestamp - 25, // 10: stream.app.v1.PlayerConfig.updated_at:type_name -> google.protobuf.Timestamp - 25, // 11: stream.app.v1.AdminPlayerConfig.created_at:type_name -> google.protobuf.Timestamp - 25, // 12: stream.app.v1.AdminPlayerConfig.updated_at:type_name -> google.protobuf.Timestamp - 25, // 13: stream.app.v1.Payment.created_at:type_name -> google.protobuf.Timestamp - 25, // 14: stream.app.v1.Payment.updated_at:type_name -> google.protobuf.Timestamp - 25, // 15: stream.app.v1.PlanSubscription.started_at:type_name -> google.protobuf.Timestamp - 25, // 16: stream.app.v1.PlanSubscription.expires_at:type_name -> google.protobuf.Timestamp - 25, // 17: stream.app.v1.PlanSubscription.created_at:type_name -> google.protobuf.Timestamp - 25, // 18: stream.app.v1.PlanSubscription.updated_at:type_name -> google.protobuf.Timestamp - 25, // 19: stream.app.v1.WalletTransaction.created_at:type_name -> google.protobuf.Timestamp - 25, // 20: stream.app.v1.WalletTransaction.updated_at:type_name -> google.protobuf.Timestamp - 25, // 21: stream.app.v1.PaymentHistoryItem.expires_at:type_name -> google.protobuf.Timestamp - 25, // 22: stream.app.v1.PaymentHistoryItem.created_at:type_name -> google.protobuf.Timestamp - 25, // 23: stream.app.v1.Video.created_at:type_name -> google.protobuf.Timestamp - 25, // 24: stream.app.v1.Video.updated_at:type_name -> google.protobuf.Timestamp - 25, // 25: stream.app.v1.AdminUser.created_at:type_name -> google.protobuf.Timestamp - 25, // 26: stream.app.v1.AdminUser.updated_at:type_name -> google.protobuf.Timestamp - 16, // 27: stream.app.v1.AdminUserReferralInfo.referrer:type_name -> stream.app.v1.ReferralUserSummary - 25, // 28: stream.app.v1.AdminUserReferralInfo.reward_granted_at:type_name -> google.protobuf.Timestamp - 15, // 29: stream.app.v1.AdminUserDetail.user:type_name -> stream.app.v1.AdminUser - 10, // 30: stream.app.v1.AdminUserDetail.subscription:type_name -> stream.app.v1.PlanSubscription - 17, // 31: stream.app.v1.AdminUserDetail.referral:type_name -> stream.app.v1.AdminUserReferralInfo - 25, // 32: stream.app.v1.AdminVideo.created_at:type_name -> google.protobuf.Timestamp - 25, // 33: stream.app.v1.AdminVideo.updated_at:type_name -> google.protobuf.Timestamp - 25, // 34: stream.app.v1.AdminPayment.created_at:type_name -> google.protobuf.Timestamp - 25, // 35: stream.app.v1.AdminPayment.updated_at:type_name -> google.protobuf.Timestamp - 25, // 36: stream.app.v1.AdminAdTemplate.created_at:type_name -> google.protobuf.Timestamp - 25, // 37: stream.app.v1.AdminAdTemplate.updated_at:type_name -> google.protobuf.Timestamp - 25, // 38: stream.app.v1.AdminJob.created_at:type_name -> google.protobuf.Timestamp - 25, // 39: stream.app.v1.AdminJob.updated_at:type_name -> google.protobuf.Timestamp - 25, // 40: stream.app.v1.AdminAgent.last_heartbeat:type_name -> google.protobuf.Timestamp - 25, // 41: stream.app.v1.AdminAgent.created_at:type_name -> google.protobuf.Timestamp - 25, // 42: stream.app.v1.AdminAgent.updated_at:type_name -> google.protobuf.Timestamp - 43, // [43:43] is the sub-list for method output_type - 43, // [43:43] is the sub-list for method input_type - 43, // [43:43] is the sub-list for extension type_name - 43, // [43:43] is the sub-list for extension extendee - 0, // [0:43] is the sub-list for field type_name + 27, // 0: stream.app.v1.User.plan_started_at:type_name -> google.protobuf.Timestamp + 27, // 1: stream.app.v1.User.plan_expires_at:type_name -> google.protobuf.Timestamp + 27, // 2: stream.app.v1.User.created_at:type_name -> google.protobuf.Timestamp + 27, // 3: stream.app.v1.User.updated_at:type_name -> google.protobuf.Timestamp + 27, // 4: stream.app.v1.Notification.created_at:type_name -> google.protobuf.Timestamp + 27, // 5: stream.app.v1.Domain.created_at:type_name -> google.protobuf.Timestamp + 27, // 6: stream.app.v1.Domain.updated_at:type_name -> google.protobuf.Timestamp + 27, // 7: stream.app.v1.AdTemplate.created_at:type_name -> google.protobuf.Timestamp + 27, // 8: stream.app.v1.AdTemplate.updated_at:type_name -> google.protobuf.Timestamp + 27, // 9: stream.app.v1.PopupAd.created_at:type_name -> google.protobuf.Timestamp + 27, // 10: stream.app.v1.PopupAd.updated_at:type_name -> google.protobuf.Timestamp + 27, // 11: stream.app.v1.PlayerConfig.created_at:type_name -> google.protobuf.Timestamp + 27, // 12: stream.app.v1.PlayerConfig.updated_at:type_name -> google.protobuf.Timestamp + 27, // 13: stream.app.v1.AdminPlayerConfig.created_at:type_name -> google.protobuf.Timestamp + 27, // 14: stream.app.v1.AdminPlayerConfig.updated_at:type_name -> google.protobuf.Timestamp + 27, // 15: stream.app.v1.Payment.created_at:type_name -> google.protobuf.Timestamp + 27, // 16: stream.app.v1.Payment.updated_at:type_name -> google.protobuf.Timestamp + 27, // 17: stream.app.v1.PlanSubscription.started_at:type_name -> google.protobuf.Timestamp + 27, // 18: stream.app.v1.PlanSubscription.expires_at:type_name -> google.protobuf.Timestamp + 27, // 19: stream.app.v1.PlanSubscription.created_at:type_name -> google.protobuf.Timestamp + 27, // 20: stream.app.v1.PlanSubscription.updated_at:type_name -> google.protobuf.Timestamp + 27, // 21: stream.app.v1.WalletTransaction.created_at:type_name -> google.protobuf.Timestamp + 27, // 22: stream.app.v1.WalletTransaction.updated_at:type_name -> google.protobuf.Timestamp + 27, // 23: stream.app.v1.PaymentHistoryItem.expires_at:type_name -> google.protobuf.Timestamp + 27, // 24: stream.app.v1.PaymentHistoryItem.created_at:type_name -> google.protobuf.Timestamp + 27, // 25: stream.app.v1.Video.created_at:type_name -> google.protobuf.Timestamp + 27, // 26: stream.app.v1.Video.updated_at:type_name -> google.protobuf.Timestamp + 27, // 27: stream.app.v1.AdminUser.created_at:type_name -> google.protobuf.Timestamp + 27, // 28: stream.app.v1.AdminUser.updated_at:type_name -> google.protobuf.Timestamp + 17, // 29: stream.app.v1.AdminUserReferralInfo.referrer:type_name -> stream.app.v1.ReferralUserSummary + 27, // 30: stream.app.v1.AdminUserReferralInfo.reward_granted_at:type_name -> google.protobuf.Timestamp + 16, // 31: stream.app.v1.AdminUserDetail.user:type_name -> stream.app.v1.AdminUser + 11, // 32: stream.app.v1.AdminUserDetail.subscription:type_name -> stream.app.v1.PlanSubscription + 18, // 33: stream.app.v1.AdminUserDetail.referral:type_name -> stream.app.v1.AdminUserReferralInfo + 27, // 34: stream.app.v1.AdminVideo.created_at:type_name -> google.protobuf.Timestamp + 27, // 35: stream.app.v1.AdminVideo.updated_at:type_name -> google.protobuf.Timestamp + 27, // 36: stream.app.v1.AdminPayment.created_at:type_name -> google.protobuf.Timestamp + 27, // 37: stream.app.v1.AdminPayment.updated_at:type_name -> google.protobuf.Timestamp + 27, // 38: stream.app.v1.AdminAdTemplate.created_at:type_name -> google.protobuf.Timestamp + 27, // 39: stream.app.v1.AdminAdTemplate.updated_at:type_name -> google.protobuf.Timestamp + 27, // 40: stream.app.v1.AdminPopupAd.created_at:type_name -> google.protobuf.Timestamp + 27, // 41: stream.app.v1.AdminPopupAd.updated_at:type_name -> google.protobuf.Timestamp + 27, // 42: stream.app.v1.AdminJob.created_at:type_name -> google.protobuf.Timestamp + 27, // 43: stream.app.v1.AdminJob.updated_at:type_name -> google.protobuf.Timestamp + 27, // 44: stream.app.v1.AdminAgent.last_heartbeat:type_name -> google.protobuf.Timestamp + 27, // 45: stream.app.v1.AdminAgent.created_at:type_name -> google.protobuf.Timestamp + 27, // 46: stream.app.v1.AdminAgent.updated_at:type_name -> google.protobuf.Timestamp + 47, // [47:47] is the sub-list for method output_type + 47, // [47:47] is the sub-list for method input_type + 47, // [47:47] is the sub-list for extension type_name + 47, // [47:47] is the sub-list for extension extendee + 0, // [0:47] is the sub-list for field type_name } func init() { file_app_v1_common_proto_init() } @@ -3813,14 +4062,13 @@ func file_app_v1_common_proto_init() { file_app_v1_common_proto_msgTypes[1].OneofWrappers = []any{} file_app_v1_common_proto_msgTypes[3].OneofWrappers = []any{} file_app_v1_common_proto_msgTypes[5].OneofWrappers = []any{} - file_app_v1_common_proto_msgTypes[6].OneofWrappers = []any{} file_app_v1_common_proto_msgTypes[7].OneofWrappers = []any{} file_app_v1_common_proto_msgTypes[8].OneofWrappers = []any{} file_app_v1_common_proto_msgTypes[9].OneofWrappers = []any{} - file_app_v1_common_proto_msgTypes[11].OneofWrappers = []any{} + file_app_v1_common_proto_msgTypes[10].OneofWrappers = []any{} file_app_v1_common_proto_msgTypes[12].OneofWrappers = []any{} file_app_v1_common_proto_msgTypes[13].OneofWrappers = []any{} - file_app_v1_common_proto_msgTypes[15].OneofWrappers = []any{} + file_app_v1_common_proto_msgTypes[14].OneofWrappers = []any{} file_app_v1_common_proto_msgTypes[16].OneofWrappers = []any{} file_app_v1_common_proto_msgTypes[17].OneofWrappers = []any{} file_app_v1_common_proto_msgTypes[18].OneofWrappers = []any{} @@ -3829,13 +4077,15 @@ func file_app_v1_common_proto_init() { file_app_v1_common_proto_msgTypes[21].OneofWrappers = []any{} file_app_v1_common_proto_msgTypes[22].OneofWrappers = []any{} file_app_v1_common_proto_msgTypes[23].OneofWrappers = []any{} + file_app_v1_common_proto_msgTypes[24].OneofWrappers = []any{} + file_app_v1_common_proto_msgTypes[25].OneofWrappers = []any{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_app_v1_common_proto_rawDesc), len(file_app_v1_common_proto_rawDesc)), NumEnums: 0, - NumMessages: 25, + NumMessages: 27, NumExtensions: 0, NumServices: 0, }, diff --git a/internal/database/model/player_configs.gen.go b/internal/database/model/player_configs.gen.go index 2171183..6184078 100644 --- a/internal/database/model/player_configs.gen.go +++ b/internal/database/model/player_configs.gen.go @@ -24,7 +24,7 @@ type PlayerConfig struct { Airplay *bool `gorm:"column:airplay;type:boolean;not null;default:true" json:"airplay"` Chromecast *bool `gorm:"column:chromecast;type:boolean;not null;default:true" json:"chromecast"` IsActive *bool `gorm:"column:is_active;type:boolean;not null;default:true" json:"is_active"` - IsDefault bool `gorm:"column:is_default;type:boolean;not null;index:idx_player_configs_user_default,priority:1;index:idx_player_configs_is_default,priority:1" json:"is_default"` + IsDefault bool `gorm:"column:is_default;type:boolean;not null;index:idx_player_configs_is_default,priority:1;index:idx_player_configs_user_default,priority:1" json:"is_default"` CreatedAt *time.Time `gorm:"column:created_at;type:timestamp(3) without time zone;not null;default:CURRENT_TIMESTAMP" json:"created_at"` UpdatedAt time.Time `gorm:"column:updated_at;type:timestamp(3) without time zone;not null" json:"updated_at"` Version *int64 `gorm:"column:version;type:bigint;not null;default:1;version" json:"-"` diff --git a/internal/database/model/popup_ads.gen.go b/internal/database/model/popup_ads.gen.go new file mode 100644 index 0000000..ddf5aac --- /dev/null +++ b/internal/database/model/popup_ads.gen.go @@ -0,0 +1,30 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package model + +import ( + "time" +) + +const TableNamePopupAd = "popup_ads" + +// PopupAd mapped from table +type PopupAd struct { + ID string `gorm:"column:id;type:uuid;primaryKey" json:"id"` + UserID string `gorm:"column:user_id;type:uuid;not null;index:idx_popup_ads_user_id,priority:1;index:idx_popup_ads_user_active,priority:2" json:"user_id"` + Type string `gorm:"column:type;type:character varying(20);not null" json:"type"` + Label string `gorm:"column:label;type:text;not null" json:"label"` + Value string `gorm:"column:value;type:text;not null" json:"value"` + IsActive *bool `gorm:"column:is_active;type:boolean;not null;index:idx_popup_ads_user_active,priority:1;default:true" json:"is_active"` + MaxTriggersPerSession *int32 `gorm:"column:max_triggers_per_session;type:integer;not null;default:3" json:"max_triggers_per_session"` + CreatedAt *time.Time `gorm:"column:created_at;type:timestamp with time zone;default:CURRENT_TIMESTAMP" json:"created_at"` + UpdatedAt *time.Time `gorm:"column:updated_at;type:timestamp with time zone" json:"updated_at"` + Version *int64 `gorm:"column:version;type:bigint;not null;default:1;version" json:"-"` +} + +// TableName PopupAd's table name +func (*PopupAd) TableName() string { + return TableNamePopupAd +} diff --git a/internal/database/query/gen.go b/internal/database/query/gen.go index 9296868..c48096c 100644 --- a/internal/database/query/gen.go +++ b/internal/database/query/gen.go @@ -25,6 +25,7 @@ var ( Plan *plan PlanSubscription *planSubscription PlayerConfig *playerConfig + PopupAd *popupAd User *user UserPreference *userPreference Video *video @@ -41,6 +42,7 @@ func SetDefault(db *gorm.DB, opts ...gen.DOOption) { Plan = &Q.Plan PlanSubscription = &Q.PlanSubscription PlayerConfig = &Q.PlayerConfig + PopupAd = &Q.PopupAd User = &Q.User UserPreference = &Q.UserPreference Video = &Q.Video @@ -58,6 +60,7 @@ func Use(db *gorm.DB, opts ...gen.DOOption) *Query { Plan: newPlan(db, opts...), PlanSubscription: newPlanSubscription(db, opts...), PlayerConfig: newPlayerConfig(db, opts...), + PopupAd: newPopupAd(db, opts...), User: newUser(db, opts...), UserPreference: newUserPreference(db, opts...), Video: newVideo(db, opts...), @@ -76,6 +79,7 @@ type Query struct { Plan plan PlanSubscription planSubscription PlayerConfig playerConfig + PopupAd popupAd User user UserPreference userPreference Video video @@ -95,6 +99,7 @@ func (q *Query) clone(db *gorm.DB) *Query { Plan: q.Plan.clone(db), PlanSubscription: q.PlanSubscription.clone(db), PlayerConfig: q.PlayerConfig.clone(db), + PopupAd: q.PopupAd.clone(db), User: q.User.clone(db), UserPreference: q.UserPreference.clone(db), Video: q.Video.clone(db), @@ -121,6 +126,7 @@ func (q *Query) ReplaceDB(db *gorm.DB) *Query { Plan: q.Plan.replaceDB(db), PlanSubscription: q.PlanSubscription.replaceDB(db), PlayerConfig: q.PlayerConfig.replaceDB(db), + PopupAd: q.PopupAd.replaceDB(db), User: q.User.replaceDB(db), UserPreference: q.UserPreference.replaceDB(db), Video: q.Video.replaceDB(db), @@ -137,6 +143,7 @@ type queryCtx struct { Plan IPlanDo PlanSubscription IPlanSubscriptionDo PlayerConfig IPlayerConfigDo + PopupAd IPopupAdDo User IUserDo UserPreference IUserPreferenceDo Video IVideoDo @@ -153,6 +160,7 @@ func (q *Query) WithContext(ctx context.Context) *queryCtx { Plan: q.Plan.WithContext(ctx), PlanSubscription: q.PlanSubscription.WithContext(ctx), PlayerConfig: q.PlayerConfig.WithContext(ctx), + PopupAd: q.PopupAd.WithContext(ctx), User: q.User.WithContext(ctx), UserPreference: q.UserPreference.WithContext(ctx), Video: q.Video.WithContext(ctx), diff --git a/internal/database/query/popup_ads.gen.go b/internal/database/query/popup_ads.gen.go new file mode 100644 index 0000000..1c1a8d0 --- /dev/null +++ b/internal/database/query/popup_ads.gen.go @@ -0,0 +1,427 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package query + +import ( + "context" + "database/sql" + + "gorm.io/gorm" + "gorm.io/gorm/clause" + "gorm.io/gorm/schema" + + "gorm.io/gen" + "gorm.io/gen/field" + + "gorm.io/plugin/dbresolver" + + "stream.api/internal/database/model" +) + +func newPopupAd(db *gorm.DB, opts ...gen.DOOption) popupAd { + _popupAd := popupAd{} + + _popupAd.popupAdDo.UseDB(db, opts...) + _popupAd.popupAdDo.UseModel(&model.PopupAd{}) + + tableName := _popupAd.popupAdDo.TableName() + _popupAd.ALL = field.NewAsterisk(tableName) + _popupAd.ID = field.NewString(tableName, "id") + _popupAd.UserID = field.NewString(tableName, "user_id") + _popupAd.Type = field.NewString(tableName, "type") + _popupAd.Label = field.NewString(tableName, "label") + _popupAd.Value = field.NewString(tableName, "value") + _popupAd.IsActive = field.NewBool(tableName, "is_active") + _popupAd.MaxTriggersPerSession = field.NewInt32(tableName, "max_triggers_per_session") + _popupAd.CreatedAt = field.NewTime(tableName, "created_at") + _popupAd.UpdatedAt = field.NewTime(tableName, "updated_at") + _popupAd.Version = field.NewInt64(tableName, "version") + + _popupAd.fillFieldMap() + + return _popupAd +} + +type popupAd struct { + popupAdDo popupAdDo + + ALL field.Asterisk + ID field.String + UserID field.String + Type field.String + Label field.String + Value field.String + IsActive field.Bool + MaxTriggersPerSession field.Int32 + CreatedAt field.Time + UpdatedAt field.Time + Version field.Int64 + + fieldMap map[string]field.Expr +} + +func (p popupAd) Table(newTableName string) *popupAd { + p.popupAdDo.UseTable(newTableName) + return p.updateTableName(newTableName) +} + +func (p popupAd) As(alias string) *popupAd { + p.popupAdDo.DO = *(p.popupAdDo.As(alias).(*gen.DO)) + return p.updateTableName(alias) +} + +func (p *popupAd) updateTableName(table string) *popupAd { + p.ALL = field.NewAsterisk(table) + p.ID = field.NewString(table, "id") + p.UserID = field.NewString(table, "user_id") + p.Type = field.NewString(table, "type") + p.Label = field.NewString(table, "label") + p.Value = field.NewString(table, "value") + p.IsActive = field.NewBool(table, "is_active") + p.MaxTriggersPerSession = field.NewInt32(table, "max_triggers_per_session") + p.CreatedAt = field.NewTime(table, "created_at") + p.UpdatedAt = field.NewTime(table, "updated_at") + p.Version = field.NewInt64(table, "version") + + p.fillFieldMap() + + return p +} + +func (p *popupAd) WithContext(ctx context.Context) IPopupAdDo { return p.popupAdDo.WithContext(ctx) } + +func (p popupAd) TableName() string { return p.popupAdDo.TableName() } + +func (p popupAd) Alias() string { return p.popupAdDo.Alias() } + +func (p popupAd) Columns(cols ...field.Expr) gen.Columns { return p.popupAdDo.Columns(cols...) } + +func (p *popupAd) GetFieldByName(fieldName string) (field.OrderExpr, bool) { + _f, ok := p.fieldMap[fieldName] + if !ok || _f == nil { + return nil, false + } + _oe, ok := _f.(field.OrderExpr) + return _oe, ok +} + +func (p *popupAd) fillFieldMap() { + p.fieldMap = make(map[string]field.Expr, 10) + p.fieldMap["id"] = p.ID + p.fieldMap["user_id"] = p.UserID + p.fieldMap["type"] = p.Type + p.fieldMap["label"] = p.Label + p.fieldMap["value"] = p.Value + p.fieldMap["is_active"] = p.IsActive + p.fieldMap["max_triggers_per_session"] = p.MaxTriggersPerSession + p.fieldMap["created_at"] = p.CreatedAt + p.fieldMap["updated_at"] = p.UpdatedAt + p.fieldMap["version"] = p.Version +} + +func (p popupAd) clone(db *gorm.DB) popupAd { + p.popupAdDo.ReplaceConnPool(db.Statement.ConnPool) + return p +} + +func (p popupAd) replaceDB(db *gorm.DB) popupAd { + p.popupAdDo.ReplaceDB(db) + return p +} + +type popupAdDo struct{ gen.DO } + +type IPopupAdDo interface { + gen.SubQuery + Debug() IPopupAdDo + WithContext(ctx context.Context) IPopupAdDo + WithResult(fc func(tx gen.Dao)) gen.ResultInfo + ReplaceDB(db *gorm.DB) + ReadDB() IPopupAdDo + WriteDB() IPopupAdDo + As(alias string) gen.Dao + Session(config *gorm.Session) IPopupAdDo + Columns(cols ...field.Expr) gen.Columns + Clauses(conds ...clause.Expression) IPopupAdDo + Not(conds ...gen.Condition) IPopupAdDo + Or(conds ...gen.Condition) IPopupAdDo + Select(conds ...field.Expr) IPopupAdDo + Where(conds ...gen.Condition) IPopupAdDo + Order(conds ...field.Expr) IPopupAdDo + Distinct(cols ...field.Expr) IPopupAdDo + Omit(cols ...field.Expr) IPopupAdDo + Join(table schema.Tabler, on ...field.Expr) IPopupAdDo + LeftJoin(table schema.Tabler, on ...field.Expr) IPopupAdDo + RightJoin(table schema.Tabler, on ...field.Expr) IPopupAdDo + Group(cols ...field.Expr) IPopupAdDo + Having(conds ...gen.Condition) IPopupAdDo + Limit(limit int) IPopupAdDo + Offset(offset int) IPopupAdDo + Count() (count int64, err error) + Scopes(funcs ...func(gen.Dao) gen.Dao) IPopupAdDo + Unscoped() IPopupAdDo + Create(values ...*model.PopupAd) error + CreateInBatches(values []*model.PopupAd, batchSize int) error + Save(values ...*model.PopupAd) error + First() (*model.PopupAd, error) + Take() (*model.PopupAd, error) + Last() (*model.PopupAd, error) + Find() ([]*model.PopupAd, error) + FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.PopupAd, err error) + FindInBatches(result *[]*model.PopupAd, batchSize int, fc func(tx gen.Dao, batch int) error) error + Pluck(column field.Expr, dest interface{}) error + Delete(...*model.PopupAd) (info gen.ResultInfo, err error) + Update(column field.Expr, value interface{}) (info gen.ResultInfo, err error) + UpdateSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error) + Updates(value interface{}) (info gen.ResultInfo, err error) + UpdateColumn(column field.Expr, value interface{}) (info gen.ResultInfo, err error) + UpdateColumnSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error) + UpdateColumns(value interface{}) (info gen.ResultInfo, err error) + UpdateFrom(q gen.SubQuery) gen.Dao + Attrs(attrs ...field.AssignExpr) IPopupAdDo + Assign(attrs ...field.AssignExpr) IPopupAdDo + Joins(fields ...field.RelationField) IPopupAdDo + Preload(fields ...field.RelationField) IPopupAdDo + FirstOrInit() (*model.PopupAd, error) + FirstOrCreate() (*model.PopupAd, error) + FindByPage(offset int, limit int) (result []*model.PopupAd, count int64, err error) + ScanByPage(result interface{}, offset int, limit int) (count int64, err error) + Rows() (*sql.Rows, error) + Row() *sql.Row + Scan(result interface{}) (err error) + Returning(value interface{}, columns ...string) IPopupAdDo + UnderlyingDB() *gorm.DB + schema.Tabler +} + +func (p popupAdDo) Debug() IPopupAdDo { + return p.withDO(p.DO.Debug()) +} + +func (p popupAdDo) WithContext(ctx context.Context) IPopupAdDo { + return p.withDO(p.DO.WithContext(ctx)) +} + +func (p popupAdDo) ReadDB() IPopupAdDo { + return p.Clauses(dbresolver.Read) +} + +func (p popupAdDo) WriteDB() IPopupAdDo { + return p.Clauses(dbresolver.Write) +} + +func (p popupAdDo) Session(config *gorm.Session) IPopupAdDo { + return p.withDO(p.DO.Session(config)) +} + +func (p popupAdDo) Clauses(conds ...clause.Expression) IPopupAdDo { + return p.withDO(p.DO.Clauses(conds...)) +} + +func (p popupAdDo) Returning(value interface{}, columns ...string) IPopupAdDo { + return p.withDO(p.DO.Returning(value, columns...)) +} + +func (p popupAdDo) Not(conds ...gen.Condition) IPopupAdDo { + return p.withDO(p.DO.Not(conds...)) +} + +func (p popupAdDo) Or(conds ...gen.Condition) IPopupAdDo { + return p.withDO(p.DO.Or(conds...)) +} + +func (p popupAdDo) Select(conds ...field.Expr) IPopupAdDo { + return p.withDO(p.DO.Select(conds...)) +} + +func (p popupAdDo) Where(conds ...gen.Condition) IPopupAdDo { + return p.withDO(p.DO.Where(conds...)) +} + +func (p popupAdDo) Order(conds ...field.Expr) IPopupAdDo { + return p.withDO(p.DO.Order(conds...)) +} + +func (p popupAdDo) Distinct(cols ...field.Expr) IPopupAdDo { + return p.withDO(p.DO.Distinct(cols...)) +} + +func (p popupAdDo) Omit(cols ...field.Expr) IPopupAdDo { + return p.withDO(p.DO.Omit(cols...)) +} + +func (p popupAdDo) Join(table schema.Tabler, on ...field.Expr) IPopupAdDo { + return p.withDO(p.DO.Join(table, on...)) +} + +func (p popupAdDo) LeftJoin(table schema.Tabler, on ...field.Expr) IPopupAdDo { + return p.withDO(p.DO.LeftJoin(table, on...)) +} + +func (p popupAdDo) RightJoin(table schema.Tabler, on ...field.Expr) IPopupAdDo { + return p.withDO(p.DO.RightJoin(table, on...)) +} + +func (p popupAdDo) Group(cols ...field.Expr) IPopupAdDo { + return p.withDO(p.DO.Group(cols...)) +} + +func (p popupAdDo) Having(conds ...gen.Condition) IPopupAdDo { + return p.withDO(p.DO.Having(conds...)) +} + +func (p popupAdDo) Limit(limit int) IPopupAdDo { + return p.withDO(p.DO.Limit(limit)) +} + +func (p popupAdDo) Offset(offset int) IPopupAdDo { + return p.withDO(p.DO.Offset(offset)) +} + +func (p popupAdDo) Scopes(funcs ...func(gen.Dao) gen.Dao) IPopupAdDo { + return p.withDO(p.DO.Scopes(funcs...)) +} + +func (p popupAdDo) Unscoped() IPopupAdDo { + return p.withDO(p.DO.Unscoped()) +} + +func (p popupAdDo) Create(values ...*model.PopupAd) error { + if len(values) == 0 { + return nil + } + return p.DO.Create(values) +} + +func (p popupAdDo) CreateInBatches(values []*model.PopupAd, batchSize int) error { + return p.DO.CreateInBatches(values, batchSize) +} + +// Save : !!! underlying implementation is different with GORM +// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values) +func (p popupAdDo) Save(values ...*model.PopupAd) error { + if len(values) == 0 { + return nil + } + return p.DO.Save(values) +} + +func (p popupAdDo) First() (*model.PopupAd, error) { + if result, err := p.DO.First(); err != nil { + return nil, err + } else { + return result.(*model.PopupAd), nil + } +} + +func (p popupAdDo) Take() (*model.PopupAd, error) { + if result, err := p.DO.Take(); err != nil { + return nil, err + } else { + return result.(*model.PopupAd), nil + } +} + +func (p popupAdDo) Last() (*model.PopupAd, error) { + if result, err := p.DO.Last(); err != nil { + return nil, err + } else { + return result.(*model.PopupAd), nil + } +} + +func (p popupAdDo) Find() ([]*model.PopupAd, error) { + result, err := p.DO.Find() + return result.([]*model.PopupAd), err +} + +func (p popupAdDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.PopupAd, err error) { + buf := make([]*model.PopupAd, 0, batchSize) + err = p.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error { + defer func() { results = append(results, buf...) }() + return fc(tx, batch) + }) + return results, err +} + +func (p popupAdDo) FindInBatches(result *[]*model.PopupAd, batchSize int, fc func(tx gen.Dao, batch int) error) error { + return p.DO.FindInBatches(result, batchSize, fc) +} + +func (p popupAdDo) Attrs(attrs ...field.AssignExpr) IPopupAdDo { + return p.withDO(p.DO.Attrs(attrs...)) +} + +func (p popupAdDo) Assign(attrs ...field.AssignExpr) IPopupAdDo { + return p.withDO(p.DO.Assign(attrs...)) +} + +func (p popupAdDo) Joins(fields ...field.RelationField) IPopupAdDo { + for _, _f := range fields { + p = *p.withDO(p.DO.Joins(_f)) + } + return &p +} + +func (p popupAdDo) Preload(fields ...field.RelationField) IPopupAdDo { + for _, _f := range fields { + p = *p.withDO(p.DO.Preload(_f)) + } + return &p +} + +func (p popupAdDo) FirstOrInit() (*model.PopupAd, error) { + if result, err := p.DO.FirstOrInit(); err != nil { + return nil, err + } else { + return result.(*model.PopupAd), nil + } +} + +func (p popupAdDo) FirstOrCreate() (*model.PopupAd, error) { + if result, err := p.DO.FirstOrCreate(); err != nil { + return nil, err + } else { + return result.(*model.PopupAd), nil + } +} + +func (p popupAdDo) FindByPage(offset int, limit int) (result []*model.PopupAd, count int64, err error) { + result, err = p.Offset(offset).Limit(limit).Find() + if err != nil { + return + } + + if size := len(result); 0 < limit && 0 < size && size < limit { + count = int64(size + offset) + return + } + + count, err = p.Offset(-1).Limit(-1).Count() + return +} + +func (p popupAdDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) { + count, err = p.Count() + if err != nil { + return + } + + err = p.Offset(offset).Limit(limit).Scan(result) + return +} + +func (p popupAdDo) Scan(result interface{}) (err error) { + return p.DO.Scan(result) +} + +func (p popupAdDo) Delete(models ...*model.PopupAd) (result gen.ResultInfo, err error) { + return p.DO.Delete(models) +} + +func (p *popupAdDo) withDO(do gen.Dao) *popupAdDo { + p.DO = *do.(*gen.DO) + return p +} diff --git a/internal/middleware/authenticator.go b/internal/middleware/authenticator.go index d4de0da..24bbf9e 100644 --- a/internal/middleware/authenticator.go +++ b/internal/middleware/authenticator.go @@ -36,17 +36,23 @@ type Actor struct { Role string } -type Authenticator struct { - db *gorm.DB - logger logger.Logger - trustedMarker string +type NotificationEventPublisher interface { + PublishNotificationCreated(ctx context.Context, notification *model.Notification) error } -func NewAuthenticator(db *gorm.DB, l logger.Logger, trustedMarker string) *Authenticator { +type Authenticator struct { + db *gorm.DB + logger logger.Logger + trustedMarker string + notificationEvents NotificationEventPublisher +} + +func NewAuthenticator(db *gorm.DB, l logger.Logger, trustedMarker string, notificationEvents NotificationEventPublisher) *Authenticator { return &Authenticator{ - db: db, - logger: l, - trustedMarker: strings.TrimSpace(trustedMarker), + db: db, + logger: l, + trustedMarker: strings.TrimSpace(trustedMarker), + notificationEvents: notificationEvents, } } @@ -210,6 +216,11 @@ func (a *Authenticator) maybeCreateSubscriptionReminderPostAuth(ctx context.Cont if err := tx.WithContext(ctx).Create(notification).Error; err != nil { return err } + if a.notificationEvents != nil { + if err := a.notificationEvents.PublishNotificationCreated(ctx, notification); err != nil { + a.logger.Error("Failed to publish notification MQTT event", "error", err, "notification_id", notification.ID, "user_id", notification.UserID) + } + } return tx.WithContext(ctx). Model(&model.PlanSubscription{}). Where("id = ?", subscription.ID). diff --git a/internal/middleware/authenticator_test.go b/internal/middleware/authenticator_test.go index 0eadbaf..740a43e 100644 --- a/internal/middleware/authenticator_test.go +++ b/internal/middleware/authenticator_test.go @@ -106,7 +106,7 @@ func newTrustedContext(userID, role string) context.Context { func TestRequireActor(t *testing.T) { - auth := NewAuthenticator(newAuthenticatorTestDB(t), testLogger{}, "trusted-marker") + auth := NewAuthenticator(newAuthenticatorTestDB(t), testLogger{}, "trusted-marker", nil) t.Run("thiếu metadata", func(t *testing.T) { _, err := auth.RequireActor(context.Background()) @@ -146,7 +146,7 @@ func TestAuthenticate(t *testing.T) { t.Run("user không tồn tại", func(t *testing.T) { db := newAuthenticatorTestDB(t) - auth := NewAuthenticator(db, testLogger{}, "trusted-marker") + auth := NewAuthenticator(db, testLogger{}, "trusted-marker", nil) _, err := auth.Authenticate(newTrustedContext(uuid.NewString(), "USER")) if status.Code(err) != codes.Unauthenticated { t.Fatalf("code = %v, want %v", status.Code(err), codes.Unauthenticated) @@ -159,7 +159,7 @@ func TestAuthenticate(t *testing.T) { if err := db.Create(&blocked).Error; err != nil { t.Fatalf("create blocked user: %v", err) } - auth := NewAuthenticator(db, testLogger{}, "trusted-marker") + auth := NewAuthenticator(db, testLogger{}, "trusted-marker", nil) _, err := auth.Authenticate(newTrustedContext(blocked.ID, "USER")) if status.Code(err) != codes.PermissionDenied { t.Fatalf("code = %v, want %v", status.Code(err), codes.PermissionDenied) @@ -188,7 +188,7 @@ func TestAuthenticate(t *testing.T) { if err := db.Create(&subscription).Error; err != nil { t.Fatalf("create subscription: %v", err) } - auth := NewAuthenticator(db, testLogger{}, "trusted-marker") + auth := NewAuthenticator(db, testLogger{}, "trusted-marker", nil) result, err := auth.Authenticate(newTrustedContext(user.ID, "USER")) if err != nil { @@ -221,7 +221,7 @@ func TestAuthenticate(t *testing.T) { if err := db.Create(&subscription).Error; err != nil { t.Fatalf("create subscription: %v", err) } - auth := NewAuthenticator(db, testLogger{}, "trusted-marker") + auth := NewAuthenticator(db, testLogger{}, "trusted-marker", nil) result, err := auth.Authenticate(newTrustedContext(user.ID, "USER")) if err != nil { @@ -268,7 +268,7 @@ func TestAuthenticate(t *testing.T) { t.Fatalf("create subscription: %v", err) } - auth := NewAuthenticator(db, testLogger{}, "trusted-marker") + auth := NewAuthenticator(db, testLogger{}, "trusted-marker", nil) for range 2 { if _, err := auth.Authenticate(newTrustedContext(user.ID, "USER")); err != nil { t.Fatalf("Authenticate() error = %v", err) diff --git a/internal/repository/popup_ad_repository.go b/internal/repository/popup_ad_repository.go new file mode 100644 index 0000000..a8f8f34 --- /dev/null +++ b/internal/repository/popup_ad_repository.go @@ -0,0 +1,105 @@ +package repository + +import ( + "context" + "strings" + + "gorm.io/gorm" + "stream.api/internal/database/model" +) + +type popupAdRepository struct { + db *gorm.DB +} + +func NewPopupAdRepository(db *gorm.DB) *popupAdRepository { + return &popupAdRepository{db: db} +} + +func (r *popupAdRepository) ListByUser(ctx context.Context, userID string, limit int32, offset int) ([]model.PopupAd, int64, error) { + db := r.baseQuery(ctx).Model(&model.PopupAd{}).Where("user_id = ?", strings.TrimSpace(userID)) + + var total int64 + if err := db.Count(&total).Error; err != nil { + return nil, 0, err + } + + var items []model.PopupAd + if err := db.Order("created_at DESC").Offset(offset).Limit(int(limit)).Find(&items).Error; err != nil { + return nil, 0, err + } + return items, total, nil +} + +func (r *popupAdRepository) ListForAdmin(ctx context.Context, search string, userID string, limit int32, offset int) ([]model.PopupAd, int64, error) { + db := r.baseQuery(ctx).Model(&model.PopupAd{}) + if trimmedSearch := strings.TrimSpace(search); trimmedSearch != "" { + like := "%" + trimmedSearch + "%" + db = db.Where("label ILIKE ?", like) + } + if trimmedUserID := strings.TrimSpace(userID); trimmedUserID != "" { + db = db.Where("user_id = ?", trimmedUserID) + } + + var total int64 + if err := db.Count(&total).Error; err != nil { + return nil, 0, err + } + + var items []model.PopupAd + if err := db.Order("created_at DESC").Offset(offset).Limit(int(limit)).Find(&items).Error; err != nil { + return nil, 0, err + } + return items, total, nil +} + +func (r *popupAdRepository) GetByID(ctx context.Context, id string) (*model.PopupAd, error) { + var item model.PopupAd + if err := r.baseQuery(ctx).Where("id = ?", strings.TrimSpace(id)).First(&item).Error; err != nil { + return nil, err + } + return &item, nil +} + +func (r *popupAdRepository) GetByIDAndUser(ctx context.Context, id string, userID string) (*model.PopupAd, error) { + var item model.PopupAd + if err := r.baseQuery(ctx).Where("id = ? AND user_id = ?", strings.TrimSpace(id), strings.TrimSpace(userID)).First(&item).Error; err != nil { + return nil, err + } + return &item, nil +} + +func (r *popupAdRepository) GetActiveByUser(ctx context.Context, userID string) (*model.PopupAd, error) { + var item model.PopupAd + err := r.baseQuery(ctx). + Where("user_id = ?", strings.TrimSpace(userID)). + Where("is_active = ?", true). + Order("created_at DESC"). + First(&item).Error + if err != nil { + return nil, err + } + return &item, nil +} + +func (r *popupAdRepository) Create(ctx context.Context, item *model.PopupAd) error { + return r.baseQuery(ctx).Create(item).Error +} + +func (r *popupAdRepository) Save(ctx context.Context, item *model.PopupAd) error { + return r.baseQuery(ctx).Save(item).Error +} + +func (r *popupAdRepository) DeleteByIDAndUser(ctx context.Context, id string, userID string) (int64, error) { + res := r.baseQuery(ctx).Where("id = ? AND user_id = ?", strings.TrimSpace(id), strings.TrimSpace(userID)).Delete(&model.PopupAd{}) + return res.RowsAffected, res.Error +} + +func (r *popupAdRepository) DeleteByID(ctx context.Context, id string) (int64, error) { + res := r.baseQuery(ctx).Where("id = ?", strings.TrimSpace(id)).Delete(&model.PopupAd{}) + return res.RowsAffected, res.Error +} + +func (r *popupAdRepository) baseQuery(ctx context.Context) *gorm.DB { + return r.db.WithContext(ctx) +} diff --git a/internal/service/__test__/service_notification_mqtt_test.go b/internal/service/__test__/service_notification_mqtt_test.go new file mode 100644 index 0000000..adb8d55 --- /dev/null +++ b/internal/service/__test__/service_notification_mqtt_test.go @@ -0,0 +1,96 @@ +package service + +import ( + "context" + "testing" + "time" + + "github.com/google/uuid" + appv1 "stream.api/internal/api/proto/app/v1" + "stream.api/internal/database/model" +) + +type publishedNotificationEvent struct { + notification *model.Notification +} + +type fakeNotificationEventPublisher struct { + events []publishedNotificationEvent +} + +func (f *fakeNotificationEventPublisher) PublishNotificationCreated(_ context.Context, notification *model.Notification) error { + copyNotification := *notification + f.events = append(f.events, publishedNotificationEvent{notification: ©Notification}) + return nil +} + +func TestExecutePaymentFlow_PublishesNotificationEvent(t *testing.T) { + db := newTestDB(t) + services := newTestAppServices(t, db) + publisher := &fakeNotificationEventPublisher{} + services.notificationEvents = publisher + + user := seedTestUser(t, db, model.User{ID: uuid.NewString(), Email: "payer@example.com", Role: ptrString("USER")}) + plan := seedTestPlan(t, db, model.Plan{ID: uuid.NewString(), Name: "Pro", Price: 10, Cycle: "monthly", StorageLimit: 100, UploadLimit: 10, QualityLimit: "1080p", IsActive: ptrBool(true)}) + seedWalletTransaction(t, db, model.WalletTransaction{ID: uuid.NewString(), UserID: user.ID, Type: walletTransactionTypeTopup, Amount: 5, Currency: ptrString("USD")}) + + result, err := services.executePaymentFlow(context.Background(), paymentExecutionInput{ + UserID: user.ID, + Plan: &plan, + TermMonths: 1, + PaymentMethod: paymentMethodTopup, + TopupAmount: ptrFloat64(5), + }) + if err != nil { + t.Fatalf("executePaymentFlow() error = %v", err) + } + if result == nil { + t.Fatal("executePaymentFlow() result is nil") + } + if len(publisher.events) != 1 { + t.Fatalf("published events = %d, want 1", len(publisher.events)) + } + if publisher.events[0].notification == nil || publisher.events[0].notification.Type != "billing.subscription" { + t.Fatalf("published notification = %#v", publisher.events[0].notification) + } +} + +func TestTopupWallet_PublishesNotificationEvent(t *testing.T) { + db := newTestDB(t) + services := newTestAppServices(t, db) + publisher := &fakeNotificationEventPublisher{} + services.notificationEvents = publisher + user := seedTestUser(t, db, model.User{ID: uuid.NewString(), Email: "user@example.com", Role: ptrString("USER")}) + + _, err := (&paymentsAppService{appServices: services}).TopupWallet(testActorIncomingContext(user.ID, "USER"), &appv1.TopupWalletRequest{Amount: 12}) + if err != nil { + t.Fatalf("TopupWallet() error = %v", err) + } + if len(publisher.events) != 1 { + t.Fatalf("published events = %d, want 1", len(publisher.events)) + } + if publisher.events[0].notification == nil || publisher.events[0].notification.Type != "billing.topup" { + t.Fatalf("published notification = %#v", publisher.events[0].notification) + } +} + +func TestBuildNotificationCreatedPayload(t *testing.T) { + now := time.Now().UTC() + notification := &model.Notification{ + ID: uuid.NewString(), + UserID: uuid.NewString(), + Type: "billing.subscription", + Title: "Subscription activated", + Message: "Your subscription is active.", + ActionURL: ptrString("/settings/billing"), + ActionLabel: ptrString("Renew plan"), + CreatedAt: &now, + } + payload := BuildNotificationCreatedPayload(notification) + if payload.ID != notification.ID || payload.UserID != notification.UserID || payload.Type != notification.Type { + t.Fatalf("payload = %#v", payload) + } + if payload.CreatedAt == "" { + t.Fatal("payload created_at should not be empty") + } +} diff --git a/internal/service/__test__/service_popup_ads_test.go b/internal/service/__test__/service_popup_ads_test.go new file mode 100644 index 0000000..46746ad --- /dev/null +++ b/internal/service/__test__/service_popup_ads_test.go @@ -0,0 +1,177 @@ +package service + +import ( + "testing" + "time" + + "github.com/google/uuid" + "google.golang.org/grpc/codes" + appv1 "stream.api/internal/api/proto/app/v1" + "stream.api/internal/database/model" +) + +func TestPopupAdsUserFlow(t *testing.T) { + t.Run("create list update delete popup ad", func(t *testing.T) { + db := newTestDB(t) + services := newTestAppServices(t, db) + user := seedTestUser(t, db, model.User{ID: uuid.NewString(), Email: "user@example.com", Role: ptrString("USER")}) + + startAt := time.Now().UTC().Add(-time.Hour) + endAt := time.Now().UTC().Add(2 * time.Hour) + createResp, err := services.CreatePopupAd(testActorIncomingContext(user.ID, "USER"), &appv1.CreatePopupAdRequest{ + Title: "Homepage Campaign", + ImageUrl: "https://cdn.example.com/banner.jpg", + TargetUrl: "https://example.com/landing", + IsActive: ptrBool(true), + StartAt: timeToProto(&startAt), + EndAt: timeToProto(&endAt), + Priority: int32Ptr(5), + CloseCooldownMinutes: int32Ptr(90), + }) + if err != nil { + t.Fatalf("CreatePopupAd() error = %v", err) + } + if createResp.Item == nil || createResp.Item.Title != "Homepage Campaign" { + t.Fatalf("CreatePopupAd() unexpected response: %#v", createResp) + } + + listResp, err := services.ListPopupAds(testActorIncomingContext(user.ID, "USER"), &appv1.ListPopupAdsRequest{}) + if err != nil { + t.Fatalf("ListPopupAds() error = %v", err) + } + if len(listResp.Items) != 1 { + t.Fatalf("ListPopupAds() count = %d, want 1", len(listResp.Items)) + } + + updateResp, err := services.UpdatePopupAd(testActorIncomingContext(user.ID, "USER"), &appv1.UpdatePopupAdRequest{ + Id: createResp.Item.Id, + Title: "Homepage Campaign v2", + ImageUrl: "https://cdn.example.com/banner-v2.jpg", + TargetUrl: "https://example.com/landing-v2", + IsActive: ptrBool(false), + Priority: int32Ptr(8), + CloseCooldownMinutes: int32Ptr(30), + }) + if err != nil { + t.Fatalf("UpdatePopupAd() error = %v", err) + } + if updateResp.Item == nil || updateResp.Item.Title != "Homepage Campaign v2" || updateResp.Item.IsActive { + t.Fatalf("UpdatePopupAd() unexpected response: %#v", updateResp) + } + + items := mustListPopupAdsByUser(t, db, user.ID) + if len(items) != 1 { + t.Fatalf("popup ad count = %d, want 1", len(items)) + } + if items[0].Priority != 8 || items[0].CloseCooldownMinutes != 30 { + t.Fatalf("popup ad values = %#v", items[0]) + } + + _, err = services.DeletePopupAd(testActorIncomingContext(user.ID, "USER"), &appv1.DeletePopupAdRequest{Id: createResp.Item.Id}) + if err != nil { + t.Fatalf("DeletePopupAd() error = %v", err) + } + items = mustListPopupAdsByUser(t, db, user.ID) + if len(items) != 0 { + t.Fatalf("popup ad count after delete = %d, want 0", len(items)) + } + }) + + t.Run("reject invalid schedule", func(t *testing.T) { + db := newTestDB(t) + services := newTestAppServices(t, db) + user := seedTestUser(t, db, model.User{ID: uuid.NewString(), Email: "user@example.com", Role: ptrString("USER")}) + startAt := time.Now().UTC().Add(time.Hour) + endAt := time.Now().UTC() + + _, err := services.CreatePopupAd(testActorIncomingContext(user.ID, "USER"), &appv1.CreatePopupAdRequest{ + Title: "Invalid", + ImageUrl: "https://cdn.example.com/banner.jpg", + TargetUrl: "https://example.com/landing", + StartAt: timeToProto(&startAt), + EndAt: timeToProto(&endAt), + }) + assertGRPCCode(t, err, codes.InvalidArgument) + }) + + t.Run("get active popup ad picks highest priority valid item", func(t *testing.T) { + db := newTestDB(t) + services := newTestAppServices(t, db) + user := seedTestUser(t, db, model.User{ID: uuid.NewString(), Email: "user@example.com", Role: ptrString("USER")}) + now := time.Now().UTC() + seedTestPopupAd(t, db, model.PopupAd{ID: uuid.NewString(), UserID: user.ID, Title: "inactive", ImageURL: "https://cdn.example.com/1.jpg", TargetURL: "https://example.com/1", IsActive: ptrBool(false), Priority: 99}) + seedTestPopupAd(t, db, model.PopupAd{ID: uuid.NewString(), UserID: user.ID, Title: "expired", ImageURL: "https://cdn.example.com/2.jpg", TargetURL: "https://example.com/2", IsActive: ptrBool(true), Priority: 50, StartAt: ptrTime(now.Add(-2 * time.Hour)), EndAt: ptrTime(now.Add(-time.Hour))}) + seedTestPopupAd(t, db, model.PopupAd{ID: uuid.NewString(), UserID: user.ID, Title: "low", ImageURL: "https://cdn.example.com/3.jpg", TargetURL: "https://example.com/3", IsActive: ptrBool(true), Priority: 1, StartAt: ptrTime(now.Add(-time.Hour)), EndAt: ptrTime(now.Add(time.Hour))}) + winner := seedTestPopupAd(t, db, model.PopupAd{ID: uuid.NewString(), UserID: user.ID, Title: "winner", ImageURL: "https://cdn.example.com/4.jpg", TargetURL: "https://example.com/4", IsActive: ptrBool(true), Priority: 10, StartAt: ptrTime(now.Add(-time.Hour)), EndAt: ptrTime(now.Add(time.Hour)), CloseCooldownMinutes: 15}) + + resp, err := services.GetActivePopupAd(testActorIncomingContext(user.ID, "USER"), &appv1.GetActivePopupAdRequest{}) + if err != nil { + t.Fatalf("GetActivePopupAd() error = %v", err) + } + if resp.Item == nil || resp.Item.Id != winner.ID { + t.Fatalf("GetActivePopupAd() = %#v, want winner %q", resp.Item, winner.ID) + } + }) +} + +func TestPopupAdsAdminFlow(t *testing.T) { + t.Run("admin create list update delete popup ad", func(t *testing.T) { + db := newTestDB(t) + services := newTestAppServices(t, db) + admin := seedTestUser(t, db, model.User{ID: uuid.NewString(), Email: "admin@example.com", Role: ptrString("ADMIN")}) + user := seedTestUser(t, db, model.User{ID: uuid.NewString(), Email: "user@example.com", Role: ptrString("USER")}) + conn, cleanup := newTestGRPCServer(t, services) + defer cleanup() + + client := newAdminClient(conn) + createResp, err := client.CreateAdminPopupAd(testActorOutgoingContext(admin.ID, "ADMIN"), &appv1.CreateAdminPopupAdRequest{ + UserId: user.ID, + Title: "Admin Campaign", + ImageUrl: "https://cdn.example.com/admin.jpg", + TargetUrl: "https://example.com/admin", + IsActive: ptrBool(true), + Priority: int32Ptr(7), + CloseCooldownMinutes: int32Ptr(45), + }) + if err != nil { + t.Fatalf("CreateAdminPopupAd() error = %v", err) + } + if createResp.Item == nil || createResp.Item.UserId != user.ID { + t.Fatalf("CreateAdminPopupAd() unexpected response: %#v", createResp) + } + + listResp, err := client.ListAdminPopupAds(testActorOutgoingContext(admin.ID, "ADMIN"), &appv1.ListAdminPopupAdsRequest{UserId: &user.ID}) + if err != nil { + t.Fatalf("ListAdminPopupAds() error = %v", err) + } + if len(listResp.Items) != 1 { + t.Fatalf("ListAdminPopupAds() count = %d, want 1", len(listResp.Items)) + } + + updateResp, err := client.UpdateAdminPopupAd(testActorOutgoingContext(admin.ID, "ADMIN"), &appv1.UpdateAdminPopupAdRequest{ + Id: createResp.Item.Id, + UserId: user.ID, + Title: "Admin Campaign v2", + ImageUrl: "https://cdn.example.com/admin-v2.jpg", + TargetUrl: "https://example.com/admin-v2", + IsActive: ptrBool(false), + Priority: int32Ptr(11), + CloseCooldownMinutes: int32Ptr(10), + }) + if err != nil { + t.Fatalf("UpdateAdminPopupAd() error = %v", err) + } + if updateResp.Item == nil || updateResp.Item.Title != "Admin Campaign v2" || updateResp.Item.IsActive { + t.Fatalf("UpdateAdminPopupAd() unexpected response: %#v", updateResp) + } + + _, err = client.DeleteAdminPopupAd(testActorOutgoingContext(admin.ID, "ADMIN"), &appv1.DeleteAdminPopupAdRequest{Id: createResp.Item.Id}) + if err != nil { + t.Fatalf("DeleteAdminPopupAd() error = %v", err) + } + items := mustListPopupAdsByUser(t, db, user.ID) + if len(items) != 0 { + t.Fatalf("popup ad count after delete = %d, want 0", len(items)) + } + }) +} diff --git a/internal/service/__test__/testdb_setup_test.go b/internal/service/__test__/testdb_setup_test.go index d9babf9..ea8673b 100644 --- a/internal/service/__test__/testdb_setup_test.go +++ b/internal/service/__test__/testdb_setup_test.go @@ -15,11 +15,12 @@ import ( "google.golang.org/grpc/test/bufconn" "gorm.io/driver/sqlite" "gorm.io/gorm" - _ "modernc.org/sqlite" + _ "github.com/mattn/go-sqlite3" appv1 "stream.api/internal/api/proto/app/v1" "stream.api/internal/database/model" "stream.api/internal/database/query" "stream.api/internal/middleware" + "stream.api/internal/repository" "stream.api/pkg/logger" ) @@ -74,7 +75,7 @@ func newTestDB(t *testing.T) *gorm.DB { t.Helper() dsn := fmt.Sprintf("file:%s?mode=memory&cache=shared", uuid.NewString()) - db, err := gorm.Open(sqlite.Dialector{DriverName: "sqlite", DSN: dsn}, &gorm.Config{}) + db, err := gorm.Open(sqlite.Dialector{DriverName: "sqlite3", DSN: dsn}, &gorm.Config{}) if err != nil { t.Fatalf("open sqlite db: %v", err) } @@ -206,6 +207,21 @@ func newTestDB(t *testing.T) *gorm.DB { encrytion_m3u8 BOOLEAN NOT NULL DEFAULT 1, logo_url TEXT )`, + `CREATE TABLE popup_ads ( + id TEXT PRIMARY KEY, + user_id TEXT NOT NULL, + title TEXT NOT NULL, + image_url TEXT NOT NULL, + target_url TEXT NOT NULL, + is_active BOOLEAN NOT NULL DEFAULT 1, + start_at DATETIME, + end_at DATETIME, + priority INTEGER NOT NULL DEFAULT 0, + close_cooldown_minutes INTEGER NOT NULL DEFAULT 60, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME, + version INTEGER NOT NULL DEFAULT 1 + )`, } { if err := db.Exec(stmt).Error; err != nil { t.Fatalf("create test schema: %v", err) @@ -226,9 +242,17 @@ func newTestAppServices(t *testing.T, db *gorm.DB) *appServices { return &appServices{ db: db, logger: testLogger{}, - authenticator: middleware.NewAuthenticator(db, testLogger{}, testTrustedMarker), + authenticator: middleware.NewAuthenticator(db, testLogger{}, testTrustedMarker, nil), // cache: &fakeCache{values: map[string]string{}}, - googleUserInfoURL: defaultGoogleUserInfoURL, + googleUserInfoURL: defaultGoogleUserInfoURL, + userRepository: repository.NewUserRepository(db), + planRepository: repository.NewPlanRepository(db), + paymentRepository: repository.NewPaymentRepository(db), + notificationRepo: repository.NewNotificationRepository(db), + domainRepository: repository.NewDomainRepository(db), + adTemplateRepository: repository.NewAdTemplateRepository(db), + popupAdRepository: repository.NewPopupAdRepository(db), + playerConfigRepo: repository.NewPlayerConfigRepository(db), } } @@ -244,6 +268,7 @@ func newTestGRPCServer(t *testing.T, services *appServices) (*grpc.ClientConn, f NotificationsServer: services, DomainsServer: services, AdTemplatesServer: services, + PopupAdsServer: services, PlayerConfigsServer: services, PlansServer: services, PaymentsServer: services, @@ -382,4 +407,33 @@ func newAdminClient(conn *grpc.ClientConn) appv1.AdminClient { return appv1.NewAdminClient(conn) } +func ptrTime(v time.Time) *time.Time { return &v } + +func seedTestPopupAd(t *testing.T, db *gorm.DB, item model.PopupAd) model.PopupAd { + t.Helper() + if item.IsActive == nil { + item.IsActive = ptrBool(true) + } + if item.CreatedAt == nil { + now := time.Now().UTC() + item.CreatedAt = &now + } + if item.CloseCooldownMinutes == 0 { + item.CloseCooldownMinutes = 60 + } + if err := db.Create(&item).Error; err != nil { + t.Fatalf("create popup ad: %v", err) + } + return item +} + +func mustListPopupAdsByUser(t *testing.T, db *gorm.DB, userID string) []model.PopupAd { + t.Helper() + var items []model.PopupAd + if err := db.Order("priority DESC, created_at DESC").Find(&items, "user_id = ?", userID).Error; err != nil { + t.Fatalf("list popup ads for user %s: %v", userID, err) + } + return items +} + var _ logger.Logger = testLogger{} diff --git a/internal/service/admin_helpers.go b/internal/service/admin_helpers.go index 037f056..a078267 100644 --- a/internal/service/admin_helpers.go +++ b/internal/service/admin_helpers.go @@ -464,6 +464,23 @@ func validateAdminAdTemplateInput(userID, name, vastTagURL, adFormat string, dur return "" } +func validateAdminPopupAdInput(userID, popupType, label, value string, maxTriggersPerSession *int32) string { + if strings.TrimSpace(userID) == "" { + return "User ID is required" + } + popupType = strings.ToLower(strings.TrimSpace(popupType)) + if popupType != "url" && popupType != "script" { + return "Popup ad type must be url or script" + } + if strings.TrimSpace(label) == "" || strings.TrimSpace(value) == "" { + return "Label and value are required" + } + if maxTriggersPerSession != nil && *maxTriggersPerSession < 1 { + return "Max triggers per session must be greater than 0" + } + return "" +} + func validateAdminPlayerConfigInput(userID, name string) string { if strings.TrimSpace(userID) == "" { return "User ID is required" @@ -503,6 +520,32 @@ func (s *appServices) buildAdminPlan(ctx context.Context, plan *model.Plan) (*ap return payload, nil } +func (s *appServices) buildAdminPopupAd(ctx context.Context, item *model.PopupAd) (*appv1.AdminPopupAd, error) { + if item == nil { + return nil, nil + } + + payload := &appv1.AdminPopupAd{ + Id: item.ID, + UserId: item.UserID, + Type: item.Type, + Label: item.Label, + Value: item.Value, + IsActive: boolValue(item.IsActive), + MaxTriggersPerSession: func() int32 { if item.MaxTriggersPerSession != nil { return *item.MaxTriggersPerSession }; return 0 }(), + CreatedAt: timeToProto(item.CreatedAt), + UpdatedAt: timeToProto(item.UpdatedAt), + } + + ownerEmail, err := s.loadAdminUserEmail(ctx, item.UserID) + if err != nil { + return nil, err + } + payload.OwnerEmail = ownerEmail + + return payload, nil +} + func (s *appServices) buildAdminAdTemplate(ctx context.Context, item *model.AdTemplate) (*appv1.AdminAdTemplate, error) { if item == nil { return nil, nil diff --git a/internal/service/catalog_mapper.go b/internal/service/catalog_mapper.go index 1f7f3ce..73fb5a3 100644 --- a/internal/service/catalog_mapper.go +++ b/internal/service/catalog_mapper.go @@ -1,7 +1,9 @@ package service -import appv1 "stream.api/internal/api/proto/app/v1" -import "stream.api/internal/database/model" +import ( + appv1 "stream.api/internal/api/proto/app/v1" + "stream.api/internal/database/model" +) func toProtoDomain(item *model.Domain) *appv1.Domain { if item == nil { @@ -33,6 +35,22 @@ func toProtoAdTemplate(item *model.AdTemplate) *appv1.AdTemplate { } } +func toProtoPopupAd(item *model.PopupAd) *appv1.PopupAd { + if item == nil { + return nil + } + return &appv1.PopupAd{ + Id: item.ID, + Type: item.Type, + Label: item.Label, + Value: item.Value, + IsActive: boolValue(item.IsActive), + MaxTriggersPerSession: func() int32 { if item.MaxTriggersPerSession != nil { return *item.MaxTriggersPerSession }; return 0 }(), + CreatedAt: timeToProto(item.CreatedAt), + UpdatedAt: timeToProto(item.UpdatedAt), + } +} + func toProtoPlayerConfig(item *model.PlayerConfig) *appv1.PlayerConfig { if item == nil { return nil diff --git a/internal/service/interface.go b/internal/service/interface.go index b867c0d..f3daa84 100644 --- a/internal/service/interface.go +++ b/internal/service/interface.go @@ -43,6 +43,10 @@ type PaymentRepository interface { ExecuteSubscriptionPayment(ctx context.Context, userID string, plan *model.Plan, termMonths int32, paymentMethod string, paymentRecord *model.Payment, invoiceID string, now time.Time, validateFunding func(currentWalletBalance float64) (float64, error)) (*model.PlanSubscription, float64, error) } +type NotificationEventPublisher interface { + PublishNotificationCreated(ctx context.Context, notification *model.Notification) error +} + type AccountRepository interface { DeleteUserAccount(ctx context.Context, userID string) error ClearUserData(ctx context.Context, userID string) error @@ -76,6 +80,18 @@ type AdTemplateRepository interface { DeleteByIDAndClearVideos(ctx context.Context, id string) error } +type PopupAdRepository interface { + ListByUser(ctx context.Context, userID string, limit int32, offset int) ([]model.PopupAd, int64, error) + ListForAdmin(ctx context.Context, search string, userID string, limit int32, offset int) ([]model.PopupAd, int64, error) + GetByID(ctx context.Context, id string) (*model.PopupAd, error) + GetByIDAndUser(ctx context.Context, id string, userID string) (*model.PopupAd, error) + GetActiveByUser(ctx context.Context, userID string) (*model.PopupAd, error) + Create(ctx context.Context, item *model.PopupAd) error + Save(ctx context.Context, item *model.PopupAd) error + DeleteByIDAndUser(ctx context.Context, id string, userID string) (int64, error) + DeleteByID(ctx context.Context, id string) (int64, error) +} + type PlayerConfigRepository interface { ListByUser(ctx context.Context, userID string) ([]model.PlayerConfig, error) ListForAdmin(ctx context.Context, search string, userID string, limit int32, offset int) ([]model.PlayerConfig, int64, error) diff --git a/internal/service/notification_events.go b/internal/service/notification_events.go new file mode 100644 index 0000000..a8e67bf --- /dev/null +++ b/internal/service/notification_events.go @@ -0,0 +1,57 @@ +package service + +import ( + "context" + "encoding/json" + "time" + + "stream.api/internal/database/model" +) + +type noopNotificationEventPublisher struct{} + +func (noopNotificationEventPublisher) PublishNotificationCreated(context.Context, *model.Notification) error { + return nil +} + +type NotificationCreatedPayload struct { + ID string `json:"id"` + UserID string `json:"user_id"` + Type string `json:"type"` + Title string `json:"title"` + Message string `json:"message"` + ActionURL *string `json:"action_url,omitempty"` + ActionLabel *string `json:"action_label,omitempty"` + CreatedAt string `json:"created_at,omitempty"` +} + +func (s *appServices) publishNotificationCreated(ctx context.Context, notification *model.Notification) { + if s == nil || s.notificationEvents == nil || notification == nil { + return + } + if err := s.notificationEvents.PublishNotificationCreated(ctx, notification); err != nil { + s.logger.Error("Failed to publish notification MQTT event", "error", err, "notification_id", notification.ID, "user_id", notification.UserID) + } +} + +func BuildNotificationCreatedPayload(notification *model.Notification) NotificationCreatedPayload { + createdAt := "" + if notification != nil && notification.CreatedAt != nil { + createdAt = notification.CreatedAt.UTC().Format(time.RFC3339) + } + return NotificationCreatedPayload{ + ID: notification.ID, + UserID: notification.UserID, + Type: notification.Type, + Title: notification.Title, + Message: notification.Message, + ActionURL: nullableTrimmedString(notification.ActionURL), + ActionLabel: nullableTrimmedString(notification.ActionLabel), + CreatedAt: createdAt, + } +} + +func mustMarshalNotificationPayload(notification *model.Notification) []byte { + encoded, _ := json.Marshal(BuildNotificationCreatedPayload(notification)) + return encoded +} diff --git a/internal/service/notification_events_test.go b/internal/service/notification_events_test.go new file mode 100644 index 0000000..57017f6 --- /dev/null +++ b/internal/service/notification_events_test.go @@ -0,0 +1,175 @@ +package service + +import ( + "context" + "fmt" + "testing" + "time" + + "github.com/google/uuid" + "google.golang.org/grpc/metadata" + _ "modernc.org/sqlite" + "gorm.io/driver/sqlite" + "gorm.io/gorm" + appv1 "stream.api/internal/api/proto/app/v1" + "stream.api/internal/database/model" + "stream.api/internal/database/query" + "stream.api/internal/middleware" + "stream.api/internal/repository" +) + +type serviceTestLogger struct{} + +func (serviceTestLogger) Info(string, ...any) {} +func (serviceTestLogger) Error(string, ...any) {} +func (serviceTestLogger) Debug(string, ...any) {} +func (serviceTestLogger) Warn(string, ...any) {} + +const notificationTestTrustedMarker = "trusted-notification-test-marker" + +type publishedNotificationEvent struct { + notification *model.Notification +} + +type fakeNotificationEventPublisher struct { + events []publishedNotificationEvent +} + +func (f *fakeNotificationEventPublisher) PublishNotificationCreated(_ context.Context, notification *model.Notification) error { + copyNotification := *notification + f.events = append(f.events, publishedNotificationEvent{notification: ©Notification}) + return nil +} + +func newNotificationTestDB(t *testing.T) *gorm.DB { + t.Helper() + dsn := fmt.Sprintf("file:%s?mode=memory&cache=shared", uuid.NewString()) + db, err := gorm.Open(sqlite.Dialector{DriverName: "sqlite", DSN: dsn}, &gorm.Config{}) + if err != nil { + t.Fatalf("open sqlite db: %v", err) + } + for _, stmt := range []string{ + `CREATE TABLE user (id TEXT PRIMARY KEY,email TEXT NOT NULL,password TEXT,username TEXT,avatar TEXT,role TEXT NOT NULL,google_id TEXT,storage_used INTEGER NOT NULL DEFAULT 0,plan_id TEXT,referred_by_user_id TEXT,referral_eligible BOOLEAN NOT NULL DEFAULT 1,referral_reward_bps INTEGER,referral_reward_granted_at DATETIME,referral_reward_payment_id TEXT,referral_reward_amount REAL,created_at DATETIME DEFAULT CURRENT_TIMESTAMP,updated_at DATETIME,version INTEGER NOT NULL DEFAULT 1,telegram_id TEXT)`, + `CREATE TABLE plan (id TEXT PRIMARY KEY,name TEXT NOT NULL,description TEXT,price REAL NOT NULL,cycle TEXT NOT NULL,storage_limit INTEGER NOT NULL,upload_limit INTEGER NOT NULL,duration_limit INTEGER NOT NULL,quality_limit TEXT NOT NULL,features JSON,is_active BOOLEAN NOT NULL DEFAULT 1,version INTEGER NOT NULL DEFAULT 1)`, + `CREATE TABLE payment (id TEXT PRIMARY KEY,user_id TEXT NOT NULL,plan_id TEXT,amount REAL NOT NULL,currency TEXT,status TEXT,provider TEXT,transaction_id TEXT,created_at DATETIME DEFAULT CURRENT_TIMESTAMP,updated_at DATETIME,version INTEGER NOT NULL DEFAULT 1)`, + `CREATE TABLE plan_subscriptions (id TEXT PRIMARY KEY,user_id TEXT NOT NULL,payment_id TEXT NOT NULL,plan_id TEXT NOT NULL,term_months INTEGER NOT NULL,payment_method TEXT NOT NULL,wallet_amount REAL NOT NULL,topup_amount REAL NOT NULL,started_at DATETIME NOT NULL,expires_at DATETIME NOT NULL,reminder_7d_sent_at DATETIME,reminder_3d_sent_at DATETIME,reminder_1d_sent_at DATETIME,created_at DATETIME DEFAULT CURRENT_TIMESTAMP,updated_at DATETIME,version INTEGER NOT NULL DEFAULT 1)`, + `CREATE TABLE wallet_transactions (id TEXT PRIMARY KEY,user_id TEXT NOT NULL,type TEXT NOT NULL,amount REAL NOT NULL,currency TEXT,note TEXT,created_at DATETIME DEFAULT CURRENT_TIMESTAMP,updated_at DATETIME,payment_id TEXT,plan_id TEXT,term_months INTEGER,version INTEGER NOT NULL DEFAULT 1)`, + `CREATE TABLE notifications (id TEXT PRIMARY KEY,user_id TEXT NOT NULL,type TEXT NOT NULL,title TEXT NOT NULL,message TEXT NOT NULL,metadata TEXT,action_url TEXT,action_label TEXT,is_read BOOLEAN NOT NULL DEFAULT 0,created_at DATETIME DEFAULT CURRENT_TIMESTAMP,updated_at DATETIME,version INTEGER NOT NULL DEFAULT 1)`, + } { + if err := db.Exec(stmt).Error; err != nil { + t.Fatalf("create test schema: %v", err) + } + } + query.SetDefault(db) + return db +} + +func newNotificationTestServices(t *testing.T, db *gorm.DB, publisher NotificationEventPublisher) *appServices { + t.Helper() + return &appServices{ + db: db, + logger: serviceTestLogger{}, + authenticator: middleware.NewAuthenticator(db, serviceTestLogger{}, notificationTestTrustedMarker, publisher), + googleUserInfoURL: defaultGoogleUserInfoURL, + userRepository: repository.NewUserRepository(db), + planRepository: repository.NewPlanRepository(db), + paymentRepository: repository.NewPaymentRepository(db), + billingRepository: repository.NewBillingRepository(db), + notificationRepo: repository.NewNotificationRepository(db), + notificationEvents: publisher, + } +} + +func notificationTestContext(userID, role string) context.Context { + return metadata.NewIncomingContext(context.Background(), metadata.Pairs( + middleware.ActorMarkerMetadataKey, notificationTestTrustedMarker, + middleware.ActorIDMetadataKey, userID, + middleware.ActorRoleMetadataKey, role, + middleware.ActorEmailMetadataKey, "actor@example.com", + )) +} + +func notificationPtrString(v string) *string { return &v } +func notificationPtrBool(v bool) *bool { return &v } +func notificationPtrFloat64(v float64) *float64 { return &v } + +func seedNotificationUser(t *testing.T, db *gorm.DB, user model.User) model.User { + t.Helper() + if user.Role == nil { + user.Role = notificationPtrString("USER") + } + if err := db.Create(&user).Error; err != nil { + t.Fatalf("create user: %v", err) + } + return user +} + +func seedNotificationPlan(t *testing.T, db *gorm.DB, plan model.Plan) model.Plan { + t.Helper() + if plan.IsActive == nil { + plan.IsActive = notificationPtrBool(true) + } + if err := db.Create(&plan).Error; err != nil { + t.Fatalf("create plan: %v", err) + } + return plan +} + +func seedNotificationWalletTransaction(t *testing.T, db *gorm.DB, tx model.WalletTransaction) model.WalletTransaction { + t.Helper() + if err := db.Create(&tx).Error; err != nil { + t.Fatalf("create wallet transaction: %v", err) + } + return tx +} + +func TestExecutePaymentFlowPublishesNotificationEvent(t *testing.T) { + db := newNotificationTestDB(t) + publisher := &fakeNotificationEventPublisher{} + services := newNotificationTestServices(t, db, publisher) + + user := seedNotificationUser(t, db, model.User{ID: uuid.NewString(), Email: "payer@example.com", Role: notificationPtrString("USER")}) + plan := seedNotificationPlan(t, db, model.Plan{ID: uuid.NewString(), Name: "Pro", Price: 10, Cycle: "monthly", StorageLimit: 100, UploadLimit: 10, QualityLimit: "1080p", IsActive: notificationPtrBool(true)}) + seedNotificationWalletTransaction(t, db, model.WalletTransaction{ID: uuid.NewString(), UserID: user.ID, Type: walletTransactionTypeTopup, Amount: 5, Currency: notificationPtrString("USD")}) + + _, err := services.executePaymentFlow(context.Background(), paymentExecutionInput{UserID: user.ID, Plan: &plan, TermMonths: 1, PaymentMethod: paymentMethodTopup, TopupAmount: notificationPtrFloat64(5)}) + if err != nil { + t.Fatalf("executePaymentFlow() error = %v", err) + } + if len(publisher.events) != 1 { + t.Fatalf("published events = %d, want 1", len(publisher.events)) + } + if publisher.events[0].notification == nil || publisher.events[0].notification.Type != "billing.subscription" { + t.Fatalf("published notification = %#v", publisher.events[0].notification) + } +} + +func TestTopupWalletPublishesNotificationEvent(t *testing.T) { + db := newNotificationTestDB(t) + publisher := &fakeNotificationEventPublisher{} + services := newNotificationTestServices(t, db, publisher) + user := seedNotificationUser(t, db, model.User{ID: uuid.NewString(), Email: "user@example.com", Role: notificationPtrString("USER")}) + + _, err := (&paymentsAppService{appServices: services}).TopupWallet(notificationTestContext(user.ID, "USER"), &appv1.TopupWalletRequest{Amount: 12}) + if err != nil { + t.Fatalf("TopupWallet() error = %v", err) + } + if len(publisher.events) != 1 { + t.Fatalf("published events = %d, want 1", len(publisher.events)) + } + if publisher.events[0].notification == nil || publisher.events[0].notification.Type != "billing.topup" { + t.Fatalf("published notification = %#v", publisher.events[0].notification) + } +} + +func TestBuildNotificationCreatedPayload(t *testing.T) { + now := time.Now().UTC() + notification := &model.Notification{ID: uuid.NewString(), UserID: uuid.NewString(), Type: "billing.subscription", Title: "Subscription activated", Message: "Your subscription is active.", ActionURL: notificationPtrString("/settings/billing"), ActionLabel: notificationPtrString("Renew plan"), CreatedAt: &now} + payload := BuildNotificationCreatedPayload(notification) + if payload.ID != notification.ID || payload.UserID != notification.UserID || payload.Type != notification.Type { + t.Fatalf("payload = %#v", payload) + } + if payload.CreatedAt == "" { + t.Fatal("payload created_at should not be empty") + } +} diff --git a/internal/service/payment_helpers.go b/internal/service/payment_helpers.go index 74b49e1..fe95ffa 100644 --- a/internal/service/payment_helpers.go +++ b/internal/service/payment_helpers.go @@ -118,6 +118,9 @@ func (s *appServices) executePaymentFlow(ctx context.Context, input paymentExecu } result.Subscription = subscription result.WalletBalance = walletBalance + if notification := latestNotificationForPayment(result.Payment, subscription, input.Plan, invoiceID); notification != nil { + s.publishNotificationCreated(ctx, notification) + } return result, nil } diff --git a/internal/service/payment_notification_helpers.go b/internal/service/payment_notification_helpers.go new file mode 100644 index 0000000..25d14e6 --- /dev/null +++ b/internal/service/payment_notification_helpers.go @@ -0,0 +1,31 @@ +package service + +import ( + "fmt" + "time" + + "stream.api/internal/database/model" +) + +func latestNotificationForPayment(paymentRecord *model.Payment, subscription *model.PlanSubscription, plan *model.Plan, invoiceID string) *model.Notification { + if paymentRecord == nil || subscription == nil || plan == nil { + return nil + } + return &model.Notification{ + ID: "", + UserID: paymentRecord.UserID, + Type: "billing.subscription", + Title: "Subscription activated", + Message: fmt.Sprintf("Your subscription to %s is active until %s.", plan.Name, subscription.ExpiresAt.UTC().Format("2006-01-02")), + Metadata: model.StringPtr(mustMarshalJSON(map[string]any{ + "payment_id": paymentRecord.ID, + "invoice_id": invoiceID, + "plan_id": plan.ID, + "term_months": subscription.TermMonths, + "payment_method": subscription.PaymentMethod, + "wallet_amount": subscription.WalletAmount, + "topup_amount": subscription.TopupAmount, + "plan_expires_at": subscription.ExpiresAt.UTC().Format(time.RFC3339), + })), + } +} diff --git a/internal/service/referral_helpers.go b/internal/service/referral_helpers.go index d0a51e6..e75a5f3 100644 --- a/internal/service/referral_helpers.go +++ b/internal/service/referral_helpers.go @@ -205,9 +205,11 @@ func (s *appServices) maybeGrantReferralReward(ctx context.Context, tx *gorm.DB, if err := s.paymentRepository.CreateWalletTransactionTx(tx, ctx, rewardTransaction); err != nil { return nil, err } - if err := s.paymentRepository.CreateNotificationTx(tx, ctx, buildReferralRewardNotification(referrer.ID, rewardAmount, referee, paymentRecord)); err != nil { + rewardNotification := buildReferralRewardNotification(referrer.ID, rewardAmount, referee, paymentRecord) + if err := s.paymentRepository.CreateNotificationTx(tx, ctx, rewardNotification); err != nil { return nil, err } + s.publishNotificationCreated(ctx, rewardNotification) now := time.Now().UTC() updates := map[string]any{ diff --git a/internal/service/register.go b/internal/service/register.go index 9d22816..d49e555 100644 --- a/internal/service/register.go +++ b/internal/service/register.go @@ -11,6 +11,7 @@ func Register(server grpc.ServiceRegistrar, services *Services) { appv1.RegisterNotificationsServer(server, services.NotificationsServer) appv1.RegisterDomainsServer(server, services.DomainsServer) appv1.RegisterAdTemplatesServer(server, services.AdTemplatesServer) + appv1.RegisterPopupAdsServer(server, services.PopupAdsServer) appv1.RegisterPlayerConfigsServer(server, services.PlayerConfigsServer) appv1.RegisterPlansServer(server, services.PlansServer) appv1.RegisterPaymentsServer(server, services.PaymentsServer) diff --git a/internal/service/service_admin_finance_catalog.go b/internal/service/service_admin_finance_catalog.go index ab79d53..00108fd 100644 --- a/internal/service/service_admin_finance_catalog.go +++ b/internal/service/service_admin_finance_catalog.go @@ -461,6 +461,150 @@ func (s *appServices) DeleteAdminAdTemplate(ctx context.Context, req *appv1.Dele return &appv1.MessageResponse{Message: "Ad template deleted"}, nil } +func (s *appServices) ListAdminPopupAds(ctx context.Context, req *appv1.ListAdminPopupAdsRequest) (*appv1.ListAdminPopupAdsResponse, error) { + if _, err := s.requireAdmin(ctx); err != nil { + return nil, err + } + + page, limit, offset := adminPageLimitOffset(req.GetPage(), req.GetLimit()) + search := strings.TrimSpace(protoStringValue(req.Search)) + userID := strings.TrimSpace(protoStringValue(req.UserId)) + + items, total, err := s.popupAdRepository.ListForAdmin(ctx, search, userID, limit, offset) + if err != nil { + return nil, status.Error(codes.Internal, "Failed to list popup ads") + } + + payload := make([]*appv1.AdminPopupAd, 0, len(items)) + for i := range items { + mapped, err := s.buildAdminPopupAd(ctx, &items[i]) + if err != nil { + return nil, status.Error(codes.Internal, "Failed to list popup ads") + } + payload = append(payload, mapped) + } + + return &appv1.ListAdminPopupAdsResponse{Items: payload, Total: total, Page: page, Limit: limit}, nil +} +func (s *appServices) GetAdminPopupAd(ctx context.Context, req *appv1.GetAdminPopupAdRequest) (*appv1.GetAdminPopupAdResponse, error) { + if _, err := s.requireAdmin(ctx); err != nil { + return nil, err + } + id := strings.TrimSpace(req.GetId()) + if id == "" { + return nil, status.Error(codes.NotFound, "Popup ad not found") + } + item, err := s.popupAdRepository.GetByID(ctx, id) + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return nil, status.Error(codes.NotFound, "Popup ad not found") + } + return nil, status.Error(codes.Internal, "Failed to load popup ad") + } + payload, err := s.buildAdminPopupAd(ctx, item) + if err != nil { + return nil, status.Error(codes.Internal, "Failed to load popup ad") + } + return &appv1.GetAdminPopupAdResponse{Item: payload}, nil +} +func (s *appServices) CreateAdminPopupAd(ctx context.Context, req *appv1.CreateAdminPopupAdRequest) (*appv1.CreateAdminPopupAdResponse, error) { + if _, err := s.requireAdmin(ctx); err != nil { + return nil, err + } + if msg := validateAdminPopupAdInput(req.GetUserId(), req.GetType(), req.GetLabel(), req.GetValue(), req.MaxTriggersPerSession); msg != "" { + return nil, status.Error(codes.InvalidArgument, msg) + } + user, err := s.userRepository.GetByID(ctx, strings.TrimSpace(req.GetUserId())) + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return nil, status.Error(codes.InvalidArgument, "User not found") + } + return nil, status.Error(codes.Internal, "Failed to save popup ad") + } + maxTriggers := int32(3) + if req.MaxTriggersPerSession != nil { + maxTriggers = *req.MaxTriggersPerSession + } + item := &model.PopupAd{ + ID: uuid.New().String(), + UserID: user.ID, + Type: strings.ToLower(strings.TrimSpace(req.GetType())), + Label: strings.TrimSpace(req.GetLabel()), + Value: strings.TrimSpace(req.GetValue()), + IsActive: model.BoolPtr(req.IsActive == nil || *req.IsActive), + MaxTriggersPerSession: int32Ptr(maxTriggers), + } + if err := s.popupAdRepository.Create(ctx, item); err != nil { + return nil, status.Error(codes.Internal, "Failed to save popup ad") + } + payload, err := s.buildAdminPopupAd(ctx, item) + if err != nil { + return nil, status.Error(codes.Internal, "Failed to save popup ad") + } + return &appv1.CreateAdminPopupAdResponse{Item: payload}, nil +} +func (s *appServices) UpdateAdminPopupAd(ctx context.Context, req *appv1.UpdateAdminPopupAdRequest) (*appv1.UpdateAdminPopupAdResponse, error) { + if _, err := s.requireAdmin(ctx); err != nil { + return nil, err + } + id := strings.TrimSpace(req.GetId()) + if id == "" { + return nil, status.Error(codes.NotFound, "Popup ad not found") + } + if msg := validateAdminPopupAdInput(req.GetUserId(), req.GetType(), req.GetLabel(), req.GetValue(), req.MaxTriggersPerSession); msg != "" { + return nil, status.Error(codes.InvalidArgument, msg) + } + user, err := s.userRepository.GetByID(ctx, strings.TrimSpace(req.GetUserId())) + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return nil, status.Error(codes.InvalidArgument, "User not found") + } + return nil, status.Error(codes.Internal, "Failed to save popup ad") + } + item, err := s.popupAdRepository.GetByID(ctx, id) + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return nil, status.Error(codes.NotFound, "Popup ad not found") + } + return nil, status.Error(codes.Internal, "Failed to save popup ad") + } + item.UserID = user.ID + item.Type = strings.ToLower(strings.TrimSpace(req.GetType())) + item.Label = strings.TrimSpace(req.GetLabel()) + item.Value = strings.TrimSpace(req.GetValue()) + if req.IsActive != nil { + item.IsActive = model.BoolPtr(*req.IsActive) + } + if req.MaxTriggersPerSession != nil { + item.MaxTriggersPerSession = int32Ptr(*req.MaxTriggersPerSession) + } + if err := s.popupAdRepository.Save(ctx, item); err != nil { + return nil, status.Error(codes.Internal, "Failed to save popup ad") + } + payload, err := s.buildAdminPopupAd(ctx, item) + if err != nil { + return nil, status.Error(codes.Internal, "Failed to save popup ad") + } + return &appv1.UpdateAdminPopupAdResponse{Item: payload}, nil +} +func (s *appServices) DeleteAdminPopupAd(ctx context.Context, req *appv1.DeleteAdminPopupAdRequest) (*appv1.MessageResponse, error) { + if _, err := s.requireAdmin(ctx); err != nil { + return nil, err + } + id := strings.TrimSpace(req.GetId()) + if id == "" { + return nil, status.Error(codes.NotFound, "Popup ad not found") + } + rowsAffected, err := s.popupAdRepository.DeleteByID(ctx, id) + if err != nil { + return nil, status.Error(codes.Internal, "Failed to delete popup ad") + } + if rowsAffected == 0 { + return nil, status.Error(codes.NotFound, "Popup ad not found") + } + return &appv1.MessageResponse{Message: "Popup ad deleted"}, nil +} + func (s *appServices) ListAdminPlayerConfigs(ctx context.Context, req *appv1.ListAdminPlayerConfigsRequest) (*appv1.ListAdminPlayerConfigsResponse, error) { if _, err := s.requireAdmin(ctx); err != nil { return nil, err diff --git a/internal/service/service_core.go b/internal/service/service_core.go index ddbb6c6..5413aa2 100644 --- a/internal/service/service_core.go +++ b/internal/service/service_core.go @@ -48,6 +48,7 @@ type Services struct { appv1.NotificationsServer appv1.DomainsServer appv1.AdTemplatesServer + appv1.PopupAdsServer appv1.PlayerConfigsServer appv1.PlansServer appv1.PaymentsServer @@ -60,6 +61,7 @@ type accountAppService struct{ *appServices } type notificationsAppService struct{ *appServices } type domainsAppService struct{ *appServices } type adTemplatesAppService struct{ *appServices } +type popupAdsAppService struct{ *appServices } type playerConfigsAppService struct{ *appServices } type plansAppService struct{ *appServices } type paymentsAppService struct{ *appServices } @@ -72,6 +74,7 @@ type appServices struct { appv1.UnimplementedNotificationsServer appv1.UnimplementedDomainsServer appv1.UnimplementedAdTemplatesServer + appv1.UnimplementedPopupAdsServer appv1.UnimplementedPlayerConfigsServer appv1.UnimplementedPlansServer appv1.UnimplementedPaymentsServer @@ -92,8 +95,10 @@ type appServices struct { paymentRepository PaymentRepository accountRepository AccountRepository notificationRepo NotificationRepository + notificationEvents NotificationEventPublisher domainRepository DomainRepository adTemplateRepository AdTemplateRepository + popupAdRepository PopupAdRepository playerConfigRepo PlayerConfigRepository agentRuntime AgentRuntime googleOauth *oauth2.Config @@ -138,7 +143,7 @@ type apiErrorBody struct { Data any `json:"data,omitempty"` } -func NewServices(c *redis.RedisAdapter, db *gorm.DB, l logger.Logger, cfg *config.Config, videoWorkflowService VideoWorkflow, agentRuntime AgentRuntime) *Services { +func NewServices(c *redis.RedisAdapter, db *gorm.DB, l logger.Logger, cfg *config.Config, videoWorkflowService VideoWorkflow, agentRuntime AgentRuntime, notificationEvents NotificationEventPublisher) *Services { var storageProvider storage.Provider if cfg != nil { provider, err := storage.NewS3Provider(cfg) @@ -175,7 +180,7 @@ func NewServices(c *redis.RedisAdapter, db *gorm.DB, l logger.Logger, cfg *confi service := &appServices{ db: db, logger: l, - authenticator: middleware.NewAuthenticator(db, l, cfg.Internal.Marker), + authenticator: middleware.NewAuthenticator(db, l, cfg.Internal.Marker, notificationEvents), cache: c, storageProvider: storageProvider, videoWorkflowService: videoWorkflowService, @@ -187,8 +192,10 @@ func NewServices(c *redis.RedisAdapter, db *gorm.DB, l logger.Logger, cfg *confi paymentRepository: repository.NewPaymentRepository(db), accountRepository: repository.NewAccountRepository(db), notificationRepo: repository.NewNotificationRepository(db), + notificationEvents: notificationEvents, domainRepository: repository.NewDomainRepository(db), adTemplateRepository: repository.NewAdTemplateRepository(db), + popupAdRepository: repository.NewPopupAdRepository(db), playerConfigRepo: repository.NewPlayerConfigRepository(db), jobRepository: repository.NewJobRepository(db), agentRuntime: agentRuntime, @@ -203,6 +210,7 @@ func NewServices(c *redis.RedisAdapter, db *gorm.DB, l logger.Logger, cfg *confi NotificationsServer: ¬ificationsAppService{appServices: service}, DomainsServer: &domainsAppService{appServices: service}, AdTemplatesServer: &adTemplatesAppService{appServices: service}, + PopupAdsServer: &popupAdsAppService{appServices: service}, PlayerConfigsServer: &playerConfigsAppService{appServices: service}, PlansServer: &plansAppService{appServices: service}, PaymentsServer: &paymentsAppService{appServices: service}, diff --git a/internal/service/service_payments.go b/internal/service/service_payments.go index 52a4669..8b200a0 100644 --- a/internal/service/service_payments.go +++ b/internal/service/service_payments.go @@ -141,6 +141,7 @@ func (s *paymentsAppService) TopupWallet(ctx context.Context, req *appv1.TopupWa s.logger.Error("Failed to top up wallet", "error", err) return nil, status.Error(codes.Internal, "Failed to top up wallet") } + s.publishNotificationCreated(ctx, notification) balance, err := s.billingRepository.GetWalletBalance(ctx, result.UserID) if err != nil { diff --git a/internal/service/service_popup_ads_test.go b/internal/service/service_popup_ads_test.go new file mode 100644 index 0000000..8c98b1f --- /dev/null +++ b/internal/service/service_popup_ads_test.go @@ -0,0 +1,354 @@ +package service + +import ( + "context" + "fmt" + "testing" + "time" + + "github.com/google/uuid" + _ "modernc.org/sqlite" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" + "gorm.io/driver/sqlite" + "gorm.io/gorm" + appv1 "stream.api/internal/api/proto/app/v1" + "stream.api/internal/database/model" + "stream.api/internal/database/query" + "stream.api/internal/middleware" + "stream.api/internal/repository" + "stream.api/pkg/logger" +) + +const popupTestTrustedMarker = "trusted-popup-test-marker" + +type popupTestLogger struct{} + +func (popupTestLogger) Info(string, ...any) {} +func (popupTestLogger) Error(string, ...any) {} +func (popupTestLogger) Debug(string, ...any) {} +func (popupTestLogger) Warn(string, ...any) {} + +func newPopupTestDB(t *testing.T) *gorm.DB { + t.Helper() + + dsn := fmt.Sprintf("file:%s?mode=memory&cache=shared", uuid.NewString()) + db, err := gorm.Open(sqlite.Dialector{DriverName: "sqlite", DSN: dsn}, &gorm.Config{}) + if err != nil { + t.Fatalf("open sqlite db: %v", err) + } + + for _, stmt := range []string{ + `CREATE TABLE user ( + id TEXT PRIMARY KEY, + email TEXT NOT NULL, + password TEXT, + username TEXT, + avatar TEXT, + role TEXT NOT NULL, + google_id TEXT, + storage_used INTEGER NOT NULL DEFAULT 0, + plan_id TEXT, + referred_by_user_id TEXT, + referral_eligible BOOLEAN NOT NULL DEFAULT 1, + referral_reward_bps INTEGER, + referral_reward_granted_at DATETIME, + referral_reward_payment_id TEXT, + referral_reward_amount REAL, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME, + version INTEGER NOT NULL DEFAULT 1, + telegram_id TEXT + )`, + `CREATE TABLE plan ( + id TEXT PRIMARY KEY, + name TEXT NOT NULL, + description TEXT, + price REAL NOT NULL, + cycle TEXT NOT NULL, + storage_limit INTEGER NOT NULL, + upload_limit INTEGER NOT NULL, + duration_limit INTEGER NOT NULL, + quality_limit TEXT NOT NULL, + features JSON, + is_active BOOLEAN NOT NULL DEFAULT 1, + version INTEGER NOT NULL DEFAULT 1 + )`, + `CREATE TABLE plan_subscriptions ( + id TEXT PRIMARY KEY, + user_id TEXT NOT NULL, + payment_id TEXT NOT NULL, + plan_id TEXT NOT NULL, + term_months INTEGER NOT NULL, + payment_method TEXT NOT NULL, + wallet_amount REAL NOT NULL, + topup_amount REAL NOT NULL, + started_at DATETIME NOT NULL, + expires_at DATETIME NOT NULL, + reminder_7d_sent_at DATETIME, + reminder_3d_sent_at DATETIME, + reminder_1d_sent_at DATETIME, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME, + version INTEGER NOT NULL DEFAULT 1 + )`, + `CREATE TABLE notifications ( + id TEXT PRIMARY KEY, + user_id TEXT NOT NULL, + type TEXT NOT NULL, + title TEXT NOT NULL, + message TEXT NOT NULL, + metadata TEXT, + action_url TEXT, + action_label TEXT, + is_read BOOLEAN NOT NULL DEFAULT 0, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME, + version INTEGER NOT NULL DEFAULT 1 + )`, + `CREATE TABLE popup_ads ( + id TEXT PRIMARY KEY, + user_id TEXT NOT NULL, + type TEXT NOT NULL, + label TEXT NOT NULL, + value TEXT NOT NULL, + is_active BOOLEAN NOT NULL DEFAULT 1, + max_triggers_per_session INTEGER NOT NULL DEFAULT 3, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME, + version INTEGER NOT NULL DEFAULT 1 + )`, + } { + if err := db.Exec(stmt).Error; err != nil { + t.Fatalf("create test schema: %v", err) + } + } + + query.SetDefault(db) + return db +} + +func newPopupTestServices(t *testing.T, db *gorm.DB) *appServices { + t.Helper() + return &appServices{ + db: db, + logger: popupTestLogger{}, + authenticator: middleware.NewAuthenticator(db, popupTestLogger{}, popupTestTrustedMarker, nil), + userRepository: repository.NewUserRepository(db), + planRepository: repository.NewPlanRepository(db), + notificationRepo: repository.NewNotificationRepository(db), + popupAdRepository: repository.NewPopupAdRepository(db), + googleUserInfoURL: defaultGoogleUserInfoURL, + } +} + +func popupTestContext(userID, role string) context.Context { + return metadata.NewIncomingContext(context.Background(), metadata.Pairs( + middleware.ActorMarkerMetadataKey, popupTestTrustedMarker, + middleware.ActorIDMetadataKey, userID, + middleware.ActorRoleMetadataKey, role, + middleware.ActorEmailMetadataKey, "actor@example.com", + )) +} + +func popupPtrString(v string) *string { return &v } +func popupPtrBool(v bool) *bool { return &v } +func popupPtrInt32(v int32) *int32 { return &v } +func popupPtrTime(v time.Time) *time.Time { return &v } + +func popupSeedUser(t *testing.T, db *gorm.DB, user model.User) model.User { + t.Helper() + if user.Role == nil { + user.Role = popupPtrString("USER") + } + if err := db.Create(&user).Error; err != nil { + t.Fatalf("create user: %v", err) + } + return user +} + +func popupSeedAd(t *testing.T, db *gorm.DB, item model.PopupAd) model.PopupAd { + t.Helper() + if item.IsActive == nil { + item.IsActive = popupPtrBool(true) + } + if *item.MaxTriggersPerSession == 0 { + *item.MaxTriggersPerSession = 60 + } + if item.CreatedAt == nil { + now := time.Now().UTC() + item.CreatedAt = &now + } + if err := db.Create(&item).Error; err != nil { + t.Fatalf("create popup ad: %v", err) + } + return item +} + +func popupMustListAds(t *testing.T, db *gorm.DB, userID string) []model.PopupAd { + t.Helper() + var items []model.PopupAd + if err := db.Order("created_at DESC").Find(&items, "user_id = ?", userID).Error; err != nil { + t.Fatalf("list popup ads: %v", err) + } + return items +} + +func popupAssertGRPCCode(t *testing.T, err error, code codes.Code) { + t.Helper() + if status.Code(err) != code { + t.Fatalf("grpc code = %v, want %v (err=%v)", status.Code(err), code, err) + } +} + +func TestPopupAdsUserFlow(t *testing.T) { + t.Run("create list update delete popup ad", func(t *testing.T) { + db := newPopupTestDB(t) + services := newPopupTestServices(t, db) + user := popupSeedUser(t, db, model.User{ID: uuid.NewString(), Email: "user@example.com", Role: popupPtrString("USER")}) + + createResp, err := (&popupAdsAppService{appServices: services}).CreatePopupAd(popupTestContext(user.ID, "USER"), &appv1.CreatePopupAdRequest{ + Type: "url", + Label: "Homepage Campaign", + Value: "https://example.com/landing", + IsActive: popupPtrBool(true), + MaxTriggersPerSession: popupPtrInt32(5), + }) + if err != nil { + t.Fatalf("CreatePopupAd() error = %v", err) + } + if createResp.Item == nil || createResp.Item.Label != "Homepage Campaign" { + t.Fatalf("CreatePopupAd() unexpected response: %#v", createResp) + } + + listResp, err := (&popupAdsAppService{appServices: services}).ListPopupAds(popupTestContext(user.ID, "USER"), &appv1.ListPopupAdsRequest{}) + if err != nil { + t.Fatalf("ListPopupAds() error = %v", err) + } + if len(listResp.Items) != 1 { + t.Fatalf("ListPopupAds() count = %d, want 1", len(listResp.Items)) + } + + updateResp, err := (&popupAdsAppService{appServices: services}).UpdatePopupAd(popupTestContext(user.ID, "USER"), &appv1.UpdatePopupAdRequest{ + Id: createResp.Item.Id, + Type: "script", + Label: "Homepage Campaign v2", + Value: ``, + IsActive: popupPtrBool(false), + MaxTriggersPerSession: popupPtrInt32(8), + }) + if err != nil { + t.Fatalf("UpdatePopupAd() error = %v", err) + } + if updateResp.Item == nil || updateResp.Item.Label != "Homepage Campaign v2" || updateResp.Item.IsActive { + t.Fatalf("UpdatePopupAd() unexpected response: %#v", updateResp) + } + + items := popupMustListAds(t, db, user.ID) + if len(items) != 1 { + t.Fatalf("popup ad count = %d, want 1", len(items)) + } + if items[0].Type != "script" || items[0].Label != "Homepage Campaign v2" || *items[0].MaxTriggersPerSession != 8 { + t.Fatalf("popup ad values = %#v", items[0]) + } + + _, err = (&popupAdsAppService{appServices: services}).DeletePopupAd(popupTestContext(user.ID, "USER"), &appv1.DeletePopupAdRequest{Id: createResp.Item.Id}) + if err != nil { + t.Fatalf("DeletePopupAd() error = %v", err) + } + items = popupMustListAds(t, db, user.ID) + if len(items) != 0 { + t.Fatalf("popup ad count after delete = %d, want 0", len(items)) + } + }) + + t.Run("reject invalid type", func(t *testing.T) { + db := newPopupTestDB(t) + services := newPopupTestServices(t, db) + user := popupSeedUser(t, db, model.User{ID: uuid.NewString(), Email: "user@example.com", Role: popupPtrString("USER")}) + + _, err := (&popupAdsAppService{appServices: services}).CreatePopupAd(popupTestContext(user.ID, "USER"), &appv1.CreatePopupAdRequest{ + Type: "image", + Label: "Invalid", + Value: "https://example.com/landing", + }) + popupAssertGRPCCode(t, err, codes.InvalidArgument) + }) + + t.Run("get active popup ad returns newest active item", func(t *testing.T) { + db := newPopupTestDB(t) + services := newPopupTestServices(t, db) + user := popupSeedUser(t, db, model.User{ID: uuid.NewString(), Email: "user@example.com", Role: popupPtrString("USER")}) + popupSeedAd(t, db, model.PopupAd{ID: uuid.NewString(), UserID: user.ID, Type: "url", Label: "inactive", Value: "https://example.com/1", IsActive: popupPtrBool(false), MaxTriggersPerSession: popupPtrInt32(2)}) + popupSeedAd(t, db, model.PopupAd{ID: uuid.NewString(), UserID: user.ID, Type: "url", Label: "older", Value: "https://example.com/3", IsActive: popupPtrBool(true), MaxTriggersPerSession: popupPtrInt32(1), CreatedAt: popupPtrTime(time.Now().UTC().Add(-time.Minute))}) + winner := popupSeedAd(t, db, model.PopupAd{ID: uuid.NewString(), UserID: user.ID, Type: "script", Label: "winner", Value: ``, IsActive: popupPtrBool(true), MaxTriggersPerSession: popupPtrInt32(3), CreatedAt: popupPtrTime(time.Now().UTC())}) + + resp, err := (&popupAdsAppService{appServices: services}).GetActivePopupAd(popupTestContext(user.ID, "USER"), &appv1.GetActivePopupAdRequest{}) + if err != nil { + t.Fatalf("GetActivePopupAd() error = %v", err) + } + if resp.Item == nil || resp.Item.Id != winner.ID { + t.Fatalf("GetActivePopupAd() = %#v, want winner %q", resp.Item, winner.ID) + } + }) +} + +func TestPopupAdsAdminFlow(t *testing.T) { + t.Run("admin create list update delete popup ad", func(t *testing.T) { + db := newPopupTestDB(t) + services := newPopupTestServices(t, db) + admin := popupSeedUser(t, db, model.User{ID: uuid.NewString(), Email: "admin@example.com", Role: popupPtrString("ADMIN")}) + user := popupSeedUser(t, db, model.User{ID: uuid.NewString(), Email: "user@example.com", Role: popupPtrString("USER")}) + + createResp, err := services.CreateAdminPopupAd(popupTestContext(admin.ID, "ADMIN"), &appv1.CreateAdminPopupAdRequest{ + UserId: user.ID, + Type: "url", + Label: "Admin Campaign", + Value: "https://example.com/admin", + IsActive: popupPtrBool(true), + MaxTriggersPerSession: popupPtrInt32(7), + }) + if err != nil { + t.Fatalf("CreateAdminPopupAd() error = %v", err) + } + if createResp.Item == nil || createResp.Item.UserId != user.ID { + t.Fatalf("CreateAdminPopupAd() unexpected response: %#v", createResp) + } + + listResp, err := services.ListAdminPopupAds(popupTestContext(admin.ID, "ADMIN"), &appv1.ListAdminPopupAdsRequest{UserId: &user.ID}) + if err != nil { + t.Fatalf("ListAdminPopupAds() error = %v", err) + } + if len(listResp.Items) != 1 { + t.Fatalf("ListAdminPopupAds() count = %d, want 1", len(listResp.Items)) + } + + updateResp, err := services.UpdateAdminPopupAd(popupTestContext(admin.ID, "ADMIN"), &appv1.UpdateAdminPopupAdRequest{ + Id: createResp.Item.Id, + UserId: user.ID, + Type: "script", + Label: "Admin Campaign v2", + Value: ``, + IsActive: popupPtrBool(false), + MaxTriggersPerSession: popupPtrInt32(11), + }) + if err != nil { + t.Fatalf("UpdateAdminPopupAd() error = %v", err) + } + if updateResp.Item == nil || updateResp.Item.Label != "Admin Campaign v2" || updateResp.Item.IsActive { + t.Fatalf("UpdateAdminPopupAd() unexpected response: %#v", updateResp) + } + + _, err = services.DeleteAdminPopupAd(popupTestContext(admin.ID, "ADMIN"), &appv1.DeleteAdminPopupAdRequest{Id: createResp.Item.Id}) + if err != nil { + t.Fatalf("DeleteAdminPopupAd() error = %v", err) + } + items := popupMustListAds(t, db, user.ID) + if len(items) != 0 { + t.Fatalf("popup ad count after delete = %d, want 0", len(items)) + } + }) +} + +var _ logger.Logger = popupTestLogger{} diff --git a/internal/service/service_user_features.go b/internal/service/service_user_features.go index 542e644..b229ce7 100644 --- a/internal/service/service_user_features.go +++ b/internal/service/service_user_features.go @@ -318,6 +318,150 @@ func (s *adTemplatesAppService) DeleteAdTemplate(ctx context.Context, req *appv1 return messageResponse("Ad template deleted"), nil } +func (s *popupAdsAppService) ListPopupAds(ctx context.Context, req *appv1.ListPopupAdsRequest) (*appv1.ListPopupAdsResponse, error) { + result, err := s.authenticate(ctx) + if err != nil { + return nil, err + } + + page, limit, offset := adminPageLimitOffset(req.GetPage(), req.GetLimit()) + items, total, err := s.popupAdRepository.ListByUser(ctx, result.UserID, limit, offset) + if err != nil { + s.logger.Error("Failed to list popup ads", "error", err) + return nil, status.Error(codes.Internal, "Failed to load popup ads") + } + + payload := make([]*appv1.PopupAd, 0, len(items)) + for _, item := range items { + copyItem := item + payload = append(payload, toProtoPopupAd(©Item)) + } + + return &appv1.ListPopupAdsResponse{Items: payload, Total: total, Page: page, Limit: limit}, nil +} +func (s *popupAdsAppService) CreatePopupAd(ctx context.Context, req *appv1.CreatePopupAdRequest) (*appv1.CreatePopupAdResponse, error) { + result, err := s.authenticate(ctx) + if err != nil { + return nil, err + } + + popupType := strings.ToLower(strings.TrimSpace(req.GetType())) + label := strings.TrimSpace(req.GetLabel()) + value := strings.TrimSpace(req.GetValue()) + maxTriggers := int32(3) + if req.MaxTriggersPerSession != nil { + maxTriggers = *req.MaxTriggersPerSession + } + if popupType != "url" && popupType != "script" { + return nil, status.Error(codes.InvalidArgument, "Popup ad type must be url or script") + } + if label == "" || value == "" { + return nil, status.Error(codes.InvalidArgument, "Label and value are required") + } + if maxTriggers < 1 { + return nil, status.Error(codes.InvalidArgument, "Max triggers per session must be greater than 0") + } + + item := &model.PopupAd{ + ID: uuid.New().String(), + UserID: result.UserID, + Type: popupType, + Label: label, + Value: value, + IsActive: model.BoolPtr(req.IsActive == nil || *req.IsActive), + MaxTriggersPerSession: int32Ptr(maxTriggers), + } + if err := s.popupAdRepository.Create(ctx, item); err != nil { + s.logger.Error("Failed to create popup ad", "error", err) + return nil, status.Error(codes.Internal, "Failed to save popup ad") + } + + return &appv1.CreatePopupAdResponse{Item: toProtoPopupAd(item)}, nil +} +func (s *popupAdsAppService) UpdatePopupAd(ctx context.Context, req *appv1.UpdatePopupAdRequest) (*appv1.UpdatePopupAdResponse, error) { + result, err := s.authenticate(ctx) + if err != nil { + return nil, err + } + + id := strings.TrimSpace(req.GetId()) + if id == "" { + return nil, status.Error(codes.NotFound, "Popup ad not found") + } + popupType := strings.ToLower(strings.TrimSpace(req.GetType())) + label := strings.TrimSpace(req.GetLabel()) + value := strings.TrimSpace(req.GetValue()) + if popupType != "url" && popupType != "script" { + return nil, status.Error(codes.InvalidArgument, "Popup ad type must be url or script") + } + if label == "" || value == "" { + return nil, status.Error(codes.InvalidArgument, "Label and value are required") + } + if req.MaxTriggersPerSession != nil && *req.MaxTriggersPerSession < 1 { + return nil, status.Error(codes.InvalidArgument, "Max triggers per session must be greater than 0") + } + + item, err := s.popupAdRepository.GetByIDAndUser(ctx, id, result.UserID) + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return nil, status.Error(codes.NotFound, "Popup ad not found") + } + s.logger.Error("Failed to load popup ad", "error", err) + return nil, status.Error(codes.Internal, "Failed to save popup ad") + } + + item.Type = popupType + item.Label = label + item.Value = value + if req.IsActive != nil { + item.IsActive = model.BoolPtr(*req.IsActive) + } + if req.MaxTriggersPerSession != nil { + item.MaxTriggersPerSession = int32Ptr(*req.MaxTriggersPerSession) + } + if err := s.popupAdRepository.Save(ctx, item); err != nil { + s.logger.Error("Failed to update popup ad", "error", err) + return nil, status.Error(codes.Internal, "Failed to save popup ad") + } + + return &appv1.UpdatePopupAdResponse{Item: toProtoPopupAd(item)}, nil +} +func (s *popupAdsAppService) DeletePopupAd(ctx context.Context, req *appv1.DeletePopupAdRequest) (*appv1.MessageResponse, error) { + result, err := s.authenticate(ctx) + if err != nil { + return nil, err + } + + id := strings.TrimSpace(req.GetId()) + if id == "" { + return nil, status.Error(codes.NotFound, "Popup ad not found") + } + rowsAffected, err := s.popupAdRepository.DeleteByIDAndUser(ctx, id, result.UserID) + if err != nil { + s.logger.Error("Failed to delete popup ad", "error", err) + return nil, status.Error(codes.Internal, "Failed to delete popup ad") + } + if rowsAffected == 0 { + return nil, status.Error(codes.NotFound, "Popup ad not found") + } + return messageResponse("Popup ad deleted"), nil +} +func (s *popupAdsAppService) GetActivePopupAd(ctx context.Context, _ *appv1.GetActivePopupAdRequest) (*appv1.GetActivePopupAdResponse, error) { + result, err := s.authenticate(ctx) + if err != nil { + return nil, err + } + + item, err := s.popupAdRepository.GetActiveByUser(ctx, result.UserID) + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return &appv1.GetActivePopupAdResponse{}, nil + } + s.logger.Error("Failed to load active popup ad", "error", err) + return nil, status.Error(codes.Internal, "Failed to load popup ad") + } + return &appv1.GetActivePopupAdResponse{Item: toProtoPopupAd(item)}, nil +} func (s *plansAppService) ListPlans(ctx context.Context, _ *appv1.ListPlansRequest) (*appv1.ListPlansResponse, error) { if _, err := s.authenticate(ctx); err != nil { return nil, err diff --git a/internal/service/value_helpers.go b/internal/service/value_helpers.go index 6df4149..9399f06 100644 --- a/internal/service/value_helpers.go +++ b/internal/service/value_helpers.go @@ -53,6 +53,14 @@ func int32Ptr(value int32) *int32 { return &value } +func protoTimestampToTime(value *timestamppb.Timestamp) *time.Time { + if value == nil { + return nil + } + timeValue := value.AsTime().UTC() + return &timeValue +} + func protoStringValue(value *string) string { if value == nil { return "" diff --git a/internal/transport/grpc/server.go b/internal/transport/grpc/server.go index c35fb04..b5f90cc 100644 --- a/internal/transport/grpc/server.go +++ b/internal/transport/grpc/server.go @@ -36,17 +36,19 @@ func NewGRPCModule(ctx context.Context, cfg *config.Config, db *gorm.DB, rds *re cfg: cfg, } + var notificationPublisher service.NotificationEventPublisher = nil if publisher, err := mqtt.NewMQTTBootstrap(jobService, agentRuntime, appLogger); err != nil { appLogger.Error("Failed to initialize MQTT publisher", "error", err) } else { module.mqttPublisher = publisher + notificationPublisher = mqtt.NewNotificationPublisher(publisher.Client(), appLogger) agentRuntime.SetAgentEventHandler(func(eventType string, agent *dto.AgentWithStats) { mqtt.PublishAgentMQTTEvent(publisher.Client(), appLogger, eventType, agent) }) } agentRuntime.Register(grpcServer) - service.Register(grpcServer, service.NewServices(rds, db, appLogger, cfg, videoService, agentRuntime)) + service.Register(grpcServer, service.NewServices(rds, db, appLogger, cfg, videoService, agentRuntime, notificationPublisher)) if module.mqttPublisher != nil { module.mqttPublisher.Start(ctx) } diff --git a/internal/transport/mqtt/bootstrap.go b/internal/transport/mqtt/bootstrap.go new file mode 100644 index 0000000..6f20463 --- /dev/null +++ b/internal/transport/mqtt/bootstrap.go @@ -0,0 +1,41 @@ +package mqtt + +import ( + "context" + + pahomqtt "github.com/eclipse/paho.mqtt.golang" + "stream.api/internal/dto" + "stream.api/internal/service" + "stream.api/pkg/logger" +) + +type MQTTBootstrap struct{ *streamEventPublisher } + +func NewMQTTBootstrap(jobService *service.JobService, agentRT agentRuntime, appLogger logger.Logger) (*MQTTBootstrap, error) { + publisher, err := newStreamEventPublisher(jobService, agentRT, appLogger) + if err != nil { + return nil, err + } + return &MQTTBootstrap{streamEventPublisher: publisher}, nil +} + +func (b *MQTTBootstrap) Start(ctx context.Context) { + if b == nil || b.streamEventPublisher == nil { + return + } + b.streamEventPublisher.start(ctx) +} + +func (b *MQTTBootstrap) Client() pahomqtt.Client { + if b == nil || b.streamEventPublisher == nil { + return nil + } + return b.client +} + +func PublishAgentMQTTEvent(client pahomqtt.Client, appLogger logger.Logger, eventType string, agent *dto.AgentWithStats) { + publishMQTTEvent(client, appLogger, defaultMQTTPrefix, mqttEvent{ + Type: eventType, + Payload: mapAgentPayload(agent), + }) +} diff --git a/internal/transport/mqtt/constants.go b/internal/transport/mqtt/constants.go new file mode 100644 index 0000000..323e7a1 --- /dev/null +++ b/internal/transport/mqtt/constants.go @@ -0,0 +1,14 @@ +package mqtt + +import "time" + +const ( + defaultMQTTBrokerURL = "tcp://broker.mqtt-dashboard.com:1883" + defaultMQTTPrefix = "picpic" + defaultPublishWait = 5 * time.Second +) + +type mqttEvent struct { + Type string `json:"type"` + Payload any `json:"payload"` +} diff --git a/internal/transport/mqtt/notification_publisher.go b/internal/transport/mqtt/notification_publisher.go new file mode 100644 index 0000000..536d21b --- /dev/null +++ b/internal/transport/mqtt/notification_publisher.go @@ -0,0 +1,44 @@ +package mqtt + +import ( + "context" + "fmt" + + pahomqtt "github.com/eclipse/paho.mqtt.golang" + "stream.api/internal/database/model" + "stream.api/internal/service" + "stream.api/pkg/logger" +) + +type notificationPublisher struct { + client pahomqtt.Client + logger logger.Logger + prefix string +} + +func NewNotificationPublisher(client pahomqtt.Client, appLogger logger.Logger) service.NotificationEventPublisher { + if client == nil { + return service.NotificationEventPublisher(serviceNotificationNoop{}) + } + return ¬ificationPublisher{client: client, logger: appLogger, prefix: defaultMQTTPrefix} +} + +type serviceNotificationNoop struct{} + +func (serviceNotificationNoop) PublishNotificationCreated(context.Context, *model.Notification) error { return nil } + +func (p *notificationPublisher) PublishNotificationCreated(_ context.Context, notification *model.Notification) error { + if p == nil || notification == nil { + return nil + } + message := mqttEvent{ + Type: "notification.created", + Payload: service.BuildNotificationCreatedPayload(notification), + } + return publishMQTTJSON(p.client, p.notificationTopic(notification.UserID), message) +} + +func (p *notificationPublisher) notificationTopic(userID string) string { + return fmt.Sprintf("%s/notifications/%s", p.prefix, userID) +} + diff --git a/internal/transport/mqtt/paho_helpers.go b/internal/transport/mqtt/publish_helpers.go similarity index 80% rename from internal/transport/mqtt/paho_helpers.go rename to internal/transport/mqtt/publish_helpers.go index 8f77dad..27f27a8 100644 --- a/internal/transport/mqtt/paho_helpers.go +++ b/internal/transport/mqtt/publish_helpers.go @@ -36,17 +36,22 @@ func publishMQTTEvent(client pahomqtt.Client, appLogger logger.Logger, prefix st return } - encoded, err := json.Marshal(event) - if err != nil { - appLogger.Error("Failed to marshal MQTT event", "error", err, "type", event.Type) - return - } - - if err := publishPahoMessage(client, fmt.Sprintf("%s/events", prefix), encoded); err != nil { + if err := publishMQTTJSON(client, fmt.Sprintf("%s/events", prefix), event); err != nil { appLogger.Error("Failed to publish MQTT event", "error", err, "type", event.Type) } } +func publishMQTTJSON(client pahomqtt.Client, topic string, payload any) error { + if client == nil { + return nil + } + encoded, err := json.Marshal(payload) + if err != nil { + return err + } + return publishPahoMessage(client, topic, encoded) +} + func publishPahoMessage(client pahomqtt.Client, topic string, payload []byte) error { if client == nil { return nil diff --git a/internal/transport/mqtt/mqtt_publisher.go b/internal/transport/mqtt/stream_event_publisher.go similarity index 61% rename from internal/transport/mqtt/mqtt_publisher.go rename to internal/transport/mqtt/stream_event_publisher.go index 2646461..a955893 100644 --- a/internal/transport/mqtt/mqtt_publisher.go +++ b/internal/transport/mqtt/stream_event_publisher.go @@ -12,17 +12,11 @@ import ( "stream.api/pkg/logger" ) -const ( - defaultMQTTBrokerURL = "tcp://broker.mqtt-dashboard.com:1883" - defaultMQTTPrefix = "picpic" - defaultPublishWait = 5 * time.Second -) - type agentRuntime interface { ListAgentsWithStats() []*dto.AgentWithStats } -type mqttPublisher struct { +type streamEventPublisher struct { client pahomqtt.Client jobService *service.JobService agentRT agentRuntime @@ -30,13 +24,13 @@ type mqttPublisher struct { prefix string } -func newMQTTPublisher(jobService *service.JobService, agentRT agentRuntime, appLogger logger.Logger) (*mqttPublisher, error) { +func newStreamEventPublisher(jobService *service.JobService, agentRT agentRuntime, appLogger logger.Logger) (*streamEventPublisher, error) { client, err := connectPahoClient(defaultMQTTBrokerURL, fmt.Sprintf("stream-api-%d", time.Now().UnixNano())) if err != nil { return nil, err } - return &mqttPublisher{ + return &streamEventPublisher{ client: client, jobService: jobService, agentRT: agentRT, @@ -45,7 +39,7 @@ func newMQTTPublisher(jobService *service.JobService, agentRT agentRuntime, appL }, nil } -func (p *mqttPublisher) start(ctx context.Context) { +func (p *streamEventPublisher) start(ctx context.Context) { if p == nil || p.jobService == nil { return } @@ -54,7 +48,7 @@ func (p *mqttPublisher) start(ctx context.Context) { go p.consumeResources(ctx) } -func (p *mqttPublisher) consumeLogs(ctx context.Context) { +func (p *streamEventPublisher) consumeLogs(ctx context.Context) { ch, err := p.jobService.SubscribeJobLogs(ctx, "") if err != nil { p.logger.Error("Failed to subscribe job logs for MQTT", "error", err) @@ -69,14 +63,14 @@ func (p *mqttPublisher) consumeLogs(ctx context.Context) { if !ok { return } - if err := p.publishJSON(p.logTopic(entry.JobID), entry); err != nil { + if err := publishMQTTJSON(p.client, p.logTopic(entry.JobID), entry); err != nil { p.logger.Error("Failed to publish MQTT job log", "error", err, "job_id", entry.JobID) } } } } -func (p *mqttPublisher) consumeJobUpdates(ctx context.Context) { +func (p *streamEventPublisher) consumeJobUpdates(ctx context.Context) { ch, err := p.jobService.SubscribeJobUpdates(ctx) if err != nil { p.logger.Error("Failed to subscribe job updates for MQTT", "error", err) @@ -106,7 +100,7 @@ func (p *mqttPublisher) consumeJobUpdates(ctx context.Context) { } } -func (p *mqttPublisher) consumeResources(ctx context.Context) { +func (p *streamEventPublisher) consumeResources(ctx context.Context) { ch, err := p.jobService.SubscribeSystemResources(ctx) if err != nil { p.logger.Error("Failed to subscribe resources for MQTT", "error", err) @@ -137,7 +131,7 @@ func (p *mqttPublisher) consumeResources(ctx context.Context) { } } -func (p *mqttPublisher) findAgent(agentID string) *dto.AgentWithStats { +func (p *streamEventPublisher) findAgent(agentID string) *dto.AgentWithStats { if p == nil || p.agentRT == nil { return nil } @@ -149,40 +143,25 @@ func (p *mqttPublisher) findAgent(agentID string) *dto.AgentWithStats { return nil } -func (p *mqttPublisher) publishEvent(eventType string, payload any, jobID string) error { +func (p *streamEventPublisher) publishEvent(eventType string, payload any, jobID string) error { message := mqttEvent{Type: eventType, Payload: payload} if jobID != "" { - if err := p.publishJSON(p.jobTopic(jobID), message); err != nil { + if err := publishMQTTJSON(p.client, p.jobTopic(jobID), message); err != nil { return err } } - return p.publishJSON(p.eventsTopic(), message) + return publishMQTTJSON(p.client, p.eventsTopic(), message) } -func (p *mqttPublisher) publishJSON(topic string, payload any) error { - encoded, err := json.Marshal(payload) - if err != nil { - return err - } - return p.publish(topic, encoded) -} - -func (p *mqttPublisher) publish(topic string, payload []byte) error { - if p == nil { - return nil - } - return publishPahoMessage(p.client, topic, payload) -} - -func (p *mqttPublisher) logTopic(jobID string) string { +func (p *streamEventPublisher) logTopic(jobID string) string { return fmt.Sprintf("%s/logs/%s", p.prefix, jobID) } -func (p *mqttPublisher) jobTopic(jobID string) string { +func (p *streamEventPublisher) jobTopic(jobID string) string { return fmt.Sprintf("%s/job/%s", p.prefix, jobID) } -func (p *mqttPublisher) eventsTopic() string { +func (p *streamEventPublisher) eventsTopic() string { return fmt.Sprintf("%s/events", p.prefix) } @@ -206,39 +185,3 @@ func mapAgentPayload(agent *dto.AgentWithStats) map[string]any { "active_job_count": agent.ActiveJobCount, } } - -type mqttEvent struct { - Type string `json:"type"` - Payload any `json:"payload"` -} - -type MQTTBootstrap struct{ *mqttPublisher } - -func NewMQTTBootstrap(jobService *service.JobService, agentRT agentRuntime, appLogger logger.Logger) (*MQTTBootstrap, error) { - publisher, err := newMQTTPublisher(jobService, agentRT, appLogger) - if err != nil { - return nil, err - } - return &MQTTBootstrap{mqttPublisher: publisher}, nil -} - -func (b *MQTTBootstrap) Start(ctx context.Context) { - if b == nil || b.mqttPublisher == nil { - return - } - b.mqttPublisher.start(ctx) -} - -func (b *MQTTBootstrap) Client() pahomqtt.Client { - if b == nil || b.mqttPublisher == nil { - return nil - } - return b.client -} - -func PublishAgentMQTTEvent(client pahomqtt.Client, appLogger logger.Logger, eventType string, agent *dto.AgentWithStats) { - publishMQTTEvent(client, appLogger, defaultMQTTPrefix, mqttEvent{ - Type: eventType, - Payload: mapAgentPayload(agent), - }) -} diff --git a/migrations/004_create_popup_ads_table.sql b/migrations/004_create_popup_ads_table.sql new file mode 100644 index 0000000..dcda143 --- /dev/null +++ b/migrations/004_create_popup_ads_table.sql @@ -0,0 +1,15 @@ +CREATE TABLE IF NOT EXISTS popup_ads ( + id UUID PRIMARY KEY, + user_id UUID NOT NULL REFERENCES "user"(id) ON DELETE CASCADE, + type VARCHAR(20) NOT NULL, + label TEXT NOT NULL, + value TEXT NOT NULL, + is_active BOOLEAN NOT NULL DEFAULT TRUE, + max_triggers_per_session INTEGER NOT NULL DEFAULT 3, + created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMPTZ, + version BIGINT NOT NULL DEFAULT 1 +); + +CREATE INDEX IF NOT EXISTS idx_popup_ads_user_id ON popup_ads(user_id); +CREATE INDEX IF NOT EXISTS idx_popup_ads_user_active ON popup_ads(user_id, is_active); diff --git a/proto/app/v1/admin.proto b/proto/app/v1/admin.proto index e8cf317..8e3e5e5 100644 --- a/proto/app/v1/admin.proto +++ b/proto/app/v1/admin.proto @@ -33,6 +33,11 @@ service Admin { rpc CreateAdminAdTemplate(CreateAdminAdTemplateRequest) returns (CreateAdminAdTemplateResponse); rpc UpdateAdminAdTemplate(UpdateAdminAdTemplateRequest) returns (UpdateAdminAdTemplateResponse); rpc DeleteAdminAdTemplate(DeleteAdminAdTemplateRequest) returns (MessageResponse); + rpc ListAdminPopupAds(ListAdminPopupAdsRequest) returns (ListAdminPopupAdsResponse); + rpc GetAdminPopupAd(GetAdminPopupAdRequest) returns (GetAdminPopupAdResponse); + rpc CreateAdminPopupAd(CreateAdminPopupAdRequest) returns (CreateAdminPopupAdResponse); + rpc UpdateAdminPopupAd(UpdateAdminPopupAdRequest) returns (UpdateAdminPopupAdResponse); + rpc DeleteAdminPopupAd(DeleteAdminPopupAdRequest) returns (MessageResponse); rpc ListAdminPlayerConfigs(ListAdminPlayerConfigsRequest) returns (ListAdminPlayerConfigsResponse); rpc GetAdminPlayerConfig(GetAdminPlayerConfigRequest) returns (GetAdminPlayerConfigResponse); rpc CreateAdminPlayerConfig(CreateAdminPlayerConfigRequest) returns (CreateAdminPlayerConfigResponse); @@ -338,6 +343,59 @@ message DeleteAdminAdTemplateRequest { string id = 1; } +message ListAdminPopupAdsRequest { + int32 page = 1; + int32 limit = 2; + optional string user_id = 3; + optional string search = 4; +} + +message ListAdminPopupAdsResponse { + repeated AdminPopupAd items = 1; + int64 total = 2; + int32 page = 3; + int32 limit = 4; +} + +message GetAdminPopupAdRequest { + string id = 1; +} + +message GetAdminPopupAdResponse { + AdminPopupAd item = 1; +} + +message CreateAdminPopupAdRequest { + string user_id = 1; + string type = 2; + string label = 3; + string value = 4; + optional bool is_active = 5; + optional int32 max_triggers_per_session = 6; +} + +message CreateAdminPopupAdResponse { + AdminPopupAd item = 1; +} + +message UpdateAdminPopupAdRequest { + string id = 1; + string user_id = 2; + string type = 3; + string label = 4; + string value = 5; + optional bool is_active = 6; + optional int32 max_triggers_per_session = 7; +} + +message UpdateAdminPopupAdResponse { + AdminPopupAd item = 1; +} + +message DeleteAdminPopupAdRequest { + string id = 1; +} + message ListAdminPlayerConfigsRequest { int32 page = 1; int32 limit = 2; diff --git a/proto/app/v1/catalog.proto b/proto/app/v1/catalog.proto index 487fbda..303a93a 100644 --- a/proto/app/v1/catalog.proto +++ b/proto/app/v1/catalog.proto @@ -19,6 +19,14 @@ service AdTemplates { rpc DeleteAdTemplate(DeleteAdTemplateRequest) returns (MessageResponse); } +service PopupAds { + rpc ListPopupAds(ListPopupAdsRequest) returns (ListPopupAdsResponse); + rpc CreatePopupAd(CreatePopupAdRequest) returns (CreatePopupAdResponse); + rpc UpdatePopupAd(UpdatePopupAdRequest) returns (UpdatePopupAdResponse); + rpc DeletePopupAd(DeletePopupAdRequest) returns (MessageResponse); + rpc GetActivePopupAd(GetActivePopupAdRequest) returns (GetActivePopupAdResponse); +} + service PlayerConfigs { rpc ListPlayerConfigs(ListPlayerConfigsRequest) returns (ListPlayerConfigsResponse); rpc CreatePlayerConfig(CreatePlayerConfigRequest) returns (CreatePlayerConfigResponse); @@ -87,6 +95,53 @@ message DeleteAdTemplateRequest { string id = 1; } +message ListPopupAdsRequest { + int32 page = 1; + int32 limit = 2; +} + +message ListPopupAdsResponse { + repeated PopupAd items = 1; + int64 total = 2; + int32 page = 3; + int32 limit = 4; +} + +message CreatePopupAdRequest { + string type = 1; + string label = 2; + string value = 3; + optional bool is_active = 4; + optional int32 max_triggers_per_session = 5; +} + +message CreatePopupAdResponse { + PopupAd item = 1; +} + +message UpdatePopupAdRequest { + string id = 1; + string type = 2; + string label = 3; + string value = 4; + optional bool is_active = 5; + optional int32 max_triggers_per_session = 6; +} + +message UpdatePopupAdResponse { + PopupAd item = 1; +} + +message DeletePopupAdRequest { + string id = 1; +} + +message GetActivePopupAdRequest {} + +message GetActivePopupAdResponse { + optional PopupAd item = 1; +} + message ListPlayerConfigsRequest {} message ListPlayerConfigsResponse { diff --git a/proto/app/v1/common.proto b/proto/app/v1/common.proto index d8cbbf7..a5293d9 100644 --- a/proto/app/v1/common.proto +++ b/proto/app/v1/common.proto @@ -79,6 +79,17 @@ message AdTemplate { google.protobuf.Timestamp updated_at = 10; } +message PopupAd { + string id = 1; + string type = 2; + string label = 3; + string value = 4; + bool is_active = 5; + int32 max_triggers_per_session = 6; + google.protobuf.Timestamp created_at = 7; + google.protobuf.Timestamp updated_at = 8; +} + message PlayerConfig { string id = 1; string name = 2; @@ -331,6 +342,19 @@ message AdminAdTemplate { google.protobuf.Timestamp updated_at = 12; } +message AdminPopupAd { + string id = 1; + string user_id = 2; + string type = 3; + string label = 4; + string value = 5; + bool is_active = 6; + int32 max_triggers_per_session = 7; + optional string owner_email = 8; + google.protobuf.Timestamp created_at = 9; + google.protobuf.Timestamp updated_at = 10; +} + message AdminJob { string id = 1; string status = 2;