feat: Add DatabaseConfig to carrier-connector config and remove InMemoryProfileStore implementation for Postgres migration

- Add DatabaseConfig struct with DSN field for Postgres connection string
- Add package documentation comments for ES2Config/DatabaseConfig/LoadES2Config
- Normalize ES2Config field alignment for BaseURL/APIKey/InsecureSkipVerify/FunctionalityRequesterID
- Remove InMemoryProfileStore struct and all methods (Create/Get/List/UpdateState/Delete) from profile.go
- Remove sync package import
This commit is contained in:
nutcas3
2026-04-24 08:59:44 +03:00
parent cb8b6c4d96
commit d27eb871e3
2 changed files with 17 additions and 105 deletions
@@ -1,17 +1,24 @@
package config
// ES2Config configures the upstream SM-DP+ ES2+ connection.
type ES2Config struct {
BaseURL string `json:"base_url"`
APIKey string `json:"api_key"`
InsecureSkipVerify bool `json:"insecure_skip_verify"`
BaseURL string `json:"base_url"`
APIKey string `json:"api_key"`
InsecureSkipVerify bool `json:"insecure_skip_verify"`
FunctionalityRequesterID string `json:"functionality_requester_id"`
}
// DatabaseConfig configures the Postgres connection for the profile repository.
type DatabaseConfig struct {
DSN string `json:"dsn"` // e.g. "host=localhost user=telecom password=... dbname=carrier port=5432 sslmode=disable"
}
// LoadES2Config returns default ES2+ configuration (override via env in main).
func LoadES2Config() *ES2Config {
return &ES2Config{
BaseURL: "https://smdp.example.com",
APIKey: "",
InsecureSkipVerify: true,
BaseURL: "https://smdp.example.com",
APIKey: "",
InsecureSkipVerify: true,
FunctionalityRequesterID: "telecom-platform",
}
}
@@ -1,10 +1,9 @@
package repository
import (
"context"
"errors"
"sync"
"time"
"context"
"errors"
"time"
)
// ErrNotFound is returned when a profile lookup misses.
@@ -18,7 +17,7 @@ type Profile struct {
MCC string `json:"mcc"`
MNC string `json:"mnc"`
ProfileType string `json:"profileType"`
State string `json:"state"` // e.g. provisioned, active, disabled, deleted
State string `json:"state"`
TenantID string `json:"tenantId,omitempty"`
ActivationCode string `json:"activationCode,omitempty"`
CreatedAt time.Time `json:"createdAt"`
@@ -41,97 +40,3 @@ type ProfileRepository interface {
UpdateState(ctx context.Context, iccid, state string) (*Profile, error)
Delete(ctx context.Context, iccid string) error
}
// InMemoryProfileStore is an in-memory ProfileRepository.
// Safe for concurrent use. Intended as a development default; production
// deployments should swap in a Postgres-backed implementation.
type InMemoryProfileStore struct {
mu sync.RWMutex
profiles map[string]*Profile
}
// NewInMemoryProfileStore constructs an empty InMemoryProfileStore.
func NewInMemoryProfileStore() *InMemoryProfileStore {
return &InMemoryProfileStore{profiles: make(map[string]*Profile)}
}
// Create inserts a profile. Returns an error if the ICCID already exists.
func (s *InMemoryProfileStore) Create(_ context.Context, p *Profile) error {
s.mu.Lock()
defer s.mu.Unlock()
if _, exists := s.profiles[p.ICCID]; exists {
return errors.New("profile already exists")
}
now := time.Now().UTC()
p.CreatedAt = now
p.UpdatedAt = now
cp := *p
s.profiles[p.ICCID] = &cp
return nil
}
// Get returns a profile by ICCID or ErrNotFound.
func (s *InMemoryProfileStore) Get(_ context.Context, iccid string) (*Profile, error) {
s.mu.RLock()
defer s.mu.RUnlock()
p, ok := s.profiles[iccid]
if !ok {
return nil, ErrNotFound
}
cp := *p
return &cp, nil
}
// List returns a filtered, paginated snapshot of profiles.
func (s *InMemoryProfileStore) List(_ context.Context, f ListFilter) ([]*Profile, int, error) {
s.mu.RLock()
defer s.mu.RUnlock()
matched := make([]*Profile, 0, len(s.profiles))
for _, p := range s.profiles {
if f.TenantID != "" && p.TenantID != f.TenantID {
continue
}
if f.State != "" && p.State != f.State {
continue
}
cp := *p
matched = append(matched, &cp)
}
total := len(matched)
start := f.Offset
if start > total {
start = total
}
end := total
if f.Limit > 0 && start+f.Limit < total {
end = start + f.Limit
}
return matched[start:end], total, nil
}
// UpdateState updates a profile's state and UpdatedAt timestamp.
func (s *InMemoryProfileStore) UpdateState(_ context.Context, iccid, state string) (*Profile, error) {
s.mu.Lock()
defer s.mu.Unlock()
p, ok := s.profiles[iccid]
if !ok {
return nil, ErrNotFound
}
p.State = state
p.UpdatedAt = time.Now().UTC()
cp := *p
return &cp, nil
}
// Delete removes a profile.
func (s *InMemoryProfileStore) Delete(_ context.Context, iccid string) error {
s.mu.Lock()
defer s.mu.Unlock()
if _, ok := s.profiles[iccid]; !ok {
return ErrNotFound
}
delete(s.profiles, iccid)
return nil
}