@vira-ui/cli 0.3.3-alpha → 0.4.0-alpha
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/go/appYaml.js +34 -0
- package/dist/go/backendEnvExample.js +21 -0
- package/dist/go/backendReadme.js +18 -0
- package/dist/go/channelHelpers.js +29 -0
- package/dist/go/configGo.js +262 -0
- package/dist/go/dbGo.js +47 -0
- package/dist/go/dbYaml.js +11 -0
- package/dist/go/dockerCompose.js +38 -0
- package/dist/go/dockerComposeProd.js +54 -0
- package/dist/go/dockerfile.js +19 -0
- package/dist/go/eventHandlerTemplate.js +34 -0
- package/dist/go/eventsAPI.js +414 -0
- package/dist/go/goMod.js +20 -0
- package/dist/go/kafkaGo.js +71 -0
- package/dist/go/kafkaYaml.js +10 -0
- package/dist/go/kanbanHandlers.js +221 -0
- package/dist/go/mainGo.js +527 -0
- package/dist/go/readme.js +14 -0
- package/dist/go/redisGo.js +35 -0
- package/dist/go/redisYaml.js +8 -0
- package/dist/go/registryGo.js +47 -0
- package/dist/go/sqlcYaml.js +17 -0
- package/dist/go/stateStore.js +119 -0
- package/dist/go/typesGo.js +15 -0
- package/dist/go/useViraState.js +160 -0
- package/dist/go/useViraStream.js +167 -0
- package/dist/index.js +608 -190
- package/dist/react/appTsx.js +52 -0
- package/dist/react/envExample.js +7 -0
- package/dist/react/envLocal.js +5 -0
- package/dist/react/indexCss.js +22 -0
- package/dist/react/indexHtml.js +16 -0
- package/dist/react/kanbanAppTsx.js +34 -0
- package/dist/react/kanbanBoard.js +63 -0
- package/dist/react/kanbanCard.js +65 -0
- package/dist/react/kanbanColumn.js +67 -0
- package/dist/react/kanbanModels.js +37 -0
- package/dist/react/kanbanService.js +119 -0
- package/dist/react/mainTsx.js +16 -0
- package/dist/react/tsconfig.js +25 -0
- package/dist/react/viteConfig.js +31 -0
- package/package.json +3 -4
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.appYaml = void 0;
|
|
4
|
+
exports.appYaml = `service: vira-engine
|
|
5
|
+
env: development
|
|
6
|
+
http:
|
|
7
|
+
port: 8080
|
|
8
|
+
logging:
|
|
9
|
+
level: info
|
|
10
|
+
db:
|
|
11
|
+
host: localhost
|
|
12
|
+
port: 5432
|
|
13
|
+
user: vira
|
|
14
|
+
password: vira
|
|
15
|
+
database: vira
|
|
16
|
+
sslmode: disable
|
|
17
|
+
redis:
|
|
18
|
+
host: localhost
|
|
19
|
+
port: 6379
|
|
20
|
+
db: 0
|
|
21
|
+
password: ""
|
|
22
|
+
kafka:
|
|
23
|
+
brokers:
|
|
24
|
+
- localhost:9092
|
|
25
|
+
groupId: vira-engine
|
|
26
|
+
topics:
|
|
27
|
+
events: vira.events
|
|
28
|
+
dlq: vira.events.dlq
|
|
29
|
+
state:
|
|
30
|
+
diffMode: merge # merge | patch
|
|
31
|
+
maxHistory: 100
|
|
32
|
+
persist: memory # memory | redis
|
|
33
|
+
ttlSeconds: 0 # 0 = no TTL
|
|
34
|
+
`;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.backendEnvExample = void 0;
|
|
4
|
+
exports.backendEnvExample = `PORT=8080
|
|
5
|
+
LOG_LEVEL=info
|
|
6
|
+
DB_HOST=localhost
|
|
7
|
+
DB_PORT=5432
|
|
8
|
+
DB_USER=vira
|
|
9
|
+
DB_PASSWORD=vira
|
|
10
|
+
DB_NAME=vira
|
|
11
|
+
DB_SSLMODE=disable
|
|
12
|
+
REDIS_HOST=localhost
|
|
13
|
+
REDIS_PORT=6379
|
|
14
|
+
REDIS_PASSWORD=
|
|
15
|
+
REDIS_DB=0
|
|
16
|
+
KAFKA_BROKERS=localhost:9092
|
|
17
|
+
KAFKA_GROUP_ID=vira-engine
|
|
18
|
+
KAFKA_TOPIC_EVENTS=vira.events
|
|
19
|
+
KAFKA_TOPIC_DLQ=vira.events.dlq
|
|
20
|
+
AUTH_TOKEN=
|
|
21
|
+
`;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.backendReadme = void 0;
|
|
4
|
+
exports.backendReadme = `# Vira Engine Backend (stub)
|
|
5
|
+
|
|
6
|
+
- HTTP сервер на :8080 с chi, middleware (RequestID, RealIP, Recoverer, логирование)
|
|
7
|
+
- Контекст: reqID (Request-ID), userID из X-User-ID
|
|
8
|
+
- Конфиги: config/app.yaml, db.yaml, redis.yaml, kafka.yaml (PORT/LOG_LEVEL/DB_*/REDIS_*/KAFKA_* env override)
|
|
9
|
+
- DB: pgx pool, sqlc.yaml scaffold (queries/, migrations/)
|
|
10
|
+
- Redis: go-redis v9 клиент с health/ping
|
|
11
|
+
- Kafka: kafka-go клиент, health/ping, writer/reader factory
|
|
12
|
+
- Docker: multi-stage Dockerfile для API, docker-compose.prod.yml (API+PG+Redis+Kafka)
|
|
13
|
+
- Дальнейшее: расширить хендлеры, миграции, Kafka outbox, Redis cache
|
|
14
|
+
- TODO: OTEL exporter (traces/logs/metrics)
|
|
15
|
+
|
|
16
|
+
## Быстрый старт
|
|
17
|
+
go run ./cmd/api
|
|
18
|
+
`;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.channelHelpers = void 0;
|
|
4
|
+
exports.channelHelpers = `package events
|
|
5
|
+
|
|
6
|
+
import "fmt"
|
|
7
|
+
|
|
8
|
+
// Channel helpers for common entity scopes.
|
|
9
|
+
func ChannelUser(id any) string {
|
|
10
|
+
return fmt.Sprintf("user:%v", id)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
func ChannelTask(id any) string {
|
|
14
|
+
return fmt.Sprintf("task:%v", id)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
func ChannelNotifications(userID any) string {
|
|
18
|
+
return fmt.Sprintf("notifications:%v", userID)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
func ChannelCustom(name string, key any) string {
|
|
22
|
+
return fmt.Sprintf("%s:%v", name, key)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// ChannelKanban returns a kanban board channel.
|
|
26
|
+
func ChannelKanban(boardID any) string {
|
|
27
|
+
return fmt.Sprintf("kanban:%v", boardID)
|
|
28
|
+
}
|
|
29
|
+
`;
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.configGo = void 0;
|
|
4
|
+
exports.configGo = `package config
|
|
5
|
+
|
|
6
|
+
import (
|
|
7
|
+
"fmt"
|
|
8
|
+
"os"
|
|
9
|
+
"strconv"
|
|
10
|
+
|
|
11
|
+
"github.com/rs/zerolog"
|
|
12
|
+
"gopkg.in/yaml.v3"
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
type Config struct {
|
|
16
|
+
Service string \`yaml:"service"\`
|
|
17
|
+
Env string \`yaml:"env"\`
|
|
18
|
+
HTTP struct {
|
|
19
|
+
Port int \`yaml:"port"\`
|
|
20
|
+
} \`yaml:"http"\`
|
|
21
|
+
Logging struct {
|
|
22
|
+
Level string \`yaml:"level"\`
|
|
23
|
+
} \`yaml:"logging"\`
|
|
24
|
+
DB struct {
|
|
25
|
+
Host string \`yaml:"host"\`
|
|
26
|
+
Port int \`yaml:"port"\`
|
|
27
|
+
User string \`yaml:"user"\`
|
|
28
|
+
Password string \`yaml:"password"\`
|
|
29
|
+
Database string \`yaml:"database"\`
|
|
30
|
+
SSLMode string \`yaml:"sslmode"\`
|
|
31
|
+
} \`yaml:"db"\`
|
|
32
|
+
Kafka struct {
|
|
33
|
+
Brokers []string \`yaml:"brokers"\`
|
|
34
|
+
GroupID string \`yaml:"groupId"\`
|
|
35
|
+
Topics struct {
|
|
36
|
+
Events string \`yaml:"events"\`
|
|
37
|
+
DLQ string \`yaml:"dlq"\`
|
|
38
|
+
} \`yaml:"topics"\`
|
|
39
|
+
} \`yaml:"kafka"\`
|
|
40
|
+
Redis struct {
|
|
41
|
+
Host string \`yaml:"host"\`
|
|
42
|
+
Port int \`yaml:"port"\`
|
|
43
|
+
Password string \`yaml:"password"\`
|
|
44
|
+
DB int \`yaml:"db"\`
|
|
45
|
+
} \`yaml:"redis"\`
|
|
46
|
+
Auth struct {
|
|
47
|
+
Token string \`yaml:"token"\`
|
|
48
|
+
} \`yaml:"auth"\`
|
|
49
|
+
State struct {
|
|
50
|
+
DiffMode string \`yaml:"diffMode"\`
|
|
51
|
+
MaxHistory int \`yaml:"maxHistory"\`
|
|
52
|
+
Persist string \`yaml:"persist"\`
|
|
53
|
+
TTLSec int \`yaml:"ttlSeconds"\`
|
|
54
|
+
} \`yaml:"state"\`
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
func Load(path string) Config {
|
|
58
|
+
var cfg Config
|
|
59
|
+
data, err := os.ReadFile(path)
|
|
60
|
+
if err != nil {
|
|
61
|
+
panic(err)
|
|
62
|
+
}
|
|
63
|
+
if err := yaml.Unmarshal(data, &cfg); err != nil {
|
|
64
|
+
panic(err)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
overrideEnv(&cfg)
|
|
68
|
+
applyDefaults(&cfg)
|
|
69
|
+
return cfg
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
func NewLogger(cfg Config) zerolog.Logger {
|
|
73
|
+
level := parseLevel(cfg.Logging.Level)
|
|
74
|
+
return zerolog.New(os.Stdout).
|
|
75
|
+
Level(level).
|
|
76
|
+
With().
|
|
77
|
+
Timestamp().
|
|
78
|
+
Str("service", cfg.Service).
|
|
79
|
+
Str("env", cfg.Env).
|
|
80
|
+
Logger()
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
func overrideEnv(cfg *Config) {
|
|
84
|
+
if port := os.Getenv("PORT"); port != "" {
|
|
85
|
+
if p := parsePort(port); p > 0 {
|
|
86
|
+
cfg.HTTP.Port = p
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
if lvl := os.Getenv("LOG_LEVEL"); lvl != "" {
|
|
90
|
+
cfg.Logging.Level = lvl
|
|
91
|
+
}
|
|
92
|
+
if host := os.Getenv("DB_HOST"); host != "" {
|
|
93
|
+
cfg.DB.Host = host
|
|
94
|
+
}
|
|
95
|
+
if port := os.Getenv("DB_PORT"); port != "" {
|
|
96
|
+
if p := parsePort(port); p > 0 {
|
|
97
|
+
cfg.DB.Port = p
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if user := os.Getenv("DB_USER"); user != "" {
|
|
101
|
+
cfg.DB.User = user
|
|
102
|
+
}
|
|
103
|
+
if pass := os.Getenv("DB_PASSWORD"); pass != "" {
|
|
104
|
+
cfg.DB.Password = pass
|
|
105
|
+
}
|
|
106
|
+
if db := os.Getenv("DB_NAME"); db != "" {
|
|
107
|
+
cfg.DB.Database = db
|
|
108
|
+
}
|
|
109
|
+
if ssl := os.Getenv("DB_SSLMODE"); ssl != "" {
|
|
110
|
+
cfg.DB.SSLMode = ssl
|
|
111
|
+
}
|
|
112
|
+
if brokers := os.Getenv("KAFKA_BROKERS"); brokers != "" {
|
|
113
|
+
cfg.Kafka.Brokers = splitAndTrim(brokers)
|
|
114
|
+
}
|
|
115
|
+
if group := os.Getenv("KAFKA_GROUP_ID"); group != "" {
|
|
116
|
+
cfg.Kafka.GroupID = group
|
|
117
|
+
}
|
|
118
|
+
if events := os.Getenv("KAFKA_TOPIC_EVENTS"); events != "" {
|
|
119
|
+
cfg.Kafka.Topics.Events = events
|
|
120
|
+
}
|
|
121
|
+
if dlq := os.Getenv("KAFKA_TOPIC_DLQ"); dlq != "" {
|
|
122
|
+
cfg.Kafka.Topics.DLQ = dlq
|
|
123
|
+
}
|
|
124
|
+
if host := os.Getenv("REDIS_HOST"); host != "" {
|
|
125
|
+
cfg.Redis.Host = host
|
|
126
|
+
}
|
|
127
|
+
if port := os.Getenv("REDIS_PORT"); port != "" {
|
|
128
|
+
if p := parsePort(port); p > 0 {
|
|
129
|
+
cfg.Redis.Port = p
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
if pass := os.Getenv("REDIS_PASSWORD"); pass != "" {
|
|
133
|
+
cfg.Redis.Password = pass
|
|
134
|
+
}
|
|
135
|
+
if db := os.Getenv("REDIS_DB"); db != "" {
|
|
136
|
+
if p := parsePort(db); p >= 0 {
|
|
137
|
+
cfg.Redis.DB = p
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
if diff := os.Getenv("DIFF_MODE"); diff != "" {
|
|
141
|
+
cfg.State.DiffMode = diff
|
|
142
|
+
}
|
|
143
|
+
if hist := os.Getenv("DIFF_MAX_HISTORY"); hist != "" {
|
|
144
|
+
if p := parsePort(hist); p > 0 {
|
|
145
|
+
cfg.State.MaxHistory = p
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
if p := os.Getenv("STATE_PERSIST"); p != "" {
|
|
149
|
+
cfg.State.Persist = p
|
|
150
|
+
}
|
|
151
|
+
if ttl := os.Getenv("STATE_TTL_SECONDS"); ttl != "" {
|
|
152
|
+
if p := parsePort(ttl); p >= 0 {
|
|
153
|
+
cfg.State.TTLSec = p
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
func applyDefaults(cfg *Config) {
|
|
159
|
+
if cfg.HTTP.Port == 0 {
|
|
160
|
+
cfg.HTTP.Port = 8080
|
|
161
|
+
}
|
|
162
|
+
if cfg.Service == "" {
|
|
163
|
+
cfg.Service = "vira-engine"
|
|
164
|
+
}
|
|
165
|
+
if cfg.Env == "" {
|
|
166
|
+
cfg.Env = "development"
|
|
167
|
+
}
|
|
168
|
+
if cfg.Logging.Level == "" {
|
|
169
|
+
cfg.Logging.Level = "info"
|
|
170
|
+
}
|
|
171
|
+
if cfg.DB.Port == 0 {
|
|
172
|
+
cfg.DB.Port = 5432
|
|
173
|
+
}
|
|
174
|
+
if cfg.DB.Host == "" {
|
|
175
|
+
cfg.DB.Host = "localhost"
|
|
176
|
+
}
|
|
177
|
+
if cfg.DB.User == "" {
|
|
178
|
+
cfg.DB.User = "vira"
|
|
179
|
+
}
|
|
180
|
+
if cfg.DB.Password == "" {
|
|
181
|
+
cfg.DB.Password = "vira"
|
|
182
|
+
}
|
|
183
|
+
if cfg.DB.Database == "" {
|
|
184
|
+
cfg.DB.Database = "vira"
|
|
185
|
+
}
|
|
186
|
+
if cfg.DB.SSLMode == "" {
|
|
187
|
+
cfg.DB.SSLMode = "disable"
|
|
188
|
+
}
|
|
189
|
+
if len(cfg.Kafka.Brokers) == 0 {
|
|
190
|
+
cfg.Kafka.Brokers = []string{"localhost:9092"}
|
|
191
|
+
}
|
|
192
|
+
if cfg.Kafka.GroupID == "" {
|
|
193
|
+
cfg.Kafka.GroupID = "vira-engine"
|
|
194
|
+
}
|
|
195
|
+
if cfg.Kafka.Topics.Events == "" {
|
|
196
|
+
cfg.Kafka.Topics.Events = "vira.events"
|
|
197
|
+
}
|
|
198
|
+
if cfg.Kafka.Topics.DLQ == "" {
|
|
199
|
+
cfg.Kafka.Topics.DLQ = "vira.events.dlq"
|
|
200
|
+
}
|
|
201
|
+
if cfg.Redis.Port == 0 {
|
|
202
|
+
cfg.Redis.Port = 6379
|
|
203
|
+
}
|
|
204
|
+
if cfg.Redis.Host == "" {
|
|
205
|
+
cfg.Redis.Host = "localhost"
|
|
206
|
+
}
|
|
207
|
+
if cfg.Redis.DB < 0 {
|
|
208
|
+
cfg.Redis.DB = 0
|
|
209
|
+
}
|
|
210
|
+
if token := os.Getenv("AUTH_TOKEN"); token != "" {
|
|
211
|
+
cfg.Auth.Token = token
|
|
212
|
+
}
|
|
213
|
+
if cfg.State.DiffMode == "" {
|
|
214
|
+
cfg.State.DiffMode = "merge" // merge | patch
|
|
215
|
+
}
|
|
216
|
+
if cfg.State.MaxHistory == 0 {
|
|
217
|
+
cfg.State.MaxHistory = 100
|
|
218
|
+
}
|
|
219
|
+
if cfg.State.Persist == "" {
|
|
220
|
+
cfg.State.Persist = "memory" // memory | redis
|
|
221
|
+
}
|
|
222
|
+
if cfg.State.TTLSec < 0 {
|
|
223
|
+
cfg.State.TTLSec = 0
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
func parseLevel(lvl string) zerolog.Level {
|
|
228
|
+
switch lvl {
|
|
229
|
+
case "debug":
|
|
230
|
+
return zerolog.DebugLevel
|
|
231
|
+
case "warn":
|
|
232
|
+
return zerolog.WarnLevel
|
|
233
|
+
case "error":
|
|
234
|
+
return zerolog.ErrorLevel
|
|
235
|
+
case "fatal":
|
|
236
|
+
return zerolog.FatalLevel
|
|
237
|
+
default:
|
|
238
|
+
return zerolog.InfoLevel
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
func parsePort(val string) int {
|
|
243
|
+
var p int
|
|
244
|
+
_, err := fmt.Sscanf(val, "%d", &p)
|
|
245
|
+
if err != nil {
|
|
246
|
+
return 0
|
|
247
|
+
}
|
|
248
|
+
return p
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
func splitAndTrim(val string) []string {
|
|
252
|
+
parts := strings.Split(val, ",")
|
|
253
|
+
out := make([]string, 0, len(parts))
|
|
254
|
+
for _, p := range parts {
|
|
255
|
+
t := strings.TrimSpace(p)
|
|
256
|
+
if t != "" {
|
|
257
|
+
out = append(out, t)
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
return out
|
|
261
|
+
}
|
|
262
|
+
`;
|
package/dist/go/dbGo.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.dbGo = void 0;
|
|
4
|
+
exports.dbGo = `package db
|
|
5
|
+
|
|
6
|
+
import (
|
|
7
|
+
"context"
|
|
8
|
+
"fmt"
|
|
9
|
+
"time"
|
|
10
|
+
|
|
11
|
+
"github.com/jackc/pgx/v5/pgxpool"
|
|
12
|
+
"github.com/rs/zerolog"
|
|
13
|
+
|
|
14
|
+
"vira-engine-backend/internal/config"
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
func NewPool(ctx context.Context, cfg config.Config, logger zerolog.Logger) (*pgxpool.Pool, error) {
|
|
18
|
+
dsn := fmt.Sprintf("postgres://%s:%s@%s:%d/%s?sslmode=%s",
|
|
19
|
+
cfg.DB.User,
|
|
20
|
+
cfg.DB.Password,
|
|
21
|
+
cfg.DB.Host,
|
|
22
|
+
cfg.DB.Port,
|
|
23
|
+
cfg.DB.Database,
|
|
24
|
+
cfg.DB.SSLMode,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
poolConfig, err := pgxpool.ParseConfig(dsn)
|
|
28
|
+
if err != nil {
|
|
29
|
+
return nil, fmt.Errorf("parse pool config: %w", err)
|
|
30
|
+
}
|
|
31
|
+
poolConfig.MaxConnLifetime = time.Hour
|
|
32
|
+
poolConfig.MaxConnIdleTime = 30 * time.Minute
|
|
33
|
+
poolConfig.HealthCheckPeriod = 30 * time.Second
|
|
34
|
+
|
|
35
|
+
pool, err := pgxpool.NewWithConfig(ctx, poolConfig)
|
|
36
|
+
if err != nil {
|
|
37
|
+
return nil, fmt.Errorf("create pool: %w", err)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if err := pool.Ping(ctx); err != nil {
|
|
41
|
+
return nil, fmt.Errorf("ping db: %w", err)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
logger.Info().Str("db.host", cfg.DB.Host).Int("db.port", cfg.DB.Port).Msg("db pool ready")
|
|
45
|
+
return pool, nil
|
|
46
|
+
}
|
|
47
|
+
`;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.dockerCompose = void 0;
|
|
4
|
+
exports.dockerCompose = `version: "3.9"
|
|
5
|
+
services:
|
|
6
|
+
postgres:
|
|
7
|
+
image: postgres:15
|
|
8
|
+
environment:
|
|
9
|
+
POSTGRES_USER: vira
|
|
10
|
+
POSTGRES_PASSWORD: vira
|
|
11
|
+
POSTGRES_DB: vira
|
|
12
|
+
ports:
|
|
13
|
+
- "5432:5432"
|
|
14
|
+
|
|
15
|
+
redis:
|
|
16
|
+
image: redis:7
|
|
17
|
+
ports:
|
|
18
|
+
- "6379:6379"
|
|
19
|
+
|
|
20
|
+
zookeeper:
|
|
21
|
+
image: bitnami/zookeeper:3.9
|
|
22
|
+
environment:
|
|
23
|
+
ALLOW_ANONYMOUS_LOGIN: "yes"
|
|
24
|
+
ports:
|
|
25
|
+
- "2181:2181"
|
|
26
|
+
|
|
27
|
+
kafka:
|
|
28
|
+
image: bitnami/kafka:3.6
|
|
29
|
+
environment:
|
|
30
|
+
KAFKA_CFG_ZOOKEEPER_CONNECT: zookeeper:2181
|
|
31
|
+
KAFKA_CFG_LISTENERS: PLAINTEXT://:9092
|
|
32
|
+
KAFKA_CFG_ADVERTISED_LISTENERS: PLAINTEXT://localhost:9092
|
|
33
|
+
ALLOW_PLAINTEXT_LISTENER: "yes"
|
|
34
|
+
depends_on:
|
|
35
|
+
- zookeeper
|
|
36
|
+
ports:
|
|
37
|
+
- "9092:9092"
|
|
38
|
+
`;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.dockerComposeProd = void 0;
|
|
4
|
+
exports.dockerComposeProd = `version: "3.9"
|
|
5
|
+
services:
|
|
6
|
+
postgres:
|
|
7
|
+
image: postgres:15
|
|
8
|
+
environment:
|
|
9
|
+
POSTGRES_USER: vira
|
|
10
|
+
POSTGRES_PASSWORD: vira
|
|
11
|
+
POSTGRES_DB: vira
|
|
12
|
+
volumes:
|
|
13
|
+
- pgdata:/var/lib/postgresql/data
|
|
14
|
+
|
|
15
|
+
redis:
|
|
16
|
+
image: redis:7
|
|
17
|
+
command: ["redis-server", "--appendonly", "yes"]
|
|
18
|
+
volumes:
|
|
19
|
+
- redisdata:/data
|
|
20
|
+
|
|
21
|
+
kafka:
|
|
22
|
+
image: bitnami/kafka:3.6
|
|
23
|
+
environment:
|
|
24
|
+
KAFKA_CFG_LISTENERS: PLAINTEXT://:9092
|
|
25
|
+
KAFKA_CFG_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092
|
|
26
|
+
ALLOW_PLAINTEXT_LISTENER: "yes"
|
|
27
|
+
ports:
|
|
28
|
+
- "9092:9092"
|
|
29
|
+
|
|
30
|
+
api:
|
|
31
|
+
build:
|
|
32
|
+
context: ../backend
|
|
33
|
+
depends_on:
|
|
34
|
+
- postgres
|
|
35
|
+
- redis
|
|
36
|
+
- kafka
|
|
37
|
+
environment:
|
|
38
|
+
PORT: 8080
|
|
39
|
+
DB_HOST: postgres
|
|
40
|
+
DB_PORT: 5432
|
|
41
|
+
DB_USER: vira
|
|
42
|
+
DB_PASSWORD: vira
|
|
43
|
+
DB_NAME: vira
|
|
44
|
+
DB_SSLMODE: disable
|
|
45
|
+
REDIS_HOST: redis
|
|
46
|
+
REDIS_PORT: 6379
|
|
47
|
+
KAFKA_BROKERS: kafka:9092
|
|
48
|
+
ports:
|
|
49
|
+
- "8080:8080"
|
|
50
|
+
|
|
51
|
+
volumes:
|
|
52
|
+
pgdata:
|
|
53
|
+
redisdata:
|
|
54
|
+
`;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.dockerfile = void 0;
|
|
4
|
+
exports.dockerfile = `# ---- build stage ----
|
|
5
|
+
FROM golang:1.21-alpine AS builder
|
|
6
|
+
WORKDIR /app
|
|
7
|
+
COPY go.mod go.sum ./
|
|
8
|
+
RUN go mod download
|
|
9
|
+
COPY . .
|
|
10
|
+
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o /app/bin/vira-api ./cmd/api
|
|
11
|
+
|
|
12
|
+
# ---- runtime stage ----
|
|
13
|
+
FROM gcr.io/distroless/base-debian12:nonroot
|
|
14
|
+
WORKDIR /app
|
|
15
|
+
COPY --from=builder /app/bin/vira-api /app/vira-api
|
|
16
|
+
COPY config ./config
|
|
17
|
+
EXPOSE 8080
|
|
18
|
+
ENTRYPOINT ["/app/vira-api"]
|
|
19
|
+
`;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.eventHandlerTemplate = void 0;
|
|
4
|
+
const eventHandlerTemplate = (name) => {
|
|
5
|
+
const pascal = name
|
|
6
|
+
.split(/[^a-zA-Z0-9]+/)
|
|
7
|
+
.filter(Boolean)
|
|
8
|
+
.map((s) => s[0].toUpperCase() + s.slice(1))
|
|
9
|
+
.join("");
|
|
10
|
+
return `package events
|
|
11
|
+
|
|
12
|
+
import (
|
|
13
|
+
"context"
|
|
14
|
+
"encoding/json"
|
|
15
|
+
"github.com/gorilla/websocket"
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
// ${pascal} handles event: ${name}
|
|
19
|
+
func ${pascal}(ctx context.Context, hub EventEmitter, conn *websocket.Conn, msg WSMessage) {
|
|
20
|
+
var payload map[string]any
|
|
21
|
+
if len(msg.Data) > 0 {
|
|
22
|
+
_ = json.Unmarshal(msg.Data, &payload)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// TODO: implement domain logic here
|
|
26
|
+
// Example: hub.Emit(ChannelCustom("demo", "echo"), payload)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
func init() {
|
|
30
|
+
Register("${name}", ${pascal})
|
|
31
|
+
}
|
|
32
|
+
`;
|
|
33
|
+
};
|
|
34
|
+
exports.eventHandlerTemplate = eventHandlerTemplate;
|