Skip to content

Commit 06b034e

Browse files
authored
Merge pull request #10 from Evently-Event-Management/new_notifiaction
New notifiaction
2 parents 7186a2d + 55a20a2 commit 06b034e

36 files changed

+4406
-189
lines changed

.env.example

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# AWS Configuration
2+
AWS_REGION=ap-south-1
3+
AWS_SQS_SESSION_SCHEDULING_URL=your-sqs-queue-url
4+
AWS_SQS_SESSION_SCHEDULING_ARN=your-sqs-queue-arn
5+
AWS_SCHEDULER_ROLE_ARN=your-scheduler-role-arn
6+
AWS_SCHEDULER_GROUP_NAME=default
7+
8+
# Keycloak Configuration
9+
KEYCLOAK_URL=http://auth.ticketly.com:8080
10+
KEYCLOAK_REALM=event-ticketing
11+
KEYCLOAK_CLIENT_ID=scheduler-service-client
12+
SCHEDULER_CLIENT_SECRET=your-keycloak-client-secret
13+
14+
# Kafka Configuration
15+
KAFKA_URL=localhost:9092
16+
EVENT_SESSIONS_KAFKA_TOPIC=dbz.ticketly.public.event_sessions
17+
18+
# Database Configuration
19+
DATABASE_HOST=localhost
20+
DATABASE_PORT=5432
21+
DATABASE_NAME=ticketly
22+
DATABASE_USER=postgres
23+
DATABASE_PASSWORD=your-database-password
24+
DATABASE_SSL_MODE=disable
25+
26+
# Email Configuration (SMTP)
27+
SMTP_HOST=smtp.gmail.com
28+
SMTP_PORT=587
29+
SMTP_USERNAME=your-email@gmail.com
30+
SMTP_PASSWORD=your-email-app-password
31+
FROM_EMAIL=noreply@ticketly.com
32+
FROM_NAME=Ticketly
33+
34+
# Other Configuration
35+
EVENT_SERVICE_URL=http://localhost:8081/api/event-seating

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,6 @@ _testmain.go
3535
.env
3636

3737
# Logs
38-
*.log
38+
*.log
39+
40+
ms-scheduling

cmd/migrate/main.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package main
2+
3+
import (
4+
"flag"
5+
"log"
6+
"ms-scheduling/internal/config"
7+
"ms-scheduling/internal/services"
8+
"os"
9+
)
10+
11+
func main() {
12+
var command = flag.String("command", "up", "Migration command: up, status")
13+
flag.Parse()
14+
15+
// Load config
16+
cfg := config.Load()
17+
18+
// Initialize database service with DSN directly
19+
dbService, err := services.NewDatabaseService(cfg.PostgresDSN)
20+
if err != nil {
21+
log.Fatalf("Failed to initialize database service: %v", err)
22+
}
23+
defer dbService.Close()
24+
25+
switch *command {
26+
case "up":
27+
log.Println("Running migrations...")
28+
if err := dbService.RunMigrations(); err != nil {
29+
log.Fatalf("Migration failed: %v", err)
30+
}
31+
log.Println("✓ Migrations completed successfully")
32+
33+
case "status":
34+
log.Println("Checking migration status...")
35+
if err := dbService.MigrationStatus(); err != nil {
36+
log.Fatalf("Failed to get migration status: %v", err)
37+
}
38+
39+
default:
40+
log.Printf("Unknown command: %s", *command)
41+
log.Println("Available commands: up, status")
42+
os.Exit(1)
43+
}
44+
}

go.mod

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,27 @@ module ms-scheduling
33
go 1.24
44

55
require (
6+
github.com/aws/aws-sdk-go-v2 v1.39.2
67
github.com/aws/aws-sdk-go-v2/config v1.30.3
8+
github.com/aws/aws-sdk-go-v2/service/scheduler v1.17.5
79
github.com/aws/aws-sdk-go-v2/service/sqs v1.40.0
10+
github.com/joho/godotenv v1.5.1
11+
github.com/lib/pq v1.10.9
812
github.com/segmentio/kafka-go v0.4.49
913
)
1014

