Spaces:
Sleeping
Sleeping
Commit
·
20807c7
1
Parent(s):
824266e
Deploy files from GitHub repository
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- controller/event/event_join_controller.go +22 -0
- controller/event/event_list_controller.go +54 -0
- repositories/event_repository.go +5 -23
- router/event_route.go +2 -2
- services/event_list_service.go +29 -0
- services/event_register_service.go +38 -0
- space/controller/event/get_all_event_controller_NEED TO FIX.go +5 -2
- space/router/event_route.go +1 -1
- space/services/get_all_event_service_NEED TO FIX.go +4 -3
- space/space/.github/workflows/main.yml +52 -0
- space/space/config/config.go +34 -0
- space/space/config/database_connection_config.go +99 -0
- space/space/controller/auth/auth_change_password_controller.go +21 -0
- space/space/controller/auth/auth_external_controller.go +20 -0
- space/space/controller/auth/auth_forgot_password_controller.go +29 -0
- space/space/controller/auth/auth_login_controller.go +20 -0
- space/space/controller/auth/auth_register_controller.go +22 -0
- space/space/controller/controller.go +71 -0
- space/space/controller/email/email_create_verification_controller.go +21 -0
- space/space/controller/email/email_validate_controller.go +23 -0
- space/space/controller/event/event_detail_controller.go +21 -0
- space/space/controller/event/event_join_controller_NEED TO FIX.go +22 -0
- space/space/controller/event/get_all_event_controller_NEED TO FIX.go +53 -0
- space/space/controller/home_controller.go +9 -0
- space/space/controller/options/option_category_controller.go +19 -0
- space/space/controller/options/option_value_controller.go +19 -0
- space/space/controller/region/city/city_list_controller.go +21 -0
- space/space/controller/region/city/city_seeds_controller.go +17 -0
- space/space/controller/region/province/province_list_controller.go +17 -0
- space/space/controller/region/province/province_seeds_controller.go +17 -0
- space/space/controller/user/user_profile_controller.go +21 -0
- space/space/controller/user/user_update_profile_controller.go +25 -0
- space/space/logs/error_log.txt +1 -0
- space/space/logs/security_log.txt +0 -0
- space/space/middleware/authentication_middleware.go +38 -0
- space/space/middleware/middleware.go +30 -0
- space/space/middleware/response_middleware.go +45 -0
- space/space/models/authentication_payload_model.go +18 -0
- space/space/models/database_orm_model.go +264 -0
- space/space/models/exception_model.go +12 -0
- space/space/models/model.go +1 -0
- space/space/models/request_model.go +56 -0
- space/space/models/response_model.go +50 -0
- space/space/repositories/academy_repository.go +73 -0
- space/space/repositories/account_repository.go +88 -0
- space/space/repositories/email_verification_repository.go +63 -0
- space/space/repositories/event_repository.go +111 -0
- space/space/repositories/external_auth_repository.go +40 -0
- space/space/repositories/forgot_password_repository.go +22 -0
- space/space/repositories/option_repository.go +43 -0
controller/event/event_join_controller.go
ADDED
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
package event
|
2 |
+
|
3 |
+
import (
|
4 |
+
"github.com/gin-gonic/gin"
|
5 |
+
"godp.abdanhafidz.com/controller"
|
6 |
+
"godp.abdanhafidz.com/models"
|
7 |
+
"godp.abdanhafidz.com/services"
|
8 |
+
)
|
9 |
+
|
10 |
+
func Register(c *gin.Context) {
|
11 |
+
eventAssign := services.JoinEventService{}
|
12 |
+
eventAssignController := controller.Controller[models.JoinEventRequest, models.JoinEventRequest, models.EventDetailResponse]{
|
13 |
+
Service: &eventAssign.Service,
|
14 |
+
}
|
15 |
+
|
16 |
+
eventAssignController.RequestJSON(c, func() {
|
17 |
+
eventAssignController.Service.Constructor.EventId = eventAssignController.Request.EventId
|
18 |
+
eventAssignController.Service.Constructor.EventCode = eventAssignController.Request.EventCode
|
19 |
+
idUser := eventAssignController.AccountData.UserID
|
20 |
+
eventAssign.Create(idUser)
|
21 |
+
})
|
22 |
+
}
|
controller/event/event_list_controller.go
ADDED
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
package event
|
2 |
+
|
3 |
+
import (
|
4 |
+
"strconv"
|
5 |
+
|
6 |
+
"github.com/gin-gonic/gin"
|
7 |
+
"godp.abdanhafidz.com/controller"
|
8 |
+
"godp.abdanhafidz.com/models"
|
9 |
+
"godp.abdanhafidz.com/repositories"
|
10 |
+
"godp.abdanhafidz.com/services"
|
11 |
+
"godp.abdanhafidz.com/utils"
|
12 |
+
)
|
13 |
+
|
14 |
+
func EventList(c *gin.Context) {
|
15 |
+
limit, err := strconv.Atoi(c.DefaultQuery("limit", "10"))
|
16 |
+
if err != nil {
|
17 |
+
service := services.Service[any, any]{
|
18 |
+
Exception: models.Exception{
|
19 |
+
Message: "Invalid limit parameter",
|
20 |
+
},
|
21 |
+
}
|
22 |
+
utils.SendResponse(c, service)
|
23 |
+
return
|
24 |
+
}
|
25 |
+
|
26 |
+
offset, err := strconv.Atoi(c.DefaultQuery("offset", "0"))
|
27 |
+
if err != nil {
|
28 |
+
service := services.Service[any, any]{
|
29 |
+
Exception: models.Exception{
|
30 |
+
Message: "Invalid offset parameter",
|
31 |
+
},
|
32 |
+
}
|
33 |
+
utils.SendResponse(c, service)
|
34 |
+
return
|
35 |
+
}
|
36 |
+
filter := c.DefaultQuery("filter", "")
|
37 |
+
filterBy := c.DefaultQuery("filter_by", "")
|
38 |
+
|
39 |
+
pagination := repositories.PaginationConstructor{
|
40 |
+
Limit: limit,
|
41 |
+
Offset: offset,
|
42 |
+
Filter: filter,
|
43 |
+
FilterBy: filterBy,
|
44 |
+
}
|
45 |
+
|
46 |
+
eventsService := services.GetAllEventService{}
|
47 |
+
getAllEventController := controller.Controller[any, models.Events, []models.Events]{
|
48 |
+
Service: &eventsService.Service,
|
49 |
+
}
|
50 |
+
|
51 |
+
eventsService.Retrieve(pagination)
|
52 |
+
|
53 |
+
getAllEventController.Response(c)
|
54 |
+
}
|
repositories/event_repository.go
CHANGED
@@ -2,40 +2,28 @@ package repositories
|
|
2 |
|
3 |
import (
|
4 |
"log"
|
5 |
-
"time"
|
6 |
|
7 |
"github.com/google/uuid"
|
8 |
"godp.abdanhafidz.com/models"
|
9 |
)
|
10 |
|
11 |
-
func
|
12 |
repo := Construct[models.Events, []models.Events](
|
13 |
models.Events{},
|
14 |
)
|
15 |
repo.Pagination = pagination
|
16 |
|
|
|
17 |
log.Printf("Pagination - Limit: %d, Offset: %d", pagination.Limit, pagination.Offset)
|
18 |
|
|
|
19 |
repo.Transactions(
|
20 |
FindAllPaginate[models.Events, []models.Events],
|
21 |
)
|
22 |
|
23 |
-
|
24 |
-
|
25 |
-
filteredEvents := []models.Events{}
|
26 |
-
for _, event := range repo.Result {
|
27 |
-
if event.IsPublic || isAssignedToEvent(userId, event.Id) {
|
28 |
-
if event.EndEvent.After(currentTime) {
|
29 |
-
filteredEvents = append(filteredEvents, event)
|
30 |
-
}
|
31 |
-
}
|
32 |
-
}
|
33 |
-
|
34 |
-
repo.Result = filteredEvents
|
35 |
-
repo.RowsCount = len(filteredEvents)
|
36 |
-
|
37 |
if repo.RowsCount == 0 {
|
38 |
-
log.Println("No
|
39 |
}
|
40 |
|
41 |
return *repo
|
@@ -103,9 +91,3 @@ func AssignEvent(eventAssign models.EventAssign) Repository[models.EventAssign,
|
|
103 |
Create(repo)
|
104 |
return *repo
|
105 |
}
|
106 |
-
|
107 |
-
func isAssignedToEvent(userId uuid.UUID, eventId uuid.UUID) bool {
|
108 |
-
repo := GetEventAssigned(eventId, userId)
|
109 |
-
|
110 |
-
return repo.RowsCount > 0
|
111 |
-
}
|
|
|
2 |
|
3 |
import (
|
4 |
"log"
|
|
|
5 |
|
6 |
"github.com/google/uuid"
|
7 |
"godp.abdanhafidz.com/models"
|
8 |
)
|
9 |
|
10 |
+
func GetAllEventsPaginate(pagination PaginationConstructor) Repository[models.Events, []models.Events] {
|
11 |
repo := Construct[models.Events, []models.Events](
|
12 |
models.Events{},
|
13 |
)
|
14 |
repo.Pagination = pagination
|
15 |
|
16 |
+
// Add debug log to verify pagination values
|
17 |
log.Printf("Pagination - Limit: %d, Offset: %d", pagination.Limit, pagination.Offset)
|
18 |
|
19 |
+
// Transactions that execute the query
|
20 |
repo.Transactions(
|
21 |
FindAllPaginate[models.Events, []models.Events],
|
22 |
)
|
23 |
|
24 |
+
// Check if there's an error or no records
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
if repo.RowsCount == 0 {
|
26 |
+
log.Println("No events found with the provided pagination")
|
27 |
}
|
28 |
|
29 |
return *repo
|
|
|
91 |
Create(repo)
|
92 |
return *repo
|
93 |
}
|
|
|
|
|
|
|
|
|
|
|
|
router/event_route.go
CHANGED
@@ -9,8 +9,8 @@ import (
|
|
9 |
func EventRoute(router *gin.Engine) {
|
10 |
routerGroup := router.Group("api/v1/events")
|
11 |
{
|
12 |
-
routerGroup.GET("/",
|
13 |
routerGroup.GET("/details/:id_event", middleware.AuthUser, event.EventDetail)
|
14 |
-
routerGroup.POST("/register-event", middleware.AuthUser, event.
|
15 |
}
|
16 |
}
|
|
|
9 |
func EventRoute(router *gin.Engine) {
|
10 |
routerGroup := router.Group("api/v1/events")
|
11 |
{
|
12 |
+
routerGroup.GET("/", event.EventList)
|
13 |
routerGroup.GET("/details/:id_event", middleware.AuthUser, event.EventDetail)
|
14 |
+
routerGroup.POST("/register-event", middleware.AuthUser, event.Register)
|
15 |
}
|
16 |
}
|
services/event_list_service.go
ADDED
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
package services
|
2 |
+
|
3 |
+
import (
|
4 |
+
"godp.abdanhafidz.com/models"
|
5 |
+
"godp.abdanhafidz.com/repositories"
|
6 |
+
)
|
7 |
+
|
8 |
+
type GetAllEventService struct {
|
9 |
+
Service[models.Events, []models.Events]
|
10 |
+
}
|
11 |
+
|
12 |
+
func (s *GetAllEventService) Retrieve(pagination repositories.PaginationConstructor) {
|
13 |
+
eventsRepo := repositories.GetAllEventsPaginate(pagination)
|
14 |
+
|
15 |
+
events := eventsRepo.Result
|
16 |
+
|
17 |
+
totalRecords := eventsRepo.RowsCount
|
18 |
+
totalPages := (totalRecords / pagination.Limit) + 1
|
19 |
+
|
20 |
+
metadata := repositories.PaginationMetadata{
|
21 |
+
TotalRecords: totalRecords,
|
22 |
+
TotalPages: totalPages,
|
23 |
+
CurrentPage: (pagination.Offset / pagination.Limit) + 1,
|
24 |
+
PageSize: pagination.Limit,
|
25 |
+
}
|
26 |
+
|
27 |
+
s.Result = events
|
28 |
+
s.MetaData = metadata
|
29 |
+
}
|
services/event_register_service.go
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
package services
|
2 |
+
|
3 |
+
import (
|
4 |
+
"github.com/google/uuid"
|
5 |
+
"godp.abdanhafidz.com/models"
|
6 |
+
"godp.abdanhafidz.com/repositories"
|
7 |
+
)
|
8 |
+
|
9 |
+
type JoinEventService struct {
|
10 |
+
Service[models.JoinEventRequest, models.EventDetailResponse]
|
11 |
+
}
|
12 |
+
|
13 |
+
func (s *JoinEventService) Create(AccountId uuid.UUID) {
|
14 |
+
event := repositories.GetEventByCode(s.Constructor.EventCode)
|
15 |
+
// log.Printf("event: %v", event)
|
16 |
+
if event.NoRecord {
|
17 |
+
s.Error = event.RowsError
|
18 |
+
s.Exception.DataNotFound = true
|
19 |
+
s.Exception.Message = "event not found"
|
20 |
+
return
|
21 |
+
}
|
22 |
+
// ngecek apakah si event dan si user udah ke assign/register
|
23 |
+
assigned := repositories.GetEventAssigned(s.Constructor.EventId, AccountId)
|
24 |
+
if assigned.NoRecord == true {
|
25 |
+
accountAssigned := &models.EventAssign{
|
26 |
+
Id: uuid.New(),
|
27 |
+
EventId: s.Constructor.EventId,
|
28 |
+
AccountId: AccountId,
|
29 |
+
}
|
30 |
+
repositories.AssignEvent(*accountAssigned)
|
31 |
+
} else {
|
32 |
+
s.Exception.DataDuplicate = true
|
33 |
+
s.Exception.Message = "account already assigned to this event"
|
34 |
+
return
|
35 |
+
}
|
36 |
+
s.Result.Data = &event.Result
|
37 |
+
s.Result.RegisterStatus = 1
|
38 |
+
}
|
space/controller/event/get_all_event_controller_NEED TO FIX.go
CHANGED
@@ -42,12 +42,15 @@ func GetAllEvent(c *gin.Context) {
|
|
42 |
FilterBy: filterBy,
|
43 |
}
|
44 |
|
45 |
-
eventsService := services.
|
46 |
getAllEventController := controller.Controller[any, models.Events, []models.Events]{
|
47 |
Service: &eventsService.Service,
|
48 |
}
|
49 |
|
50 |
-
|
|
|
|
|
|
|
51 |
|
52 |
getAllEventController.Response(c)
|
53 |
}
|
|
|
42 |
FilterBy: filterBy,
|
43 |
}
|
44 |
|
45 |
+
eventsService := services.EventList{}
|
46 |
getAllEventController := controller.Controller[any, models.Events, []models.Events]{
|
47 |
Service: &eventsService.Service,
|
48 |
}
|
49 |
|
50 |
+
getAllEventController.HeaderParse(c, func() {
|
51 |
+
userid := getAllEventController.AccountData.UserID
|
52 |
+
eventsService.EventListWithFilter(userid, pagination)
|
53 |
+
})
|
54 |
|
55 |
getAllEventController.Response(c)
|
56 |
}
|
space/router/event_route.go
CHANGED
@@ -9,7 +9,7 @@ import (
|
|
9 |
func EventRoute(router *gin.Engine) {
|
10 |
routerGroup := router.Group("api/v1/events")
|
11 |
{
|
12 |
-
routerGroup.GET("/", event.GetAllEvent)
|
13 |
routerGroup.GET("/details/:id_event", middleware.AuthUser, event.EventDetail)
|
14 |
routerGroup.POST("/register-event", middleware.AuthUser, event.JoinEvent)
|
15 |
}
|
|
|
9 |
func EventRoute(router *gin.Engine) {
|
10 |
routerGroup := router.Group("api/v1/events")
|
11 |
{
|
12 |
+
routerGroup.GET("/", middleware.AuthUser, event.GetAllEvent)
|
13 |
routerGroup.GET("/details/:id_event", middleware.AuthUser, event.EventDetail)
|
14 |
routerGroup.POST("/register-event", middleware.AuthUser, event.JoinEvent)
|
15 |
}
|
space/services/get_all_event_service_NEED TO FIX.go
CHANGED
@@ -1,16 +1,17 @@
|
|
1 |
package services
|
2 |
|
3 |
import (
|
|
|
4 |
"godp.abdanhafidz.com/models"
|
5 |
"godp.abdanhafidz.com/repositories"
|
6 |
)
|
7 |
|
8 |
-
type
|
9 |
Service[models.Events, []models.Events]
|
10 |
}
|
11 |
|
12 |
-
func (s *
|
13 |
-
eventsRepo := repositories.
|
14 |
|
15 |
events := eventsRepo.Result
|
16 |
|
|
|
1 |
package services
|
2 |
|
3 |
import (
|
4 |
+
"github.com/google/uuid"
|
5 |
"godp.abdanhafidz.com/models"
|
6 |
"godp.abdanhafidz.com/repositories"
|
7 |
)
|
8 |
|
9 |
+
type EventList struct {
|
10 |
Service[models.Events, []models.Events]
|
11 |
}
|
12 |
|
13 |
+
func (s *EventList) EventListWithFilter(userid uuid.UUID, pagination repositories.PaginationConstructor) {
|
14 |
+
eventsRepo := repositories.EventListWithFilter(userid, pagination)
|
15 |
|
16 |
events := eventsRepo.Result
|
17 |
|
space/space/.github/workflows/main.yml
ADDED
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
name: Deploy to Huggingface
|
2 |
+
|
3 |
+
on:
|
4 |
+
push:
|
5 |
+
branches:
|
6 |
+
- master
|
7 |
+
|
8 |
+
jobs:
|
9 |
+
deploy-to-huggingface:
|
10 |
+
runs-on: ubuntu-latest
|
11 |
+
|
12 |
+
steps:
|
13 |
+
# Checkout repository
|
14 |
+
- name: Checkout Repository
|
15 |
+
uses: actions/checkout@v3
|
16 |
+
|
17 |
+
# Setup Git
|
18 |
+
- name: Setup Git for Huggingface
|
19 |
+
run: |
|
20 |
+
git config --global user.email "abdan.hafidz@gmail.com"
|
21 |
+
git config --global user.name "abdanhafidz"
|
22 |
+
|
23 |
+
# Clone Huggingface Space Repository
|
24 |
+
- name: Clone Huggingface Space
|
25 |
+
env:
|
26 |
+
HF_TOKEN: ${{ secrets.HF_TOKEN }}
|
27 |
+
run: |
|
28 |
+
git clone https://huggingface.co/spaces/lifedebugger/quzuu-api-dev space
|
29 |
+
|
30 |
+
# Update Git Remote URL and Pull Latest Changes
|
31 |
+
- name: Update Remote and Pull Changes
|
32 |
+
env:
|
33 |
+
HF_TOKEN: ${{ secrets.HF_TOKEN }}
|
34 |
+
run: |
|
35 |
+
cd space
|
36 |
+
git remote set-url origin https://lifedebugger:$HF_TOKEN@huggingface.co/spaces/lifedebugger/quzuu-api-dev
|
37 |
+
git pull origin main || echo "No changes to pull"
|
38 |
+
|
39 |
+
# Copy Files to Huggingface Space
|
40 |
+
- name: Copy Files to Space
|
41 |
+
run: |
|
42 |
+
rsync -av --exclude='.git' ./ space/
|
43 |
+
|
44 |
+
# Commit and Push to Huggingface Space
|
45 |
+
- name: Commit and Push to Huggingface
|
46 |
+
env:
|
47 |
+
HF_TOKEN: ${{ secrets.HF_TOKEN }}
|
48 |
+
run: |
|
49 |
+
cd space
|
50 |
+
git add .
|
51 |
+
git commit -m "Deploy files from GitHub repository" || echo "No changes to commit"
|
52 |
+
git push origin main || echo "No changes to push"
|
space/space/config/config.go
ADDED
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
package config
|
2 |
+
|
3 |
+
import (
|
4 |
+
"os"
|
5 |
+
"strconv"
|
6 |
+
|
7 |
+
"github.com/joho/godotenv"
|
8 |
+
)
|
9 |
+
|
10 |
+
var TCP_ADDRESS string
|
11 |
+
var LOG_PATH string
|
12 |
+
|
13 |
+
var HOST_ADDRESS string
|
14 |
+
var HOST_PORT string
|
15 |
+
var EMAIL_VERIFICATION_DURATION int
|
16 |
+
|
17 |
+
var SMTP_SENDER_EMAIL string
|
18 |
+
var SMTP_SENDER_PASSWORD string
|
19 |
+
var SMTP_HOST string
|
20 |
+
var SMTP_PORT string
|
21 |
+
|
22 |
+
func init() {
|
23 |
+
godotenv.Load()
|
24 |
+
HOST_ADDRESS = os.Getenv("HOST_ADDRESS")
|
25 |
+
HOST_PORT = os.Getenv("HOST_PORT")
|
26 |
+
TCP_ADDRESS = HOST_ADDRESS + ":" + HOST_PORT
|
27 |
+
LOG_PATH = os.Getenv("LOG_PATH")
|
28 |
+
EMAIL_VERIFICATION_DURATION, _ = strconv.Atoi(os.Getenv("EMAIL_VERIFICATION_DURATION"))
|
29 |
+
SMTP_SENDER_EMAIL = os.Getenv("SMTP_SENDER_EMAIL")
|
30 |
+
SMTP_SENDER_PASSWORD = os.Getenv("SMTP_SENDER_PASSWORD")
|
31 |
+
SMTP_HOST = os.Getenv("SMTP_HOST")
|
32 |
+
SMTP_PORT = os.Getenv("SMTP_PORT")
|
33 |
+
// Menampilkan nilai variabel lingkungan
|
34 |
+
}
|
space/space/config/database_connection_config.go
ADDED
@@ -0,0 +1,99 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
package config
|
2 |
+
|
3 |
+
import (
|
4 |
+
"fmt"
|
5 |
+
"godp.abdanhafidz.com/models"
|
6 |
+
"log"
|
7 |
+
"os"
|
8 |
+
|
9 |
+
"gorm.io/driver/postgres"
|
10 |
+
"gorm.io/gorm"
|
11 |
+
"gorm.io/gorm/logger"
|
12 |
+
|
13 |
+
"github.com/joho/godotenv"
|
14 |
+
)
|
15 |
+
|
16 |
+
var DB *gorm.DB
|
17 |
+
var err error
|
18 |
+
var Salt string
|
19 |
+
|
20 |
+
func init() {
|
21 |
+
godotenv.Load()
|
22 |
+
if err != nil {
|
23 |
+
fmt.Println("Gagal membaca file .env")
|
24 |
+
return
|
25 |
+
}
|
26 |
+
os.Setenv("TZ", "Asia/Jakarta")
|
27 |
+
dbHost := os.Getenv("DB_HOST")
|
28 |
+
dbPort := os.Getenv("DB_PORT")
|
29 |
+
dbUser := os.Getenv("DB_USER")
|
30 |
+
dbPassword := os.Getenv("DB_PASSWORD")
|
31 |
+
dbName := os.Getenv("DB_NAME")
|
32 |
+
Salt := os.Getenv("SALT")
|
33 |
+
dsn := "host=" + dbHost + " user=" + dbUser + " password=" + dbPassword + " dbname=" + dbName + " port=" + dbPort + " sslmode=disable TimeZone=Asia/Jakarta"
|
34 |
+
DB, err = gorm.Open(postgres.Open(dsn), &gorm.Config{TranslateError: true})
|
35 |
+
if err != nil {
|
36 |
+
panic(err)
|
37 |
+
}
|
38 |
+
if Salt == "" {
|
39 |
+
Salt = "D3f4u|t"
|
40 |
+
}
|
41 |
+
|
42 |
+
// Call AutoMigrateAll to perform auto-migration
|
43 |
+
AutoMigrateAll(DB)
|
44 |
+
}
|
45 |
+
|
46 |
+
func AutoMigrateAll(db *gorm.DB) {
|
47 |
+
// Enable logger to see SQL logs
|
48 |
+
db.Logger.LogMode(logger.Info)
|
49 |
+
|
50 |
+
// Auto-migrate all models
|
51 |
+
db.Exec("CREATE EXTENSION IF NOT EXISTS \"uuid-ossp\";")
|
52 |
+
if err := db.AutoMigrate(&models.Account{}); err != nil {
|
53 |
+
log.Fatal(err)
|
54 |
+
}
|
55 |
+
if err := db.AutoMigrate(&models.AccountDetails{}); err != nil {
|
56 |
+
log.Fatal(err)
|
57 |
+
}
|
58 |
+
if err := db.AutoMigrate(&models.EmailVerification{}); err != nil {
|
59 |
+
log.Fatal(err)
|
60 |
+
}
|
61 |
+
if err := db.AutoMigrate(&models.ExternalAuth{}); err != nil {
|
62 |
+
log.Fatal(err)
|
63 |
+
}
|
64 |
+
if err := db.AutoMigrate(&models.FCM{}); err != nil {
|
65 |
+
log.Fatal(err)
|
66 |
+
}
|
67 |
+
if err := db.AutoMigrate(&models.ForgotPassword{}); err != nil {
|
68 |
+
log.Fatal(err)
|
69 |
+
}
|
70 |
+
if err := db.AutoMigrate(&models.Events{}); err != nil {
|
71 |
+
log.Fatal(err)
|
72 |
+
}
|
73 |
+
if err := db.AutoMigrate(&models.Announcement{}); err != nil {
|
74 |
+
log.Fatal(err)
|
75 |
+
}
|
76 |
+
if err := db.AutoMigrate(&models.ProblemSet{}); err != nil {
|
77 |
+
log.Fatal(err)
|
78 |
+
}
|
79 |
+
if err := db.AutoMigrate(&models.Questions{}); err != nil {
|
80 |
+
log.Fatal(err)
|
81 |
+
}
|
82 |
+
if err := db.AutoMigrate(&models.EventAssign{}); err != nil {
|
83 |
+
log.Fatal(err)
|
84 |
+
}
|
85 |
+
if err := db.AutoMigrate(&models.ProblemSetAssign{}); err != nil {
|
86 |
+
log.Fatal(err)
|
87 |
+
}
|
88 |
+
if err := db.AutoMigrate(&models.ExamProgress{}); err != nil {
|
89 |
+
log.Fatal(err)
|
90 |
+
}
|
91 |
+
if err := db.AutoMigrate(&models.ExamProgress_Result{}); err != nil {
|
92 |
+
log.Fatal(err)
|
93 |
+
}
|
94 |
+
if err := db.AutoMigrate(&models.Result{}); err != nil {
|
95 |
+
log.Fatal(err)
|
96 |
+
}
|
97 |
+
|
98 |
+
fmt.Println("Migration completed successfully.")
|
99 |
+
}
|
space/space/controller/auth/auth_change_password_controller.go
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
package auth
|
2 |
+
|
3 |
+
import (
|
4 |
+
"github.com/gin-gonic/gin"
|
5 |
+
"godp.abdanhafidz.com/controller"
|
6 |
+
"godp.abdanhafidz.com/models"
|
7 |
+
"godp.abdanhafidz.com/services"
|
8 |
+
)
|
9 |
+
|
10 |
+
func ChangePassword(c *gin.Context) {
|
11 |
+
authentication := services.AuthenticationService{}
|
12 |
+
changePasswordController := controller.Controller[models.ChangePasswordRequest, models.Account, models.AuthenticatedUser]{
|
13 |
+
Service: &authentication.Service,
|
14 |
+
}
|
15 |
+
changePasswordController.HeaderParse(c, func() {
|
16 |
+
changePasswordController.Service.Constructor.Id = changePasswordController.AccountData.UserID
|
17 |
+
})
|
18 |
+
changePasswordController.RequestJSON(c, func() {
|
19 |
+
authentication.Update(changePasswordController.Request.OldPassword, changePasswordController.Request.NewPassword)
|
20 |
+
})
|
21 |
+
}
|
space/space/controller/auth/auth_external_controller.go
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
package auth
|
2 |
+
|
3 |
+
import (
|
4 |
+
"github.com/gin-gonic/gin"
|
5 |
+
"godp.abdanhafidz.com/controller"
|
6 |
+
"godp.abdanhafidz.com/models"
|
7 |
+
"godp.abdanhafidz.com/services"
|
8 |
+
)
|
9 |
+
|
10 |
+
func ExternalAuth(c *gin.Context) {
|
11 |
+
ExternalAuthController := controller.Controller[models.ExternalAuthRequest, models.ExternalAuth, models.AuthenticatedUser]{}
|
12 |
+
ExternalAuthController.RequestJSON(c, func() {
|
13 |
+
if ExternalAuthController.Request.OauthProvider == "google" {
|
14 |
+
GoogleLogin := services.GoogleAuthService{}
|
15 |
+
ExternalAuthController.Service = &GoogleLogin.Service
|
16 |
+
ExternalAuthController.Service.Constructor.OauthID = ExternalAuthController.Request.OauthID
|
17 |
+
GoogleLogin.Authenticate(true)
|
18 |
+
}
|
19 |
+
})
|
20 |
+
}
|
space/space/controller/auth/auth_forgot_password_controller.go
ADDED
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
package auth
|
2 |
+
|
3 |
+
import (
|
4 |
+
"github.com/gin-gonic/gin"
|
5 |
+
"godp.abdanhafidz.com/controller"
|
6 |
+
"godp.abdanhafidz.com/models"
|
7 |
+
"godp.abdanhafidz.com/services"
|
8 |
+
)
|
9 |
+
|
10 |
+
func CreateForgotPassword(c *gin.Context) {
|
11 |
+
ForgotPassword := services.ForgotPasswordService{}
|
12 |
+
ForgotPasswordController := controller.Controller[models.ForgotPasswordRequest, models.ForgotPassword, models.ForgotPassword]{
|
13 |
+
Service: &ForgotPassword.Service,
|
14 |
+
}
|
15 |
+
ForgotPasswordController.RequestJSON(c, func() {
|
16 |
+
ForgotPassword.Create(ForgotPasswordController.Request.Email)
|
17 |
+
})
|
18 |
+
|
19 |
+
}
|
20 |
+
func ValidateForgotPassword(c *gin.Context) {
|
21 |
+
ForgotPassword := services.ForgotPasswordService{}
|
22 |
+
ForgotPasswordController := controller.Controller[models.ValidateForgotPasswordRequest, models.ForgotPassword, models.ForgotPassword]{
|
23 |
+
Service: &ForgotPassword.Service,
|
24 |
+
}
|
25 |
+
ForgotPasswordController.RequestJSON(c, func() {
|
26 |
+
ForgotPasswordController.Service.Constructor.Token = ForgotPasswordController.Request.Token
|
27 |
+
ForgotPassword.Validate(&ForgotPasswordController.Request.NewPassword)
|
28 |
+
})
|
29 |
+
}
|
space/space/controller/auth/auth_login_controller.go
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
package auth
|
2 |
+
|
3 |
+
import (
|
4 |
+
"github.com/gin-gonic/gin"
|
5 |
+
"godp.abdanhafidz.com/controller"
|
6 |
+
"godp.abdanhafidz.com/models"
|
7 |
+
"godp.abdanhafidz.com/services"
|
8 |
+
)
|
9 |
+
|
10 |
+
func Login(c *gin.Context) {
|
11 |
+
authentication := services.AuthenticationService{}
|
12 |
+
loginController := controller.Controller[models.LoginRequest, models.Account, models.AuthenticatedUser]{
|
13 |
+
Service: &authentication.Service,
|
14 |
+
}
|
15 |
+
loginController.RequestJSON(c, func() {
|
16 |
+
loginController.Service.Constructor.Email = loginController.Request.Email
|
17 |
+
loginController.Service.Constructor.Password = loginController.Request.Password
|
18 |
+
authentication.Authenticate()
|
19 |
+
})
|
20 |
+
}
|
space/space/controller/auth/auth_register_controller.go
ADDED
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
package auth
|
2 |
+
|
3 |
+
import (
|
4 |
+
"github.com/gin-gonic/gin"
|
5 |
+
"godp.abdanhafidz.com/controller"
|
6 |
+
"godp.abdanhafidz.com/models"
|
7 |
+
"godp.abdanhafidz.com/services"
|
8 |
+
)
|
9 |
+
|
10 |
+
func Register(c *gin.Context) {
|
11 |
+
register := services.RegisterService{}
|
12 |
+
registerController := controller.Controller[models.RegisterRequest, models.Account, models.Account]{
|
13 |
+
Service: ®ister.Service,
|
14 |
+
}
|
15 |
+
registerController.RequestJSON(c, func() {
|
16 |
+
registerController.Service.Constructor.Password = registerController.Request.Password
|
17 |
+
registerController.Service.Constructor.Email = registerController.Request.Email
|
18 |
+
registerController.Service.Constructor.Username = registerController.Request.Username
|
19 |
+
registerController.Service.Constructor.Role = "USER"
|
20 |
+
register.Create()
|
21 |
+
})
|
22 |
+
}
|
space/space/controller/controller.go
ADDED
@@ -0,0 +1,71 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
package controller
|
2 |
+
|
3 |
+
import (
|
4 |
+
"github.com/gin-gonic/gin"
|
5 |
+
"godp.abdanhafidz.com/models"
|
6 |
+
"godp.abdanhafidz.com/repositories"
|
7 |
+
"godp.abdanhafidz.com/services"
|
8 |
+
"godp.abdanhafidz.com/utils"
|
9 |
+
)
|
10 |
+
|
11 |
+
type (
|
12 |
+
Controllers interface {
|
13 |
+
RequestJSON(c *gin.Context)
|
14 |
+
Response(c *gin.Context)
|
15 |
+
}
|
16 |
+
Controller[TRequest any, TConstructor any, TResult any] struct {
|
17 |
+
AccountData models.AccountData
|
18 |
+
Request TRequest
|
19 |
+
Service *services.Service[TConstructor, TResult]
|
20 |
+
}
|
21 |
+
)
|
22 |
+
|
23 |
+
func (controller *Controller[T1, T2, T3]) HeaderParse(c *gin.Context, act func()) {
|
24 |
+
cParam, _ := c.Get("accountData")
|
25 |
+
if cParam != nil {
|
26 |
+
controller.AccountData = cParam.(models.AccountData)
|
27 |
+
}
|
28 |
+
act()
|
29 |
+
}
|
30 |
+
func (controller *Controller[T1, T2, T3]) RequestJSON(c *gin.Context, act func()) {
|
31 |
+
cParam, _ := c.Get("accountData")
|
32 |
+
if cParam != nil {
|
33 |
+
controller.AccountData = cParam.(models.AccountData)
|
34 |
+
}
|
35 |
+
errBinding := c.ShouldBindJSON(&controller.Request)
|
36 |
+
if errBinding != nil {
|
37 |
+
utils.ResponseFAIL(c, 400, models.Exception{
|
38 |
+
BadRequest: true,
|
39 |
+
Message: "Invalid Request!, recheck your request, there's must be some problem about required parameter or type parameter",
|
40 |
+
})
|
41 |
+
return
|
42 |
+
} else {
|
43 |
+
act()
|
44 |
+
controller.Response(c)
|
45 |
+
}
|
46 |
+
}
|
47 |
+
func (controller *Controller[T1, T2, T3]) Response(c *gin.Context) {
|
48 |
+
switch {
|
49 |
+
case controller.Service.Error != nil:
|
50 |
+
utils.LogError(controller.Service.Error)
|
51 |
+
utils.ResponseFAIL(c, 500, models.Exception{
|
52 |
+
InternalServerError: true,
|
53 |
+
Message: "Internal Server Error",
|
54 |
+
})
|
55 |
+
|
56 |
+
case controller.Service.Exception.DataDuplicate:
|
57 |
+
utils.ResponseFAIL(c, 400, controller.Service.Exception)
|
58 |
+
case controller.Service.Exception.Unauthorized:
|
59 |
+
utils.ResponseFAIL(c, 401, controller.Service.Exception)
|
60 |
+
case controller.Service.Exception.DataNotFound:
|
61 |
+
utils.ResponseFAIL(c, 404, controller.Service.Exception)
|
62 |
+
case controller.Service.Exception.Message != "":
|
63 |
+
utils.ResponseFAIL(c, 400, controller.Service.Exception)
|
64 |
+
default:
|
65 |
+
if controller.Service.MetaData != (repositories.PaginationMetadata{}) {
|
66 |
+
utils.ResponseOK(c, controller.Service.Result, controller.Service.MetaData)
|
67 |
+
} else {
|
68 |
+
utils.ResponseOK(c, controller.Service.Result, struct{}{})
|
69 |
+
}
|
70 |
+
}
|
71 |
+
}
|
space/space/controller/email/email_create_verification_controller.go
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
package controller
|
2 |
+
|
3 |
+
import (
|
4 |
+
"github.com/gin-gonic/gin"
|
5 |
+
"godp.abdanhafidz.com/controller"
|
6 |
+
"godp.abdanhafidz.com/models"
|
7 |
+
"godp.abdanhafidz.com/services"
|
8 |
+
)
|
9 |
+
|
10 |
+
func CreateVerification(c *gin.Context) {
|
11 |
+
emailVerification := services.EmailVerificationService{}
|
12 |
+
emailVerificationController := controller.Controller[models.CreateVerifyEmailRequest, models.EmailVerification, models.EmailVerification]{
|
13 |
+
Service: &emailVerification.Service,
|
14 |
+
}
|
15 |
+
emailVerificationController.HeaderParse(c, func() {
|
16 |
+
emailVerificationController.Service.Constructor.AccountId = emailVerificationController.AccountData.UserID
|
17 |
+
emailVerification.Create()
|
18 |
+
emailVerificationController.Response(c)
|
19 |
+
})
|
20 |
+
|
21 |
+
}
|
space/space/controller/email/email_validate_controller.go
ADDED
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
package controller
|
2 |
+
|
3 |
+
import (
|
4 |
+
"github.com/gin-gonic/gin"
|
5 |
+
"godp.abdanhafidz.com/controller"
|
6 |
+
"godp.abdanhafidz.com/models"
|
7 |
+
"godp.abdanhafidz.com/services"
|
8 |
+
)
|
9 |
+
|
10 |
+
func Verify(c *gin.Context) {
|
11 |
+
emailVerification := services.EmailVerificationService{}
|
12 |
+
emailVerificationController := controller.Controller[models.CreateVerifyEmailRequest, models.EmailVerification, models.EmailVerification]{
|
13 |
+
Service: &emailVerification.Service,
|
14 |
+
}
|
15 |
+
emailVerificationController.HeaderParse(c, func() {
|
16 |
+
emailVerificationController.Service.Constructor.AccountId = emailVerificationController.AccountData.UserID
|
17 |
+
emailVerificationController.RequestJSON(c, func() {
|
18 |
+
emailVerificationController.Service.Constructor.Token = emailVerificationController.Request.Token
|
19 |
+
emailVerification.Validate()
|
20 |
+
})
|
21 |
+
})
|
22 |
+
|
23 |
+
}
|
space/space/controller/event/event_detail_controller.go
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
package event
|
2 |
+
|
3 |
+
import (
|
4 |
+
"github.com/gin-gonic/gin"
|
5 |
+
"godp.abdanhafidz.com/controller"
|
6 |
+
"godp.abdanhafidz.com/models"
|
7 |
+
"godp.abdanhafidz.com/services"
|
8 |
+
)
|
9 |
+
|
10 |
+
func EventDetail(c *gin.Context) {
|
11 |
+
eventDetail := services.EventDetailService{}
|
12 |
+
eventDetailController := controller.Controller[any, models.Events, models.EventDetailResponse]{
|
13 |
+
Service: &eventDetail.Service,
|
14 |
+
}
|
15 |
+
|
16 |
+
eventDetailController.HeaderParse(c, func() {
|
17 |
+
eventDetailController.Service.Constructor.Slug = c.Param("event_slug")
|
18 |
+
eventDetail.Retrieve(eventDetailController.AccountData.UserID)
|
19 |
+
eventDetailController.Response(c)
|
20 |
+
})
|
21 |
+
}
|
space/space/controller/event/event_join_controller_NEED TO FIX.go
ADDED
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
package event
|
2 |
+
|
3 |
+
import (
|
4 |
+
"github.com/gin-gonic/gin"
|
5 |
+
"godp.abdanhafidz.com/controller"
|
6 |
+
"godp.abdanhafidz.com/models"
|
7 |
+
"godp.abdanhafidz.com/services"
|
8 |
+
)
|
9 |
+
|
10 |
+
func JoinEvent(c *gin.Context) {
|
11 |
+
eventAssign := services.JoinEventService{}
|
12 |
+
eventAssignController := controller.Controller[models.JoinEventRequest, models.JoinEventRequest, models.EventDetailResponse]{
|
13 |
+
Service: &eventAssign.Service,
|
14 |
+
}
|
15 |
+
|
16 |
+
eventAssignController.RequestJSON(c, func() {
|
17 |
+
eventAssignController.Service.Constructor.EventId = eventAssignController.Request.EventId
|
18 |
+
eventAssignController.Service.Constructor.EventCode = eventAssignController.Request.EventCode
|
19 |
+
idUser := eventAssignController.AccountData.UserID
|
20 |
+
eventAssign.Create(idUser)
|
21 |
+
})
|
22 |
+
}
|
space/space/controller/event/get_all_event_controller_NEED TO FIX.go
ADDED
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
package event
|
2 |
+
|
3 |
+
import (
|
4 |
+
"github.com/gin-gonic/gin"
|
5 |
+
"godp.abdanhafidz.com/controller"
|
6 |
+
"godp.abdanhafidz.com/models"
|
7 |
+
"godp.abdanhafidz.com/repositories"
|
8 |
+
"godp.abdanhafidz.com/services"
|
9 |
+
"godp.abdanhafidz.com/utils"
|
10 |
+
"strconv"
|
11 |
+
)
|
12 |
+
|
13 |
+
func GetAllEvent(c *gin.Context) {
|
14 |
+
limit, err := strconv.Atoi(c.DefaultQuery("limit", "10"))
|
15 |
+
if err != nil {
|
16 |
+
service := services.Service[any, any]{
|
17 |
+
Exception: models.Exception{
|
18 |
+
Message: "Invalid limit parameter",
|
19 |
+
},
|
20 |
+
}
|
21 |
+
utils.SendResponse(c, service)
|
22 |
+
return
|
23 |
+
}
|
24 |
+
|
25 |
+
offset, err := strconv.Atoi(c.DefaultQuery("offset", "0"))
|
26 |
+
if err != nil {
|
27 |
+
service := services.Service[any, any]{
|
28 |
+
Exception: models.Exception{
|
29 |
+
Message: "Invalid offset parameter",
|
30 |
+
},
|
31 |
+
}
|
32 |
+
utils.SendResponse(c, service)
|
33 |
+
return
|
34 |
+
}
|
35 |
+
filter := c.DefaultQuery("filter", "")
|
36 |
+
filterBy := c.DefaultQuery("filter_by", "")
|
37 |
+
|
38 |
+
pagination := repositories.PaginationConstructor{
|
39 |
+
Limit: limit,
|
40 |
+
Offset: offset,
|
41 |
+
Filter: filter,
|
42 |
+
FilterBy: filterBy,
|
43 |
+
}
|
44 |
+
|
45 |
+
eventsService := services.GetAllEventService{}
|
46 |
+
getAllEventController := controller.Controller[any, models.Events, []models.Events]{
|
47 |
+
Service: &eventsService.Service,
|
48 |
+
}
|
49 |
+
|
50 |
+
eventsService.GetAllEventPaginate(pagination)
|
51 |
+
|
52 |
+
getAllEventController.Response(c)
|
53 |
+
}
|
space/space/controller/home_controller.go
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
package controller
|
2 |
+
|
3 |
+
import "github.com/gin-gonic/gin"
|
4 |
+
|
5 |
+
func HomeController(c *gin.Context) {
|
6 |
+
c.JSON(200, gin.H{
|
7 |
+
"message": "Api Qobiltu 2025!",
|
8 |
+
})
|
9 |
+
}
|
space/space/controller/options/option_category_controller.go
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
package options
|
2 |
+
|
3 |
+
import (
|
4 |
+
"github.com/gin-gonic/gin"
|
5 |
+
"godp.abdanhafidz.com/controller"
|
6 |
+
"godp.abdanhafidz.com/models"
|
7 |
+
"godp.abdanhafidz.com/services"
|
8 |
+
)
|
9 |
+
|
10 |
+
func AddOptions(c *gin.Context) {
|
11 |
+
options := services.OptionService{}
|
12 |
+
addOptionController := controller.Controller[[]models.OptionsRequest, []models.OptionsRequest, models.OptionsResponse]{
|
13 |
+
Service: &options.Service,
|
14 |
+
}
|
15 |
+
addOptionController.RequestJSON(c, func() {
|
16 |
+
options.Constructor = addOptionController.Request
|
17 |
+
options.Create()
|
18 |
+
})
|
19 |
+
}
|
space/space/controller/options/option_value_controller.go
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
package options
|
2 |
+
|
3 |
+
import (
|
4 |
+
"github.com/gin-gonic/gin"
|
5 |
+
"godp.abdanhafidz.com/controller"
|
6 |
+
"godp.abdanhafidz.com/models"
|
7 |
+
"godp.abdanhafidz.com/services"
|
8 |
+
)
|
9 |
+
|
10 |
+
func List(c *gin.Context) {
|
11 |
+
options := services.OptionValueService{}
|
12 |
+
optionValueController := controller.Controller[any, models.OptionCategory, models.Options]{
|
13 |
+
Service: &options.Service,
|
14 |
+
}
|
15 |
+
slug := c.Param("slug")
|
16 |
+
options.Constructor.OptionSlug = slug
|
17 |
+
options.Retrieve()
|
18 |
+
optionValueController.Response(c)
|
19 |
+
}
|
space/space/controller/region/city/city_list_controller.go
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
package city
|
2 |
+
|
3 |
+
import (
|
4 |
+
"strconv"
|
5 |
+
|
6 |
+
"github.com/gin-gonic/gin"
|
7 |
+
"godp.abdanhafidz.com/controller"
|
8 |
+
"godp.abdanhafidz.com/models"
|
9 |
+
"godp.abdanhafidz.com/services"
|
10 |
+
)
|
11 |
+
|
12 |
+
func List(c *gin.Context) {
|
13 |
+
city := services.CityService{}
|
14 |
+
CityController := controller.Controller[any, models.RegionCity, []models.RegionCity]{
|
15 |
+
Service: &city.Service,
|
16 |
+
}
|
17 |
+
ProvinceID, _ := strconv.Atoi(c.Query("province_id"))
|
18 |
+
city.Constructor.ProvinceId = uint(ProvinceID)
|
19 |
+
city.Retrieve()
|
20 |
+
CityController.Response(c)
|
21 |
+
}
|
space/space/controller/region/city/city_seeds_controller.go
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
package city
|
2 |
+
|
3 |
+
import (
|
4 |
+
"github.com/gin-gonic/gin"
|
5 |
+
"godp.abdanhafidz.com/controller"
|
6 |
+
"godp.abdanhafidz.com/models"
|
7 |
+
"godp.abdanhafidz.com/services"
|
8 |
+
)
|
9 |
+
|
10 |
+
func Seeds(c *gin.Context) {
|
11 |
+
city := services.CityService{}
|
12 |
+
CityController := controller.Controller[any, models.RegionCity, []models.RegionCity]{
|
13 |
+
Service: &city.Service,
|
14 |
+
}
|
15 |
+
city.Create()
|
16 |
+
CityController.Response(c)
|
17 |
+
}
|
space/space/controller/region/province/province_list_controller.go
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
package province
|
2 |
+
|
3 |
+
import (
|
4 |
+
"github.com/gin-gonic/gin"
|
5 |
+
"godp.abdanhafidz.com/controller"
|
6 |
+
"godp.abdanhafidz.com/models"
|
7 |
+
"godp.abdanhafidz.com/services"
|
8 |
+
)
|
9 |
+
|
10 |
+
func List(c *gin.Context) {
|
11 |
+
province := services.ProvinceService{}
|
12 |
+
ProvinceController := controller.Controller[any, models.RegionProvince, []models.RegionProvince]{
|
13 |
+
Service: &province.Service,
|
14 |
+
}
|
15 |
+
province.Retrieve()
|
16 |
+
ProvinceController.Response(c)
|
17 |
+
}
|
space/space/controller/region/province/province_seeds_controller.go
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
package province
|
2 |
+
|
3 |
+
import (
|
4 |
+
"github.com/gin-gonic/gin"
|
5 |
+
"godp.abdanhafidz.com/controller"
|
6 |
+
"godp.abdanhafidz.com/models"
|
7 |
+
"godp.abdanhafidz.com/services"
|
8 |
+
)
|
9 |
+
|
10 |
+
func Seeds(c *gin.Context) {
|
11 |
+
province := services.ProvinceService{}
|
12 |
+
ProvinceController := controller.Controller[any, models.RegionProvince, []models.RegionProvince]{
|
13 |
+
Service: &province.Service,
|
14 |
+
}
|
15 |
+
province.Create()
|
16 |
+
ProvinceController.Response(c)
|
17 |
+
}
|
space/space/controller/user/user_profile_controller.go
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
package user
|
2 |
+
|
3 |
+
import (
|
4 |
+
"github.com/gin-gonic/gin"
|
5 |
+
"godp.abdanhafidz.com/controller"
|
6 |
+
"godp.abdanhafidz.com/models"
|
7 |
+
"godp.abdanhafidz.com/services"
|
8 |
+
)
|
9 |
+
|
10 |
+
func Profile(c *gin.Context) {
|
11 |
+
userProfile := services.UserProfileService{}
|
12 |
+
userProfileController := controller.Controller[any, models.AccountDetails, models.UserProfileResponse]{
|
13 |
+
Service: &userProfile.Service,
|
14 |
+
}
|
15 |
+
userProfileController.HeaderParse(c, func() {
|
16 |
+
userProfileController.Service.Constructor.AccountId = userProfileController.AccountData.UserID
|
17 |
+
userProfile.Retrieve()
|
18 |
+
userProfileController.Response(c)
|
19 |
+
},
|
20 |
+
)
|
21 |
+
}
|
space/space/controller/user/user_update_profile_controller.go
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
package user
|
2 |
+
|
3 |
+
import (
|
4 |
+
"github.com/gin-gonic/gin"
|
5 |
+
"godp.abdanhafidz.com/controller"
|
6 |
+
"godp.abdanhafidz.com/models"
|
7 |
+
"godp.abdanhafidz.com/services"
|
8 |
+
)
|
9 |
+
|
10 |
+
func UpdateProfile(c *gin.Context) {
|
11 |
+
userProfile := services.UserProfileService{}
|
12 |
+
userUpdateProfileController := controller.Controller[models.AccountDetails, models.AccountDetails, models.UserProfileResponse]{
|
13 |
+
Service: &userProfile.Service,
|
14 |
+
}
|
15 |
+
|
16 |
+
userUpdateProfileController.RequestJSON(c, func() {
|
17 |
+
userUpdateProfileController.Service.Constructor = userUpdateProfileController.Request
|
18 |
+
userUpdateProfileController.HeaderParse(c, func() {
|
19 |
+
userUpdateProfileController.Service.Constructor.AccountId = userUpdateProfileController.AccountData.UserID
|
20 |
+
|
21 |
+
})
|
22 |
+
userProfile.Update()
|
23 |
+
},
|
24 |
+
)
|
25 |
+
}
|
space/space/logs/error_log.txt
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
|
space/space/logs/security_log.txt
ADDED
File without changes
|
space/space/middleware/authentication_middleware.go
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
// auth/auth.go
|
2 |
+
|
3 |
+
package middleware
|
4 |
+
|
5 |
+
import (
|
6 |
+
"github.com/gin-gonic/gin"
|
7 |
+
"github.com/google/uuid"
|
8 |
+
"godp.abdanhafidz.com/models"
|
9 |
+
"godp.abdanhafidz.com/services"
|
10 |
+
"godp.abdanhafidz.com/utils"
|
11 |
+
)
|
12 |
+
|
13 |
+
func AuthUser(c *gin.Context) {
|
14 |
+
var currAccData models.AccountData
|
15 |
+
if c.Request.Header["Authorization"] != nil {
|
16 |
+
token := c.Request.Header["Authorization"]
|
17 |
+
|
18 |
+
currAccData.UserID, currAccData.VerifyStatus, currAccData.ErrVerif = services.VerifyToken(token[0])
|
19 |
+
|
20 |
+
if currAccData.VerifyStatus == "invalid-token" || currAccData.VerifyStatus == "expired" {
|
21 |
+
currAccData.UserID = uuid.UUID{}
|
22 |
+
utils.ResponseFAIL(c, 401, models.Exception{Unauthorized: true, Message: "Your session is expired, Please re-Login!"})
|
23 |
+
c.Abort()
|
24 |
+
return
|
25 |
+
} else {
|
26 |
+
c.Set("accountData", currAccData)
|
27 |
+
c.Next()
|
28 |
+
}
|
29 |
+
} else {
|
30 |
+
currAccData.UserID = uuid.UUID{}
|
31 |
+
currAccData.VerifyStatus = "no-token"
|
32 |
+
currAccData.ErrVerif = nil
|
33 |
+
utils.ResponseFAIL(c, 401, models.Exception{Unauthorized: true, Message: "You have to login first!"})
|
34 |
+
c.Abort()
|
35 |
+
return
|
36 |
+
}
|
37 |
+
|
38 |
+
}
|
space/space/middleware/middleware.go
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
package middleware
|
2 |
+
|
3 |
+
import (
|
4 |
+
"math"
|
5 |
+
"time"
|
6 |
+
|
7 |
+
"gorm.io/gorm"
|
8 |
+
)
|
9 |
+
|
10 |
+
func RecordCheck(rows *gorm.DB) (string, error) {
|
11 |
+
count := rows.RowsAffected
|
12 |
+
err := rows.Error
|
13 |
+
|
14 |
+
if count == 0 {
|
15 |
+
return "no-record", err
|
16 |
+
} else if err != nil {
|
17 |
+
return "query-error", err
|
18 |
+
} else {
|
19 |
+
return "ok", err
|
20 |
+
}
|
21 |
+
}
|
22 |
+
|
23 |
+
func DiffTime(t1 time.Time, t2 time.Time) (int, int, int) {
|
24 |
+
hs := t1.Sub(t2).Hours()
|
25 |
+
hs, mf := math.Modf(hs)
|
26 |
+
ms := mf * 60
|
27 |
+
ms, sf := math.Modf(ms)
|
28 |
+
ss := sf * 60
|
29 |
+
return int(hs), int(ms), int(ss)
|
30 |
+
}
|
space/space/middleware/response_middleware.go
ADDED
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
package middleware
|
2 |
+
|
3 |
+
import (
|
4 |
+
"net/http"
|
5 |
+
|
6 |
+
"github.com/gin-gonic/gin"
|
7 |
+
)
|
8 |
+
|
9 |
+
// SendJSON200 sends a JSON response with HTTP status code 200
|
10 |
+
func SendJSON200(c *gin.Context, data interface{}) {
|
11 |
+
c.JSON(http.StatusOK, gin.H{"status": "success", "data": data})
|
12 |
+
return
|
13 |
+
}
|
14 |
+
|
15 |
+
// SendJSON400 sends a JSON response with HTTP status code 400
|
16 |
+
func SendJSON400(c *gin.Context, error_status *string, message *string) {
|
17 |
+
c.JSON(http.StatusBadRequest, gin.H{"status": "error", "error-status": error_status, "message": message})
|
18 |
+
return
|
19 |
+
}
|
20 |
+
|
21 |
+
// SendJSON401 sends a JSON response with HTTP status code 401
|
22 |
+
func SendJSON401(c *gin.Context, error_status *string, message *string) {
|
23 |
+
c.JSON(http.StatusUnauthorized, gin.H{"status": "error", "error-status": error_status, "message": message})
|
24 |
+
return
|
25 |
+
}
|
26 |
+
|
27 |
+
// SendJSON403 sends a JSON response with HTTP status code 403
|
28 |
+
func SendJSON403(c *gin.Context, message *string) {
|
29 |
+
c.JSON(http.StatusForbidden, gin.H{"status": "error", "message": message})
|
30 |
+
return
|
31 |
+
}
|
32 |
+
|
33 |
+
// SendJSON404 sends a JSON response with HTTP status code 404
|
34 |
+
func SendJSON404(c *gin.Context, message *string) {
|
35 |
+
c.JSON(http.StatusNotFound, gin.H{"status": "error", "message": message})
|
36 |
+
return
|
37 |
+
}
|
38 |
+
|
39 |
+
// SendJSON500 sends a JSON response with HTTP status code 500
|
40 |
+
func SendJSON500(c *gin.Context, error_status *string, message *string) {
|
41 |
+
c.JSON(http.StatusInternalServerError, gin.H{"status": "error", "error-status": error_status, "message": message})
|
42 |
+
return
|
43 |
+
}
|
44 |
+
|
45 |
+
// JSONResponseMiddleware is a middleware that provides functions for sending JSON responses
|
space/space/models/authentication_payload_model.go
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
package models
|
2 |
+
|
3 |
+
import (
|
4 |
+
"github.com/golang-jwt/jwt/v5"
|
5 |
+
"github.com/google/uuid"
|
6 |
+
)
|
7 |
+
|
8 |
+
type AccountData struct {
|
9 |
+
UserID uuid.UUID
|
10 |
+
VerifyStatus string
|
11 |
+
Role string
|
12 |
+
ErrVerif error
|
13 |
+
}
|
14 |
+
type CustomClaims struct {
|
15 |
+
jwt.RegisteredClaims
|
16 |
+
UserID uuid.UUID `json:"id"`
|
17 |
+
Role string `json:"role"`
|
18 |
+
}
|
space/space/models/database_orm_model.go
ADDED
@@ -0,0 +1,264 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
package models
|
2 |
+
|
3 |
+
import (
|
4 |
+
"time"
|
5 |
+
|
6 |
+
"github.com/google/uuid"
|
7 |
+
"github.com/jinzhu/gorm/dialects/postgres"
|
8 |
+
)
|
9 |
+
|
10 |
+
type Account struct {
|
11 |
+
Id uuid.UUID `gorm:"type:uuid;primary_key;default:uuid_generate_v4()" json:"id"`
|
12 |
+
Username string `gorm:"uniqueIndex" json:"username"`
|
13 |
+
Email string `gorm:"uniqueIndex" json:"email"`
|
14 |
+
Role string `json:"role"`
|
15 |
+
Password string `json:"password"`
|
16 |
+
IsEmailVerified bool `json:"is_email_verified"`
|
17 |
+
IsDetailCompleted bool `json:"is_detail_completed"`
|
18 |
+
CreatedAt time.Time `json:"created_at"`
|
19 |
+
DeletedAt *time.Time `json:"deleted_at" gorm:"default:null"`
|
20 |
+
}
|
21 |
+
|
22 |
+
type AccountDetails struct {
|
23 |
+
Id uuid.UUID `gorm:"type:uuid;primary_key;default:uuid_generate_v4()" json:"id"`
|
24 |
+
AccountId uuid.UUID `json:"account_id"`
|
25 |
+
FullName *string `json:"full_name"`
|
26 |
+
SchoolName *string `json:"school_name"`
|
27 |
+
Province *string `json:"province"`
|
28 |
+
City *string `json:"city"`
|
29 |
+
Avatar *string `json:"avatar"`
|
30 |
+
PhoneNumber *string `json:"phone_number"`
|
31 |
+
Account *Account `gorm:"foreignKey:AccountId"`
|
32 |
+
}
|
33 |
+
|
34 |
+
type EmailVerification struct {
|
35 |
+
Id uuid.UUID `gorm:"type:uuid;primary_key;default:uuid_generate_v4()" json:"id"`
|
36 |
+
Token uint `json:"token"`
|
37 |
+
AccountId uuid.UUID `json:"account_id"`
|
38 |
+
IsExpired bool `json:"is_expired"`
|
39 |
+
CreatedAt time.Time `json:"created_at"`
|
40 |
+
ExpiredAt time.Time `json:"expired_at"`
|
41 |
+
|
42 |
+
Account *Account `gorm:"foreignKey:AccountId"`
|
43 |
+
}
|
44 |
+
|
45 |
+
type ExternalAuth struct {
|
46 |
+
Id uuid.UUID `gorm:"type:uuid;primary_key;default:uuid_generate_v4()" json:"id"`
|
47 |
+
OauthID string `json:"oauth_id"`
|
48 |
+
AccountId uuid.UUID `json:"account_id"`
|
49 |
+
OauthProvider string `json:"oauth_provider"`
|
50 |
+
}
|
51 |
+
|
52 |
+
type FCM struct {
|
53 |
+
Id uuid.UUID `gorm:"type:uuid;primary_key;default:uuid_generate_v4()" json:"id"`
|
54 |
+
AccountId uuid.UUID `json:"account_id"`
|
55 |
+
FCMToken string `json:"fcm_token"`
|
56 |
+
}
|
57 |
+
|
58 |
+
type ForgotPassword struct {
|
59 |
+
Id uuid.UUID `gorm:"type:uuid;primary_key;default:uuid_generate_v4()" json:"id"`
|
60 |
+
Token uint `json:"token"`
|
61 |
+
AccountId uuid.UUID `json:"account_id"`
|
62 |
+
IsExpired bool `json:"is_expired"`
|
63 |
+
CreatedAt time.Time `json:"created_at"`
|
64 |
+
ExpiredAt time.Time `json:"expired_at"`
|
65 |
+
}
|
66 |
+
|
67 |
+
type Events struct {
|
68 |
+
Id uuid.UUID `gorm:"type:uuid;primary_key;default:uuid_generate_v4()" json:"id_event"`
|
69 |
+
Title string `json:"title"`
|
70 |
+
Slug string `json:"slug"`
|
71 |
+
StartEvent time.Time `json:"start_event"`
|
72 |
+
EndEvent time.Time `json:"end_event"`
|
73 |
+
EventCode string `json:"event_code"`
|
74 |
+
IsPublic bool `json:"is_public"`
|
75 |
+
}
|
76 |
+
|
77 |
+
type Announcement struct {
|
78 |
+
Id uuid.UUID `gorm:"type:uuid;primary_key;default:uuid_generate_v4()" json:"id_announcement"`
|
79 |
+
Title string `json:"title"`
|
80 |
+
CreatedAt time.Time `json:"created_at"`
|
81 |
+
Message string `json:"message"`
|
82 |
+
Publisher string `json:"publisher"`
|
83 |
+
EventId uuid.UUID `json:"id_event"`
|
84 |
+
}
|
85 |
+
|
86 |
+
type ProblemSet struct {
|
87 |
+
Id uuid.UUID `gorm:"type:uuid;primary_key;default:uuid_generate_v4()" json:"id_problem_set"`
|
88 |
+
Title string `json:"title"`
|
89 |
+
Duration time.Duration `json:"duration"`
|
90 |
+
Randomize uint `json:"randomize"`
|
91 |
+
MC_Count uint `json:"mc_count"`
|
92 |
+
SA_Count uint `json:"sa_count"`
|
93 |
+
Essay_Count uint `json:"essay_count"`
|
94 |
+
}
|
95 |
+
|
96 |
+
type Questions struct {
|
97 |
+
Id uuid.UUID `gorm:"type:uuid;primary_key;default:uuid_generate_v4()" json:"id_question"`
|
98 |
+
Type string `json:"type"` //MultChoices, ShortAns, Essay, IntPuzzle, IntType
|
99 |
+
Question string `json:"question"`
|
100 |
+
Options []string `gorm:"type:text[]" json:"options"`
|
101 |
+
AnsKey []string `gorm:"type:text[]" json:"ans_key"`
|
102 |
+
CorrMark float64 `json:"corr_mark"`
|
103 |
+
IncorrMark float64 `json:"incorr_mark"`
|
104 |
+
NullMark float64 `json:"null_mark"`
|
105 |
+
ProblemSetId uuid.UUID `json:"id_problem_set"`
|
106 |
+
|
107 |
+
ProblemSet *ProblemSet `gorm:"foreignKey:ProblemSetId"`
|
108 |
+
}
|
109 |
+
|
110 |
+
type EventAssign struct {
|
111 |
+
Id uuid.UUID `gorm:"type:uuid;primary_key;default:uuid_generate_v4()" json:"id_assign"`
|
112 |
+
AccountId uuid.UUID `json:"id_account"`
|
113 |
+
EventId uuid.UUID `json:"id_event"`
|
114 |
+
AssignedAt time.Time `json:"assigned_at"`
|
115 |
+
|
116 |
+
Account *Account `gorm:"foreignKey:AccountId"`
|
117 |
+
Event *Events `gorm:"foreignKey:EventId"`
|
118 |
+
}
|
119 |
+
|
120 |
+
type ProblemSetAssign struct {
|
121 |
+
Id uuid.UUID `gorm:"type:uuid;primary_key;default:uuid_generate_v4()" json:"id_problem_set_assign"`
|
122 |
+
EventId uuid.UUID `json:"id_event"`
|
123 |
+
ProblemSetId uuid.UUID `json:"id_problem_set"`
|
124 |
+
|
125 |
+
Event *Events `gorm:"foreignKey:EventId"`
|
126 |
+
ProblemSet *ProblemSet `gorm:"foreignKey:ProblemSetId"`
|
127 |
+
}
|
128 |
+
|
129 |
+
type ExamProgress struct {
|
130 |
+
Id uuid.UUID `gorm:"type:uuid;primary_key;default:uuid_generate_v4()" json:"id_progress"`
|
131 |
+
AccountId uuid.UUID `json:"id_account"`
|
132 |
+
EventId uuid.UUID `json:"id_event"`
|
133 |
+
ProblemSetId uuid.UUID `json:"id_problem_set"`
|
134 |
+
CreatedAt time.Time `json:"created_at"`
|
135 |
+
DueAt time.Time `json:"due_at"`
|
136 |
+
QuestionsOrder []string `gorm:"type:text[]" json:"questions_order"`
|
137 |
+
Answers any `gorm:"type:jsonb" json:"answers"`
|
138 |
+
|
139 |
+
Account *Account `gorm:"foreignKey:AccountId"`
|
140 |
+
Event *Events `gorm:"foreignKey:EventId"`
|
141 |
+
ProblemSet *ProblemSet `gorm:"foreignKey:ProblemSetId"`
|
142 |
+
}
|
143 |
+
|
144 |
+
type ExamProgress_Result struct {
|
145 |
+
Id uuid.UUID `gorm:"type:uuid;primary_key;default:uuid_generate_v4()" json:"id_progress"`
|
146 |
+
AccountId uuid.UUID `json:"id_account"`
|
147 |
+
EventId uuid.UUID `json:"id_event"`
|
148 |
+
ProblemSetId uuid.UUID `json:"id_problem_set"`
|
149 |
+
CreatedAt time.Time `json:"created_at"`
|
150 |
+
DueAt time.Time `json:"due_at"`
|
151 |
+
QuestionsOrder []string `gorm:"type:text[]" json:"questions_order"`
|
152 |
+
Answers postgres.Jsonb `gorm:"type:jsonb" json:"answers"`
|
153 |
+
|
154 |
+
Account *Account `gorm:"foreignKey:AccountId"`
|
155 |
+
Event *Events `gorm:"foreignKey:EventId"`
|
156 |
+
ProblemSet *ProblemSet `gorm:"foreignKey:ProblemSetId"`
|
157 |
+
}
|
158 |
+
|
159 |
+
type Result struct {
|
160 |
+
Id uuid.UUID `gorm:"type:uuid;primary_key;default:uuid_generate_v4()" json:"id_result"`
|
161 |
+
AccountId uuid.UUID `json:"id_account"`
|
162 |
+
EventId uuid.UUID `json:"id_event"`
|
163 |
+
ProblemSetId uuid.UUID `json:"id_problem_set"`
|
164 |
+
ProgressId uuid.UUID `json:"id_progress"`
|
165 |
+
FinishTime time.Time `json:"finish_time"`
|
166 |
+
Correct uint `json:"correct"`
|
167 |
+
Incorrect uint `json:"incorrect"`
|
168 |
+
Empty uint `json:"empty"`
|
169 |
+
OnCorrection uint `json:"on_correction"`
|
170 |
+
ManualScoring float64 `json:"manual_scoring"`
|
171 |
+
MCScore float64 `json:"mc_score"`
|
172 |
+
ManualScore float64 `json:"manual_score"`
|
173 |
+
FinalScore float64 `json:"final_score"`
|
174 |
+
|
175 |
+
Account *Account `gorm:"foreignKey:AccountId"`
|
176 |
+
Event *Events `gorm:"foreignKey:EventId"`
|
177 |
+
ProblemSet *ProblemSet `gorm:"foreignKey:ProblemSetId"`
|
178 |
+
ExamProgress *ExamProgress `gorm:"foreignKey:ProgressId"`
|
179 |
+
}
|
180 |
+
|
181 |
+
type Academy struct {
|
182 |
+
Id uuid.UUID `gorm:"primaryKey" json:"id"`
|
183 |
+
Title string `json:"title"`
|
184 |
+
Slug string `json:"slug"`
|
185 |
+
Description string `json:"description"`
|
186 |
+
}
|
187 |
+
|
188 |
+
type AcademyMaterial struct {
|
189 |
+
ID uuid.UUID `gorm:"primaryKey" json:"id"`
|
190 |
+
AcademyId uint `json:"academy_id"`
|
191 |
+
Title string `json:"title"`
|
192 |
+
Slug string `json:"slug"`
|
193 |
+
Description string `json:"description"`
|
194 |
+
}
|
195 |
+
|
196 |
+
type AcademyContent struct {
|
197 |
+
Id uuid.UUID `gorm:"primaryKey" json:"id"`
|
198 |
+
Title string `json:"title"`
|
199 |
+
Order uint `json:"order"`
|
200 |
+
AcademyMaterialId uint `json:"academy_material_id"`
|
201 |
+
Description string `json:"description"`
|
202 |
+
}
|
203 |
+
type OptionCategory struct {
|
204 |
+
Id uint `gorm:"primaryKey" json:"id"`
|
205 |
+
OptionName string `json:"option_name"`
|
206 |
+
OptionSlug string `json:"option_slug"`
|
207 |
+
}
|
208 |
+
|
209 |
+
type OptionValues struct {
|
210 |
+
Id uint `gorm:"primaryKey" json:"id"`
|
211 |
+
OptionCategoryId uint `json:"option_category_id"`
|
212 |
+
OptionValue string `json:"option_value"`
|
213 |
+
}
|
214 |
+
type AcademyMaterialProgress struct {
|
215 |
+
Id uuid.UUID `gorm:"primaryKey" json:"id"`
|
216 |
+
AccountId uint `json:"account_id"`
|
217 |
+
AcademyMaterialId uint `json:"academy_material_id"`
|
218 |
+
Progress uint `json:"progress"`
|
219 |
+
}
|
220 |
+
|
221 |
+
type AcademyContentProgress struct {
|
222 |
+
Id uuid.UUID `gorm:"primaryKey" json:"id"`
|
223 |
+
AccountId uuid.UUID `json:"account_id"`
|
224 |
+
AcademyId uuid.UUID `json:"academy_id"`
|
225 |
+
}
|
226 |
+
|
227 |
+
type RegionProvince struct {
|
228 |
+
Id uint `json:"id"`
|
229 |
+
Name string `json:"name"`
|
230 |
+
Code string `json:"code"`
|
231 |
+
}
|
232 |
+
|
233 |
+
type RegionCity struct {
|
234 |
+
Id uint `json:"id"`
|
235 |
+
Type string `json:"type"`
|
236 |
+
Name string `json:"name"`
|
237 |
+
Code string `json:"code"`
|
238 |
+
FullCode string `json:"full_code"`
|
239 |
+
ProvinceId uint `json:"province_id"`
|
240 |
+
}
|
241 |
+
|
242 |
+
// Gorm table name settings
|
243 |
+
func (Account) TableName() string { return "account" }
|
244 |
+
func (AccountDetails) TableName() string { return "account_details" }
|
245 |
+
func (EmailVerification) TableName() string { return "email_verification" }
|
246 |
+
func (ExternalAuth) TableName() string { return "external_auth" }
|
247 |
+
func (FCM) TableName() string { return "fcm" }
|
248 |
+
func (ForgotPassword) TableName() string { return "forgot_password" }
|
249 |
+
func (Events) TableName() string { return "events" }
|
250 |
+
func (Announcement) TableName() string { return "announcement" }
|
251 |
+
func (ProblemSet) TableName() string { return "problem_sets" }
|
252 |
+
func (Questions) TableName() string { return "questions" }
|
253 |
+
func (EventAssign) TableName() string { return "event_assign" }
|
254 |
+
func (ProblemSetAssign) TableName() string { return "problem_sets_assign" }
|
255 |
+
func (Result) TableName() string { return "result" }
|
256 |
+
func (ExamProgress) TableName() string { return "exam_progress" }
|
257 |
+
func (ExamProgress_Result) TableName() string { return "exam_progress_result" }
|
258 |
+
func (Academy) TableName() string { return "academy" }
|
259 |
+
func (AcademyMaterial) TableName() string { return "academy_materials" }
|
260 |
+
func (AcademyContent) TableName() string { return "academy_contents" }
|
261 |
+
func (AcademyMaterialProgress) TableName() string { return "academy_materials_progress" }
|
262 |
+
func (AcademyContentProgress) TableName() string { return "academy_contents_progress" }
|
263 |
+
func (RegionProvince) TableName() string { return "region_provinces" }
|
264 |
+
func (RegionCity) TableName() string { return "region_cities" }
|
space/space/models/exception_model.go
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
package models
|
2 |
+
|
3 |
+
type Exception struct {
|
4 |
+
Unauthorized bool `json:"unauthorized,omitempty"`
|
5 |
+
BadRequest bool `json:"bad_request,omitempty"`
|
6 |
+
DataNotFound bool `json:"data_not_found,omitempty"`
|
7 |
+
InternalServerError bool `json:"internal_server_error,omitempty"`
|
8 |
+
DataDuplicate bool `json:"data_duplicate,omitempty"`
|
9 |
+
QueryError bool `json:"query_error,omitempty"`
|
10 |
+
InvalidPasswordLength bool `json:"invalid_password_length,omitempty"`
|
11 |
+
Message string `json:"message,omitempty"`
|
12 |
+
}
|
space/space/models/model.go
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
package models
|
space/space/models/request_model.go
ADDED
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
package models
|
2 |
+
|
3 |
+
import "github.com/google/uuid"
|
4 |
+
|
5 |
+
type LoginRequest struct {
|
6 |
+
Email string `json:"email" binding:"required"`
|
7 |
+
Password string `json:"password" binding:"required"`
|
8 |
+
}
|
9 |
+
|
10 |
+
type RegisterRequest struct {
|
11 |
+
Name string `json:"name"`
|
12 |
+
Email string `json:"email" binding:"required,email"`
|
13 |
+
Username string `json:"username" binding:"required"`
|
14 |
+
Password string `json:"password" binding:"required"`
|
15 |
+
}
|
16 |
+
|
17 |
+
type CreateEmailVerificationRequest struct {
|
18 |
+
AccountId uuid.UUID `json:"account_id" binding:"required"`
|
19 |
+
}
|
20 |
+
|
21 |
+
type ChangePasswordRequest struct {
|
22 |
+
OldPassword string `json:"old_password" binding:"required" `
|
23 |
+
NewPassword string `json:"new_password" binding:"required" `
|
24 |
+
}
|
25 |
+
|
26 |
+
type EventDetailRequest struct {
|
27 |
+
IdUser uuid.UUID `json:"id_user"`
|
28 |
+
EventId uuid.UUID `json:"id_event"`
|
29 |
+
}
|
30 |
+
|
31 |
+
type JoinEventRequest struct {
|
32 |
+
EventId uuid.UUID `json:"id_event"`
|
33 |
+
EventCode string `json:"event_code"`
|
34 |
+
}
|
35 |
+
|
36 |
+
type CreateVerifyEmailRequest struct {
|
37 |
+
Token uint `json:"token" binding:"required"`
|
38 |
+
}
|
39 |
+
|
40 |
+
type OptionsRequest struct {
|
41 |
+
OptionName string `json:"option_name" binding:"required"`
|
42 |
+
OptionValue []string `json:"option_values" binding:"required"`
|
43 |
+
}
|
44 |
+
|
45 |
+
type ExternalAuthRequest struct {
|
46 |
+
OauthID string `json:"oauth_id" binding:"required"`
|
47 |
+
OauthProvider string `json:"oauth_provider" binding:"required"`
|
48 |
+
}
|
49 |
+
|
50 |
+
type ForgotPasswordRequest struct {
|
51 |
+
Email string `json:"email" binding:"required,email"`
|
52 |
+
}
|
53 |
+
type ValidateForgotPasswordRequest struct {
|
54 |
+
Token uint `json:"token" binding:"required"`
|
55 |
+
NewPassword string `json:"new_password"`
|
56 |
+
}
|
space/space/models/response_model.go
ADDED
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
package models
|
2 |
+
|
3 |
+
type SuccessResponse struct {
|
4 |
+
Status string `json:"status"`
|
5 |
+
Message string `json:"message"`
|
6 |
+
Data any `json:"data"`
|
7 |
+
MetaData any `json:"meta_data"`
|
8 |
+
}
|
9 |
+
|
10 |
+
type ErrorResponse struct {
|
11 |
+
Status string `json:"status"`
|
12 |
+
Message string `json:"message"`
|
13 |
+
Errors Exception `json:"errors"`
|
14 |
+
MetaData any `json:"meta_data"`
|
15 |
+
}
|
16 |
+
type AuthenticatedUser struct {
|
17 |
+
Account Account `json:"account"`
|
18 |
+
Token string `json:"token"`
|
19 |
+
}
|
20 |
+
|
21 |
+
type EventDetailResponse struct {
|
22 |
+
Data *Events
|
23 |
+
RegisterStatus int `json:"register_status"`
|
24 |
+
}
|
25 |
+
|
26 |
+
type Options struct {
|
27 |
+
OptionCategory OptionCategory `json:"option_category"`
|
28 |
+
OptionValues []OptionValues `json:"option_values"`
|
29 |
+
}
|
30 |
+
type OptionsResponse struct {
|
31 |
+
Options []Options `json:"options"`
|
32 |
+
}
|
33 |
+
|
34 |
+
type UserProfileResponse struct {
|
35 |
+
Account Account `json:"account"`
|
36 |
+
Details AccountDetails `json:"details"`
|
37 |
+
}
|
38 |
+
|
39 |
+
type AcademyMaterialResponse struct {
|
40 |
+
Materials AcademyMaterial
|
41 |
+
Contents []AcademyContent
|
42 |
+
}
|
43 |
+
type AcademyResponse struct {
|
44 |
+
Academy Academy `json:"academy"`
|
45 |
+
Materials []AcademyMaterialResponse `json:"academy_materials"`
|
46 |
+
}
|
47 |
+
|
48 |
+
type AllAcademyResponse struct {
|
49 |
+
Academies []AcademyResponse `json:"academy_dasar"`
|
50 |
+
}
|
space/space/repositories/academy_repository.go
ADDED
@@ -0,0 +1,73 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
package repositories
|
2 |
+
|
3 |
+
import "godp.abdanhafidz.com/models"
|
4 |
+
|
5 |
+
func GetAllAcademy() Repository[models.Academy, []models.Academy] {
|
6 |
+
repo := Construct[models.Academy, []models.Academy](
|
7 |
+
models.Academy{},
|
8 |
+
)
|
9 |
+
repo.Transactions(
|
10 |
+
WhereGivenConstructor[models.Academy, []models.Academy],
|
11 |
+
Find[models.Academy, []models.Academy],
|
12 |
+
)
|
13 |
+
return *repo
|
14 |
+
}
|
15 |
+
|
16 |
+
func GetAcademyDataBySlug(slug string) Repository[models.Academy, models.Academy] {
|
17 |
+
repo := Construct[models.Academy, models.Academy](
|
18 |
+
models.Academy{Slug: slug},
|
19 |
+
)
|
20 |
+
repo.Transactions(
|
21 |
+
WhereGivenConstructor[models.Academy, models.Academy],
|
22 |
+
Find[models.Academy, models.Academy],
|
23 |
+
)
|
24 |
+
return *repo
|
25 |
+
}
|
26 |
+
|
27 |
+
func GetAllAcademyMaterialsByAcademyId(acaddemyId uint) Repository[models.AcademyMaterial, []models.AcademyMaterial] {
|
28 |
+
repo := Construct[models.AcademyMaterial, []models.AcademyMaterial](
|
29 |
+
models.AcademyMaterial{AcademyId: acaddemyId},
|
30 |
+
)
|
31 |
+
repo.Transactions(
|
32 |
+
WhereGivenConstructor[models.AcademyMaterial, []models.AcademyMaterial],
|
33 |
+
Find[models.AcademyMaterial, []models.AcademyMaterial],
|
34 |
+
)
|
35 |
+
return *repo
|
36 |
+
}
|
37 |
+
|
38 |
+
func GetAllAcademyContentsByMaterialID(materialId uint) Repository[models.AcademyContent, []models.AcademyContent] {
|
39 |
+
repo := Construct[models.AcademyContent, []models.AcademyContent](
|
40 |
+
models.AcademyContent{AcademyMaterialId: materialId},
|
41 |
+
)
|
42 |
+
repo.Transactions(
|
43 |
+
WhereGivenConstructor[models.AcademyContent, []models.AcademyContent],
|
44 |
+
Find[models.AcademyContent, []models.AcademyContent],
|
45 |
+
)
|
46 |
+
return *repo
|
47 |
+
}
|
48 |
+
|
49 |
+
func CreateAcademy(academies models.Academy) Repository[models.Academy, models.Academy] {
|
50 |
+
repo := Construct[models.Academy, models.Academy](
|
51 |
+
academies,
|
52 |
+
)
|
53 |
+
|
54 |
+
Create(repo)
|
55 |
+
return *repo
|
56 |
+
}
|
57 |
+
|
58 |
+
func CreateAcademyMaterial(academyMaterial models.AcademyMaterial) Repository[models.AcademyMaterial, models.AcademyMaterial] {
|
59 |
+
repo := Construct[models.AcademyMaterial, models.AcademyMaterial](
|
60 |
+
academyMaterial,
|
61 |
+
)
|
62 |
+
|
63 |
+
Create(repo)
|
64 |
+
return *repo
|
65 |
+
}
|
66 |
+
|
67 |
+
func CreateAcademyContent(academyContent models.AcademyContent) Repository[models.AcademyContent, models.AcademyContent] {
|
68 |
+
repo := Construct[models.AcademyContent, models.AcademyContent](
|
69 |
+
academyContent,
|
70 |
+
)
|
71 |
+
Create(repo)
|
72 |
+
return *repo
|
73 |
+
}
|
space/space/repositories/account_repository.go
ADDED
@@ -0,0 +1,88 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
package repositories
|
2 |
+
|
3 |
+
import (
|
4 |
+
"github.com/google/uuid"
|
5 |
+
"godp.abdanhafidz.com/models"
|
6 |
+
)
|
7 |
+
|
8 |
+
func GetAccountbyEmail(email string) Repository[models.Account, models.Account] {
|
9 |
+
repo := Construct[models.Account, models.Account](
|
10 |
+
models.Account{Email: email},
|
11 |
+
)
|
12 |
+
repo.Transactions(
|
13 |
+
WhereGivenConstructor[models.Account, models.Account],
|
14 |
+
Find[models.Account, models.Account],
|
15 |
+
)
|
16 |
+
return *repo
|
17 |
+
}
|
18 |
+
|
19 |
+
func GetAllAccount() Repository[models.Account, []models.Account] {
|
20 |
+
repo := Construct[models.Account, []models.Account](
|
21 |
+
models.Account{},
|
22 |
+
)
|
23 |
+
repo.Transactions(
|
24 |
+
Find[models.Account, []models.Account],
|
25 |
+
)
|
26 |
+
return *repo
|
27 |
+
}
|
28 |
+
func GetAccountById(AccountId uuid.UUID) Repository[models.Account, models.Account] {
|
29 |
+
repo := Construct[models.Account, models.Account](
|
30 |
+
models.Account{Id: AccountId},
|
31 |
+
)
|
32 |
+
repo.Transactions(
|
33 |
+
WhereGivenConstructor[models.Account, models.Account],
|
34 |
+
Find[models.Account, models.Account],
|
35 |
+
)
|
36 |
+
return *repo
|
37 |
+
}
|
38 |
+
|
39 |
+
func UpdateAccount(account models.Account) Repository[models.Account, models.Account] {
|
40 |
+
repo := Construct[models.Account, models.Account](
|
41 |
+
account,
|
42 |
+
)
|
43 |
+
repo.Transaction.Save(&repo.Constructor)
|
44 |
+
repo.Result = repo.Constructor
|
45 |
+
return *repo
|
46 |
+
}
|
47 |
+
|
48 |
+
func GetDetailAccountById(AccountId uuid.UUID) Repository[models.AccountDetails, models.AccountDetails] {
|
49 |
+
repo := Construct[models.AccountDetails, models.AccountDetails](
|
50 |
+
models.AccountDetails{AccountId: AccountId},
|
51 |
+
)
|
52 |
+
|
53 |
+
// fmt.Println("Account ID:", repo.Constructor.AccountId)
|
54 |
+
repo.Transactions(
|
55 |
+
WhereGivenConstructor[models.AccountDetails, models.AccountDetails],
|
56 |
+
Find[models.AccountDetails, models.AccountDetails],
|
57 |
+
)
|
58 |
+
return *repo
|
59 |
+
}
|
60 |
+
|
61 |
+
func CreateAccount(account models.Account) Repository[models.Account, models.Account] {
|
62 |
+
repo := Construct[models.Account, models.Account](
|
63 |
+
account,
|
64 |
+
)
|
65 |
+
Create(repo)
|
66 |
+
return *repo
|
67 |
+
}
|
68 |
+
|
69 |
+
func CreateAccountDetails(accountDetails models.AccountDetails) Repository[models.AccountDetails, models.AccountDetails] {
|
70 |
+
repo := Construct[models.AccountDetails, models.AccountDetails](
|
71 |
+
accountDetails,
|
72 |
+
)
|
73 |
+
Create(repo)
|
74 |
+
return *repo
|
75 |
+
}
|
76 |
+
|
77 |
+
func UpdateAccountDetails(accountDetails models.AccountDetails) Repository[models.AccountDetails, models.AccountDetails] {
|
78 |
+
repo := Construct[models.AccountDetails, models.AccountDetails](
|
79 |
+
models.AccountDetails{AccountId: accountDetails.AccountId},
|
80 |
+
)
|
81 |
+
repo.Transaction.Where("account_id = ?", accountDetails.AccountId).First(&repo.Constructor)
|
82 |
+
accountDetails.Id = repo.Constructor.Id
|
83 |
+
// fmt.Println(repo.Constructor)
|
84 |
+
// fmt.Println(accountDetails)
|
85 |
+
repo.Transaction.Updates(accountDetails)
|
86 |
+
repo.Result = accountDetails
|
87 |
+
return *repo
|
88 |
+
}
|
space/space/repositories/email_verification_repository.go
ADDED
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
package repositories
|
2 |
+
|
3 |
+
import (
|
4 |
+
"time"
|
5 |
+
|
6 |
+
"github.com/google/uuid"
|
7 |
+
"godp.abdanhafidz.com/models"
|
8 |
+
)
|
9 |
+
|
10 |
+
func CreateEmailVerification(uuid uuid.UUID, AccountId uuid.UUID, dueTime time.Time, token uint) Repository[models.EmailVerification, models.EmailVerification] {
|
11 |
+
repo := Construct[models.EmailVerification, models.EmailVerification](
|
12 |
+
models.EmailVerification{
|
13 |
+
AccountId: AccountId,
|
14 |
+
IsExpired: false,
|
15 |
+
ExpiredAt: dueTime,
|
16 |
+
Token: token,
|
17 |
+
Id: uuid,
|
18 |
+
},
|
19 |
+
)
|
20 |
+
Create(repo)
|
21 |
+
return *repo
|
22 |
+
}
|
23 |
+
|
24 |
+
func GetEmailVerification(AccountId uuid.UUID, token uint) Repository[models.EmailVerification, models.EmailVerification] {
|
25 |
+
repo := Construct[models.EmailVerification, models.EmailVerification](
|
26 |
+
models.EmailVerification{
|
27 |
+
AccountId: AccountId,
|
28 |
+
IsExpired: false,
|
29 |
+
Token: token,
|
30 |
+
},
|
31 |
+
)
|
32 |
+
repo.Transactions(
|
33 |
+
WhereGivenConstructor[models.EmailVerification, models.EmailVerification],
|
34 |
+
Find[models.EmailVerification, models.EmailVerification],
|
35 |
+
)
|
36 |
+
return *repo
|
37 |
+
}
|
38 |
+
|
39 |
+
func UpdateExpiredEmailVerification(uuid uuid.UUID) Repository[models.EmailVerification, models.EmailVerification] {
|
40 |
+
repo := Construct[models.EmailVerification, models.EmailVerification](
|
41 |
+
models.EmailVerification{Id: uuid},
|
42 |
+
)
|
43 |
+
|
44 |
+
repo.Transaction.Where("UUID = ?", uuid).First(&repo.Constructor)
|
45 |
+
repo.Constructor.IsExpired = true
|
46 |
+
repo.Transaction.Updates(repo.Constructor)
|
47 |
+
repo.Result = repo.Constructor
|
48 |
+
return *repo
|
49 |
+
}
|
50 |
+
|
51 |
+
func DeleteEmailVerification(token uint) Repository[models.EmailVerification, models.EmailVerification] {
|
52 |
+
repo := Construct[models.EmailVerification, models.EmailVerification](
|
53 |
+
models.EmailVerification{
|
54 |
+
Token: token,
|
55 |
+
},
|
56 |
+
)
|
57 |
+
|
58 |
+
repo.Transactions(
|
59 |
+
WhereGivenConstructor[models.EmailVerification, models.EmailVerification],
|
60 |
+
Delete[models.EmailVerification],
|
61 |
+
)
|
62 |
+
return *repo
|
63 |
+
}
|
space/space/repositories/event_repository.go
ADDED
@@ -0,0 +1,111 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
package repositories
|
2 |
+
|
3 |
+
import (
|
4 |
+
"log"
|
5 |
+
"time"
|
6 |
+
|
7 |
+
"github.com/google/uuid"
|
8 |
+
"godp.abdanhafidz.com/models"
|
9 |
+
)
|
10 |
+
|
11 |
+
func EventListWithFilter(userId uuid.UUID, pagination PaginationConstructor) Repository[models.Events, []models.Events] {
|
12 |
+
repo := Construct[models.Events, []models.Events](
|
13 |
+
models.Events{},
|
14 |
+
)
|
15 |
+
repo.Pagination = pagination
|
16 |
+
|
17 |
+
log.Printf("Pagination - Limit: %d, Offset: %d", pagination.Limit, pagination.Offset)
|
18 |
+
|
19 |
+
repo.Transactions(
|
20 |
+
FindAllPaginate[models.Events, []models.Events],
|
21 |
+
)
|
22 |
+
|
23 |
+
currentTime := time.Now()
|
24 |
+
|
25 |
+
filteredEvents := []models.Events{}
|
26 |
+
for _, event := range repo.Result {
|
27 |
+
if event.IsPublic || isAssignedToEvent(userId, event.Id) {
|
28 |
+
if event.EndEvent.After(currentTime) {
|
29 |
+
filteredEvents = append(filteredEvents, event)
|
30 |
+
}
|
31 |
+
}
|
32 |
+
}
|
33 |
+
|
34 |
+
repo.Result = filteredEvents
|
35 |
+
repo.RowsCount = len(filteredEvents)
|
36 |
+
|
37 |
+
if repo.RowsCount == 0 {
|
38 |
+
log.Println("No accessible events found for the user")
|
39 |
+
}
|
40 |
+
|
41 |
+
return *repo
|
42 |
+
}
|
43 |
+
|
44 |
+
func GetEventDetailByEventId(EventId uuid.UUID) Repository[models.Events, models.Events] {
|
45 |
+
repo := Construct[models.Events, models.Events](
|
46 |
+
models.Events{
|
47 |
+
Id: EventId,
|
48 |
+
},
|
49 |
+
)
|
50 |
+
repo.Transactions(
|
51 |
+
WhereGivenConstructor[models.Events, models.Events],
|
52 |
+
Find[models.Events, models.Events],
|
53 |
+
)
|
54 |
+
return *repo
|
55 |
+
}
|
56 |
+
|
57 |
+
func GetEventDetailBySlug(slug string) Repository[models.Events, models.Events] {
|
58 |
+
repo := Construct[models.Events, models.Events](
|
59 |
+
models.Events{
|
60 |
+
Slug: slug,
|
61 |
+
},
|
62 |
+
)
|
63 |
+
repo.Transactions(
|
64 |
+
WhereGivenConstructor[models.Events, models.Events],
|
65 |
+
Find[models.Events, models.Events],
|
66 |
+
)
|
67 |
+
return *repo
|
68 |
+
}
|
69 |
+
|
70 |
+
func GetEventAssigned(EventId uuid.UUID, AccountId uuid.UUID) Repository[models.EventAssign, models.EventAssign] {
|
71 |
+
repo := Construct[models.EventAssign, models.EventAssign](
|
72 |
+
models.EventAssign{
|
73 |
+
EventId: EventId,
|
74 |
+
AccountId: AccountId,
|
75 |
+
},
|
76 |
+
)
|
77 |
+
repo.Transactions(
|
78 |
+
WhereGivenConstructor[models.EventAssign, models.EventAssign],
|
79 |
+
Find[models.EventAssign, models.EventAssign],
|
80 |
+
)
|
81 |
+
return *repo
|
82 |
+
}
|
83 |
+
|
84 |
+
func GetEventByCode(code string) Repository[models.Events, models.Events] {
|
85 |
+
repo := Construct[models.Events, models.Events](
|
86 |
+
models.Events{EventCode: code},
|
87 |
+
)
|
88 |
+
|
89 |
+
repo.Transactions(
|
90 |
+
WhereGivenConstructor[models.Events, models.Events],
|
91 |
+
Find[models.Events, models.Events],
|
92 |
+
)
|
93 |
+
if repo.RowsCount == 0 {
|
94 |
+
log.Println("No events found with the provided code")
|
95 |
+
}
|
96 |
+
return *repo
|
97 |
+
}
|
98 |
+
|
99 |
+
func AssignEvent(eventAssign models.EventAssign) Repository[models.EventAssign, models.EventAssign] {
|
100 |
+
repo := Construct[models.EventAssign, models.EventAssign](
|
101 |
+
eventAssign,
|
102 |
+
)
|
103 |
+
Create(repo)
|
104 |
+
return *repo
|
105 |
+
}
|
106 |
+
|
107 |
+
func isAssignedToEvent(userId uuid.UUID, eventId uuid.UUID) bool {
|
108 |
+
repo := GetEventAssigned(eventId, userId)
|
109 |
+
|
110 |
+
return repo.RowsCount > 0
|
111 |
+
}
|
space/space/repositories/external_auth_repository.go
ADDED
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
package repositories
|
2 |
+
|
3 |
+
import (
|
4 |
+
"github.com/google/uuid"
|
5 |
+
"godp.abdanhafidz.com/models"
|
6 |
+
)
|
7 |
+
|
8 |
+
func CreateExternalAuth(oauth models.ExternalAuth) Repository[models.ExternalAuth, models.ExternalAuth] {
|
9 |
+
repo := Construct[models.ExternalAuth, models.ExternalAuth](
|
10 |
+
oauth,
|
11 |
+
)
|
12 |
+
Create(repo)
|
13 |
+
return *repo
|
14 |
+
}
|
15 |
+
|
16 |
+
func GetExternalAuthByAccountId(AccountId uuid.UUID) Repository[models.ExternalAuth, []models.ExternalAuth] {
|
17 |
+
repo := Construct[models.ExternalAuth, []models.ExternalAuth](
|
18 |
+
models.ExternalAuth{
|
19 |
+
AccountId: AccountId,
|
20 |
+
},
|
21 |
+
)
|
22 |
+
repo.Transactions(
|
23 |
+
WhereGivenConstructor[models.ExternalAuth, []models.ExternalAuth],
|
24 |
+
Find[models.ExternalAuth, []models.ExternalAuth],
|
25 |
+
)
|
26 |
+
return *repo
|
27 |
+
}
|
28 |
+
|
29 |
+
func GetExternalAccountByOauthId(oauthId string) Repository[models.ExternalAuth, models.ExternalAuth] {
|
30 |
+
repo := Construct[models.ExternalAuth, models.ExternalAuth](
|
31 |
+
models.ExternalAuth{
|
32 |
+
OauthID: oauthId,
|
33 |
+
},
|
34 |
+
)
|
35 |
+
repo.Transactions(
|
36 |
+
WhereGivenConstructor[models.ExternalAuth, models.ExternalAuth],
|
37 |
+
Find[models.ExternalAuth, models.ExternalAuth],
|
38 |
+
)
|
39 |
+
return *repo
|
40 |
+
}
|
space/space/repositories/forgot_password_repository.go
ADDED
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
package repositories
|
2 |
+
|
3 |
+
import "godp.abdanhafidz.com/models"
|
4 |
+
|
5 |
+
func CreateForgotPassword(forgotPassword models.ForgotPassword) Repository[models.ForgotPassword, models.ForgotPassword] {
|
6 |
+
repo := Construct[models.ForgotPassword, models.ForgotPassword](
|
7 |
+
forgotPassword,
|
8 |
+
)
|
9 |
+
Create(repo)
|
10 |
+
return *repo
|
11 |
+
}
|
12 |
+
|
13 |
+
func GetForgotPasswordByToken(token uint) Repository[models.ForgotPassword, models.ForgotPassword] {
|
14 |
+
repo := Construct[models.ForgotPassword, models.ForgotPassword](
|
15 |
+
models.ForgotPassword{Token: token},
|
16 |
+
)
|
17 |
+
repo.Transactions(
|
18 |
+
WhereGivenConstructor[models.ForgotPassword, models.ForgotPassword],
|
19 |
+
Find[models.ForgotPassword, models.ForgotPassword],
|
20 |
+
)
|
21 |
+
return *repo
|
22 |
+
}
|
space/space/repositories/option_repository.go
ADDED
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
package repositories
|
2 |
+
|
3 |
+
import (
|
4 |
+
"godp.abdanhafidz.com/models"
|
5 |
+
)
|
6 |
+
|
7 |
+
func CreateOptionCategory(categories models.OptionCategory) Repository[models.OptionCategory, models.OptionCategory] {
|
8 |
+
repo := Construct[models.OptionCategory, models.OptionCategory](
|
9 |
+
categories,
|
10 |
+
)
|
11 |
+
Create(repo)
|
12 |
+
return *repo
|
13 |
+
}
|
14 |
+
|
15 |
+
func CreateOptionValues(values models.OptionValues) Repository[models.OptionValues, models.OptionValues] {
|
16 |
+
repo := Construct[models.OptionValues, models.OptionValues](
|
17 |
+
values,
|
18 |
+
)
|
19 |
+
Create(repo)
|
20 |
+
return *repo
|
21 |
+
}
|
22 |
+
|
23 |
+
func GetOptionCategoryBySlug(slug string) Repository[models.OptionCategory, models.OptionCategory] {
|
24 |
+
repo := Construct[models.OptionCategory, models.OptionCategory](
|
25 |
+
models.OptionCategory{OptionSlug: slug},
|
26 |
+
)
|
27 |
+
repo.Transactions(
|
28 |
+
WhereGivenConstructor[models.OptionCategory, models.OptionCategory],
|
29 |
+
Find[models.OptionCategory, models.OptionCategory],
|
30 |
+
)
|
31 |
+
return *repo
|
32 |
+
}
|
33 |
+
|
34 |
+
func GetOptionValuesByCategoryId(categoryId uint) Repository[models.OptionValues, []models.OptionValues] {
|
35 |
+
repo := Construct[models.OptionValues, []models.OptionValues](
|
36 |
+
models.OptionValues{OptionCategoryId: categoryId},
|
37 |
+
)
|
38 |
+
repo.Transactions(
|
39 |
+
WhereGivenConstructor[models.OptionValues, []models.OptionValues],
|
40 |
+
Find[models.OptionValues, []models.OptionValues],
|
41 |
+
)
|
42 |
+
return *repo
|
43 |
+
}
|