Documentation
¶
Overview ¶
Package pilot holds the pilot access list: who may register, and keep using the service, while the pilot access gate is on.
A person is approved per phone number and national ID. Both must match an active pilot_users row. One person may hold several rows (each new SIM is re-approved), so revoking and restoring act on every row sharing the national ID.
Index ¶
- Variables
- func NormalizeNationalID(id string) string
- func NormalizePhone(s string) string
- type Gate
- type Selector
- type Store
- func (s *Store) Add(ctx context.Context, u User) (User, error)
- func (s *Store) Get(ctx context.Context, number string) (User, error)
- func (s *Store) List(ctx context.Context, includeRevoked bool) ([]User, error)
- func (s *Store) Matches(ctx context.Context, number, nationalID string) (bool, error)
- func (s *Store) PendingInvites(ctx context.Context) ([]User, error)
- func (s *Store) PhoneActive(ctx context.Context, number string) (bool, error)
- func (s *Store) RecordInvite(ctx context.Context, number string, sendErr error) error
- func (s *Store) Registered(ctx context.Context, number string) (bool, error)
- func (s *Store) Restore(ctx context.Context, sel Selector) ([]User, error)
- func (s *Store) Revoke(ctx context.Context, sel Selector, reason string) ([]User, error)
- func (s *Store) Unlisted(ctx context.Context) ([]Unlisted, error)
- func (s *Store) UserActive(ctx context.Context, userID string) (bool, error)
- type Unlisted
- type User
Constants ¶
This section is empty.
Variables ¶
var ErrNotFound = errors.New("pilot: not found")
ErrNotFound is a phone number or national ID with no pilot_users row.
Functions ¶
func NormalizeNationalID ¶
NormalizeNationalID strips whitespace and upper-cases id.
func NormalizePhone ¶
NormalizePhone returns phone as country code and subscriber digits with no leading +, the form users.mobile_number holds, reading 07…/01… as Kenyan. It returns "" when the number cannot be resolved.
Types ¶
type Gate ¶
type Gate interface {
// PhoneActive reports whether number has an active row.
PhoneActive(ctx context.Context, number string) (bool, error)
// Matches reports whether number has an active row for nationalID.
Matches(ctx context.Context, number, nationalID string) (bool, error)
// UserActive reports whether a registered user's current phone number and
// national ID match an active row.
UserActive(ctx context.Context, userID string) (bool, error)
}
Gate answers access questions while the pilot access gate is on. A nil Gate means the gate is off.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store is the Postgres-backed pilot list.
func (*Store) Add ¶
Add inserts u, or updates the row for its phone number and clears any revoke on it. Phone and national ID are normalised; Language defaults to en.
func (*Store) PendingInvites ¶
PendingInvites returns active rows never invited whose number has not registered.
func (*Store) PhoneActive ¶
PhoneActive implements Gate.
func (*Store) RecordInvite ¶
RecordInvite records one invite attempt for number: a success stamps invited_at, a failure only the error. Both count the attempt.
func (*Store) Registered ¶
Registered reports whether number already belongs to a registered user.
func (*Store) Restore ¶
Restore clears the revoke on every row for the selected person and returns them.
type Unlisted ¶
Unlisted is a registered user without an active row matching both their phone number and national ID.
type User ¶
type User struct {
PhoneNumber string `gorm:"primaryKey"`
NationalID string
FullName string
Language string
Note *string
AddedBy *string
CreatedAt time.Time
UpdatedAt time.Time
RevokedAt *time.Time
RevokedReason *string
InvitedAt *time.Time
InviteCount int
LastInviteError *string
}
User is one pilot_users row.