1115
require (
12-
github.com/aws/aws-sdk-go-v2 v1.39.2 // indirect
1316
github.com/aws/aws-sdk-go-v2/credentials v1.18.3 // indirect
1417
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.2 // indirect
1518
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.9 // indirect
1619
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.9 // indirect
1720
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect
1821
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.0 // indirect
1922
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.2 // indirect
20-
github.com/aws/aws-sdk-go-v2/service/scheduler v1.17.5 // indirect
2123
github.com/aws/aws-sdk-go-v2/service/sso v1.27.0 // indirect
2224
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.32.0 // indirect
2325
github.com/aws/aws-sdk-go-v2/service/sts v1.36.0 // indirect
2426
github.com/aws/smithy-go v1.23.0 // indirect
25-
github.com/joho/godotenv v1.5.1 // indirect
2627
github.com/klauspost/compress v1.15.9 // indirect
2728
github.com/pierrec/lz4/v4 v4.1.15 // indirect
2829
)

go.sum

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
github.com/aws/aws-sdk-go-v2 v1.37.2 h1:xkW1iMYawzcmYFYEV0UCMxc8gSsjCGEhBXQkdQywVbo=
2-
github.com/aws/aws-sdk-go-v2 v1.37.2/go.mod h1:9Q0OoGQoboYIAJyslFyF1f5K1Ryddop8gqMhWx/n4Wg=
31
github.com/aws/aws-sdk-go-v2 v1.39.2 h1:EJLg8IdbzgeD7xgvZ+I8M1e0fL0ptn/M47lianzth0I=
42
github.com/aws/aws-sdk-go-v2 v1.39.2/go.mod h1:sDioUELIUO9Znk23YVmIk86/9DOpkbyyVb1i/gUNFXY=
53
github.com/aws/aws-sdk-go-v2/config v1.30.3 h1:utupeVnE3bmB221W08P0Moz1lDI3OwYa2fBtUhl7TCc=
@@ -8,12 +6,8 @@ github.com/aws/aws-sdk-go-v2/credentials v1.18.3 h1:ptfyXmv+ooxzFwyuBth0yqABcjVI
86
github.com/aws/aws-sdk-go-v2/credentials v1.18.3/go.mod h1:Q43Nci++Wohb0qUh4m54sNln0dbxJw8PvQWkrwOkGOI=
97
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.2 h1:nRniHAvjFJGUCl04F3WaAj7qp/rcz5Gi1OVoj5ErBkc=
108
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.2/go.mod h1:eJDFKAMHHUvv4a0Zfa7bQb//wFNUXGrbFpYRCHe2kD0=
11-
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.2 h1:sPiRHLVUIIQcoVZTNwqQcdtjkqkPopyYmIX0M5ElRf4=
12-
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.2/go.mod h1:ik86P3sgV+Bk7c1tBFCwI3VxMoSEwl4YkRB9xn1s340=
139
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.9 h1:se2vOWGD3dWQUtfn4wEjRQJb1HK1XsNIt825gskZ970=
1410
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.9/go.mod h1:hijCGH2VfbZQxqCDN7bwz/4dzxV+hkyhjawAtdPWKZA=
15-
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.2 h1:ZdzDAg075H6stMZtbD2o+PyB933M/f20e9WmCBC17wA=
16-
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.2/go.mod h1:eE1IIzXG9sdZCB0pNNpMpsYTLl4YdOQD3njiVN1e/E4=
1711
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.9 h1:6RBnKZLkJM4hQ+kN6E7yWFveOTg8NLPHAkqrs4ZPlTU=
1812
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.9/go.mod h1:V9rQKRmK7AWuEsOMnHzKj8WyrIir1yUJbZxDuZLFvXI=
1913
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 h1:bIqFDwgGXXN1Kpp99pDOdKMTTb5d2KyU5X/BZxjOkRo=
@@ -32,8 +26,6 @@ github.com/aws/aws-sdk-go-v2/service/ssooidc v1.32.0 h1:ywQF2N4VjqX+Psw+jLjMmUL2
3226
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.32.0/go.mod h1:Z+qv5Q6b7sWiclvbJyPSOT1BRVU9wfSUPaqQzZ1Xg3E=
3327
github.com/aws/aws-sdk-go-v2/service/sts v1.36.0 h1:bRP/a9llXSSgDPk7Rqn5GD/DQCGo6uk95plBFKoXt2M=
3428
github.com/aws/aws-sdk-go-v2/service/sts v1.36.0/go.mod h1:tgBsFzxwl65BWkuJ/x2EUs59bD4SfYKgikvFDJi1S58=
35-
github.com/aws/smithy-go v1.22.5 h1:P9ATCXPMb2mPjYBgueqJNCA5S9UfktsW0tTxi+a7eqw=
36-
github.com/aws/smithy-go v1.22.5/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI=
3729
github.com/aws/smithy-go v1.23.0 h1:8n6I3gXzWJB2DxBDnfxgBaSX6oe0d/t10qGz7OKqMCE=
3830
github.com/aws/smithy-go v1.23.0/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI=
3931
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@@ -42,6 +34,8 @@ github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
4234
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
4335
github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY=
4436
github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
37+
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
38+
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
4539
github.com/pierrec/lz4/v4 v4.1.15 h1:MO0/ucJhngq7299dKLwIMtgTfbkoSPF6AoMYDd8Q4q0=
4640
github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
4741
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=

