Skip to content

Commit 2249a90

Browse files
committed
1 parent dd52f56 commit 2249a90

4 files changed

Lines changed: 315 additions & 8 deletions

File tree

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
package polycode
22

3-
type RealtimeChannel struct {
3+
type ClientChannel struct {
44
name string
55
sessionId string
66
serviceClient *ServiceClient
77
}
88

9-
func (r RealtimeChannel) Emit(data any) error {
9+
func (r ClientChannel) Emit(data any) error {
1010
req := RealtimeEventEmitRequest{
1111
Channel: r.name,
1212
Input: data,

polycode/config.go

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"encoding/json"
66
"errors"
7+
"time"
78
)
89

910
type AppConfig map[string]interface{}
@@ -26,3 +27,70 @@ func FromAppConfig(ctx context.Context, configObj any) error {
2627

2728
return errors.New("invalid context")
2829
}
30+
31+
type ConfigScope uint64
32+
33+
const (
34+
Global ConfigScope = iota
35+
App
36+
)
37+
38+
type Config struct {
39+
Id string `polycode:"id" json:"id"`
40+
Name string `json:"name"`
41+
Value string `json:"value"`
42+
Version uint64 `json:"version"`
43+
IsSecret bool `json:"isSecret"`
44+
Type string `json:"type"`
45+
Scope ConfigScope `json:"scope"`
46+
Group string `json:"group"`
47+
App string `json:"app"`
48+
CreatedBy string `json:"createdBy"`
49+
CreatedAt time.Time `json:"createdAt"`
50+
UpdatedBy string `json:"updatedBy"`
51+
UpdatedAt time.Time `json:"updatedAt"`
52+
}
53+
54+
type GetConfigRequest struct {
55+
Id string `json:"id"`
56+
}
57+
58+
type ConfigGroup struct {
59+
Name string `polycode:"id" json:"name"`
60+
}
61+
62+
type AuditTrail struct {
63+
Id string `polycode:"id" json:"id"`
64+
ConfigId string `json:"configId"`
65+
ConfigName string `json:"configName"`
66+
Action string `json:"action"`
67+
OldValue string `json:"oldValue"`
68+
NewValue string `json:"newValue"`
69+
User string `json:"user"`
70+
Timestamp time.Time `json:"timestamp"`
71+
IsSecret bool `json:"isSecret"`
72+
}
73+
74+
type SaveConfigRequest struct {
75+
Name string `json:"name"`
76+
Value string `json:"value"`
77+
IsSecret bool `json:"isSecret"`
78+
Type string `json:"type"`
79+
Scope ConfigScope `json:"scope"`
80+
Group string `json:"group"`
81+
App string `json:"app"`
82+
}
83+
84+
type ListConfigGroupsRequest struct {
85+
}
86+
87+
type CreateConfigGroupRequest struct {
88+
Name string `polycode:"id" json:"name"`
89+
}
90+
91+
type ListConfigRequest struct {
92+
Name string `json:"name"`
93+
Scope ConfigScope `json:"scope"`
94+
Group string `json:"group"`
95+
App string `json:"app"`
96+
}

polycode/configstore.go

Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
package polycode
2+
3+
import (
4+
"errors"
5+
"fmt"
6+
"time"
7+
)
8+
9+
type ParamWrapper struct {
10+
collection Collection
11+
exist bool
12+
config Config
13+
}
14+
15+
func (p *ParamWrapper) IsExist() bool {
16+
return p.exist
17+
}
18+
19+
func (p *ParamWrapper) Get() (string, error) {
20+
if !p.exist {
21+
return "", errors.New("config not found")
22+
}
23+
24+
return p.config.Value, nil
25+
}
26+
27+
func (p *ParamWrapper) Set(value string) error {
28+
p.config = Config{
29+
Id: p.config.Id,
30+
Name: p.config.Name,
31+
Value: value,
32+
Version: p.config.Version + 1,
33+
IsSecret: p.config.IsSecret,
34+
Type: p.config.Type,
35+
Scope: p.config.Scope,
36+
Group: p.config.Group,
37+
CreatedBy: p.config.CreatedBy,
38+
CreatedAt: p.config.CreatedAt,
39+
UpdatedAt: time.Now(),
40+
}
41+
42+
err := p.collection.UpsertOne(p.config)
43+
if err != nil {
44+
return err
45+
}
46+
47+
p.exist = true
48+
return nil
49+
}
50+
51+
type ParamStore struct {
52+
collection Collection
53+
}
54+
55+
func (p ParamStore) GlobalVar(group string, name string) (ParamWrapper, error) {
56+
config := Config{}
57+
exist, err := p.collection.GetOne(name, &config)
58+
if err != nil {
59+
return ParamWrapper{}, err
60+
}
61+
62+
if exist {
63+
if config.Group != group {
64+
return ParamWrapper{}, errors.New("config group mismatch")
65+
}
66+
67+
if config.IsSecret {
68+
return ParamWrapper{}, errors.New("config is secret")
69+
}
70+
71+
return ParamWrapper{
72+
collection: p.collection,
73+
exist: true,
74+
config: config,
75+
}, nil
76+
} else {
77+
return ParamWrapper{
78+
collection: p.collection,
79+
exist: false,
80+
config: Config{
81+
Id: name,
82+
Name: name,
83+
Value: "",
84+
Version: 0,
85+
IsSecret: false,
86+
Type: "string",
87+
Scope: Global,
88+
App: "",
89+
Group: group,
90+
CreatedBy: "",
91+
CreatedAt: time.Now(),
92+
UpdatedBy: "",
93+
UpdatedAt: time.Now(),
94+
},
95+
}, nil
96+
}
97+
}
98+
99+
func (p ParamStore) GlobalSecret(group string, name string) (ParamWrapper, error) {
100+
config := Config{}
101+
exist, err := p.collection.GetOne(name, &config)
102+
if err != nil {
103+
return ParamWrapper{}, err
104+
}
105+
106+
if exist {
107+
if config.Group != group {
108+
return ParamWrapper{}, errors.New("config group mismatch")
109+
}
110+
111+
if !config.IsSecret {
112+
return ParamWrapper{}, errors.New("config is var")
113+
}
114+
115+
return ParamWrapper{
116+
collection: p.collection,
117+
exist: true,
118+
config: config,
119+
}, nil
120+
} else {
121+
return ParamWrapper{
122+
collection: p.collection,
123+
exist: false,
124+
config: Config{
125+
Id: name,
126+
Name: name,
127+
Value: "",
128+
Version: 0,
129+
IsSecret: true,
130+
Type: "string",
131+
Scope: Global,
132+
App: "",
133+
Group: group,
134+
CreatedBy: "",
135+
CreatedAt: time.Now(),
136+
UpdatedBy: "",
137+
UpdatedAt: time.Now(),
138+
},
139+
}, nil
140+
}
141+
}
142+
143+
func (p ParamStore) AppVar(group string, name string) (ParamWrapper, error) {
144+
id := fmt.Sprintf("%s::%s", group, name)
145+
146+
config := Config{}
147+
exist, err := p.collection.GetOne(id, &config)
148+
if err != nil {
149+
return ParamWrapper{}, err
150+
}
151+
152+
if exist {
153+
if config.Group != group {
154+
return ParamWrapper{}, errors.New("config group mismatch")
155+
}
156+
157+
if config.IsSecret {
158+
return ParamWrapper{}, errors.New("config is secret")
159+
}
160+
161+
return ParamWrapper{
162+
collection: p.collection,
163+
exist: true,
164+
config: config,
165+
}, nil
166+
} else {
167+
return ParamWrapper{
168+
collection: p.collection,
169+
exist: false,
170+
config: Config{
171+
Id: id,
172+
Name: name,
173+
Value: "",
174+
Version: 0,
175+
IsSecret: false,
176+
Type: "string",
177+
Scope: App,
178+
App: GetClientEnv().AppName,
179+
Group: group,
180+
CreatedBy: "",
181+
CreatedAt: time.Now(),
182+
UpdatedBy: "",
183+
UpdatedAt: time.Now(),
184+
},
185+
}, nil
186+
}
187+
}
188+
189+
func (p ParamStore) AppSecret(group string, name string) (ParamWrapper, error) {
190+
id := fmt.Sprintf("%s::%s", group, name)
191+
192+
config := Config{}
193+
exist, err := p.collection.GetOne(id, &config)
194+
if err != nil {
195+
return ParamWrapper{}, err
196+
}
197+
198+
if exist {
199+
if config.Group != group {
200+
return ParamWrapper{}, errors.New("config group mismatch")
201+
}
202+
203+
if !config.IsSecret {
204+
return ParamWrapper{}, errors.New("config is var")
205+
}
206+
207+
return ParamWrapper{
208+
collection: p.collection,
209+
exist: true,
210+
config: config,
211+
}, nil
212+
} else {
213+
return ParamWrapper{
214+
collection: p.collection,
215+
exist: false,
216+
config: Config{
217+
Id: id,
218+
Name: name,
219+
Value: "",
220+
Version: 0,
221+
IsSecret: false,
222+
Type: "string",
223+
Scope: App,
224+
App: GetClientEnv().AppName,
225+
Group: group,
226+
CreatedBy: "",
227+
CreatedAt: time.Now(),
228+
UpdatedBy: "",
229+
UpdatedAt: time.Now(),
230+
},
231+
}, nil
232+
}
233+
}

polycode/context.go

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,14 @@ type BaseContext interface {
1515
AppConfig() AppConfig
1616
AuthContext() AuthContext
1717
Logger() Logger
18+
ParamStore() ParamStore
19+
UnsafeDb() *UnsafeDataStoreBuilder
20+
FileStore() FileStore
1821
}
1922

2023
type ServiceContext interface {
2124
BaseContext
2225
Db() DataStore
23-
UnsafeDb() *UnsafeDataStoreBuilder
24-
FileStore() FileStore
2526
}
2627

2728
type WorkflowContext interface {
@@ -32,10 +33,9 @@ type WorkflowContext interface {
3233
AppEx(envId string, appName string) RemoteApp
3334
Controller(controller string) RemoteController
3435
ControllerEx(envId string, controller string) RemoteController
35-
UnsafeDb() *UnsafeDataStoreBuilder
3636
Memo(getter func() (any, error)) Response
3737
Signal(signalName string) Signal
38-
RealtimeChannel(channelName string) RealtimeChannel
38+
ClientChannel(channelName string) ClientChannel
3939
}
4040

4141
type ApiContext interface {
@@ -91,6 +91,12 @@ func (s ContextImpl) Db() DataStore {
9191
return s.dataStore
9292
}
9393

94+
func (s ContextImpl) ParamStore() ParamStore {
95+
return ParamStore{
96+
collection: s.Db().Collection("config"),
97+
}
98+
}
99+
94100
func (s ContextImpl) FileStore() FileStore {
95101
return s.fileStore
96102
}
@@ -150,8 +156,8 @@ func (s ContextImpl) Signal(signalName string) Signal {
150156
}
151157
}
152158

153-
func (s ContextImpl) RealtimeChannel(channelName string) RealtimeChannel {
154-
return RealtimeChannel{
159+
func (s ContextImpl) ClientChannel(channelName string) ClientChannel {
160+
return ClientChannel{
155161
name: channelName,
156162
sessionId: s.sessionId,
157163
serviceClient: s.serviceClient,

0 commit comments

Comments
 (0)