Spaces:
Runtime error
Runtime error
Commit ·
32ac45b
1
Parent(s): 34b6250
Deploy files from GitHub repository
Browse files- be.zip +3 -0
- controllers/event_controller.go +7 -0
- go.mod +9 -2
- go.sum +19 -0
- middleware/authorization_middleware.go +44 -0
- models/entity/entity.go +2 -1
- models/error/error.go +2 -0
- provider/middleware_provider.go +8 -0
- repositories/problem_set_assign_repository.go +81 -0
- repositories/problem_set_repository.go +83 -0
- router/event_router.go +3 -1
- services/event_service.go +33 -2
- services/problem_set_service.go +39 -0
- services/service.go +1 -0
- space/.gitattributes +35 -0
- space/.github/workflows/main.yml +49 -0
- space/.gitignore +1 -0
be.zip
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:7af1f7cd34ab1c2616a47109faa7db30888af3175a1a36a885d22c4dc7477e00
|
| 3 |
+
size 41335
|
controllers/event_controller.go
CHANGED
|
@@ -14,6 +14,7 @@ type EventController interface {
|
|
| 14 |
List(ctx *gin.Context)
|
| 15 |
DetailBySlug(ctx *gin.Context)
|
| 16 |
Join(ctx *gin.Context)
|
|
|
|
| 17 |
}
|
| 18 |
|
| 19 |
type eventController struct {
|
|
@@ -52,3 +53,9 @@ func (c *eventController) Join(ctx *gin.Context) {
|
|
| 52 |
res, err := c.eventService.JoinByCode(ctx.Request.Context(), accountId, req.EventCode)
|
| 53 |
ResponseJSON(ctx, req, res, err)
|
| 54 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14 |
List(ctx *gin.Context)
|
| 15 |
DetailBySlug(ctx *gin.Context)
|
| 16 |
Join(ctx *gin.Context)
|
| 17 |
+
QuizListByEvent(ctx *gin.Context)
|
| 18 |
}
|
| 19 |
|
| 20 |
type eventController struct {
|
|
|
|
| 53 |
res, err := c.eventService.JoinByCode(ctx.Request.Context(), accountId, req.EventCode)
|
| 54 |
ResponseJSON(ctx, req, res, err)
|
| 55 |
}
|
| 56 |
+
|
| 57 |
+
func (c *eventController) QuizListByEvent(ctx *gin.Context) {
|
| 58 |
+
slug := ctx.Param("slug")
|
| 59 |
+
res, err := c.eventService.QuizListByEvent(ctx.Request.Context(), slug)
|
| 60 |
+
ResponseJSON(ctx, gin.H{"slug": slug}, res, err)
|
| 61 |
+
}
|
go.mod
CHANGED
|
@@ -3,12 +3,12 @@ module abdanhafidz.com/go-boilerplate
|
|
| 3 |
go 1.24.5
|
| 4 |
|
| 5 |
require (
|
| 6 |
-
github.com/gin-gonic/gin v1.
|
| 7 |
github.com/golang-jwt/jwt/v4 v4.5.2
|
| 8 |
github.com/joho/godotenv v1.5.1
|
| 9 |
github.com/satori/go.uuid v1.2.0
|
| 10 |
gorm.io/driver/postgres v1.6.0
|
| 11 |
-
gorm.io/gorm v1.
|
| 12 |
)
|
| 13 |
|
| 14 |
require (
|
|
@@ -27,6 +27,8 @@ require (
|
|
| 27 |
github.com/go-playground/universal-translator v0.18.1 // indirect
|
| 28 |
github.com/go-playground/validator/v10 v10.27.0 // indirect
|
| 29 |
github.com/goccy/go-json v0.10.5 // indirect
|
|
|
|
|
|
|
| 30 |
github.com/golang-jwt/jwt/v5 v5.3.0 // indirect
|
| 31 |
github.com/google/s2a-go v0.1.9 // indirect
|
| 32 |
github.com/google/uuid v1.6.0 // indirect
|
|
@@ -50,6 +52,8 @@ require (
|
|
| 50 |
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
| 51 |
github.com/modern-go/reflect2 v1.0.2 // indirect
|
| 52 |
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
|
|
|
|
|
|
|
| 53 |
github.com/rogpeppe/go-internal v1.14.1 // indirect
|
| 54 |
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
| 55 |
github.com/ugorji/go/codec v1.3.0 // indirect
|
|
@@ -58,13 +62,16 @@ require (
|
|
| 58 |
go.opentelemetry.io/otel v1.37.0 // indirect
|
| 59 |
go.opentelemetry.io/otel/metric v1.37.0 // indirect
|
| 60 |
go.opentelemetry.io/otel/trace v1.37.0 // indirect
|
|
|
|
| 61 |
golang.org/x/arch v0.20.0 // indirect
|
| 62 |
golang.org/x/crypto v0.43.0 // indirect
|
|
|
|
| 63 |
golang.org/x/net v0.46.0 // indirect
|
| 64 |
golang.org/x/oauth2 v0.32.0 // indirect
|
| 65 |
golang.org/x/sync v0.17.0 // indirect
|
| 66 |
golang.org/x/sys v0.37.0 // indirect
|
| 67 |
golang.org/x/text v0.30.0 // indirect
|
|
|
|
| 68 |
google.golang.org/api v0.253.0 // indirect
|
| 69 |
google.golang.org/genproto/googleapis/rpc v0.0.0-20251014184007-4626949a642f // indirect
|
| 70 |
google.golang.org/grpc v1.76.0 // indirect
|
|
|
|
| 3 |
go 1.24.5
|
| 4 |
|
| 5 |
require (
|
| 6 |
+
github.com/gin-gonic/gin v1.11.0
|
| 7 |
github.com/golang-jwt/jwt/v4 v4.5.2
|
| 8 |
github.com/joho/godotenv v1.5.1
|
| 9 |
github.com/satori/go.uuid v1.2.0
|
| 10 |
gorm.io/driver/postgres v1.6.0
|
| 11 |
+
gorm.io/gorm v1.31.0
|
| 12 |
)
|
| 13 |
|
| 14 |
require (
|
|
|
|
| 27 |
github.com/go-playground/universal-translator v0.18.1 // indirect
|
| 28 |
github.com/go-playground/validator/v10 v10.27.0 // indirect
|
| 29 |
github.com/goccy/go-json v0.10.5 // indirect
|
| 30 |
+
github.com/goccy/go-yaml v1.18.0 // indirect
|
| 31 |
+
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
|
| 32 |
github.com/golang-jwt/jwt/v5 v5.3.0 // indirect
|
| 33 |
github.com/google/s2a-go v0.1.9 // indirect
|
| 34 |
github.com/google/uuid v1.6.0 // indirect
|
|
|
|
| 52 |
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
| 53 |
github.com/modern-go/reflect2 v1.0.2 // indirect
|
| 54 |
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
|
| 55 |
+
github.com/quic-go/qpack v0.5.1 // indirect
|
| 56 |
+
github.com/quic-go/quic-go v0.54.0 // indirect
|
| 57 |
github.com/rogpeppe/go-internal v1.14.1 // indirect
|
| 58 |
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
| 59 |
github.com/ugorji/go/codec v1.3.0 // indirect
|
|
|
|
| 62 |
go.opentelemetry.io/otel v1.37.0 // indirect
|
| 63 |
go.opentelemetry.io/otel/metric v1.37.0 // indirect
|
| 64 |
go.opentelemetry.io/otel/trace v1.37.0 // indirect
|
| 65 |
+
go.uber.org/mock v0.5.0 // indirect
|
| 66 |
golang.org/x/arch v0.20.0 // indirect
|
| 67 |
golang.org/x/crypto v0.43.0 // indirect
|
| 68 |
+
golang.org/x/mod v0.28.0 // indirect
|
| 69 |
golang.org/x/net v0.46.0 // indirect
|
| 70 |
golang.org/x/oauth2 v0.32.0 // indirect
|
| 71 |
golang.org/x/sync v0.17.0 // indirect
|
| 72 |
golang.org/x/sys v0.37.0 // indirect
|
| 73 |
golang.org/x/text v0.30.0 // indirect
|
| 74 |
+
golang.org/x/tools v0.37.0 // indirect
|
| 75 |
google.golang.org/api v0.253.0 // indirect
|
| 76 |
google.golang.org/genproto/googleapis/rpc v0.0.0-20251014184007-4626949a642f // indirect
|
| 77 |
google.golang.org/grpc v1.76.0 // indirect
|
go.sum
CHANGED
|
@@ -26,6 +26,8 @@ github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w
|
|
| 26 |
github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM=
|
| 27 |
github.com/gin-gonic/gin v1.10.1 h1:T0ujvqyCSqRopADpgPgiTT63DUQVSfojyME59Ei63pQ=
|
| 28 |
github.com/gin-gonic/gin v1.10.1/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
|
|
|
|
|
|
|
| 29 |
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
| 30 |
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
|
| 31 |
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
|
@@ -42,6 +44,10 @@ github.com/go-playground/validator/v10 v10.27.0/go.mod h1:I5QpIEbmr8On7W0TktmJAu
|
|
| 42 |
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
| 43 |
github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
|
| 44 |
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
|
|
|
|
|
|
|
|
|
|
|
|
| 45 |
github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI=
|
| 46 |
github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
| 47 |
github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=
|
|
@@ -103,6 +109,10 @@ github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0
|
|
| 103 |
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
|
| 104 |
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
| 105 |
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
|
|
|
|
|
|
|
|
|
|
|
|
| 106 |
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
|
| 107 |
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
| 108 |
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
|
|
@@ -117,6 +127,7 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
|
|
| 117 |
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
| 118 |
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
| 119 |
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
|
|
|
| 120 |
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
| 121 |
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
| 122 |
github.com/ugorji/go/codec v1.3.0 h1:Qd2W2sQawAfG8XSvzwhBeoGq71zXOC/Q1E9y/wUcsUA=
|
|
@@ -131,6 +142,8 @@ go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/Wgbsd
|
|
| 131 |
go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E=
|
| 132 |
go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4=
|
| 133 |
go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0=
|
|
|
|
|
|
|
| 134 |
golang.org/x/arch v0.20.0 h1:dx1zTU0MAE98U+TQ8BLl7XsJbgze2WnNKF/8tGp/Q6c=
|
| 135 |
golang.org/x/arch v0.20.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk=
|
| 136 |
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
|
@@ -140,6 +153,8 @@ golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4=
|
|
| 140 |
golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc=
|
| 141 |
golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04=
|
| 142 |
golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0=
|
|
|
|
|
|
|
| 143 |
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
| 144 |
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
| 145 |
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
@@ -167,6 +182,8 @@ golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
|
|
| 167 |
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
|
| 168 |
golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k=
|
| 169 |
golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM=
|
|
|
|
|
|
|
| 170 |
google.golang.org/api v0.253.0 h1:apU86Eq9Q2eQco3NsUYFpVTfy7DwemojL7LmbAj7g/I=
|
| 171 |
google.golang.org/api v0.253.0/go.mod h1:PX09ad0r/4du83vZVAaGg7OaeyGnaUmT/CYPNvtLCbw=
|
| 172 |
google.golang.org/genproto/googleapis/rpc v0.0.0-20251014184007-4626949a642f h1:1FTH6cpXFsENbPR5Bu8NQddPSaUUE6NA2XdZdDSAJK4=
|
|
@@ -187,3 +204,5 @@ gorm.io/driver/postgres v1.6.0 h1:2dxzU8xJ+ivvqTRph34QX+WrRaJlmfyPqXmoGVjMBa4=
|
|
| 187 |
gorm.io/driver/postgres v1.6.0/go.mod h1:vUw0mrGgrTK+uPHEhAdV4sfFELrByKVGnaVRkXDhtWo=
|
| 188 |
gorm.io/gorm v1.30.1 h1:lSHg33jJTBxs2mgJRfRZeLDG+WZaHYCk3Wtfl6Ngzo4=
|
| 189 |
gorm.io/gorm v1.30.1/go.mod h1:8Z33v652h4//uMA76KjeDH8mJXPm1QNCYrMeatR0DOE=
|
|
|
|
|
|
|
|
|
| 26 |
github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM=
|
| 27 |
github.com/gin-gonic/gin v1.10.1 h1:T0ujvqyCSqRopADpgPgiTT63DUQVSfojyME59Ei63pQ=
|
| 28 |
github.com/gin-gonic/gin v1.10.1/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
|
| 29 |
+
github.com/gin-gonic/gin v1.11.0 h1:OW/6PLjyusp2PPXtyxKHU0RbX6I/l28FTdDlae5ueWk=
|
| 30 |
+
github.com/gin-gonic/gin v1.11.0/go.mod h1:+iq/FyxlGzII0KHiBGjuNn4UNENUlKbGlNmc+W50Dls=
|
| 31 |
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
| 32 |
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
|
| 33 |
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
|
|
|
| 44 |
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
| 45 |
github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
|
| 46 |
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
| 47 |
+
github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw=
|
| 48 |
+
github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
|
| 49 |
+
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
|
| 50 |
+
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
|
| 51 |
github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI=
|
| 52 |
github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
| 53 |
github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=
|
|
|
|
| 109 |
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
|
| 110 |
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
| 111 |
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
| 112 |
+
github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI=
|
| 113 |
+
github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg=
|
| 114 |
+
github.com/quic-go/quic-go v0.54.0 h1:6s1YB9QotYI6Ospeiguknbp2Znb/jZYjZLRXn9kMQBg=
|
| 115 |
+
github.com/quic-go/quic-go v0.54.0/go.mod h1:e68ZEaCdyviluZmy44P6Iey98v/Wfz6HCjQEm+l8zTY=
|
| 116 |
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
|
| 117 |
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
| 118 |
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
|
|
|
|
| 127 |
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
| 128 |
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
| 129 |
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
| 130 |
+
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
| 131 |
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
| 132 |
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
| 133 |
github.com/ugorji/go/codec v1.3.0 h1:Qd2W2sQawAfG8XSvzwhBeoGq71zXOC/Q1E9y/wUcsUA=
|
|
|
|
| 142 |
go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E=
|
| 143 |
go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4=
|
| 144 |
go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0=
|
| 145 |
+
go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU=
|
| 146 |
+
go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM=
|
| 147 |
golang.org/x/arch v0.20.0 h1:dx1zTU0MAE98U+TQ8BLl7XsJbgze2WnNKF/8tGp/Q6c=
|
| 148 |
golang.org/x/arch v0.20.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk=
|
| 149 |
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
|
|
|
| 153 |
golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc=
|
| 154 |
golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04=
|
| 155 |
golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0=
|
| 156 |
+
golang.org/x/mod v0.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U=
|
| 157 |
+
golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI=
|
| 158 |
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
| 159 |
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
| 160 |
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
|
|
| 182 |
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
|
| 183 |
golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k=
|
| 184 |
golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM=
|
| 185 |
+
golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE=
|
| 186 |
+
golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w=
|
| 187 |
google.golang.org/api v0.253.0 h1:apU86Eq9Q2eQco3NsUYFpVTfy7DwemojL7LmbAj7g/I=
|
| 188 |
google.golang.org/api v0.253.0/go.mod h1:PX09ad0r/4du83vZVAaGg7OaeyGnaUmT/CYPNvtLCbw=
|
| 189 |
google.golang.org/genproto/googleapis/rpc v0.0.0-20251014184007-4626949a642f h1:1FTH6cpXFsENbPR5Bu8NQddPSaUUE6NA2XdZdDSAJK4=
|
|
|
|
| 204 |
gorm.io/driver/postgres v1.6.0/go.mod h1:vUw0mrGgrTK+uPHEhAdV4sfFELrByKVGnaVRkXDhtWo=
|
| 205 |
gorm.io/gorm v1.30.1 h1:lSHg33jJTBxs2mgJRfRZeLDG+WZaHYCk3Wtfl6Ngzo4=
|
| 206 |
gorm.io/gorm v1.30.1/go.mod h1:8Z33v652h4//uMA76KjeDH8mJXPm1QNCYrMeatR0DOE=
|
| 207 |
+
gorm.io/gorm v1.31.0 h1:0VlycGreVhK7RF/Bwt51Fk8v0xLiiiFdbGDPIZQ7mJY=
|
| 208 |
+
gorm.io/gorm v1.31.0/go.mod h1:XyQVbO2k6YkOis7C2437jSit3SsDK72s7n7rsSHd+Gs=
|
middleware/authorization_middleware.go
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package middleware
|
| 2 |
+
|
| 3 |
+
import (
|
| 4 |
+
http_error "abdanhafidz.com/go-boilerplate/models/error"
|
| 5 |
+
"abdanhafidz.com/go-boilerplate/services"
|
| 6 |
+
utils "abdanhafidz.com/go-boilerplate/utils"
|
| 7 |
+
"github.com/gin-gonic/gin"
|
| 8 |
+
"github.com/google/uuid"
|
| 9 |
+
)
|
| 10 |
+
|
| 11 |
+
type AuthorizationMiddleware interface {
|
| 12 |
+
AuthorizeUserToEvent(ctx *gin.Context)
|
| 13 |
+
}
|
| 14 |
+
type authorizationMiddleware struct {
|
| 15 |
+
eventService services.EventService
|
| 16 |
+
}
|
| 17 |
+
|
| 18 |
+
func NewAuthorizationMiddleware(eventService services.EventService) AuthorizationMiddleware {
|
| 19 |
+
return &authorizationMiddleware{
|
| 20 |
+
eventService: eventService,
|
| 21 |
+
}
|
| 22 |
+
}
|
| 23 |
+
|
| 24 |
+
func (m *authorizationMiddleware) AuthorizeUserToEvent(c *gin.Context) {
|
| 25 |
+
|
| 26 |
+
eventSlug := c.Param("slug")
|
| 27 |
+
accountId, exists := c.Get("account_id")
|
| 28 |
+
if !exists {
|
| 29 |
+
utils.ResponseFAILED(c, eventSlug, http_error.DATA_NOT_FOUND)
|
| 30 |
+
c.Abort()
|
| 31 |
+
return
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
err := m.eventService.AuthorizeUserToEvent(c.Request.Context(), eventSlug, accountId.(uuid.UUID))
|
| 35 |
+
|
| 36 |
+
if err != nil {
|
| 37 |
+
utils.ResponseFAILED(c, eventSlug, err)
|
| 38 |
+
c.Abort()
|
| 39 |
+
return
|
| 40 |
+
}
|
| 41 |
+
|
| 42 |
+
c.Next()
|
| 43 |
+
|
| 44 |
+
}
|
models/entity/entity.go
CHANGED
|
@@ -183,8 +183,9 @@ type AcademyContent struct {
|
|
| 183 |
Title string `json:"title"`
|
| 184 |
Order uint `json:"order"`
|
| 185 |
AcademyMaterialId uint `json:"academy_material_id"`
|
| 186 |
-
|
| 187 |
}
|
|
|
|
| 188 |
type OptionCategory struct {
|
| 189 |
Id uint `gorm:"primaryKey" json:"id"`
|
| 190 |
OptionName string `json:"option_name"`
|
|
|
|
| 183 |
Title string `json:"title"`
|
| 184 |
Order uint `json:"order"`
|
| 185 |
AcademyMaterialId uint `json:"academy_material_id"`
|
| 186 |
+
Contents string `json:"contents"`
|
| 187 |
}
|
| 188 |
+
|
| 189 |
type OptionCategory struct {
|
| 190 |
Id uint `gorm:"primaryKey" json:"id"`
|
| 191 |
OptionName string `json:"option_name"`
|
models/error/error.go
CHANGED
|
@@ -17,4 +17,6 @@ var (
|
|
| 17 |
EXPIRED_TOKEN = errors.New("Token expired")
|
| 18 |
ALREADY_REGISTERED_TO_EVENT = errors.New("Account already registered to this event")
|
| 19 |
EMAIL_ALREADY_EXISTS = errors.New("Email already registered")
|
|
|
|
|
|
|
| 20 |
)
|
|
|
|
| 17 |
EXPIRED_TOKEN = errors.New("Token expired")
|
| 18 |
ALREADY_REGISTERED_TO_EVENT = errors.New("Account already registered to this event")
|
| 19 |
EMAIL_ALREADY_EXISTS = errors.New("Email already registered")
|
| 20 |
+
NOT_REGISTERED_TO_EVENT = errors.New("Account is not registered to this event")
|
| 21 |
+
|
| 22 |
)
|
provider/middleware_provider.go
CHANGED
|
@@ -4,15 +4,19 @@ import "abdanhafidz.com/go-boilerplate/middleware"
|
|
| 4 |
|
| 5 |
type MiddlewareProvider interface {
|
| 6 |
ProvideAuthenticationMiddleware() middleware.AuthenticationMiddleware
|
|
|
|
| 7 |
}
|
| 8 |
|
| 9 |
type middlewareProvider struct {
|
|
|
|
| 10 |
authenticationMiddleware middleware.AuthenticationMiddleware
|
| 11 |
}
|
| 12 |
|
| 13 |
func NewMiddlewareProvider(servicesProvider ServicesProvider) MiddlewareProvider {
|
|
|
|
| 14 |
authenticationMiddleware := middleware.NewAuthenticationMiddleware(servicesProvider.ProvideJWTService())
|
| 15 |
return &middlewareProvider{
|
|
|
|
| 16 |
authenticationMiddleware: authenticationMiddleware,
|
| 17 |
}
|
| 18 |
}
|
|
@@ -20,3 +24,7 @@ func NewMiddlewareProvider(servicesProvider ServicesProvider) MiddlewareProvider
|
|
| 20 |
func (p *middlewareProvider) ProvideAuthenticationMiddleware() middleware.AuthenticationMiddleware {
|
| 21 |
return p.authenticationMiddleware
|
| 22 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4 |
|
| 5 |
type MiddlewareProvider interface {
|
| 6 |
ProvideAuthenticationMiddleware() middleware.AuthenticationMiddleware
|
| 7 |
+
ProvideAuthorizationMiddleware() middleware.AuthorizationMiddleware
|
| 8 |
}
|
| 9 |
|
| 10 |
type middlewareProvider struct {
|
| 11 |
+
authorizationMiddleware middleware.AuthorizationMiddleware
|
| 12 |
authenticationMiddleware middleware.AuthenticationMiddleware
|
| 13 |
}
|
| 14 |
|
| 15 |
func NewMiddlewareProvider(servicesProvider ServicesProvider) MiddlewareProvider {
|
| 16 |
+
authorizationMiddleware := middleware.NewAuthorizationMiddleware(servicesProvider.ProvideEventService())
|
| 17 |
authenticationMiddleware := middleware.NewAuthenticationMiddleware(servicesProvider.ProvideJWTService())
|
| 18 |
return &middlewareProvider{
|
| 19 |
+
authorizationMiddleware: authorizationMiddleware,
|
| 20 |
authenticationMiddleware: authenticationMiddleware,
|
| 21 |
}
|
| 22 |
}
|
|
|
|
| 24 |
func (p *middlewareProvider) ProvideAuthenticationMiddleware() middleware.AuthenticationMiddleware {
|
| 25 |
return p.authenticationMiddleware
|
| 26 |
}
|
| 27 |
+
|
| 28 |
+
func (p *middlewareProvider) ProvideAuthorizationMiddleware() middleware.AuthorizationMiddleware {
|
| 29 |
+
return p.authorizationMiddleware
|
| 30 |
+
}
|
repositories/problem_set_assign_repository.go
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package repositories
|
| 2 |
+
|
| 3 |
+
import (
|
| 4 |
+
"context"
|
| 5 |
+
|
| 6 |
+
entity "abdanhafidz.com/go-boilerplate/models/entity"
|
| 7 |
+
"github.com/google/uuid"
|
| 8 |
+
"gorm.io/gorm"
|
| 9 |
+
)
|
| 10 |
+
|
| 11 |
+
type ProblemSetAssignRepository interface {
|
| 12 |
+
CreateProblemSetAssign(ctx context.Context, psa entity.ProblemSetAssign) (entity.ProblemSetAssign, error)
|
| 13 |
+
GetProblemSetAssignByID(ctx context.Context, id uuid.UUID) (entity.ProblemSetAssign, error)
|
| 14 |
+
GetProblemSetAssignByEventID(ctx context.Context, eventID uuid.UUID) ([]entity.ProblemSetAssign, error)
|
| 15 |
+
GetAllProblemSetAssign(ctx context.Context) ([]entity.ProblemSetAssign, error)
|
| 16 |
+
UpdateProblemSetAssign(ctx context.Context, psa entity.ProblemSetAssign) (entity.ProblemSetAssign, error)
|
| 17 |
+
DeleteProblemSetAssign(ctx context.Context, id uuid.UUID) error
|
| 18 |
+
}
|
| 19 |
+
|
| 20 |
+
type problemSetAssignRepository struct {
|
| 21 |
+
db *gorm.DB
|
| 22 |
+
}
|
| 23 |
+
|
| 24 |
+
func NewProblemSetAssignRepository(db *gorm.DB) ProblemSetAssignRepository {
|
| 25 |
+
return &problemSetAssignRepository{db: db}
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
func (r *problemSetAssignRepository) CreateProblemSetAssign(ctx context.Context, psa entity.ProblemSetAssign) (entity.ProblemSetAssign, error) {
|
| 29 |
+
if err := r.db.WithContext(ctx).Create(&psa).Error; err != nil {
|
| 30 |
+
return entity.ProblemSetAssign{}, err
|
| 31 |
+
}
|
| 32 |
+
return psa, nil
|
| 33 |
+
}
|
| 34 |
+
|
| 35 |
+
func (r *problemSetAssignRepository) GetProblemSetAssignByID(ctx context.Context, id uuid.UUID) (entity.ProblemSetAssign, error) {
|
| 36 |
+
var psa entity.ProblemSetAssign
|
| 37 |
+
if err := r.db.WithContext(ctx).
|
| 38 |
+
Preload("Event").
|
| 39 |
+
Preload("ProblemSet").
|
| 40 |
+
First(&psa, "id = ?", id).Error; err != nil {
|
| 41 |
+
return entity.ProblemSetAssign{}, err
|
| 42 |
+
}
|
| 43 |
+
return psa, nil
|
| 44 |
+
}
|
| 45 |
+
|
| 46 |
+
func (r *problemSetAssignRepository) GetProblemSetAssignByEventID(ctx context.Context, eventID uuid.UUID) ([]entity.ProblemSetAssign, error) {
|
| 47 |
+
var psas []entity.ProblemSetAssign
|
| 48 |
+
if err := r.db.WithContext(ctx).
|
| 49 |
+
Preload("Event").
|
| 50 |
+
Preload("ProblemSet").
|
| 51 |
+
Where("event_id = ?", eventID).
|
| 52 |
+
Find(&psas).Error; err != nil {
|
| 53 |
+
return nil, err
|
| 54 |
+
}
|
| 55 |
+
if len(psas) == 0 {
|
| 56 |
+
// Optional logging or custom error
|
| 57 |
+
}
|
| 58 |
+
return psas, nil
|
| 59 |
+
}
|
| 60 |
+
|
| 61 |
+
func (r *problemSetAssignRepository) GetAllProblemSetAssign(ctx context.Context) ([]entity.ProblemSetAssign, error) {
|
| 62 |
+
var psas []entity.ProblemSetAssign
|
| 63 |
+
if err := r.db.WithContext(ctx).
|
| 64 |
+
Preload("Event").
|
| 65 |
+
Preload("ProblemSet").
|
| 66 |
+
Find(&psas).Error; err != nil {
|
| 67 |
+
return nil, err
|
| 68 |
+
}
|
| 69 |
+
return psas, nil
|
| 70 |
+
}
|
| 71 |
+
|
| 72 |
+
func (r *problemSetAssignRepository) UpdateProblemSetAssign(ctx context.Context, psa entity.ProblemSetAssign) (entity.ProblemSetAssign, error) {
|
| 73 |
+
if err := r.db.WithContext(ctx).Save(&psa).Error; err != nil {
|
| 74 |
+
return entity.ProblemSetAssign{}, err
|
| 75 |
+
}
|
| 76 |
+
return psa, nil
|
| 77 |
+
}
|
| 78 |
+
|
| 79 |
+
func (r *problemSetAssignRepository) DeleteProblemSetAssign(ctx context.Context, id uuid.UUID) error {
|
| 80 |
+
return r.db.WithContext(ctx).Unscoped().Delete(&entity.ProblemSetAssign{}, "id = ?", id).Error
|
| 81 |
+
}
|
repositories/problem_set_repository.go
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package repositories
|
| 2 |
+
|
| 3 |
+
import (
|
| 4 |
+
"context"
|
| 5 |
+
|
| 6 |
+
entity "abdanhafidz.com/go-boilerplate/models/entity"
|
| 7 |
+
"github.com/google/uuid"
|
| 8 |
+
"gorm.io/gorm"
|
| 9 |
+
)
|
| 10 |
+
|
| 11 |
+
type ProblemSetRepository interface {
|
| 12 |
+
CreateProblemSet(ctx context.Context, problemSet entity.ProblemSet) (entity.ProblemSet, error)
|
| 13 |
+
GetProblemSetByID(ctx context.Context, id uuid.UUID) (entity.ProblemSet, error)
|
| 14 |
+
GetAllProblemSets(ctx context.Context) ([]entity.ProblemSet, error)
|
| 15 |
+
UpdateProblemSet(ctx context.Context, problemSet entity.ProblemSet) (entity.ProblemSet, error)
|
| 16 |
+
DeleteProblemSet(ctx context.Context, id uuid.UUID) error
|
| 17 |
+
GetProblemSetsWithQuestions(ctx context.Context) ([]entity.ProblemSet, error)
|
| 18 |
+
GetProblemSetWithQuestionsByID(ctx context.Context, id uuid.UUID) (entity.ProblemSet, error)
|
| 19 |
+
}
|
| 20 |
+
|
| 21 |
+
type problemSetRepository struct {
|
| 22 |
+
db *gorm.DB
|
| 23 |
+
}
|
| 24 |
+
|
| 25 |
+
func NewProblemSetRepository(db *gorm.DB) ProblemSetRepository {
|
| 26 |
+
return &problemSetRepository{db: db}
|
| 27 |
+
}
|
| 28 |
+
|
| 29 |
+
func (r *problemSetRepository) CreateProblemSet(ctx context.Context, problemSet entity.ProblemSet) (entity.ProblemSet, error) {
|
| 30 |
+
if err := r.db.WithContext(ctx).Create(&problemSet).Error; err != nil {
|
| 31 |
+
return entity.ProblemSet{}, err
|
| 32 |
+
}
|
| 33 |
+
return problemSet, nil
|
| 34 |
+
}
|
| 35 |
+
|
| 36 |
+
func (r *problemSetRepository) GetProblemSetByID(ctx context.Context, id uuid.UUID) (entity.ProblemSet, error) {
|
| 37 |
+
var problemSet entity.ProblemSet
|
| 38 |
+
if err := r.db.WithContext(ctx).First(&problemSet, "id = ?", id).Error; err != nil {
|
| 39 |
+
return entity.ProblemSet{}, err
|
| 40 |
+
}
|
| 41 |
+
return problemSet, nil
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
func (r *problemSetRepository) GetAllProblemSets(ctx context.Context) ([]entity.ProblemSet, error) {
|
| 45 |
+
var problemSets []entity.ProblemSet
|
| 46 |
+
if err := r.db.WithContext(ctx).Find(&problemSets).Error; err != nil {
|
| 47 |
+
return nil, err
|
| 48 |
+
}
|
| 49 |
+
return problemSets, nil
|
| 50 |
+
}
|
| 51 |
+
|
| 52 |
+
func (r *problemSetRepository) UpdateProblemSet(ctx context.Context, problemSet entity.ProblemSet) (entity.ProblemSet, error) {
|
| 53 |
+
if err := r.db.WithContext(ctx).Save(&problemSet).Error; err != nil {
|
| 54 |
+
return entity.ProblemSet{}, err
|
| 55 |
+
}
|
| 56 |
+
return problemSet, nil
|
| 57 |
+
}
|
| 58 |
+
|
| 59 |
+
func (r *problemSetRepository) DeleteProblemSet(ctx context.Context, id uuid.UUID) error {
|
| 60 |
+
return r.db.WithContext(ctx).Unscoped().Delete(&entity.ProblemSet{}, "id = ?", id).Error
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
// Get all ProblemSets with preloaded questions (JOIN)
|
| 64 |
+
func (r *problemSetRepository) GetProblemSetsWithQuestions(ctx context.Context) ([]entity.ProblemSet, error) {
|
| 65 |
+
var problemSets []entity.ProblemSet
|
| 66 |
+
if err := r.db.WithContext(ctx).
|
| 67 |
+
Preload("Questions").
|
| 68 |
+
Find(&problemSets).Error; err != nil {
|
| 69 |
+
return nil, err
|
| 70 |
+
}
|
| 71 |
+
return problemSets, nil
|
| 72 |
+
}
|
| 73 |
+
|
| 74 |
+
// Get single ProblemSet (by ID) with Questions
|
| 75 |
+
func (r *problemSetRepository) GetProblemSetWithQuestionsByID(ctx context.Context, id uuid.UUID) (entity.ProblemSet, error) {
|
| 76 |
+
var problemSet entity.ProblemSet
|
| 77 |
+
if err := r.db.WithContext(ctx).
|
| 78 |
+
Preload("Questions").
|
| 79 |
+
First(&problemSet, "id = ?", id).Error; err != nil {
|
| 80 |
+
return entity.ProblemSet{}, err
|
| 81 |
+
}
|
| 82 |
+
return problemSet, nil
|
| 83 |
+
}
|
router/event_router.go
CHANGED
|
@@ -8,10 +8,12 @@ import (
|
|
| 8 |
func EventRouter(router *gin.Engine, middleware provider.MiddlewareProvider, controller provider.ControllerProvider) {
|
| 9 |
eventController := controller.ProvideEventController()
|
| 10 |
authenticationMiddleware := middleware.ProvideAuthenticationMiddleware()
|
|
|
|
| 11 |
routerGroup := router.Group("api/v1/events")
|
| 12 |
{
|
| 13 |
routerGroup.GET("/", eventController.List)
|
| 14 |
-
routerGroup.GET("/
|
| 15 |
routerGroup.POST("/register-event", authenticationMiddleware.VerifyAccount, eventController.Join)
|
|
|
|
| 16 |
}
|
| 17 |
}
|
|
|
|
| 8 |
func EventRouter(router *gin.Engine, middleware provider.MiddlewareProvider, controller provider.ControllerProvider) {
|
| 9 |
eventController := controller.ProvideEventController()
|
| 10 |
authenticationMiddleware := middleware.ProvideAuthenticationMiddleware()
|
| 11 |
+
authorizationMiddleware := middleware.ProvideAuthorizationMiddleware()
|
| 12 |
routerGroup := router.Group("api/v1/events")
|
| 13 |
{
|
| 14 |
routerGroup.GET("/", eventController.List)
|
| 15 |
+
routerGroup.GET("/:slug", authenticationMiddleware.VerifyAccount, eventController.DetailBySlug)
|
| 16 |
routerGroup.POST("/register-event", authenticationMiddleware.VerifyAccount, eventController.Join)
|
| 17 |
+
routerGroup.GET("/:slug/quizzes", authenticationMiddleware.VerifyAccount, authorizationMiddleware.AuthorizeUserToEvent, eventController.QuizListByEvent)
|
| 18 |
}
|
| 19 |
}
|
services/event_service.go
CHANGED
|
@@ -12,20 +12,45 @@ import (
|
|
| 12 |
)
|
| 13 |
|
| 14 |
type EventService interface {
|
|
|
|
| 15 |
List(ctx context.Context, p repositories.Pagination) ([]entity.Events, int64, error)
|
| 16 |
DetailBySlug(ctx context.Context, slug string, accountId uuid.UUID) (dto.EventDetailResponse, error)
|
| 17 |
JoinByCode(ctx context.Context, accountID uuid.UUID, code string) (dto.EventDetailResponse, error)
|
|
|
|
| 18 |
}
|
| 19 |
|
| 20 |
type eventService struct {
|
| 21 |
-
|
| 22 |
-
|
|
|
|
| 23 |
}
|
| 24 |
|
| 25 |
func NewEventService(eventsRepo repositories.EventsRepository, eventAssignRepo repositories.EventAssignRepository) EventService {
|
| 26 |
return &eventService{eventsRepo: eventsRepo, eventAssignRepo: eventAssignRepo}
|
| 27 |
}
|
| 28 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 29 |
func (s *eventService) List(ctx context.Context, pagination repositories.Pagination) ([]entity.Events, int64, error) {
|
| 30 |
list, total, err := s.eventsRepo.GetAllPaginate(ctx, pagination)
|
| 31 |
return list, total, err
|
|
@@ -69,3 +94,9 @@ func (s *eventService) JoinByCode(ctx context.Context, accountID uuid.UUID, code
|
|
| 69 |
|
| 70 |
return dto.EventDetailResponse{Data: &ev, RegisterStatus: 1}, nil
|
| 71 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 12 |
)
|
| 13 |
|
| 14 |
type EventService interface {
|
| 15 |
+
AuthorizeUserToEvent(ctx context.Context, slug string, accountId uuid.UUID) error
|
| 16 |
List(ctx context.Context, p repositories.Pagination) ([]entity.Events, int64, error)
|
| 17 |
DetailBySlug(ctx context.Context, slug string, accountId uuid.UUID) (dto.EventDetailResponse, error)
|
| 18 |
JoinByCode(ctx context.Context, accountID uuid.UUID, code string) (dto.EventDetailResponse, error)
|
| 19 |
+
QuizListByEvent(ctx context.Context, slug string) ([]entity.ProblemSet, error)
|
| 20 |
}
|
| 21 |
|
| 22 |
type eventService struct {
|
| 23 |
+
problemSetService ProblemSetService
|
| 24 |
+
eventsRepo repositories.EventsRepository
|
| 25 |
+
eventAssignRepo repositories.EventAssignRepository
|
| 26 |
}
|
| 27 |
|
| 28 |
func NewEventService(eventsRepo repositories.EventsRepository, eventAssignRepo repositories.EventAssignRepository) EventService {
|
| 29 |
return &eventService{eventsRepo: eventsRepo, eventAssignRepo: eventAssignRepo}
|
| 30 |
}
|
| 31 |
|
| 32 |
+
func (s *eventService) AuthorizeUserToEvent(ctx context.Context, slug string, accountId uuid.UUID) error {
|
| 33 |
+
ev, err := s.eventsRepo.GetBySlug(ctx, slug)
|
| 34 |
+
|
| 35 |
+
if err != nil {
|
| 36 |
+
return err
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
evAssign, err := s.eventAssignRepo.GetByEventAndAccount(ctx, ev.Id, accountId)
|
| 40 |
+
if err == nil && evAssign.Id != uuid.Nil {
|
| 41 |
+
return nil
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
event, err := s.eventsRepo.GetByID(ctx, evAssign.EventId)
|
| 45 |
+
|
| 46 |
+
if event.IsPublic {
|
| 47 |
+
return http_error.NOT_REGISTERED_TO_EVENT
|
| 48 |
+
} else if !event.IsPublic {
|
| 49 |
+
return http_error.UNAUTHORIZED
|
| 50 |
+
}
|
| 51 |
+
|
| 52 |
+
return err
|
| 53 |
+
}
|
| 54 |
func (s *eventService) List(ctx context.Context, pagination repositories.Pagination) ([]entity.Events, int64, error) {
|
| 55 |
list, total, err := s.eventsRepo.GetAllPaginate(ctx, pagination)
|
| 56 |
return list, total, err
|
|
|
|
| 94 |
|
| 95 |
return dto.EventDetailResponse{Data: &ev, RegisterStatus: 1}, nil
|
| 96 |
}
|
| 97 |
+
|
| 98 |
+
func (s *eventService) QuizListByEvent(ctx context.Context, slug string) ([]entity.ProblemSet, error) {
|
| 99 |
+
ev, err := s.eventsRepo.GetBySlug(ctx, slug)
|
| 100 |
+
psList, err := s.problemSetService.GetProblemSetListByEventId(ctx, ev.Id)
|
| 101 |
+
return psList, err
|
| 102 |
+
}
|
services/problem_set_service.go
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package services
|
| 2 |
+
|
| 3 |
+
import (
|
| 4 |
+
"context"
|
| 5 |
+
|
| 6 |
+
entity "abdanhafidz.com/go-boilerplate/models/entity"
|
| 7 |
+
"abdanhafidz.com/go-boilerplate/repositories"
|
| 8 |
+
"github.com/google/uuid"
|
| 9 |
+
)
|
| 10 |
+
|
| 11 |
+
type ProblemSetService interface {
|
| 12 |
+
GetProblemSetListByEventId(ctx context.Context, eventId uuid.UUID) ([]entity.ProblemSet, error)
|
| 13 |
+
}
|
| 14 |
+
|
| 15 |
+
type problemSetService struct {
|
| 16 |
+
problemSetRepo repositories.ProblemSetRepository
|
| 17 |
+
problemSetAssignRepo repositories.ProblemSetAssignRepository
|
| 18 |
+
}
|
| 19 |
+
|
| 20 |
+
func NewProblemSetService(problemSetRepo repositories.ProblemSetRepository, problemSetAssignRepo repositories.ProblemSetAssignRepository) ProblemSetService {
|
| 21 |
+
return &problemSetService{problemSetRepo: problemSetRepo, problemSetAssignRepo: problemSetAssignRepo}
|
| 22 |
+
}
|
| 23 |
+
|
| 24 |
+
func (s *problemSetService) GetProblemSetListByEventId(ctx context.Context, eventId uuid.UUID) ([]entity.ProblemSet, error) {
|
| 25 |
+
psas, err := s.problemSetAssignRepo.GetProblemSetAssignByEventID(ctx, eventId)
|
| 26 |
+
if err != nil {
|
| 27 |
+
return nil, err
|
| 28 |
+
}
|
| 29 |
+
var problemSets []entity.ProblemSet
|
| 30 |
+
for _, psa := range psas {
|
| 31 |
+
ps, err := s.problemSetRepo.GetProblemSetByID(ctx, psa.ProblemSetId)
|
| 32 |
+
if err != nil {
|
| 33 |
+
return nil, err
|
| 34 |
+
}
|
| 35 |
+
|
| 36 |
+
problemSets = append(problemSets, ps)
|
| 37 |
+
}
|
| 38 |
+
return problemSets, nil
|
| 39 |
+
}
|
services/service.go
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
package services
|
space/.gitattributes
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
*.7z filter=lfs diff=lfs merge=lfs -text
|
| 2 |
+
*.arrow filter=lfs diff=lfs merge=lfs -text
|
| 3 |
+
*.bin filter=lfs diff=lfs merge=lfs -text
|
| 4 |
+
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
| 5 |
+
*.ckpt filter=lfs diff=lfs merge=lfs -text
|
| 6 |
+
*.ftz filter=lfs diff=lfs merge=lfs -text
|
| 7 |
+
*.gz filter=lfs diff=lfs merge=lfs -text
|
| 8 |
+
*.h5 filter=lfs diff=lfs merge=lfs -text
|
| 9 |
+
*.joblib filter=lfs diff=lfs merge=lfs -text
|
| 10 |
+
*.lfs.* filter=lfs diff=lfs merge=lfs -text
|
| 11 |
+
*.mlmodel filter=lfs diff=lfs merge=lfs -text
|
| 12 |
+
*.model filter=lfs diff=lfs merge=lfs -text
|
| 13 |
+
*.msgpack filter=lfs diff=lfs merge=lfs -text
|
| 14 |
+
*.npy filter=lfs diff=lfs merge=lfs -text
|
| 15 |
+
*.npz filter=lfs diff=lfs merge=lfs -text
|
| 16 |
+
*.onnx filter=lfs diff=lfs merge=lfs -text
|
| 17 |
+
*.ot filter=lfs diff=lfs merge=lfs -text
|
| 18 |
+
*.parquet filter=lfs diff=lfs merge=lfs -text
|
| 19 |
+
*.pb filter=lfs diff=lfs merge=lfs -text
|
| 20 |
+
*.pickle filter=lfs diff=lfs merge=lfs -text
|
| 21 |
+
*.pkl filter=lfs diff=lfs merge=lfs -text
|
| 22 |
+
*.pt filter=lfs diff=lfs merge=lfs -text
|
| 23 |
+
*.pth filter=lfs diff=lfs merge=lfs -text
|
| 24 |
+
*.rar filter=lfs diff=lfs merge=lfs -text
|
| 25 |
+
*.safetensors filter=lfs diff=lfs merge=lfs -text
|
| 26 |
+
saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
| 27 |
+
*.tar.* filter=lfs diff=lfs merge=lfs -text
|
| 28 |
+
*.tar filter=lfs diff=lfs merge=lfs -text
|
| 29 |
+
*.tflite filter=lfs diff=lfs merge=lfs -text
|
| 30 |
+
*.tgz filter=lfs diff=lfs merge=lfs -text
|
| 31 |
+
*.wasm filter=lfs diff=lfs merge=lfs -text
|
| 32 |
+
*.xz filter=lfs diff=lfs merge=lfs -text
|
| 33 |
+
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
+
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
+
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
space/.github/workflows/main.yml
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
name: Deploy to Huggingface
|
| 2 |
+
on:
|
| 3 |
+
push:
|
| 4 |
+
branches:
|
| 5 |
+
- main
|
| 6 |
+
jobs:
|
| 7 |
+
deploy-to-huggingface:
|
| 8 |
+
runs-on: ubuntu-latest
|
| 9 |
+
steps:
|
| 10 |
+
# Checkout repository
|
| 11 |
+
- name: Checkout Repository
|
| 12 |
+
uses: actions/checkout@v3
|
| 13 |
+
# Setup Git
|
| 14 |
+
- name: Setup Git for Huggingface
|
| 15 |
+
run: |
|
| 16 |
+
git config --global user.email "abdan.hafidz@gmail.com"
|
| 17 |
+
git config --global user.name "abdanhafidz"
|
| 18 |
+
# Clone Huggingface Space Repository
|
| 19 |
+
- name: Clone Huggingface Space
|
| 20 |
+
env:
|
| 21 |
+
HF_TOKEN: ${{ secrets.HF_TOKEN }}
|
| 22 |
+
run: |
|
| 23 |
+
git clone https://huggingface.co/spaces/lifedebugger/quzuu-api-dev-v2 space
|
| 24 |
+
# Update Git Remote URL and Pull Latest Changes
|
| 25 |
+
- name: Update Remote and Pull Changes
|
| 26 |
+
env:
|
| 27 |
+
HF_TOKEN: ${{ secrets.HF_TOKEN }}
|
| 28 |
+
run: |
|
| 29 |
+
cd space
|
| 30 |
+
git remote set-url origin https://lifedebugger:$HF_TOKEN@huggingface.co/spaces/lifedebugger/quzuu-api-dev-v2
|
| 31 |
+
git pull origin main || echo "No changes to pull"
|
| 32 |
+
# Clean Space Directory - Delete all files except .git
|
| 33 |
+
- name: Clean Space Directory
|
| 34 |
+
run: |
|
| 35 |
+
cd space
|
| 36 |
+
find . -mindepth 1 -not -path "./.git*" -delete
|
| 37 |
+
# Copy Files to Huggingface Space
|
| 38 |
+
- name: Copy Files to Space
|
| 39 |
+
run: |
|
| 40 |
+
rsync -av --exclude='.git' ./ space/
|
| 41 |
+
# Commit and Push to Huggingface Space
|
| 42 |
+
- name: Commit and Push to Huggingface
|
| 43 |
+
env:
|
| 44 |
+
HF_TOKEN: ${{ secrets.HF_TOKEN }}
|
| 45 |
+
run: |
|
| 46 |
+
cd space
|
| 47 |
+
git add .
|
| 48 |
+
git commit -m "Deploy files from GitHub repository" || echo "No changes to commit"
|
| 49 |
+
git push origin main || echo "No changes to push"
|
space/.gitignore
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
/.env
|