97 lines
2.0 KiB
Go
97 lines
2.0 KiB
Go
// Package leads : gestion des prospects (feature "leads" du back-office).
|
|
package leads
|
|
|
|
import (
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
type Status string
|
|
|
|
const (
|
|
StatusNew Status = "new"
|
|
StatusContacted Status = "contacted"
|
|
StatusDemo Status = "demo"
|
|
StatusWon Status = "won"
|
|
StatusLost Status = "lost"
|
|
)
|
|
|
|
func (s Status) Valid() bool {
|
|
switch s {
|
|
case StatusNew, StatusContacted, StatusDemo, StatusWon, StatusLost:
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
// Lead : prospect. Modèle GORM.
|
|
type Lead struct {
|
|
ID string `gorm:"type:uuid;primaryKey" json:"id"`
|
|
Telegram string `gorm:"size:120;not null" json:"telegram"`
|
|
Message string `gorm:"size:2000" json:"message"`
|
|
Status Status `gorm:"size:20;not null;index" json:"status"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
}
|
|
|
|
// TableName force le nom de table.
|
|
func (Lead) TableName() string { return "leads" }
|
|
|
|
// Store : persistance des leads. Impl mémoire ici, Postgres plus tard.
|
|
type Store interface {
|
|
Create(l Lead) (Lead, error)
|
|
List() ([]Lead, error)
|
|
Get(id string) (Lead, bool)
|
|
SetStatus(id string, s Status) (Lead, bool)
|
|
}
|
|
|
|
// MemStore : implémentation en mémoire (dev/tests).
|
|
type MemStore struct {
|
|
mu sync.RWMutex
|
|
items map[string]Lead
|
|
}
|
|
|
|
func NewMemStore() *MemStore {
|
|
return &MemStore{items: make(map[string]Lead)}
|
|
}
|
|
|
|
func (m *MemStore) Create(l Lead) (Lead, error) {
|
|
m.mu.Lock()
|
|
defer m.mu.Unlock()
|
|
l.ID = uuid.NewString()
|
|
l.Status = StatusNew
|
|
l.CreatedAt = time.Now().UTC()
|
|
m.items[l.ID] = l
|
|
return l, nil
|
|
}
|
|
|
|
func (m *MemStore) List() ([]Lead, error) {
|
|
m.mu.RLock()
|
|
defer m.mu.RUnlock()
|
|
out := make([]Lead, 0, len(m.items))
|
|
for _, l := range m.items {
|
|
out = append(out, l)
|
|
}
|
|
return out, nil
|
|
}
|
|
|
|
func (m *MemStore) Get(id string) (Lead, bool) {
|
|
m.mu.RLock()
|
|
defer m.mu.RUnlock()
|
|
l, ok := m.items[id]
|
|
return l, ok
|
|
}
|
|
|
|
func (m *MemStore) SetStatus(id string, s Status) (Lead, bool) {
|
|
m.mu.Lock()
|
|
defer m.mu.Unlock()
|
|
l, ok := m.items[id]
|
|
if !ok {
|
|
return Lead{}, false
|
|
}
|
|
l.Status = s
|
|
m.items[id] = l
|
|
return l, true
|
|
}
|