internal/config/config.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,23 @@ type Config struct {
2121
EventSessionsKafkaTopic string
2222
SQSSessionSchedulingQueueURL string
2323
SQSSessionSchedulingQueueARN string
24+
SQSSessionRemindersQueueURL string
25+
SQSSessionRemindersQueueARN string
2426
SQSTrendingQueueURL string
2527
SQSTrendingQueueARN string
2628
SchedulerRoleARN string
2729
SchedulerGroupName string
30+
31+
// Database configuration
32+
PostgresDSN string
33+
34+
// Email configuration
35+
SMTPHost string
36+
SMTPPort string
37+
SMTPUsername string
38+
SMTPPassword string
39+
FromEmail string
40+
FromName string
2841
}
2942

3043
// LoadEnv loads environment variables from .env files
@@ -66,10 +79,23 @@ func Load() Config {
6679
EventSessionsKafkaTopic: getEnv("EVENT_SESSIONS_KAFKA_TOPIC", "dbz.ticketly.public.event_sessions"),
6780
SQSSessionSchedulingQueueURL: getEnv("AWS_SQS_SESSION_SCHEDULING_URL", ""),
6881
SQSSessionSchedulingQueueARN: getEnv("AWS_SQS_SESSION_SCHEDULING_ARN", ""),
82+
SQSSessionRemindersQueueURL: getEnv("AWS_SQS_SESSION_REMINDERS_URL", ""),
83+
SQSSessionRemindersQueueARN: getEnv("AWS_SQS_SESSION_REMINDERS_ARN", ""),
6984
SQSTrendingQueueURL: getEnv("AWS_SQS_TRENDING_JOB_URL", ""),
7085
SQSTrendingQueueARN: getEnv("AWS_SQS_TRENDING_JOB_ARN", ""),
7186
SchedulerRoleARN: getEnv("AWS_SCHEDULER_ROLE_ARN", ""),
7287
SchedulerGroupName: getEnv("AWS_SCHEDULER_GROUP_NAME", "default"),
88+
89+
// Database configuration
90+
PostgresDSN: getEnv("POSTGRES_DSN", "host=localhost port=5432 user=postgres password= dbname=ticketly sslmode=disable"),
91+
92+
// Email configuration
93+
SMTPHost: getEnv("SMTP_HOST", "smtp.gmail.com"),
94+
SMTPPort: getEnv("SMTP_PORT", "587"),
95+
SMTPUsername: getEnv("SMTP_USERNAME", ""),
96+
SMTPPassword: getEnv("SMTP_PASSWORD", ""),
97+
FromEmail: getEnv("FROM_EMAIL", "noreply@ticketly.com"),
98+
FromName: getEnv("FROM_NAME", "Ticketly"),
7399
}
74100
}
75101

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
// internal/scheduler/scheduler.go
2-
package scheduler
1+
// internal/eventbridge/scheduler.gopackage eventbridge
2+
3+
package eventbridge
34

45
import (
56
"context"
@@ -31,22 +32,43 @@ func NewService(cfg appconfig.Config, schedulerClient *scheduler.Client) *Servic
3132
}
3233
}
3334

34-
// CreateOrUpdateSchedule handles the idempotent logic for creating/updating a schedule.
35-
func (s *Service) CreateOrUpdateSchedule(sessionID string, scheduleTime time.Time, namePrefix, queueArn, action, logContext string) error {
35+
// CreateOrUpdateSchedule handles the idempotent logic for creating/updating a standard schedule.
36+
func (s *Service) CreateOrUpdateSchedule(sessionID string, scheduleTime time.Time, namePrefix, action, logContext string) error {
37+
// Create standard message body
38+
messageBody := models.SQSMessageBody{
39+
SessionID: sessionID,
40+
Action: action,
41+
}
42+
43+
// Use the common scheduling method with the Session Scheduling Queue ARN
44+
return s.createOrUpdateScheduleWithPayload(sessionID, scheduleTime, namePrefix, s.Config.SQSSessionSchedulingQueueARN, messageBody, logContext)
45+
}
46+
47+
// CreateOrUpdateReminderSchedule creates or updates a reminder-specific schedule
48+
func (s *Service) CreateOrUpdateReminderSchedule(sessionID string, scheduleTime time.Time, namePrefix, action, reminderType, logContext string) error {
49+
// Create reminder-specific message body with additional fields
50+
messageBody := models.SQSReminderMessageBody{
51+
SessionID: sessionID,
52+
Action: action,
53+
ReminderType: reminderType,
54+
TemplateID: "session-reminder-template",
55+
NotificationID: fmt.Sprintf("reminder-%s-%s", reminderType, sessionID),
56+
}
57+
58+
// Use the common scheduling method with the reminder message body
59+
return s.createOrUpdateScheduleWithPayload(sessionID, scheduleTime, namePrefix, s.Config.SQSSessionRemindersQueueARN, messageBody, logContext)
60+
}
61+
62+
// createOrUpdateScheduleWithPayload is a generic method that handles the scheduling logic with any payload
63+
func (s *Service) createOrUpdateScheduleWithPayload(sessionID string, scheduleTime time.Time, namePrefix, queueArn string, payload interface{}, logContext string) error {
3664
scheduleName := namePrefix + sessionID
3765
log.Printf("Creating/updating schedule '%s' at time: %s", scheduleName, scheduleTime)
3866

3967
// Format time for EventBridge Scheduler expression: at(YYYY-MM-DDTHH:mm:ss)
4068
scheduleExpression := fmt.Sprintf("at(%s)", scheduleTime.UTC().Format("2006-01-02T15:04:05"))
4169

42-
// Use the SQSMessageBody struct to ensure consistency between producer and consumer
43-
messageBody := models.SQSMessageBody{
44-
SessionID: sessionID,
45-
Action: action,
46-
}
47-
48-
// Marshal the struct to JSON
49-
inputJSON, err := json.Marshal(messageBody)
70+
// Marshal the payload to JSON
71+
inputJSON, err := json.Marshal(payload)
5072
if err != nil {
5173
log.Printf("Error marshaling message body to JSON: %v", err)
5274
return err

0 commit comments

Comments
 (0)