From 2fc8a0e5a7cbffafce8fa1904c5c200d1d9919c7 Mon Sep 17 00:00:00 2001
From: Carlosokumu <carlosokumu254@gmail.com>
Date: Wed, 4 Sep 2024 19:57:08 +0300
Subject: [PATCH 01/47] use fsDb for the resources

---
 cmd/main.go | 62 ++++++++++++++++++++++++++---------------------------
 1 file changed, 30 insertions(+), 32 deletions(-)

diff --git a/cmd/main.go b/cmd/main.go
index 72d1d11..017f150 100644
--- a/cmd/main.go
+++ b/cmd/main.go
@@ -11,6 +11,7 @@ import (
 	"strconv"
 
 	"git.defalsify.org/vise.git/cache"
+	fsdb "git.defalsify.org/vise.git/db/fs"
 	"git.defalsify.org/vise.git/engine"
 	"git.defalsify.org/vise.git/persist"
 	"git.defalsify.org/vise.git/resource"
@@ -20,8 +21,20 @@ import (
 
 var (
 	scriptDir = path.Join("services", "registration")
+	store     = fsdb.NewFsDb()
+	pr        = persist.NewPersister(store)
 )
 
+type menuResource struct {
+	*resource.DbResource
+}
+
+func newMenuResource(rs *resource.DbResource) resource.Resource {
+	return &menuResource{
+		rs,
+	}
+}
+
 func main() {
 	var dir string
 	var root string
@@ -35,8 +48,6 @@ func main() {
 	fmt.Fprintf(os.Stderr, "starting session at symbol '%s' using resource dir: %s\n", root, dir)
 
 	ctx := context.Background()
-	st := state.NewState(16)
-	st.UseDebug()
 
 	pfp := path.Join(scriptDir, "pp.csv")
 	file, err := os.Open(pfp)
@@ -74,11 +85,11 @@ func main() {
 		state.FlagDebugger.Register(uint32(flagValue), flagName)
 	}
 
-	rfs := resource.NewFsResource(scriptDir)
 	ca := cache.NewCache()
 	cfg := engine.Config{
 		Root:      "root",
 		SessionId: sessionId,
+		FlagCount: uint32(16),
 	}
 
 	dp := path.Join(scriptDir, ".state")
@@ -87,25 +98,26 @@ func main() {
 		fmt.Fprintf(os.Stderr, "state dir create exited with error: %v\n", err)
 		os.Exit(1)
 	}
-	pr := persist.NewFsPersister(dp)
-	en, err := engine.NewPersistedEngine(ctx, cfg, pr, rfs)
 
+	store := fsdb.NewFsDb()
+	err = store.Connect(ctx, scriptDir)
 	if err != nil {
-		pr = pr.WithContent(&st, ca)
-		err = pr.Save(cfg.SessionId)
-		if err != nil {
-			fmt.Fprintf(os.Stderr, "Failed to save state with error: %v\n", err)
-		}
-		en, err = engine.NewPersistedEngine(ctx, cfg, pr, rfs)
-		if err != nil {
-			fmt.Fprintf(os.Stderr, "engine create exited with error: %v\n", err)
-			os.Exit(1)
-		}
+		panic(err)
 	}
 
+	rfs := resource.NewDbResource(store)
+
+	rs, ok := newMenuResource(rfs).(*menuResource)
+	if !ok {
+		os.Exit(1)
+	}
+	en := engine.NewEngine(cfg, rs)
+	en = en.WithMemory(ca)
+	en = en.WithPersister(pr)
+
 	fp := path.Join(dp, sessionId)
 
-	ussdHandlers, err := ussd.NewHandlers(fp, &st,sessionId)
+	ussdHandlers, err := ussd.NewHandlers(fp, pr.State, sessionId)
 
 	if err != nil {
 		fmt.Fprintf(os.Stderr, "handler setup failed with error: %v\n", err)
@@ -144,26 +156,12 @@ func main() {
 	rfs.AddLocalFunc("set_reset_single_edit", ussdHandlers.SetResetSingleEdit)
 	rfs.AddLocalFunc("initiate_transaction", ussdHandlers.InitiateTransaction)
 
-	cont, err := en.Init(ctx)
-	en.SetDebugger(engine.NewSimpleDebug(nil))
+	_, err = en.Init(ctx)
 	if err != nil {
 		fmt.Fprintf(os.Stderr, "engine init exited with error: %v\n", err)
 		os.Exit(1)
 	}
-	if !cont {
-		_, err = en.WriteResult(ctx, os.Stdout)
-		if err != nil {
-			fmt.Fprintf(os.Stderr, "dead init write error: %v\n", err)
-			os.Exit(1)
-		}
-		err = en.Finish()
-		if err != nil {
-			fmt.Fprintf(os.Stderr, "engine finish error: %v\n", err)
-			os.Exit(1)
-		}
-		os.Stdout.Write([]byte{0x0a})
-		os.Exit(0)
-	}
+
 	err = engine.Loop(ctx, en, os.Stdin, os.Stdout)
 	if err != nil {
 		fmt.Fprintf(os.Stderr, "loop exited with error: %v\n", err)

From 220c5b2081a8eeacf1c3ae4c822336ebffe3b405 Mon Sep 17 00:00:00 2001
From: Carlosokumu <carlosokumu254@gmail.com>
Date: Wed, 4 Sep 2024 20:22:25 +0300
Subject: [PATCH 02/47] remove commented code

---
 internal/handlers/ussd/menuhandler.go | 2 --
 1 file changed, 2 deletions(-)

diff --git a/internal/handlers/ussd/menuhandler.go b/internal/handlers/ussd/menuhandler.go
index c47f2e0..004f8b2 100644
--- a/internal/handlers/ussd/menuhandler.go
+++ b/internal/handlers/ussd/menuhandler.go
@@ -11,7 +11,6 @@ import (
 	"strings"
 
 	"git.defalsify.org/vise.git/asm"
-	"git.defalsify.org/vise.git/engine"
 	"git.defalsify.org/vise.git/lang"
 	"git.defalsify.org/vise.git/resource"
 	"git.defalsify.org/vise.git/state"
@@ -255,7 +254,6 @@ func (h *Handlers) VerifyPin(ctx context.Context, sym string, input []byte) (res
 // codeFromCtx retrieves language codes from the context that can be used for handling translations
 func codeFromCtx(ctx context.Context) string {
 	var code string
-	engine.Logg.DebugCtxf(ctx, "in msg", "ctx", ctx, "val", code)
 	if ctx.Value("Language") != nil {
 		lang := ctx.Value("Language").(lang.Language)
 		code = lang.Code

From 771a1e81695450f64b1c89bdeb720de986d54002 Mon Sep 17 00:00:00 2001
From: Carlosokumu <carlosokumu254@gmail.com>
Date: Thu, 5 Sep 2024 17:07:20 +0300
Subject: [PATCH 03/47] code refactoring

---
 cmd/main.go                           | 230 ++++++++------
 internal/handlers/ussd/menuhandler.go | 439 +++++++++++++-------------
 internal/utils/account_utils.go       |  67 ++--
 3 files changed, 403 insertions(+), 333 deletions(-)

diff --git a/cmd/main.go b/cmd/main.go
index 017f150..cf9875f 100644
--- a/cmd/main.go
+++ b/cmd/main.go
@@ -2,16 +2,15 @@ package main
 
 import (
 	"context"
-	"encoding/csv"
 	"flag"
 	"fmt"
-	"io"
 	"os"
 	"path"
-	"strconv"
 
-	"git.defalsify.org/vise.git/cache"
+	"git.defalsify.org/vise.git/asm"
+	"git.defalsify.org/vise.git/db"
 	fsdb "git.defalsify.org/vise.git/db/fs"
+	gdbmdb "git.defalsify.org/vise.git/db/gdbm"
 	"git.defalsify.org/vise.git/engine"
 	"git.defalsify.org/vise.git/persist"
 	"git.defalsify.org/vise.git/resource"
@@ -25,136 +24,165 @@ var (
 	pr        = persist.NewPersister(store)
 )
 
-type menuResource struct {
-	*resource.DbResource
+func getFlags(fp string, debug bool) (*asm.FlagParser, error) {
+	flagParser := asm.NewFlagParser().WithDebug()
+	_, err := flagParser.Load(fp)
+	if err != nil {
+		return nil, err
+	}
+	return flagParser, nil
 }
 
-func newMenuResource(rs *resource.DbResource) resource.Resource {
-	return &menuResource{
-		rs,
+func getHandler(appFlags *asm.FlagParser, rs *resource.DbResource, pe *persist.Persister, userdataStore db.Db) (*ussd.Handlers, error) {
+
+	ussdHandlers, err := ussd.NewHandlers(appFlags, pr, store)
+	if err != nil {
+		return nil, err
 	}
+	rs.AddLocalFunc("select_language", ussdHandlers.SetLanguage)
+	rs.AddLocalFunc("create_account", ussdHandlers.CreateAccount)
+	rs.AddLocalFunc("save_pin", ussdHandlers.SavePin)
+	rs.AddLocalFunc("verify_pin", ussdHandlers.VerifyPin)
+	rs.AddLocalFunc("check_identifier", ussdHandlers.CheckIdentifier)
+	rs.AddLocalFunc("check_account_status", ussdHandlers.CheckAccountStatus)
+	rs.AddLocalFunc("authorize_account", ussdHandlers.Authorize)
+	rs.AddLocalFunc("quit", ussdHandlers.Quit)
+	rs.AddLocalFunc("check_balance", ussdHandlers.CheckBalance)
+	rs.AddLocalFunc("validate_recipient", ussdHandlers.ValidateRecipient)
+	rs.AddLocalFunc("transaction_reset", ussdHandlers.TransactionReset)
+	rs.AddLocalFunc("max_amount", ussdHandlers.MaxAmount)
+	rs.AddLocalFunc("validate_amount", ussdHandlers.ValidateAmount)
+	rs.AddLocalFunc("reset_transaction_amount", ussdHandlers.ResetTransactionAmount)
+	rs.AddLocalFunc("get_recipient", ussdHandlers.GetRecipient)
+	rs.AddLocalFunc("get_sender", ussdHandlers.GetSender)
+	rs.AddLocalFunc("get_amount", ussdHandlers.GetAmount)
+	rs.AddLocalFunc("reset_incorrect", ussdHandlers.ResetIncorrectPin)
+	rs.AddLocalFunc("save_firstname", ussdHandlers.SaveFirstname)
+	rs.AddLocalFunc("save_familyname", ussdHandlers.SaveFamilyname)
+	rs.AddLocalFunc("save_gender", ussdHandlers.SaveGender)
+	rs.AddLocalFunc("save_location", ussdHandlers.SaveLocation)
+	rs.AddLocalFunc("save_yob", ussdHandlers.SaveYob)
+	rs.AddLocalFunc("save_offerings", ussdHandlers.SaveOfferings)
+	rs.AddLocalFunc("quit_with_balance", ussdHandlers.QuitWithBalance)
+	rs.AddLocalFunc("reset_account_authorized", ussdHandlers.ResetAccountAuthorized)
+	rs.AddLocalFunc("reset_allow_update", ussdHandlers.ResetAllowUpdate)
+	rs.AddLocalFunc("get_profile_info", ussdHandlers.GetProfileInfo)
+	rs.AddLocalFunc("verify_yob", ussdHandlers.VerifyYob)
+	rs.AddLocalFunc("reset_incorrect_date_format", ussdHandlers.ResetIncorrectYob)
+	rs.AddLocalFunc("set_reset_single_edit", ussdHandlers.SetResetSingleEdit)
+	rs.AddLocalFunc("initiate_transaction", ussdHandlers.InitiateTransaction)
+
+	return ussdHandlers, nil
+}
+
+func getPersister(dbDir string, ctx context.Context) (*persist.Persister, error) {
+	err := os.MkdirAll(dbDir, 0700)
+	if err != nil {
+		return nil, fmt.Errorf("state dir create exited with error: %v\n", err)
+	}
+	store := gdbmdb.NewGdbmDb()
+	storeFile := path.Join(dbDir, ".state")
+	store.Connect(ctx, storeFile)
+	pr := persist.NewPersister(store)
+	return pr, nil
+}
+
+func getUserdataDb(dbDir string, ctx context.Context) db.Db {
+	store := gdbmdb.NewGdbmDb()
+	storeFile := path.Join(dbDir, "userdata.gdbm")
+	store.Connect(ctx, storeFile)
+	
+	return store
+}
+
+func getResource(resourceDir string, ctx context.Context) (resource.Resource, error) {
+	store := fsdb.NewFsDb()
+	err := store.Connect(ctx, resourceDir)
+	if err != nil {
+		return nil, err
+	}
+	rfs := resource.NewDbResource(store)
+	return rfs, nil
+}
+
+func getEngine(cfg engine.Config, rs resource.Resource, pr *persist.Persister) *engine.DefaultEngine {
+	en := engine.NewEngine(cfg, rs)
+	en = en.WithPersister(pr)
+	return en
 }
 
 func main() {
-	var dir string
-	var root string
+	//var dir string
+	var dbDir string
+	var resourceDir string
+	//var root string
 	var size uint
 	var sessionId string
-	flag.StringVar(&dir, "d", ".", "resource dir to read from")
-	flag.UintVar(&size, "s", 0, "max size of output")
-	flag.StringVar(&root, "root", "root", "entry point symbol")
-	flag.StringVar(&sessionId, "session-id", "default", "session id")
-	flag.Parse()
-	fmt.Fprintf(os.Stderr, "starting session at symbol '%s' using resource dir: %s\n", root, dir)
+	//flag.StringVar(&dir, "d", ".", "resource dir to read from")
+	// flag.UintVar(&size, "s", 0, "max size of output")
+	// flag.StringVar(&root, "root", "root", "entry point symbol")
+	flag.StringVar(&sessionId, "session-id", "075xx2123", "session id")
+	// flag.Parse()
+	// fmt.Fprintf(os.Stderr, "starting session at symbol '%s' using resource dir: %s\n", root, dir)
+	//logg.Infof("starting session", "symbol", root, "dbdir", dbDir, "sessionid", sessionId, "outsize", size)
+
+	flag.StringVar(&dbDir, "dbdir", ".state", "database dir to read from")
+	flag.StringVar(&resourceDir, "resourcedir", path.Join("services", "registration"), "resource dir")
+	flag.UintVar(&size, "s", 160, "max size of output")
 
 	ctx := context.Background()
-
+	
+   
+    ctx = context.WithValue(ctx, "SessionId",sessionId)
 	pfp := path.Join(scriptDir, "pp.csv")
-	file, err := os.Open(pfp)
+	flagParser, err := getFlags(pfp, true)
+
 	if err != nil {
-		fmt.Fprintf(os.Stderr, "Failed to open CSV file: %v\n", err)
 		os.Exit(1)
 	}
-	defer file.Close()
-	reader := csv.NewReader(file)
 
-	// Iterate through the CSV records and register the flags
-	for {
-		record, err := reader.Read()
-		if err != nil {
-			if err == io.EOF {
-				break
-			}
-			fmt.Fprintf(os.Stderr, "Error reading CSV file: %v\n", err)
-			os.Exit(1)
-		}
-
-		// Ensure the record starts with "flag" and has at least 3 columns
-		if len(record) < 3 || record[0] != "flag" {
-			continue
-		}
-
-		flagName := record[1]
-		flagValue, err := strconv.Atoi(record[2])
-		if err != nil {
-			fmt.Fprintf(os.Stderr, "Failed to convert flag value %s to integer: %v\n", record[2], err)
-			continue
-		}
-
-		// Register the flag
-		state.FlagDebugger.Register(uint32(flagValue), flagName)
-	}
-
-	ca := cache.NewCache()
 	cfg := engine.Config{
-		Root:      "root",
-		SessionId: sessionId,
-		FlagCount: uint32(16),
+		Root:       "root",
+		SessionId:  sessionId,
+		OutputSize: uint32(size),
+		FlagCount:  uint32(16),
 	}
+	//ca := cache.Cache{}
+
+	rs, err := getResource(resourceDir, ctx)
 
-	dp := path.Join(scriptDir, ".state")
-	err = os.MkdirAll(dp, 0700)
 	if err != nil {
-		fmt.Fprintf(os.Stderr, "state dir create exited with error: %v\n", err)
+		fmt.Fprintf(os.Stderr, err.Error())
 		os.Exit(1)
 	}
 
-	store := fsdb.NewFsDb()
-	err = store.Connect(ctx, scriptDir)
+	pr, err := getPersister(dbDir, ctx)
+	//pr.WithContent(state.NewState(uint32(16)),&ca)
+
 	if err != nil {
-		panic(err)
+		fmt.Fprintf(os.Stderr, err.Error())
+		os.Exit(1)
 	}
 
-	rfs := resource.NewDbResource(store)
+	store := getUserdataDb(dbDir, ctx)
+	if err != nil {
+		fmt.Fprintf(os.Stderr, err.Error())
+		os.Exit(1)
+	}
+	dbResource, ok := rs.(*resource.DbResource)
 
-	rs, ok := newMenuResource(rfs).(*menuResource)
 	if !ok {
 		os.Exit(1)
 	}
-	en := engine.NewEngine(cfg, rs)
-	en = en.WithMemory(ca)
-	en = en.WithPersister(pr)
-
-	fp := path.Join(dp, sessionId)
-
-	ussdHandlers, err := ussd.NewHandlers(fp, pr.State, sessionId)
 
+	_, err = getHandler(flagParser, dbResource, pr, store)
 	if err != nil {
-		fmt.Fprintf(os.Stderr, "handler setup failed with error: %v\n", err)
+		fmt.Fprintf(os.Stderr, err.Error())
+		os.Exit(1)
 	}
 
-	rfs.AddLocalFunc("select_language", ussdHandlers.SetLanguage)
-	rfs.AddLocalFunc("create_account", ussdHandlers.CreateAccount)
-	rfs.AddLocalFunc("save_pin", ussdHandlers.SavePin)
-	rfs.AddLocalFunc("verify_pin", ussdHandlers.VerifyPin)
-	rfs.AddLocalFunc("check_identifier", ussdHandlers.CheckIdentifier)
-	rfs.AddLocalFunc("check_account_status", ussdHandlers.CheckAccountStatus)
-	rfs.AddLocalFunc("authorize_account", ussdHandlers.Authorize)
-	rfs.AddLocalFunc("quit", ussdHandlers.Quit)
-	rfs.AddLocalFunc("check_balance", ussdHandlers.CheckBalance)
-	rfs.AddLocalFunc("validate_recipient", ussdHandlers.ValidateRecipient)
-	rfs.AddLocalFunc("transaction_reset", ussdHandlers.TransactionReset)
-	rfs.AddLocalFunc("max_amount", ussdHandlers.MaxAmount)
-	rfs.AddLocalFunc("validate_amount", ussdHandlers.ValidateAmount)
-	rfs.AddLocalFunc("reset_transaction_amount", ussdHandlers.ResetTransactionAmount)
-	rfs.AddLocalFunc("get_recipient", ussdHandlers.GetRecipient)
-	rfs.AddLocalFunc("get_sender", ussdHandlers.GetSender)
-	rfs.AddLocalFunc("get_amount", ussdHandlers.GetAmount)
-	rfs.AddLocalFunc("reset_incorrect", ussdHandlers.ResetIncorrectPin)
-	rfs.AddLocalFunc("save_firstname", ussdHandlers.SaveFirstname)
-	rfs.AddLocalFunc("save_familyname", ussdHandlers.SaveFamilyname)
-	rfs.AddLocalFunc("save_gender", ussdHandlers.SaveGender)
-	rfs.AddLocalFunc("save_location", ussdHandlers.SaveLocation)
-	rfs.AddLocalFunc("save_yob", ussdHandlers.SaveYob)
-	rfs.AddLocalFunc("save_offerings", ussdHandlers.SaveOfferings)
-	rfs.AddLocalFunc("quit_with_balance", ussdHandlers.QuitWithBalance)
-	rfs.AddLocalFunc("reset_account_authorized", ussdHandlers.ResetAccountAuthorized)
-	rfs.AddLocalFunc("reset_allow_update", ussdHandlers.ResetAllowUpdate)
-	rfs.AddLocalFunc("get_profile_info", ussdHandlers.GetProfileInfo)
-	rfs.AddLocalFunc("verify_yob", ussdHandlers.VerifyYob)
-	rfs.AddLocalFunc("reset_incorrect_date_format", ussdHandlers.ResetIncorrectYob)
-	rfs.AddLocalFunc("set_reset_single_edit", ussdHandlers.SetResetSingleEdit)
-	rfs.AddLocalFunc("initiate_transaction", ussdHandlers.InitiateTransaction)
+	en := getEngine(cfg, rs, pr)
+	en.WithState(state.NewState(uint32(16)))
 
 	_, err = en.Init(ctx)
 	if err != nil {
diff --git a/internal/handlers/ussd/menuhandler.go b/internal/handlers/ussd/menuhandler.go
index 004f8b2..5972445 100644
--- a/internal/handlers/ussd/menuhandler.go
+++ b/internal/handlers/ussd/menuhandler.go
@@ -3,7 +3,6 @@ package ussd
 import (
 	"bytes"
 	"context"
-	"errors"
 	"fmt"
 	"path"
 	"regexp"
@@ -11,12 +10,15 @@ import (
 	"strings"
 
 	"git.defalsify.org/vise.git/asm"
+
+	"git.defalsify.org/vise.git/cache"
+	"git.defalsify.org/vise.git/db"
 	"git.defalsify.org/vise.git/lang"
+	"git.defalsify.org/vise.git/persist"
 	"git.defalsify.org/vise.git/resource"
 	"git.defalsify.org/vise.git/state"
 	"git.grassecon.net/urdt/ussd/internal/handlers/server"
 	"git.grassecon.net/urdt/ussd/internal/utils"
-	"github.com/graygnuorg/go-gdbm"
 	"gopkg.in/leonelquinteros/gotext.v1"
 )
 
@@ -42,10 +44,6 @@ const (
 	AccountCreated = "ACCOUNTCREATED"
 )
 
-func toBytes(s string) []byte {
-	return []byte(s)
-}
-
 type FSData struct {
 	Path string
 	St   *state.State
@@ -74,35 +72,37 @@ func (fm *FlagManager) GetFlag(label string) (uint32, error) {
 	return fm.parser.GetFlag(label)
 }
 
+// type Handlers struct {
+// 	fs                 *FSData
+// 	db                 *gdbm.Database
+// 	flagManager        *FlagManager
+// 	accountFileHandler utils.AccountFileHandlerInterface
+// 	accountService     server.AccountServiceInterface
+// }
+
 type Handlers struct {
-	fs                 *FSData
-	db                 *gdbm.Database
-	flagManager        *FlagManager
-	accountFileHandler utils.AccountFileHandlerInterface
+	st                 *state.State
+	ca                 cache.Memory
+	userdataStore      db.Db
+	flagManager        *asm.FlagParser
+	accountFileHandler *utils.AccountFileHandler
 	accountService     server.AccountServiceInterface
 }
 
-func NewHandlers(dir string, st *state.State, sessionId string) (*Handlers, error) {
-	filename := path.Join(scriptDir, sessionId+"_userdata.gdbm")
-	db, err := gdbm.Open(filename, gdbm.ModeWrcreat)
-	if err != nil {
-		panic(err)
-	}
-	pfp := path.Join(scriptDir, "pp.csv")
-	flagManager, err := NewFlagManager(pfp)
-	if err != nil {
-		return nil, fmt.Errorf("failed to create flag manager: %v", err)
-	}
-	return &Handlers{
-		db: db,
-		fs: &FSData{
-			Path: dir,
-			St:   st,
-		},
-		flagManager:        flagManager,
-		accountFileHandler: utils.NewAccountFileHandler(dir + "_data"),
+func NewHandlers(appFlags *asm.FlagParser, pe *persist.Persister, userdataStore db.Db) (*Handlers, error) {
+	h := &Handlers{
+		st:                 state.NewState(uint32(16)),
+		ca:                 pe.GetMemory(),
+		userdataStore:      userdataStore,
+		flagManager:        appFlags,
+		accountFileHandler: utils.NewAccountFileHandler(userdataStore),
 		accountService:     &server.AccountService{},
-	}, nil
+	}
+	if h.st == nil || h.ca == nil || h.userdataStore == nil || h.flagManager == nil {
+		//logg.Errorf("have nil for essential value in handler", "state", h.st, "cache", h.ca, "store", h.userdataStore, "flags", h.flagManager)
+		return nil, fmt.Errorf("have nil for essential value")
+	}
+	return h, nil
 }
 
 // Define the regex pattern as a constant
@@ -138,45 +138,53 @@ func (h *Handlers) SetLanguage(ctx context.Context, sym string, input []byte) (r
 	return res, nil
 }
 
+func (h *Handlers) createAccountNoExist(ctx context.Context, sessionId string, res *resource.Result) error {
+	accountResp, err := h.accountService.CreateAccount()
+	data := map[utils.DataTyp]string{
+		utils.DATA_TRACKING_ID:  accountResp.Result.TrackingId,
+		utils.DATA_PUBLIC_KEY:   accountResp.Result.PublicKey,
+		utils.DATA_CUSTODIAL_ID: accountResp.Result.CustodialId.String(),
+	}
+
+	for key, value := range data {
+		err := utils.WriteEntry(ctx, h.userdataStore, sessionId, key, []byte(value))
+		if err != nil {
+			return err
+		}
+	}
+	flag_account_created, _ := h.flagManager.GetFlag("flag_account_created")
+	res.FlagSet = append(res.FlagSet, flag_account_created)
+	return err
+
+}
+
 // CreateAccount checks if any account exists on the JSON data file, and if not
 // creates an account on the API,
 // sets the default values and flags
 func (h *Handlers) CreateAccount(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 	res := resource.Result{}
-
-	_, err := h.db.Fetch([]byte(AccountCreated))
+	var err error
+	sessionId, ok := ctx.Value("SessionId").(string)
+	if !ok {
+		return res, fmt.Errorf("missing session")
+	}
+	_, err = utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_ACCOUNT_CREATED)
 	if err != nil {
-		if errors.Is(err, gdbm.ErrItemNotFound) {
-			accountResp, err := h.accountService.CreateAccount()
+		if db.IsNotFound(err) {
+			fmt.Println("Creating an account because it doesn't exist")
+			err = h.createAccountNoExist(ctx, sessionId, &res)
 			if err != nil {
-				flag_account_creation_failed, _ := h.flagManager.GetFlag("flag_account_creation_failed")
-				res.FlagSet = append(res.FlagSet, flag_account_creation_failed)
 				return res, err
 			}
-			data := map[string]string{
-				TrackingIdKey:  accountResp.Result.TrackingId,
-				PublicKeyKey:   accountResp.Result.PublicKey,
-				CustodialIdKey: accountResp.Result.CustodialId.String(),
-			}
-
-			for key, value := range data {
-				err := h.db.Store(toBytes(key), toBytes(value), true)
-				if err != nil {
-					return res, err
-				}
-			}
-			key := []byte(AccountCreated)
-			value := []byte("1")
-			h.db.Store(key, value, true)
-			flag_account_created, _ := h.flagManager.GetFlag("flag_account_created")
-			res.FlagSet = append(res.FlagSet, flag_account_created)
-			return res, err
 		} else {
-			return res, err
+			fmt.Println("Error here:", err)
+			err = h.createAccountNoExist(ctx, sessionId, &res)
+			if err != nil {
+				return res, err
+			}
 		}
-	} else {
-		return res, nil
 	}
+	return res, nil
 }
 
 // SavePin persists the user's PIN choice into the filesystem
@@ -194,10 +202,10 @@ func (h *Handlers) SavePin(ctx context.Context, sym string, input []byte) (resou
 
 	res.FlagReset = append(res.FlagReset, flag_incorrect_pin)
 
-	key := []byte(AccountPin)
-	value := []byte(accountPIN)
+	// key := []byte(AccountPin)
+	// value := []byte(accountPIN)
 
-	h.db.Store(key, value, true)
+	//h.db.Store(key, value, true)
 	return res, nil
 }
 
@@ -236,10 +244,11 @@ func (h *Handlers) VerifyPin(ctx context.Context, sym string, input []byte) (res
 	flag_pin_mismatch, _ := h.flagManager.GetFlag("flag_pin_mismatch")
 	flag_pin_set, _ := h.flagManager.GetFlag("flag_pin_set")
 
-	AccountPin, err := h.db.Fetch([]byte(AccountPin))
-	if err != nil {
-		return res, err
-	}
+	// AccountPin, err := h.db.Fetch([]byte(AccountPin))
+	// if err != nil {
+	// 	return res, err
+	// }
+	AccountPin := []byte("2768")
 	if bytes.Equal(input, AccountPin) {
 		res.FlagSet = []uint32{flag_valid_pin}
 		res.FlagReset = []uint32{flag_pin_mismatch}
@@ -265,10 +274,10 @@ func codeFromCtx(ctx context.Context) string {
 func (h *Handlers) SaveFirstname(cxt context.Context, sym string, input []byte) (resource.Result, error) {
 	res := resource.Result{}
 	if len(input) > 0 {
-		name := string(input)
-		key := []byte(FirstName)
-		value := []byte(name)
-		h.db.Store(key, value, true)
+		//name := string(input)
+		//key := []byte(FirstName)
+		//value := []byte(name)
+		//h.db.Store(key, value, true)
 	}
 
 	return res, nil
@@ -278,10 +287,10 @@ func (h *Handlers) SaveFirstname(cxt context.Context, sym string, input []byte)
 func (h *Handlers) SaveFamilyname(cxt context.Context, sym string, input []byte) (resource.Result, error) {
 	res := resource.Result{}
 	if len(input) > 0 {
-		secondname := string(input)
-		key := []byte(FamilyName)
-		value := []byte(secondname)
-		h.db.Store(key, value, true)
+		//secondname := string(input)
+		//key := []byte(FamilyName)
+		//value := []byte(secondname)
+		//h.db.Store(key, value, true)
 	}
 
 	return res, nil
@@ -292,10 +301,10 @@ func (h *Handlers) SaveYob(cxt context.Context, sym string, input []byte) (resou
 	res := resource.Result{}
 	yob := string(input)
 	if len(yob) == 4 {
-		yob := string(input)
-		key := []byte(YearOfBirth)
-		value := []byte(yob)
-		h.db.Store(key, value, true)
+		//yob := string(input)
+		//key := []byte(YearOfBirth)
+		//value := []byte(yob)
+		//h.db.Store(key, value, true)
 	}
 
 	return res, nil
@@ -305,11 +314,11 @@ func (h *Handlers) SaveYob(cxt context.Context, sym string, input []byte) (resou
 func (h *Handlers) SaveLocation(cxt context.Context, sym string, input []byte) (resource.Result, error) {
 	res := resource.Result{}
 	if len(input) > 0 {
-		location := string(input)
-		key := []byte(Location)
-		value := []byte(location)
+		//location := string(input)
+		//key := []byte(Location)
+		//value := []byte(location)
 
-		h.db.Store(key, value, true)
+		//h.db.Store(key, value, true)
 	}
 
 	return res, nil
@@ -328,9 +337,9 @@ func (h *Handlers) SaveGender(ctx context.Context, sym string, input []byte) (re
 		case "3":
 			gender = "Unspecified"
 		}
-		key := []byte(Gender)
-		value := []byte(gender)
-		h.db.Store(key, value, true)
+		//key := []byte(Gender)
+		//value := []byte(gender)
+		//h.db.Store(key, value, true)
 	}
 	return res, nil
 }
@@ -339,10 +348,10 @@ func (h *Handlers) SaveGender(ctx context.Context, sym string, input []byte) (re
 func (h *Handlers) SaveOfferings(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 	res := resource.Result{}
 	if len(input) > 0 {
-		offerings := string(input)
-		key := []byte(Offerings)
-		value := []byte(offerings)
-		h.db.Store(key, value, true)
+		//offerings := string(input)
+		//key := []byte(Offerings)
+		//value := []byte(offerings)
+		//h.db.Store(key, value, true)
 	}
 	return res, nil
 }
@@ -370,11 +379,11 @@ func (h *Handlers) ResetAccountAuthorized(ctx context.Context, sym string, input
 // CheckIdentifier retrieves the PublicKey from the JSON data file.
 func (h *Handlers) CheckIdentifier(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 	res := resource.Result{}
-	publicKey, err := h.db.Fetch([]byte(PublicKeyKey))
-	if err != nil {
-		return res, err
-	}
-	res.Content = string(publicKey)
+	//publicKey, err := h.db.Fetch([]byte(PublicKeyKey))
+	// if err != nil {
+	// 	return res, err
+	// }
+	res.Content = "string(publicKey)"
 	return res, nil
 }
 
@@ -383,32 +392,32 @@ func (h *Handlers) CheckIdentifier(ctx context.Context, sym string, input []byte
 func (h *Handlers) Authorize(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 	res := resource.Result{}
 
-	flag_incorrect_pin, _ := h.flagManager.GetFlag("flag_incorrect_pin")
-	flag_account_authorized, _ := h.flagManager.GetFlag("flag_account_authorized")
-	flag_allow_update, _ := h.flagManager.GetFlag("flag_allow_update")
+	// flag_incorrect_pin, _ := h.flagManager.GetFlag("flag_incorrect_pin")
+	// flag_account_authorized, _ := h.flagManager.GetFlag("flag_account_authorized")
+	// flag_allow_update, _ := h.flagManager.GetFlag("flag_allow_update")
 
-	storedpin, err := h.db.Fetch([]byte(AccountPin))
-	if err == nil {
-		if len(input) == 4 {
-			if bytes.Equal(input, storedpin) {
-				if h.fs.St.MatchFlag(flag_account_authorized, false) {
-					res.FlagReset = append(res.FlagReset, flag_incorrect_pin)
-					res.FlagSet = append(res.FlagSet, flag_allow_update, flag_account_authorized)
-				} else {
-					res.FlagSet = append(res.FlagSet, flag_allow_update)
-					res.FlagReset = append(res.FlagReset, flag_account_authorized)
-				}
-			} else {
-				res.FlagSet = append(res.FlagSet, flag_incorrect_pin)
-				res.FlagReset = append(res.FlagReset, flag_account_authorized)
-				return res, nil
-			}
-		}
-	} else if errors.Is(err, gdbm.ErrItemNotFound) {
-		return res, err
-	} else {
-		return res, err
-	}
+	// storedpin, err := h.db.Fetch([]byte(AccountPin))
+	// if err == nil {
+	// 	if len(input) == 4 {
+	// 		if bytes.Equal(input, storedpin) {
+	// 			if h.fs.St.MatchFlag(flag_account_authorized, false) {
+	// 				res.FlagReset = append(res.FlagReset, flag_incorrect_pin)
+	// 				res.FlagSet = append(res.FlagSet, flag_allow_update, flag_account_authorized)
+	// 			} else {
+	// 				res.FlagSet = append(res.FlagSet, flag_allow_update)
+	// 				res.FlagReset = append(res.FlagReset, flag_account_authorized)
+	// 			}
+	// 		} else {
+	// 			res.FlagSet = append(res.FlagSet, flag_incorrect_pin)
+	// 			res.FlagReset = append(res.FlagReset, flag_account_authorized)
+	// 			return res, nil
+	// 		}
+	// 	}
+	// } else if errors.Is(err, gdbm.ErrItemNotFound) {
+	// 	return res, err
+	// } else {
+	// 	return res, err
+	// }
 	return res, nil
 }
 
@@ -430,13 +439,15 @@ func (h *Handlers) CheckAccountStatus(ctx context.Context, sym string, input []b
 	flag_account_success, _ := h.flagManager.GetFlag("flag_account_success")
 	flag_account_pending, _ := h.flagManager.GetFlag("flag_account_pending")
 
-	trackingId, err := h.db.Fetch([]byte(TrackingIdKey))
-
-	if err != nil {
-		return res, err
+	sessionId, ok := ctx.Value("SessionId").(string)
+	if !ok {
+		return res, fmt.Errorf("missing session")
 	}
 
-	status, err := h.accountService.CheckAccountStatus(string(trackingId))
+	trackingId, err := utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_TRACKING_ID)
+	fmt.Println("Checking status with tracking id:", string(trackingId))
+
+	status, err := h.accountService.CheckAccountStatus(string("1234"))
 
 	if err != nil {
 		fmt.Println("Error checking account status:", err)
@@ -444,15 +455,15 @@ func (h *Handlers) CheckAccountStatus(ctx context.Context, sym string, input []b
 
 	}
 
-	err = h.db.Store(toBytes(AccountStatus), toBytes(status), true)
-	if err != nil {
-		return res, nil
-	}
+	// err = h.db.Store(toBytes(AccountStatus), toBytes(status), true)
+	// if err != nil {
+	// 	return res, nil
+	// }
 
-	err = h.db.Store(toBytes(TrackingIdKey), toBytes(status), true)
-	if err != nil {
-		return res, nil
-	}
+	// err = h.db.Store(toBytes(TrackingIdKey), toBytes(status), true)
+	// if err != nil {
+	// 	return res, nil
+	// }
 
 	if status == "SUCCESS" {
 		res.FlagSet = append(res.FlagSet, flag_account_success)
@@ -516,13 +527,13 @@ func (h *Handlers) ResetIncorrectYob(ctx context.Context, sym string, input []by
 // the balance as the result content
 func (h *Handlers) CheckBalance(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 	res := resource.Result{}
-	publicKey, err := h.db.Fetch([]byte(PublicKeyKey))
+	// publicKey, err := h.db.Fetch([]byte(PublicKeyKey))
 
-	if err != nil {
-		return res, err
-	}
+	// if err != nil {
+	// 	return res, err
+	// }
 
-	balance, err := h.accountService.CheckBalance(string(publicKey))
+	balance, err := h.accountService.CheckBalance(string("publicKey"))
 	if err != nil {
 		return res, nil
 	}
@@ -548,10 +559,10 @@ func (h *Handlers) ValidateRecipient(ctx context.Context, sym string, input []by
 		}
 
 		// accountData["Recipient"] = recipient
-		key := []byte(Recipient)
-		value := []byte(recipient)
+		// key := []byte(Recipient)
+		// value := []byte(recipient)
 
-		h.db.Store(key, value, true)
+		// h.db.Store(key, value, true)
 	}
 
 	return res, nil
@@ -565,14 +576,14 @@ func (h *Handlers) TransactionReset(ctx context.Context, sym string, input []byt
 	flag_invalid_recipient, _ := h.flagManager.GetFlag("flag_invalid_recipient")
 	flag_invalid_recipient_with_invite, _ := h.flagManager.GetFlag("flag_invalid_recipient_with_invite")
 
-	err := h.db.Delete([]byte(Amount))
-	if err != nil && !errors.Is(err, gdbm.ErrItemNotFound) {
-		return res, err
-	}
-	err = h.db.Delete([]byte(Recipient))
-	if err != nil && !errors.Is(err, gdbm.ErrItemNotFound) {
-		return res, err
-	}
+	// err := h.db.Delete([]byte(Amount))
+	// if err != nil && !errors.Is(err, gdbm.ErrItemNotFound) {
+	// 	return res, err
+	// }
+	// err = h.db.Delete([]byte(Recipient))
+	// if err != nil && !errors.Is(err, gdbm.ErrItemNotFound) {
+	// 	return res, err
+	// }
 
 	res.FlagReset = append(res.FlagReset, flag_invalid_recipient, flag_invalid_recipient_with_invite)
 
@@ -585,10 +596,10 @@ func (h *Handlers) ResetTransactionAmount(ctx context.Context, sym string, input
 
 	flag_invalid_amount, _ := h.flagManager.GetFlag("flag_invalid_amount")
 
-	err := h.db.Delete([]byte(Amount))
-	if err != nil && !errors.Is(err, gdbm.ErrItemNotFound) {
-		return res, err
-	}
+	// err := h.db.Delete([]byte(Amount))
+	// if err != nil && !errors.Is(err, gdbm.ErrItemNotFound) {
+	// 	return res, err
+	// }
 
 	res.FlagReset = append(res.FlagReset, flag_invalid_amount)
 
@@ -599,12 +610,12 @@ func (h *Handlers) ResetTransactionAmount(ctx context.Context, sym string, input
 // the result content.
 func (h *Handlers) MaxAmount(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 	res := resource.Result{}
-	publicKey, err := h.db.Fetch([]byte(PublicKeyKey))
-	if err != nil {
-		return res, err
-	}
+	// publicKey, err := h.db.Fetch([]byte(PublicKeyKey))
+	// if err != nil {
+	// 	return res, err
+	// }
 
-	balance, err := h.accountService.CheckBalance(string(publicKey))
+	balance, err := h.accountService.CheckBalance(string("publicKey"))
 	if err != nil {
 		return res, nil
 	}
@@ -622,13 +633,13 @@ func (h *Handlers) ValidateAmount(ctx context.Context, sym string, input []byte)
 	flag_invalid_amount, _ := h.flagManager.GetFlag("flag_invalid_amount")
 
 	amountStr := string(input)
-	publicKey, err := h.db.Fetch([]byte(PublicKeyKey))
+	// publicKey, err := h.db.Fetch([]byte(PublicKeyKey))
 
-	if err != nil {
-		return res, err
-	}
+	// if err != nil {
+	// 	return res, err
+	// }
 
-	balanceStr, err := h.accountService.CheckBalance(string(publicKey))
+	balanceStr, err := h.accountService.CheckBalance(string("publicKey"))
 
 	if err != nil {
 		return res, err
@@ -668,9 +679,9 @@ func (h *Handlers) ValidateAmount(ctx context.Context, sym string, input []byte)
 	}
 
 	res.Content = fmt.Sprintf("%.3f", inputAmount) // Format to 3 decimal places
-	key := []byte(Amount)
-	value := []byte(res.Content)
-	h.db.Store(key, value, true)
+	// key := []byte(Amount)
+	// value := []byte(res.Content)
+	// h.db.Store(key, value, true)
 
 	if err != nil {
 		return res, err
@@ -682,12 +693,12 @@ func (h *Handlers) ValidateAmount(ctx context.Context, sym string, input []byte)
 // GetRecipient returns the transaction recipient from a JSON data file.
 func (h *Handlers) GetRecipient(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 	res := resource.Result{}
-	recipient, err := h.db.Fetch([]byte(Recipient))
-	if err != nil {
-		return res, err
-	}
+	// recipient, err := h.db.Fetch([]byte(Recipient))
+	// if err != nil {
+	// 	return res, err
+	// }
 
-	res.Content = string(recipient)
+	res.Content = string("recipient")
 
 	return res, nil
 }
@@ -695,12 +706,12 @@ func (h *Handlers) GetRecipient(ctx context.Context, sym string, input []byte) (
 // GetSender retrieves the public key from the Gdbm Db
 func (h *Handlers) GetSender(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 	res := resource.Result{}
-	publicKey, err := h.db.Fetch([]byte(PublicKeyKey))
-	if err != nil {
-		return res, err
-	}
+	// publicKey, err := h.db.Fetch([]byte(PublicKeyKey))
+	// if err != nil {
+	// 	return res, err
+	// }
 
-	res.Content = string(publicKey)
+	res.Content = string("publicKey")
 
 	return res, nil
 }
@@ -708,11 +719,11 @@ func (h *Handlers) GetSender(ctx context.Context, sym string, input []byte) (res
 // GetAmount retrieves the amount from teh Gdbm Db
 func (h *Handlers) GetAmount(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 	res := resource.Result{}
-	amount, err := h.db.Fetch([]byte(Amount))
-	if err != nil {
-		return res, err
-	}
-	res.Content = string(amount)
+	// amount, err := h.db.Fetch([]byte(Amount))
+	// if err != nil {
+	// 	return res, err
+	// }
+	res.Content = string("amount")
 
 	return res, nil
 }
@@ -727,11 +738,11 @@ func (h *Handlers) QuitWithBalance(ctx context.Context, sym string, input []byte
 	code := codeFromCtx(ctx)
 	l := gotext.NewLocale(translationDir, code)
 	l.AddDomain("default")
-	publicKey, err := h.db.Fetch([]byte(PublicKeyKey))
-	if err != nil {
-		return res, err
-	}
-	balance, err := h.accountService.CheckBalance(string(publicKey))
+	// publicKey, err := h.db.Fetch([]byte(PublicKeyKey))
+	// if err != nil {
+	// 	return res, err
+	// }
+	balance, err := h.accountService.CheckBalance(string("publicKey"))
 	if err != nil {
 		return res, nil
 	}
@@ -750,20 +761,20 @@ func (h *Handlers) InitiateTransaction(ctx context.Context, sym string, input []
 	// TODO
 	// Use the amount, recipient and sender to call the API and initialize the transaction
 
-	publicKey, err := h.db.Fetch([]byte(PublicKeyKey))
-	if err != nil {
-		return res, err
-	}
-	amount, err := h.db.Fetch([]byte(Amount))
-	if err != nil {
-		return res, err
-	}
-	recipient, err := h.db.Fetch([]byte(Recipient))
-	if err != nil {
-		return res, err
-	}
+	// publicKey, err := h.db.Fetch([]byte(PublicKeyKey))
+	// if err != nil {
+	// 	return res, err
+	// }
+	// amount, err := h.db.Fetch([]byte(Amount))
+	// if err != nil {
+	// 	return res, err
+	// }
+	// recipient, err := h.db.Fetch([]byte(Recipient))
+	// if err != nil {
+	// 	return res, err
+	// }
 
-	res.Content = l.Get("Your request has been sent. %s will receive %s from %s.", string(recipient), string(amount), string(publicKey))
+	//res.Content = l.Get("Your request has been sent. %s will receive %s from %s.", string(recipient), string(amount), string(publicKey))
 
 	account_authorized_flag, err := h.flagManager.GetFlag("flag_account_authorized")
 	if err != nil {
@@ -788,27 +799,27 @@ func (h *Handlers) GetProfileInfo(ctx context.Context, sym string, input []byte)
 	offerings := defaultValue
 
 	// Fetch data using a map for better organization
-	dataKeys := map[string]*string{
-		FirstName:   &name,
-		FamilyName:  &familyName,
-		YearOfBirth: &yob,
-		Location:    &location,
-		Gender:      &gender,
-		Offerings:   &offerings,
-	}
+	// dataKeys := map[string]*string{
+	// 	FirstName:   &name,
+	// 	FamilyName:  &familyName,
+	// 	YearOfBirth: &yob,
+	// 	Location:    &location,
+	// 	Gender:      &gender,
+	// 	Offerings:   &offerings,
+	// }
 
 	// Iterate over keys and fetch values
 	//iter := h.db.Iterator()
-	next := h.db.Iterator()
-	//defer iter.Close() // Ensure the iterator is closed
-	for key, err := next(); err == nil; key, err = next() {
-		if valuePointer, ok := dataKeys[string(key)]; ok {
-			value, fetchErr := h.db.Fetch(key)
-			if fetchErr == nil {
-				*valuePointer = string(value)
-			}
-		}
-	}
+	// next := h.db.Iterator()
+	// //defer iter.Close() // Ensure the iterator is closed
+	// for key, err := next(); err == nil; key, err = next() {
+	// 	if valuePointer, ok := dataKeys[string(key)]; ok {
+	// 		// value, fetchErr := h.db.Fetch(key)
+	// 		// if fetchErr == nil {
+	// 		// 	*valuePointer = string(value)
+	// 		// }
+	// 	}
+	// }
 
 	// Construct the full name
 	if familyName != defaultValue {
diff --git a/internal/utils/account_utils.go b/internal/utils/account_utils.go
index 39fb66b..1ab34b8 100644
--- a/internal/utils/account_utils.go
+++ b/internal/utils/account_utils.go
@@ -1,46 +1,77 @@
 package utils
 
 import (
+	"context"
 	"encoding/json"
-	"os"
+
+	"git.defalsify.org/vise.git/db"
 )
 
 type AccountFileHandler struct {
-	FilePath string
+	//FilePath string
+	store db.Db
 }
 
-func NewAccountFileHandler(path string) *AccountFileHandler {
-	return &AccountFileHandler{FilePath: path}
-}
+// func NewAccountFileHandler(path string) *AccountFileHandler {
+// 	return &AccountFileHandler{FilePath: path}
+// }
 
-func (afh *AccountFileHandler) ReadAccountData() (map[string]string, error) {
-	jsonData, err := os.ReadFile(afh.FilePath)
-	if err != nil {
-		return nil, err
+func NewAccountFileHandler(store db.Db) *AccountFileHandler {
+	return &AccountFileHandler{
+		store: store,
 	}
+}
 
+// func (afh *AccountFileHandler) ReadAccountData() (map[string]string, error) {
+// 	jsonData, err := os.ReadFile(afh.FilePath)
+// 	if err != nil {
+// 		return nil, err
+// 	}
+
+// 	var accountData map[string]string
+// 	err = json.Unmarshal(jsonData, &accountData)
+// 	if err != nil {
+// 		return nil, err
+// 	}
+
+// 	return accountData, nil
+// }
+
+func (afh *AccountFileHandler) ReadAccountData(ctx context.Context, sessionId string) (map[string]string, error) {
 	var accountData map[string]string
+	jsonData, err := ReadEntry(ctx, afh.store, sessionId, DATA_ACCOUNT)
 	err = json.Unmarshal(jsonData, &accountData)
 	if err != nil {
 		return nil, err
 	}
-
 	return accountData, nil
 }
 
-func (afh *AccountFileHandler) WriteAccountData(accountData map[string]string) error {
-	jsonData, err := json.Marshal(accountData)
+// func (afh *AccountFileHandler) WriteAccountData(accountData map[string]string) error {
+// 	jsonData, err := json.Marshal(accountData)
+// 	if err != nil {
+// 		return err
+// 	}
+
+// 	return os.WriteFile(afh.FilePath, jsonData, 0644)
+// }
+
+func (afh *AccountFileHandler) WriteAccountData(ctx context.Context, sessionId string, accountData map[string]string) error {
+	_, err := json.Marshal(accountData)
 	if err != nil {
 		return err
 	}
 
-	return os.WriteFile(afh.FilePath, jsonData, 0644)
+	return nil
 }
 
+//	func (afh *AccountFileHandler) EnsureFileExists() error {
+//		f, err := os.OpenFile(afh.FilePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
+//		if err != nil {
+//			return err
+//		}
+//		return f.Close()
+//	}
 func (afh *AccountFileHandler) EnsureFileExists() error {
-	f, err := os.OpenFile(afh.FilePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
-	if err != nil {
-		return err
-	}
-	return f.Close()
+	return nil
 }

From 98c74dffc42edc887467bc93cfbe5bbc5e857dc2 Mon Sep 17 00:00:00 2001
From: Carlosokumu <carlosokumu254@gmail.com>
Date: Thu, 5 Sep 2024 17:09:30 +0300
Subject: [PATCH 04/47] use state from persister

---
 internal/handlers/ussd/menuhandler.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/internal/handlers/ussd/menuhandler.go b/internal/handlers/ussd/menuhandler.go
index 5972445..eb78919 100644
--- a/internal/handlers/ussd/menuhandler.go
+++ b/internal/handlers/ussd/menuhandler.go
@@ -91,7 +91,7 @@ type Handlers struct {
 
 func NewHandlers(appFlags *asm.FlagParser, pe *persist.Persister, userdataStore db.Db) (*Handlers, error) {
 	h := &Handlers{
-		st:                 state.NewState(uint32(16)),
+		st:                 pe.State,
 		ca:                 pe.GetMemory(),
 		userdataStore:      userdataStore,
 		flagManager:        appFlags,

From 2bf7a5c246a7a2f05bac0780017316682d14991c Mon Sep 17 00:00:00 2001
From: Carlosokumu <carlosokumu254@gmail.com>
Date: Thu, 5 Sep 2024 17:12:38 +0300
Subject: [PATCH 05/47] setup db keys

---
 internal/utils/db.go | 51 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 51 insertions(+)
 create mode 100644 internal/utils/db.go

diff --git a/internal/utils/db.go b/internal/utils/db.go
new file mode 100644
index 0000000..bd8c5ee
--- /dev/null
+++ b/internal/utils/db.go
@@ -0,0 +1,51 @@
+package utils
+
+import (
+	"context"
+	"encoding/binary"
+
+	"git.defalsify.org/vise.git/db"
+)
+
+type DataTyp uint16
+
+const (
+	DATA_ACCOUNT DataTyp = iota
+	DATA_ACCOUNT_CREATED
+	DATA_TRACKING_ID
+	DATA_PUBLIC_KEY
+	DATA_CUSTODIAL_ID
+)
+
+func typToBytes(typ DataTyp) []byte {
+	//var b []byte
+	b := make([]byte, 2) 
+	binary.BigEndian.PutUint16(b, uint16(typ))
+	return b
+}
+
+func packKey(typ DataTyp, data []byte) []byte {
+	v := typToBytes(typ)
+	return append(v, data...)
+}
+
+func ReadEntry(ctx context.Context, store db.Db, sessionId string, typ DataTyp) ([]byte, error) {
+	store.SetPrefix(db.DATATYPE_USERDATA)
+	 store.SetSession(sessionId)
+	 k := packKey(typ, []byte(sessionId))
+	//k := []byte(sessionId)
+	b, err := store.Get(ctx, k)
+	if err != nil {
+		return nil, err
+	}
+	return b, nil
+
+}
+
+func WriteEntry(ctx context.Context, store db.Db, sessionId string, typ DataTyp, value []byte) error {
+	store.SetPrefix(db.DATATYPE_USERDATA)
+	store.SetSession(sessionId)
+	//k := packKey(typ, []byte(sessionId))
+	k := []byte(sessionId)
+	return store.Put(ctx, k, value)
+}
\ No newline at end of file

From 6fa5f49bc022781556bd97414c5517f0f5953567 Mon Sep 17 00:00:00 2001
From: lash <dev@holbrook.no>
Date: Thu, 5 Sep 2024 15:28:53 +0100
Subject: [PATCH 06/47] Remove impossible nil check in handler

---
 go-vise                               |  2 +-
 internal/handlers/ussd/menuhandler.go | 10 ++++++----
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/go-vise b/go-vise
index 1f47a67..326bdb5 160000
--- a/go-vise
+++ b/go-vise
@@ -1 +1 @@
-Subproject commit 1f47a674d95380be8c387f410f0342eb72357df5
+Subproject commit 326bdb5018ae81ee493371b56bd4564a8b35da59
diff --git a/internal/handlers/ussd/menuhandler.go b/internal/handlers/ussd/menuhandler.go
index eb78919..c9d42ec 100644
--- a/internal/handlers/ussd/menuhandler.go
+++ b/internal/handlers/ussd/menuhandler.go
@@ -17,12 +17,14 @@ import (
 	"git.defalsify.org/vise.git/persist"
 	"git.defalsify.org/vise.git/resource"
 	"git.defalsify.org/vise.git/state"
+	"git.defalsify.org/vise.git/logging"
 	"git.grassecon.net/urdt/ussd/internal/handlers/server"
 	"git.grassecon.net/urdt/ussd/internal/utils"
 	"gopkg.in/leonelquinteros/gotext.v1"
 )
 
 var (
+	logg = logging.NewVanilla().WithDomain("ussdmenuhandler")
 	scriptDir      = path.Join("services", "registration")
 	translationDir = path.Join(scriptDir, "locale")
 )
@@ -98,10 +100,10 @@ func NewHandlers(appFlags *asm.FlagParser, pe *persist.Persister, userdataStore
 		accountFileHandler: utils.NewAccountFileHandler(userdataStore),
 		accountService:     &server.AccountService{},
 	}
-	if h.st == nil || h.ca == nil || h.userdataStore == nil || h.flagManager == nil {
-		//logg.Errorf("have nil for essential value in handler", "state", h.st, "cache", h.ca, "store", h.userdataStore, "flags", h.flagManager)
-		return nil, fmt.Errorf("have nil for essential value")
-	}
+//	if h.st == nil || h.ca == nil || h.userdataStore == nil || h.flagManager == nil {
+//		logg.Errorf("have nil for essential value in handler", "state", h.st, "cache", h.ca, "store", h.userdataStore, "flags", h.flagManager)
+//		return nil, fmt.Errorf("have nil for essential value")
+//	}
 	return h, nil
 }
 

From 62b7adb9671eaaf5b78b953e1c7c7b680941dfc9 Mon Sep 17 00:00:00 2001
From: lash <dev@holbrook.no>
Date: Thu, 5 Sep 2024 15:41:27 +0100
Subject: [PATCH 07/47] Fix missing byte allocation for typ serialize

---
 internal/utils/db.go | 17 +++++++----------
 1 file changed, 7 insertions(+), 10 deletions(-)

diff --git a/internal/utils/db.go b/internal/utils/db.go
index bd8c5ee..1104452 100644
--- a/internal/utils/db.go
+++ b/internal/utils/db.go
@@ -18,10 +18,9 @@ const (
 )
 
 func typToBytes(typ DataTyp) []byte {
-	//var b []byte
-	b := make([]byte, 2) 
-	binary.BigEndian.PutUint16(b, uint16(typ))
-	return b
+	var b [2]byte
+	binary.BigEndian.PutUint16(b[:], uint16(typ))
+	return b[:]
 }
 
 func packKey(typ DataTyp, data []byte) []byte {
@@ -31,9 +30,8 @@ func packKey(typ DataTyp, data []byte) []byte {
 
 func ReadEntry(ctx context.Context, store db.Db, sessionId string, typ DataTyp) ([]byte, error) {
 	store.SetPrefix(db.DATATYPE_USERDATA)
-	 store.SetSession(sessionId)
-	 k := packKey(typ, []byte(sessionId))
-	//k := []byte(sessionId)
+	store.SetSession(sessionId)
+	k := packKey(typ, []byte(sessionId))
 	b, err := store.Get(ctx, k)
 	if err != nil {
 		return nil, err
@@ -45,7 +43,6 @@ func ReadEntry(ctx context.Context, store db.Db, sessionId string, typ DataTyp)
 func WriteEntry(ctx context.Context, store db.Db, sessionId string, typ DataTyp, value []byte) error {
 	store.SetPrefix(db.DATATYPE_USERDATA)
 	store.SetSession(sessionId)
-	//k := packKey(typ, []byte(sessionId))
-	k := []byte(sessionId)
+	k := packKey(typ, []byte(sessionId))
 	return store.Put(ctx, k, value)
-}
\ No newline at end of file
+}

From db3ec1991d7081705a1bda320e3d6ba98bca26c5 Mon Sep 17 00:00:00 2001
From: lash <dev@holbrook.no>
Date: Thu, 5 Sep 2024 16:45:35 +0100
Subject: [PATCH 08/47] Remove obsolete store and persister global

---
 cmd/main.go                           | 30 ++++++++-------------------
 internal/handlers/ussd/menuhandler.go |  5 -----
 2 files changed, 9 insertions(+), 26 deletions(-)

diff --git a/cmd/main.go b/cmd/main.go
index cf9875f..0529e81 100644
--- a/cmd/main.go
+++ b/cmd/main.go
@@ -15,13 +15,13 @@ import (
 	"git.defalsify.org/vise.git/persist"
 	"git.defalsify.org/vise.git/resource"
 	"git.defalsify.org/vise.git/state"
+	"git.defalsify.org/vise.git/logging"
 	"git.grassecon.net/urdt/ussd/internal/handlers/ussd"
 )
 
 var (
+	logg = logging.NewVanilla()
 	scriptDir = path.Join("services", "registration")
-	store     = fsdb.NewFsDb()
-	pr        = persist.NewPersister(store)
 )
 
 func getFlags(fp string, debug bool) (*asm.FlagParser, error) {
@@ -35,7 +35,7 @@ func getFlags(fp string, debug bool) (*asm.FlagParser, error) {
 
 func getHandler(appFlags *asm.FlagParser, rs *resource.DbResource, pe *persist.Persister, userdataStore db.Db) (*ussd.Handlers, error) {
 
-	ussdHandlers, err := ussd.NewHandlers(appFlags, pr, store)
+	ussdHandlers, err := ussd.NewHandlers(appFlags, pe, userdataStore)
 	if err != nil {
 		return nil, err
 	}
@@ -81,7 +81,7 @@ func getPersister(dbDir string, ctx context.Context) (*persist.Persister, error)
 		return nil, fmt.Errorf("state dir create exited with error: %v\n", err)
 	}
 	store := gdbmdb.NewGdbmDb()
-	storeFile := path.Join(dbDir, ".state")
+	storeFile := path.Join(dbDir, "state.gdbm")
 	store.Connect(ctx, storeFile)
 	pr := persist.NewPersister(store)
 	return pr, nil
@@ -112,28 +112,20 @@ func getEngine(cfg engine.Config, rs resource.Resource, pr *persist.Persister) *
 }
 
 func main() {
-	//var dir string
 	var dbDir string
 	var resourceDir string
-	//var root string
 	var size uint
 	var sessionId string
-	//flag.StringVar(&dir, "d", ".", "resource dir to read from")
-	// flag.UintVar(&size, "s", 0, "max size of output")
-	// flag.StringVar(&root, "root", "root", "entry point symbol")
 	flag.StringVar(&sessionId, "session-id", "075xx2123", "session id")
-	// flag.Parse()
-	// fmt.Fprintf(os.Stderr, "starting session at symbol '%s' using resource dir: %s\n", root, dir)
-	//logg.Infof("starting session", "symbol", root, "dbdir", dbDir, "sessionid", sessionId, "outsize", size)
-
 	flag.StringVar(&dbDir, "dbdir", ".state", "database dir to read from")
 	flag.StringVar(&resourceDir, "resourcedir", path.Join("services", "registration"), "resource dir")
 	flag.UintVar(&size, "s", 160, "max size of output")
+	flag.Parse()
+
+	logg.Infof("start command", "dbdir", dbDir, "resourcedir", resourceDir,  "outputsize", size)
 
 	ctx := context.Background()
-	
-   
-    ctx = context.WithValue(ctx, "SessionId",sessionId)
+	ctx = context.WithValue(ctx, "SessionId",sessionId)
 	pfp := path.Join(scriptDir, "pp.csv")
 	flagParser, err := getFlags(pfp, true)
 
@@ -147,18 +139,14 @@ func main() {
 		OutputSize: uint32(size),
 		FlagCount:  uint32(16),
 	}
-	//ca := cache.Cache{}
 
 	rs, err := getResource(resourceDir, ctx)
-
 	if err != nil {
 		fmt.Fprintf(os.Stderr, err.Error())
 		os.Exit(1)
 	}
 
 	pr, err := getPersister(dbDir, ctx)
-	//pr.WithContent(state.NewState(uint32(16)),&ca)
-
 	if err != nil {
 		fmt.Fprintf(os.Stderr, err.Error())
 		os.Exit(1)
@@ -169,8 +157,8 @@ func main() {
 		fmt.Fprintf(os.Stderr, err.Error())
 		os.Exit(1)
 	}
-	dbResource, ok := rs.(*resource.DbResource)
 
+	dbResource, ok := rs.(*resource.DbResource)
 	if !ok {
 		os.Exit(1)
 	}
diff --git a/internal/handlers/ussd/menuhandler.go b/internal/handlers/ussd/menuhandler.go
index c9d42ec..2eb11b1 100644
--- a/internal/handlers/ussd/menuhandler.go
+++ b/internal/handlers/ussd/menuhandler.go
@@ -100,10 +100,6 @@ func NewHandlers(appFlags *asm.FlagParser, pe *persist.Persister, userdataStore
 		accountFileHandler: utils.NewAccountFileHandler(userdataStore),
 		accountService:     &server.AccountService{},
 	}
-//	if h.st == nil || h.ca == nil || h.userdataStore == nil || h.flagManager == nil {
-//		logg.Errorf("have nil for essential value in handler", "state", h.st, "cache", h.ca, "store", h.userdataStore, "flags", h.flagManager)
-//		return nil, fmt.Errorf("have nil for essential value")
-//	}
 	return h, nil
 }
 
@@ -179,7 +175,6 @@ func (h *Handlers) CreateAccount(ctx context.Context, sym string, input []byte)
 				return res, err
 			}
 		} else {
-			fmt.Println("Error here:", err)
 			err = h.createAccountNoExist(ctx, sessionId, &res)
 			if err != nil {
 				return res, err

From 17804e764119f786193e0239dd7f338c7ae9f87c Mon Sep 17 00:00:00 2001
From: alfred-mk <alfredmwaik@gmail.com>
Date: Thu, 5 Sep 2024 19:50:02 +0300
Subject: [PATCH 09/47] Save the actual PIN and verify it

---
 internal/handlers/ussd/menuhandler.go | 48 +++++++++++++--------------
 internal/utils/db.go                  |  2 +-
 2 files changed, 25 insertions(+), 25 deletions(-)

diff --git a/internal/handlers/ussd/menuhandler.go b/internal/handlers/ussd/menuhandler.go
index 2eb11b1..5ac9456 100644
--- a/internal/handlers/ussd/menuhandler.go
+++ b/internal/handlers/ussd/menuhandler.go
@@ -74,14 +74,6 @@ func (fm *FlagManager) GetFlag(label string) (uint32, error) {
 	return fm.parser.GetFlag(label)
 }
 
-// type Handlers struct {
-// 	fs                 *FSData
-// 	db                 *gdbm.Database
-// 	flagManager        *FlagManager
-// 	accountFileHandler utils.AccountFileHandlerInterface
-// 	accountService     server.AccountServiceInterface
-// }
-
 type Handlers struct {
 	st                 *state.State
 	ca                 cache.Memory
@@ -187,6 +179,10 @@ func (h *Handlers) CreateAccount(ctx context.Context, sym string, input []byte)
 // SavePin persists the user's PIN choice into the filesystem
 func (h *Handlers) SavePin(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 	res := resource.Result{}
+	sessionId, ok := ctx.Value("SessionId").(string)
+	if !ok {
+		return res, fmt.Errorf("missing session")
+	}
 
 	flag_incorrect_pin, _ := h.flagManager.GetFlag("flag_incorrect_pin")
 
@@ -199,10 +195,11 @@ func (h *Handlers) SavePin(ctx context.Context, sym string, input []byte) (resou
 
 	res.FlagReset = append(res.FlagReset, flag_incorrect_pin)
 
-	// key := []byte(AccountPin)
-	// value := []byte(accountPIN)
+	err := utils.WriteEntry(ctx, h.userdataStore, sessionId, utils.DATA_ACCOUNT_PIN, []byte(accountPIN))
+	if err != nil {
+		return res, nil
+	}
 
-	//h.db.Store(key, value, true)
 	return res, nil
 }
 
@@ -241,11 +238,13 @@ func (h *Handlers) VerifyPin(ctx context.Context, sym string, input []byte) (res
 	flag_pin_mismatch, _ := h.flagManager.GetFlag("flag_pin_mismatch")
 	flag_pin_set, _ := h.flagManager.GetFlag("flag_pin_set")
 
-	// AccountPin, err := h.db.Fetch([]byte(AccountPin))
-	// if err != nil {
-	// 	return res, err
-	// }
-	AccountPin := []byte("2768")
+	sessionId, ok := ctx.Value("SessionId").(string)
+	if !ok {
+		return res, fmt.Errorf("missing session")
+	}
+
+	AccountPin, _ := utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_ACCOUNT_PIN)
+		
 	if bytes.Equal(input, AccountPin) {
 		res.FlagSet = []uint32{flag_valid_pin}
 		res.FlagReset = []uint32{flag_pin_mismatch}
@@ -441,10 +440,9 @@ func (h *Handlers) CheckAccountStatus(ctx context.Context, sym string, input []b
 		return res, fmt.Errorf("missing session")
 	}
 
-	trackingId, err := utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_TRACKING_ID)
-	fmt.Println("Checking status with tracking id:", string(trackingId))
+	trackingId, _ := utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_TRACKING_ID)
 
-	status, err := h.accountService.CheckAccountStatus(string("1234"))
+	status, err := h.accountService.CheckAccountStatus(string(trackingId))
 
 	if err != nil {
 		fmt.Println("Error checking account status:", err)
@@ -524,13 +522,15 @@ func (h *Handlers) ResetIncorrectYob(ctx context.Context, sym string, input []by
 // the balance as the result content
 func (h *Handlers) CheckBalance(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 	res := resource.Result{}
-	// publicKey, err := h.db.Fetch([]byte(PublicKeyKey))
 
-	// if err != nil {
-	// 	return res, err
-	// }
+	sessionId, ok := ctx.Value("SessionId").(string)
+	if !ok {
+		return res, fmt.Errorf("missing session")
+	}
 
-	balance, err := h.accountService.CheckBalance(string("publicKey"))
+	publicKey, _ := utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_PUBLIC_KEY)
+
+	balance, err := h.accountService.CheckBalance(string(publicKey))
 	if err != nil {
 		return res, nil
 	}
diff --git a/internal/utils/db.go b/internal/utils/db.go
index 1104452..bfaf2e1 100644
--- a/internal/utils/db.go
+++ b/internal/utils/db.go
@@ -15,6 +15,7 @@ const (
 	DATA_TRACKING_ID
 	DATA_PUBLIC_KEY
 	DATA_CUSTODIAL_ID
+	DATA_ACCOUNT_PIN
 )
 
 func typToBytes(typ DataTyp) []byte {
@@ -37,7 +38,6 @@ func ReadEntry(ctx context.Context, store db.Db, sessionId string, typ DataTyp)
 		return nil, err
 	}
 	return b, nil
-
 }
 
 func WriteEntry(ctx context.Context, store db.Db, sessionId string, typ DataTyp, value []byte) error {

From 5abaf28f490d145532f914e2d06f54bc2e119bbb Mon Sep 17 00:00:00 2001
From: Carlosokumu <carlosokumu254@gmail.com>
Date: Thu, 5 Sep 2024 20:26:52 +0300
Subject: [PATCH 10/47] remove explicit attachment of state to engine

---
 cmd/main.go | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/cmd/main.go b/cmd/main.go
index 0529e81..dcb0b15 100644
--- a/cmd/main.go
+++ b/cmd/main.go
@@ -14,7 +14,6 @@ import (
 	"git.defalsify.org/vise.git/engine"
 	"git.defalsify.org/vise.git/persist"
 	"git.defalsify.org/vise.git/resource"
-	"git.defalsify.org/vise.git/state"
 	"git.defalsify.org/vise.git/logging"
 	"git.grassecon.net/urdt/ussd/internal/handlers/ussd"
 )
@@ -170,7 +169,7 @@ func main() {
 	}
 
 	en := getEngine(cfg, rs, pr)
-	en.WithState(state.NewState(uint32(16)))
+	
 
 	_, err = en.Init(ctx)
 	if err != nil {

From 643b4d87a974a4c1c53e40f3db3b2c4d120809b9 Mon Sep 17 00:00:00 2001
From: Carlosokumu <carlosokumu254@gmail.com>
Date: Thu, 5 Sep 2024 20:30:28 +0300
Subject: [PATCH 11/47] read account pin of gdbm store

---
 internal/handlers/ussd/menuhandler.go | 59 ++++++++++++++-------------
 1 file changed, 31 insertions(+), 28 deletions(-)

diff --git a/internal/handlers/ussd/menuhandler.go b/internal/handlers/ussd/menuhandler.go
index 5ac9456..92c401e 100644
--- a/internal/handlers/ussd/menuhandler.go
+++ b/internal/handlers/ussd/menuhandler.go
@@ -14,17 +14,17 @@ import (
 	"git.defalsify.org/vise.git/cache"
 	"git.defalsify.org/vise.git/db"
 	"git.defalsify.org/vise.git/lang"
+	"git.defalsify.org/vise.git/logging"
 	"git.defalsify.org/vise.git/persist"
 	"git.defalsify.org/vise.git/resource"
 	"git.defalsify.org/vise.git/state"
-	"git.defalsify.org/vise.git/logging"
 	"git.grassecon.net/urdt/ussd/internal/handlers/server"
 	"git.grassecon.net/urdt/ussd/internal/utils"
 	"gopkg.in/leonelquinteros/gotext.v1"
 )
 
 var (
-	logg = logging.NewVanilla().WithDomain("ussdmenuhandler")
+	logg           = logging.NewVanilla().WithDomain("ussdmenuhandler")
 	scriptDir      = path.Join("services", "registration")
 	translationDir = path.Join(scriptDir, "locale")
 )
@@ -244,7 +244,7 @@ func (h *Handlers) VerifyPin(ctx context.Context, sym string, input []byte) (res
 	}
 
 	AccountPin, _ := utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_ACCOUNT_PIN)
-		
+
 	if bytes.Equal(input, AccountPin) {
 		res.FlagSet = []uint32{flag_valid_pin}
 		res.FlagReset = []uint32{flag_pin_mismatch}
@@ -388,32 +388,35 @@ func (h *Handlers) CheckIdentifier(ctx context.Context, sym string, input []byte
 func (h *Handlers) Authorize(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 	res := resource.Result{}
 
-	// flag_incorrect_pin, _ := h.flagManager.GetFlag("flag_incorrect_pin")
-	// flag_account_authorized, _ := h.flagManager.GetFlag("flag_account_authorized")
-	// flag_allow_update, _ := h.flagManager.GetFlag("flag_allow_update")
+	flag_incorrect_pin, _ := h.flagManager.GetFlag("flag_incorrect_pin")
+	flag_account_authorized, _ := h.flagManager.GetFlag("flag_account_authorized")
+	flag_allow_update, _ := h.flagManager.GetFlag("flag_allow_update")
+	sessionId, ok := ctx.Value("SessionId").(string)
+	if !ok {
+		return res, fmt.Errorf("missing session")
+	}
+	AccountPin, err := utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_ACCOUNT_PIN)
+
+	if err == nil {
+		if len(input) == 4 {
+			if bytes.Equal(input, AccountPin) {
+				if h.st.MatchFlag(flag_account_authorized, false) {
+					res.FlagReset = append(res.FlagReset, flag_incorrect_pin)
+					res.FlagSet = append(res.FlagSet, flag_allow_update, flag_account_authorized)
+				} else {
+					res.FlagSet = append(res.FlagSet, flag_allow_update)
+					res.FlagReset = append(res.FlagReset, flag_account_authorized)
+				}
+			} else {
+				res.FlagSet = append(res.FlagSet, flag_incorrect_pin)
+				res.FlagReset = append(res.FlagReset, flag_account_authorized)
+				return res, nil
+			}
+		}
+	} else {
+		return res, nil
+	}
 
-	// storedpin, err := h.db.Fetch([]byte(AccountPin))
-	// if err == nil {
-	// 	if len(input) == 4 {
-	// 		if bytes.Equal(input, storedpin) {
-	// 			if h.fs.St.MatchFlag(flag_account_authorized, false) {
-	// 				res.FlagReset = append(res.FlagReset, flag_incorrect_pin)
-	// 				res.FlagSet = append(res.FlagSet, flag_allow_update, flag_account_authorized)
-	// 			} else {
-	// 				res.FlagSet = append(res.FlagSet, flag_allow_update)
-	// 				res.FlagReset = append(res.FlagReset, flag_account_authorized)
-	// 			}
-	// 		} else {
-	// 			res.FlagSet = append(res.FlagSet, flag_incorrect_pin)
-	// 			res.FlagReset = append(res.FlagReset, flag_account_authorized)
-	// 			return res, nil
-	// 		}
-	// 	}
-	// } else if errors.Is(err, gdbm.ErrItemNotFound) {
-	// 	return res, err
-	// } else {
-	// 	return res, err
-	// }
 	return res, nil
 }
 

From 0feb013c78a7039ddbf26141b54ec56d26eb4ed2 Mon Sep 17 00:00:00 2001
From: lash <dev@holbrook.no>
Date: Thu, 5 Sep 2024 20:35:51 +0100
Subject: [PATCH 12/47] Ensure handler init when state and cache is available

---
 go-vise                               |   2 +-
 internal/handlers/ussd/menuhandler.go | 200 ++++++++++++++++++++------
 internal/utils/filehandler.go         |  13 --
 services/registration/Makefile        |   2 +-
 4 files changed, 161 insertions(+), 56 deletions(-)
 delete mode 100644 internal/utils/filehandler.go

diff --git a/go-vise b/go-vise
index 326bdb5..2bddc36 160000
--- a/go-vise
+++ b/go-vise
@@ -1 +1 @@
-Subproject commit 326bdb5018ae81ee493371b56bd4564a8b35da59
+Subproject commit 2bddc363f20210ab019eec29d8ba4104d147e9b7
diff --git a/internal/handlers/ussd/menuhandler.go b/internal/handlers/ussd/menuhandler.go
index 92c401e..c43cb3b 100644
--- a/internal/handlers/ussd/menuhandler.go
+++ b/internal/handlers/ussd/menuhandler.go
@@ -75,6 +75,7 @@ func (fm *FlagManager) GetFlag(label string) (uint32, error) {
 }
 
 type Handlers struct {
+	pe	*persist.Persister
 	st                 *state.State
 	ca                 cache.Memory
 	userdataStore      db.Db
@@ -84,9 +85,14 @@ type Handlers struct {
 }
 
 func NewHandlers(appFlags *asm.FlagParser, pe *persist.Persister, userdataStore db.Db) (*Handlers, error) {
+	if pe == nil {
+		return nil, fmt.Errorf("cannot create handler with nil persister")
+	}
+	if userdataStore == nil {
+		return nil, fmt.Errorf("cannot create handler with nil userdata store")
+	}
 	h := &Handlers{
-		st:                 pe.State,
-		ca:                 pe.GetMemory(),
+		pe:	pe,
 		userdataStore:      userdataStore,
 		flagManager:        appFlags,
 		accountFileHandler: utils.NewAccountFileHandler(userdataStore),
@@ -104,9 +110,28 @@ func isValidPIN(pin string) bool {
 	return match
 }
 
+func (h *Handlers) Init(ctx context.Context, sym string, input []byte) (resource.Result, error) {
+	var r resource.Result
+	if h.pe == nil {
+		logg.WarnCtxf(ctx, "handler init called before it is ready or more than once", "state", h.st, "cache", h.ca)
+		return r, nil
+	}
+	h.st = h.pe.GetState()
+	h.ca = h.pe.GetMemory()
+	if h.st == nil || h.ca == nil {
+		logg.ErrorCtxf(ctx, "perister fail in handler", "state", h.st, "cache", h.ca)
+		return r, fmt.Errorf("cannot get state and memory for handler")
+	}	
+	h.pe = nil
+	return r, nil
+}
+
 // SetLanguage sets the language across the menu
 func (h *Handlers) SetLanguage(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res := resource.Result{}
+	res, err := h.Init(ctx, sym, input)
+	if err != nil {
+		return res, err
+	}
 
 	inputStr := string(input)
 	switch inputStr {
@@ -152,8 +177,10 @@ func (h *Handlers) createAccountNoExist(ctx context.Context, sessionId string, r
 // creates an account on the API,
 // sets the default values and flags
 func (h *Handlers) CreateAccount(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res := resource.Result{}
-	var err error
+	res, err := h.Init(ctx, sym, input)
+	if err != nil {
+		return res, err
+	}
 	sessionId, ok := ctx.Value("SessionId").(string)
 	if !ok {
 		return res, fmt.Errorf("missing session")
@@ -178,7 +205,10 @@ func (h *Handlers) CreateAccount(ctx context.Context, sym string, input []byte)
 
 // SavePin persists the user's PIN choice into the filesystem
 func (h *Handlers) SavePin(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res := resource.Result{}
+	res, err := h.Init(ctx, sym, input)
+	if err != nil {
+		return res, err
+	}
 	sessionId, ok := ctx.Value("SessionId").(string)
 	if !ok {
 		return res, fmt.Errorf("missing session")
@@ -195,7 +225,7 @@ func (h *Handlers) SavePin(ctx context.Context, sym string, input []byte) (resou
 
 	res.FlagReset = append(res.FlagReset, flag_incorrect_pin)
 
-	err := utils.WriteEntry(ctx, h.userdataStore, sessionId, utils.DATA_ACCOUNT_PIN, []byte(accountPIN))
+	err = utils.WriteEntry(ctx, h.userdataStore, sessionId, utils.DATA_ACCOUNT_PIN, []byte(accountPIN))
 	if err != nil {
 		return res, nil
 	}
@@ -205,7 +235,10 @@ func (h *Handlers) SavePin(ctx context.Context, sym string, input []byte) (resou
 
 // SetResetSingleEdit sets and resets  flags to allow gradual editing of profile information.
 func (h *Handlers) SetResetSingleEdit(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res := resource.Result{}
+	res, err := h.Init(ctx, sym, input)
+	if err != nil {
+		return res, err
+	}
 	menuOption := string(input)
 
 	flag_allow_update, _ := h.flagManager.GetFlag("flag_allow_update")
@@ -232,7 +265,10 @@ func (h *Handlers) SetResetSingleEdit(ctx context.Context, sym string, input []b
 // If similar, it sets the USERFLAG_PIN_SET flag allowing the user
 // to access the main menu
 func (h *Handlers) VerifyPin(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res := resource.Result{}
+	res, err := h.Init(ctx, sym, input)
+	if err != nil {
+		return res, err
+	}
 
 	flag_valid_pin, _ := h.flagManager.GetFlag("flag_valid_pin")
 	flag_pin_mismatch, _ := h.flagManager.GetFlag("flag_pin_mismatch")
@@ -267,8 +303,11 @@ func codeFromCtx(ctx context.Context) string {
 }
 
 // SaveFirstname updates the first name in a JSON data file with the provided input.
-func (h *Handlers) SaveFirstname(cxt context.Context, sym string, input []byte) (resource.Result, error) {
-	res := resource.Result{}
+func (h *Handlers) SaveFirstname(ctx context.Context, sym string, input []byte) (resource.Result, error) {
+	res, err := h.Init(ctx, sym, input)
+	if err != nil {
+		return res, err
+	}
 	if len(input) > 0 {
 		//name := string(input)
 		//key := []byte(FirstName)
@@ -280,8 +319,11 @@ func (h *Handlers) SaveFirstname(cxt context.Context, sym string, input []byte)
 }
 
 // SaveFamilyname updates the family name in a JSON data file with the provided input.
-func (h *Handlers) SaveFamilyname(cxt context.Context, sym string, input []byte) (resource.Result, error) {
-	res := resource.Result{}
+func (h *Handlers) SaveFamilyname(ctx context.Context, sym string, input []byte) (resource.Result, error) {
+	res, err := h.Init(ctx, sym, input)
+	if err != nil {
+		return res, err
+	}
 	if len(input) > 0 {
 		//secondname := string(input)
 		//key := []byte(FamilyName)
@@ -293,8 +335,11 @@ func (h *Handlers) SaveFamilyname(cxt context.Context, sym string, input []byte)
 }
 
 // SaveYOB updates the Year of Birth(YOB) in a JSON data file with the provided input.
-func (h *Handlers) SaveYob(cxt context.Context, sym string, input []byte) (resource.Result, error) {
-	res := resource.Result{}
+func (h *Handlers) SaveYob(ctx context.Context, sym string, input []byte) (resource.Result, error) {
+	res, err := h.Init(ctx, sym, input)
+	if err != nil {
+		return res, err
+	}
 	yob := string(input)
 	if len(yob) == 4 {
 		//yob := string(input)
@@ -307,8 +352,11 @@ func (h *Handlers) SaveYob(cxt context.Context, sym string, input []byte) (resou
 }
 
 // SaveLocation updates the location in a JSON data file with the provided input.
-func (h *Handlers) SaveLocation(cxt context.Context, sym string, input []byte) (resource.Result, error) {
-	res := resource.Result{}
+func (h *Handlers) SaveLocation(ctx context.Context, sym string, input []byte) (resource.Result, error) {
+	res, err := h.Init(ctx, sym, input)
+	if err != nil {
+		return res, err
+	}
 	if len(input) > 0 {
 		//location := string(input)
 		//key := []byte(Location)
@@ -322,7 +370,10 @@ func (h *Handlers) SaveLocation(cxt context.Context, sym string, input []byte) (
 
 // SaveGender updates the gender in a JSON data file with the provided input.
 func (h *Handlers) SaveGender(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res := resource.Result{}
+	res, err := h.Init(ctx, sym, input)
+	if err != nil {
+		return res, err
+	}
 	if len(input) > 0 {
 		gender := string(input)
 		switch gender {
@@ -342,7 +393,10 @@ func (h *Handlers) SaveGender(ctx context.Context, sym string, input []byte) (re
 
 // SaveOfferings updates the offerings(goods and services provided by the user) in a JSON data file with the provided input.
 func (h *Handlers) SaveOfferings(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res := resource.Result{}
+	res, err := h.Init(ctx, sym, input)
+	if err != nil {
+		return res, err
+	}
 	if len(input) > 0 {
 		//offerings := string(input)
 		//key := []byte(Offerings)
@@ -354,7 +408,10 @@ func (h *Handlers) SaveOfferings(ctx context.Context, sym string, input []byte)
 
 // ResetAllowUpdate resets the allowupdate flag that allows a user to update  profile data.
 func (h *Handlers) ResetAllowUpdate(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res := resource.Result{}
+	res, err := h.Init(ctx, sym, input)
+	if err != nil {
+		return res, err
+	}
 
 	flag_allow_update, _ := h.flagManager.GetFlag("flag_allow_update")
 
@@ -364,7 +421,10 @@ func (h *Handlers) ResetAllowUpdate(ctx context.Context, sym string, input []byt
 
 // ResetAccountAuthorized resets the account authorization flag after a successful PIN entry.
 func (h *Handlers) ResetAccountAuthorized(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res := resource.Result{}
+	res, err := h.Init(ctx, sym, input)
+	if err != nil {
+		return res, err
+	}
 
 	flag_account_authorized, _ := h.flagManager.GetFlag("flag_account_authorized")
 
@@ -374,7 +434,10 @@ func (h *Handlers) ResetAccountAuthorized(ctx context.Context, sym string, input
 
 // CheckIdentifier retrieves the PublicKey from the JSON data file.
 func (h *Handlers) CheckIdentifier(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res := resource.Result{}
+	res, err := h.Init(ctx, sym, input)
+	if err != nil {
+		return res, err
+	}
 	//publicKey, err := h.db.Fetch([]byte(PublicKeyKey))
 	// if err != nil {
 	// 	return res, err
@@ -386,7 +449,10 @@ func (h *Handlers) CheckIdentifier(ctx context.Context, sym string, input []byte
 // Authorize attempts to unlock the next sequential nodes by verifying the provided PIN against the already set PIN.
 // It sets the required flags that control the flow.
 func (h *Handlers) Authorize(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res := resource.Result{}
+	res, err := h.Init(ctx, sym, input)
+	if err != nil {
+		return res, err
+	}
 
 	flag_incorrect_pin, _ := h.flagManager.GetFlag("flag_incorrect_pin")
 	flag_account_authorized, _ := h.flagManager.GetFlag("flag_account_authorized")
@@ -422,7 +488,10 @@ func (h *Handlers) Authorize(ctx context.Context, sym string, input []byte) (res
 
 // ResetIncorrectPin resets the incorrect pin flag  after a new PIN attempt.
 func (h *Handlers) ResetIncorrectPin(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res := resource.Result{}
+	res, err := h.Init(ctx, sym, input)
+	if err != nil {
+		return res, err
+	}
 
 	flag_incorrect_pin, _ := h.flagManager.GetFlag("flag_incorrect_pin")
 
@@ -433,7 +502,10 @@ func (h *Handlers) ResetIncorrectPin(ctx context.Context, sym string, input []by
 // CheckAccountStatus queries the API using the TrackingId and sets flags
 // based on the account status
 func (h *Handlers) CheckAccountStatus(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res := resource.Result{}
+	res, err := h.Init(ctx, sym, input)
+	if err != nil {
+		return res, err
+	}
 
 	flag_account_success, _ := h.flagManager.GetFlag("flag_account_success")
 	flag_account_pending, _ := h.flagManager.GetFlag("flag_account_pending")
@@ -475,7 +547,10 @@ func (h *Handlers) CheckAccountStatus(ctx context.Context, sym string, input []b
 
 // Quit displays the Thank you message and exits the menu
 func (h *Handlers) Quit(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res := resource.Result{}
+	res, err := h.Init(ctx, sym, input)
+	if err != nil {
+		return res, err
+	}
 
 	flag_account_authorized, _ := h.flagManager.GetFlag("flag_account_authorized")
 
@@ -490,12 +565,15 @@ func (h *Handlers) Quit(ctx context.Context, sym string, input []byte) (resource
 
 // VerifyYob verifies the length of the given input
 func (h *Handlers) VerifyYob(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res := resource.Result{}
+	res, err := h.Init(ctx, sym, input)
+	if err != nil {
+		return res, err
+	}
 
 	flag_incorrect_date_format, _ := h.flagManager.GetFlag("flag_incorrect_date_format")
 
 	date := string(input)
-	_, err := strconv.Atoi(date)
+	_, err = strconv.Atoi(date)
 	if err != nil {
 		// If conversion fails, input is not numeric
 		res.FlagSet = append(res.FlagSet, flag_incorrect_date_format)
@@ -513,7 +591,10 @@ func (h *Handlers) VerifyYob(ctx context.Context, sym string, input []byte) (res
 
 // ResetIncorrectYob resets the incorrect date format flag after a new attempt
 func (h *Handlers) ResetIncorrectYob(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res := resource.Result{}
+	res, err := h.Init(ctx, sym, input)
+	if err != nil {
+		return res, err
+	}
 
 	flag_incorrect_date_format, _ := h.flagManager.GetFlag("flag_incorrect_date_format")
 
@@ -524,7 +605,11 @@ func (h *Handlers) ResetIncorrectYob(ctx context.Context, sym string, input []by
 // CheckBalance retrieves the balance from the API using the "PublicKey" and sets
 // the balance as the result content
 func (h *Handlers) CheckBalance(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res := resource.Result{}
+	res, err := h.Init(ctx, sym, input)
+	if err != nil {
+		return res, err
+	}
+	// publicKey, err := h.db.Fetch([]byte(PublicKeyKey))
 
 	sessionId, ok := ctx.Value("SessionId").(string)
 	if !ok {
@@ -544,7 +629,10 @@ func (h *Handlers) CheckBalance(ctx context.Context, sym string, input []byte) (
 
 // ValidateRecipient validates that the given input is a valid phone number.
 func (h *Handlers) ValidateRecipient(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res := resource.Result{}
+	res, err := h.Init(ctx, sym, input)
+	if err != nil {
+		return res, err
+	}
 	recipient := string(input)
 
 	flag_invalid_recipient, _ := h.flagManager.GetFlag("flag_invalid_recipient")
@@ -571,7 +659,10 @@ func (h *Handlers) ValidateRecipient(ctx context.Context, sym string, input []by
 // TransactionReset resets the previous transaction data (Recipient and Amount)
 // as well as the invalid flags
 func (h *Handlers) TransactionReset(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res := resource.Result{}
+	res, err := h.Init(ctx, sym, input)
+	if err != nil {
+		return res, err
+	}
 
 	flag_invalid_recipient, _ := h.flagManager.GetFlag("flag_invalid_recipient")
 	flag_invalid_recipient_with_invite, _ := h.flagManager.GetFlag("flag_invalid_recipient_with_invite")
@@ -592,7 +683,10 @@ func (h *Handlers) TransactionReset(ctx context.Context, sym string, input []byt
 
 // ResetTransactionAmount resets the transaction amount and invalid flag
 func (h *Handlers) ResetTransactionAmount(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res := resource.Result{}
+	res, err := h.Init(ctx, sym, input)
+	if err != nil {
+		return res, err
+	}
 
 	flag_invalid_amount, _ := h.flagManager.GetFlag("flag_invalid_amount")
 
@@ -609,7 +703,10 @@ func (h *Handlers) ResetTransactionAmount(ctx context.Context, sym string, input
 // MaxAmount gets the current balance from the API and sets it as
 // the result content.
 func (h *Handlers) MaxAmount(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res := resource.Result{}
+	res, err := h.Init(ctx, sym, input)
+	if err != nil {
+		return res, err
+	}
 	// publicKey, err := h.db.Fetch([]byte(PublicKeyKey))
 	// if err != nil {
 	// 	return res, err
@@ -628,7 +725,10 @@ func (h *Handlers) MaxAmount(ctx context.Context, sym string, input []byte) (res
 // ValidateAmount ensures that the given input is a valid amount and that
 // it is not more than the current balance.
 func (h *Handlers) ValidateAmount(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res := resource.Result{}
+	res, err := h.Init(ctx, sym, input)
+	if err != nil {
+		return res, err
+	}
 
 	flag_invalid_amount, _ := h.flagManager.GetFlag("flag_invalid_amount")
 
@@ -692,7 +792,10 @@ func (h *Handlers) ValidateAmount(ctx context.Context, sym string, input []byte)
 
 // GetRecipient returns the transaction recipient from a JSON data file.
 func (h *Handlers) GetRecipient(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res := resource.Result{}
+	res, err := h.Init(ctx, sym, input)
+	if err != nil {
+		return res, err
+	}
 	// recipient, err := h.db.Fetch([]byte(Recipient))
 	// if err != nil {
 	// 	return res, err
@@ -705,7 +808,10 @@ func (h *Handlers) GetRecipient(ctx context.Context, sym string, input []byte) (
 
 // GetSender retrieves the public key from the Gdbm Db
 func (h *Handlers) GetSender(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res := resource.Result{}
+	res, err := h.Init(ctx, sym, input)
+	if err != nil {
+		return res, err
+	}
 	// publicKey, err := h.db.Fetch([]byte(PublicKeyKey))
 	// if err != nil {
 	// 	return res, err
@@ -718,7 +824,10 @@ func (h *Handlers) GetSender(ctx context.Context, sym string, input []byte) (res
 
 // GetAmount retrieves the amount from teh Gdbm Db
 func (h *Handlers) GetAmount(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res := resource.Result{}
+	res, err := h.Init(ctx, sym, input)
+	if err != nil {
+		return res, err
+	}
 	// amount, err := h.db.Fetch([]byte(Amount))
 	// if err != nil {
 	// 	return res, err
@@ -731,7 +840,10 @@ func (h *Handlers) GetAmount(ctx context.Context, sym string, input []byte) (res
 // QuickWithBalance retrieves the balance for a given public key from the custodial balance API endpoint before
 // gracefully exiting the session.
 func (h *Handlers) QuitWithBalance(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res := resource.Result{}
+	res, err := h.Init(ctx, sym, input)
+	if err != nil {
+		return res, err
+	}
 
 	flag_account_authorized, _ := h.flagManager.GetFlag("flag_account_authorized")
 
@@ -754,7 +866,10 @@ func (h *Handlers) QuitWithBalance(ctx context.Context, sym string, input []byte
 // InitiateTransaction returns a confirmation and resets the transaction data
 // on the JSON file.
 func (h *Handlers) InitiateTransaction(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res := resource.Result{}
+	res, err := h.Init(ctx, sym, input)
+	if err != nil {
+		return res, err
+	}
 	code := codeFromCtx(ctx)
 	l := gotext.NewLocale(translationDir, code)
 	l.AddDomain("default")
@@ -787,7 +902,10 @@ func (h *Handlers) InitiateTransaction(ctx context.Context, sym string, input []
 
 // GetProfileInfo retrieves and formats the profile information of a user from a Gdbm backed storage.
 func (h *Handlers) GetProfileInfo(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res := resource.Result{}
+	res, err := h.Init(ctx, sym, input)
+	if err != nil {
+		return res, err
+	}
 
 	// Define default values
 	defaultValue := "Not provided"
diff --git a/internal/utils/filehandler.go b/internal/utils/filehandler.go
deleted file mode 100644
index 8b11e29..0000000
--- a/internal/utils/filehandler.go
+++ /dev/null
@@ -1,13 +0,0 @@
-package utils
-
-
-
-
-type AccountFileHandlerInterface interface {
-    EnsureFileExists() error
-    ReadAccountData() (map[string]string, error)
-    WriteAccountData(data map[string]string) error
-}
-
-
-
diff --git a/services/registration/Makefile b/services/registration/Makefile
index 1863b0b..af8b8c1 100644
--- a/services/registration/Makefile
+++ b/services/registration/Makefile
@@ -4,7 +4,7 @@ TXTS = $(wildcard ./*.txt.orig)
 
 # Rule to build .bin files from .vis files
 %.vis:
-	go run ../../go-vise/dev/asm -f pp.csv $(basename $@).vis > $(basename $@).bin
+	go run  ../../go-vise/dev/asm/main.go -f pp.csv $(basename $@).vis > $(basename $@).bin
 	@echo "Built $(basename $@).bin from $(basename $@).vis"
 
 # Rule to copy .orig files to .txt

From cad8e86c8b74e55cf473a66642f69c4b6f752767 Mon Sep 17 00:00:00 2001
From: lash <dev@holbrook.no>
Date: Thu, 5 Sep 2024 23:55:51 +0100
Subject: [PATCH 13/47] Remove manual init calls in handler funcs

---
 cmd/main.go                           |   9 +-
 internal/handlers/ussd/menuhandler.go | 191 +++++++++-----------------
 2 files changed, 70 insertions(+), 130 deletions(-)

diff --git a/cmd/main.go b/cmd/main.go
index dcb0b15..a7f7174 100644
--- a/cmd/main.go
+++ b/cmd/main.go
@@ -115,9 +115,11 @@ func main() {
 	var resourceDir string
 	var size uint
 	var sessionId string
+	var debug bool
 	flag.StringVar(&sessionId, "session-id", "075xx2123", "session id")
 	flag.StringVar(&dbDir, "dbdir", ".state", "database dir to read from")
 	flag.StringVar(&resourceDir, "resourcedir", path.Join("services", "registration"), "resource dir")
+	flag.BoolVar(&debug, "d", false, "use engine debug output")
 	flag.UintVar(&size, "s", 160, "max size of output")
 	flag.Parse()
 
@@ -162,14 +164,17 @@ func main() {
 		os.Exit(1)
 	}
 
-	_, err = getHandler(flagParser, dbResource, pr, store)
+	hl, err := getHandler(flagParser, dbResource, pr, store)
 	if err != nil {
 		fmt.Fprintf(os.Stderr, err.Error())
 		os.Exit(1)
 	}
 
 	en := getEngine(cfg, rs, pr)
-	
+	en = en.WithFirst(hl.Init)
+	if debug {
+		en = en.WithDebug(nil)
+	}
 
 	_, err = en.Init(ctx)
 	if err != nil {
diff --git a/internal/handlers/ussd/menuhandler.go b/internal/handlers/ussd/menuhandler.go
index c43cb3b..8b22753 100644
--- a/internal/handlers/ussd/menuhandler.go
+++ b/internal/handlers/ussd/menuhandler.go
@@ -112,6 +112,7 @@ func isValidPIN(pin string) bool {
 
 func (h *Handlers) Init(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 	var r resource.Result
+
 	if h.pe == nil {
 		logg.WarnCtxf(ctx, "handler init called before it is ready or more than once", "state", h.st, "cache", h.ca)
 		return r, nil
@@ -123,15 +124,16 @@ func (h *Handlers) Init(ctx context.Context, sym string, input []byte) (resource
 		return r, fmt.Errorf("cannot get state and memory for handler")
 	}	
 	h.pe = nil
+
+	logg.DebugCtxf(ctx, "handler has been initialized", "state", h.st, "cache", h.ca)
+
 	return r, nil
 }
 
 // SetLanguage sets the language across the menu
 func (h *Handlers) SetLanguage(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res, err := h.Init(ctx, sym, input)
-	if err != nil {
-		return res, err
-	}
+	var res resource.Result
+	var err error
 
 	inputStr := string(input)
 	switch inputStr {
@@ -177,10 +179,9 @@ func (h *Handlers) createAccountNoExist(ctx context.Context, sessionId string, r
 // creates an account on the API,
 // sets the default values and flags
 func (h *Handlers) CreateAccount(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res, err := h.Init(ctx, sym, input)
-	if err != nil {
-		return res, err
-	}
+	var res resource.Result
+	var err error
+
 	sessionId, ok := ctx.Value("SessionId").(string)
 	if !ok {
 		return res, fmt.Errorf("missing session")
@@ -205,10 +206,9 @@ func (h *Handlers) CreateAccount(ctx context.Context, sym string, input []byte)
 
 // SavePin persists the user's PIN choice into the filesystem
 func (h *Handlers) SavePin(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res, err := h.Init(ctx, sym, input)
-	if err != nil {
-		return res, err
-	}
+	var res resource.Result
+	var err error
+	
 	sessionId, ok := ctx.Value("SessionId").(string)
 	if !ok {
 		return res, fmt.Errorf("missing session")
@@ -235,10 +235,8 @@ func (h *Handlers) SavePin(ctx context.Context, sym string, input []byte) (resou
 
 // SetResetSingleEdit sets and resets  flags to allow gradual editing of profile information.
 func (h *Handlers) SetResetSingleEdit(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res, err := h.Init(ctx, sym, input)
-	if err != nil {
-		return res, err
-	}
+	var res resource.Result
+	
 	menuOption := string(input)
 
 	flag_allow_update, _ := h.flagManager.GetFlag("flag_allow_update")
@@ -265,10 +263,7 @@ func (h *Handlers) SetResetSingleEdit(ctx context.Context, sym string, input []b
 // If similar, it sets the USERFLAG_PIN_SET flag allowing the user
 // to access the main menu
 func (h *Handlers) VerifyPin(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res, err := h.Init(ctx, sym, input)
-	if err != nil {
-		return res, err
-	}
+	var res resource.Result
 
 	flag_valid_pin, _ := h.flagManager.GetFlag("flag_valid_pin")
 	flag_pin_mismatch, _ := h.flagManager.GetFlag("flag_pin_mismatch")
@@ -304,10 +299,8 @@ func codeFromCtx(ctx context.Context) string {
 
 // SaveFirstname updates the first name in a JSON data file with the provided input.
 func (h *Handlers) SaveFirstname(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res, err := h.Init(ctx, sym, input)
-	if err != nil {
-		return res, err
-	}
+	var res resource.Result
+
 	if len(input) > 0 {
 		//name := string(input)
 		//key := []byte(FirstName)
@@ -320,10 +313,8 @@ func (h *Handlers) SaveFirstname(ctx context.Context, sym string, input []byte)
 
 // SaveFamilyname updates the family name in a JSON data file with the provided input.
 func (h *Handlers) SaveFamilyname(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res, err := h.Init(ctx, sym, input)
-	if err != nil {
-		return res, err
-	}
+	var res resource.Result
+
 	if len(input) > 0 {
 		//secondname := string(input)
 		//key := []byte(FamilyName)
@@ -336,10 +327,8 @@ func (h *Handlers) SaveFamilyname(ctx context.Context, sym string, input []byte)
 
 // SaveYOB updates the Year of Birth(YOB) in a JSON data file with the provided input.
 func (h *Handlers) SaveYob(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res, err := h.Init(ctx, sym, input)
-	if err != nil {
-		return res, err
-	}
+	var res resource.Result
+
 	yob := string(input)
 	if len(yob) == 4 {
 		//yob := string(input)
@@ -353,10 +342,8 @@ func (h *Handlers) SaveYob(ctx context.Context, sym string, input []byte) (resou
 
 // SaveLocation updates the location in a JSON data file with the provided input.
 func (h *Handlers) SaveLocation(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res, err := h.Init(ctx, sym, input)
-	if err != nil {
-		return res, err
-	}
+	var res resource.Result
+
 	if len(input) > 0 {
 		//location := string(input)
 		//key := []byte(Location)
@@ -370,10 +357,8 @@ func (h *Handlers) SaveLocation(ctx context.Context, sym string, input []byte) (
 
 // SaveGender updates the gender in a JSON data file with the provided input.
 func (h *Handlers) SaveGender(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res, err := h.Init(ctx, sym, input)
-	if err != nil {
-		return res, err
-	}
+	var res resource.Result
+
 	if len(input) > 0 {
 		gender := string(input)
 		switch gender {
@@ -393,10 +378,8 @@ func (h *Handlers) SaveGender(ctx context.Context, sym string, input []byte) (re
 
 // SaveOfferings updates the offerings(goods and services provided by the user) in a JSON data file with the provided input.
 func (h *Handlers) SaveOfferings(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res, err := h.Init(ctx, sym, input)
-	if err != nil {
-		return res, err
-	}
+	var res resource.Result
+
 	if len(input) > 0 {
 		//offerings := string(input)
 		//key := []byte(Offerings)
@@ -408,10 +391,7 @@ func (h *Handlers) SaveOfferings(ctx context.Context, sym string, input []byte)
 
 // ResetAllowUpdate resets the allowupdate flag that allows a user to update  profile data.
 func (h *Handlers) ResetAllowUpdate(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res, err := h.Init(ctx, sym, input)
-	if err != nil {
-		return res, err
-	}
+	var res resource.Result
 
 	flag_allow_update, _ := h.flagManager.GetFlag("flag_allow_update")
 
@@ -421,10 +401,7 @@ func (h *Handlers) ResetAllowUpdate(ctx context.Context, sym string, input []byt
 
 // ResetAccountAuthorized resets the account authorization flag after a successful PIN entry.
 func (h *Handlers) ResetAccountAuthorized(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res, err := h.Init(ctx, sym, input)
-	if err != nil {
-		return res, err
-	}
+	var res resource.Result
 
 	flag_account_authorized, _ := h.flagManager.GetFlag("flag_account_authorized")
 
@@ -434,10 +411,8 @@ func (h *Handlers) ResetAccountAuthorized(ctx context.Context, sym string, input
 
 // CheckIdentifier retrieves the PublicKey from the JSON data file.
 func (h *Handlers) CheckIdentifier(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res, err := h.Init(ctx, sym, input)
-	if err != nil {
-		return res, err
-	}
+	var res resource.Result
+
 	//publicKey, err := h.db.Fetch([]byte(PublicKeyKey))
 	// if err != nil {
 	// 	return res, err
@@ -449,10 +424,8 @@ func (h *Handlers) CheckIdentifier(ctx context.Context, sym string, input []byte
 // Authorize attempts to unlock the next sequential nodes by verifying the provided PIN against the already set PIN.
 // It sets the required flags that control the flow.
 func (h *Handlers) Authorize(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res, err := h.Init(ctx, sym, input)
-	if err != nil {
-		return res, err
-	}
+	var res resource.Result
+	var err error
 
 	flag_incorrect_pin, _ := h.flagManager.GetFlag("flag_incorrect_pin")
 	flag_account_authorized, _ := h.flagManager.GetFlag("flag_account_authorized")
@@ -488,10 +461,7 @@ func (h *Handlers) Authorize(ctx context.Context, sym string, input []byte) (res
 
 // ResetIncorrectPin resets the incorrect pin flag  after a new PIN attempt.
 func (h *Handlers) ResetIncorrectPin(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res, err := h.Init(ctx, sym, input)
-	if err != nil {
-		return res, err
-	}
+	var res resource.Result
 
 	flag_incorrect_pin, _ := h.flagManager.GetFlag("flag_incorrect_pin")
 
@@ -502,10 +472,7 @@ func (h *Handlers) ResetIncorrectPin(ctx context.Context, sym string, input []by
 // CheckAccountStatus queries the API using the TrackingId and sets flags
 // based on the account status
 func (h *Handlers) CheckAccountStatus(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res, err := h.Init(ctx, sym, input)
-	if err != nil {
-		return res, err
-	}
+	var res resource.Result
 
 	flag_account_success, _ := h.flagManager.GetFlag("flag_account_success")
 	flag_account_pending, _ := h.flagManager.GetFlag("flag_account_pending")
@@ -547,10 +514,7 @@ func (h *Handlers) CheckAccountStatus(ctx context.Context, sym string, input []b
 
 // Quit displays the Thank you message and exits the menu
 func (h *Handlers) Quit(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res, err := h.Init(ctx, sym, input)
-	if err != nil {
-		return res, err
-	}
+	var res resource.Result
 
 	flag_account_authorized, _ := h.flagManager.GetFlag("flag_account_authorized")
 
@@ -565,10 +529,8 @@ func (h *Handlers) Quit(ctx context.Context, sym string, input []byte) (resource
 
 // VerifyYob verifies the length of the given input
 func (h *Handlers) VerifyYob(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res, err := h.Init(ctx, sym, input)
-	if err != nil {
-		return res, err
-	}
+	var res resource.Result
+	var err error
 
 	flag_incorrect_date_format, _ := h.flagManager.GetFlag("flag_incorrect_date_format")
 
@@ -591,10 +553,7 @@ func (h *Handlers) VerifyYob(ctx context.Context, sym string, input []byte) (res
 
 // ResetIncorrectYob resets the incorrect date format flag after a new attempt
 func (h *Handlers) ResetIncorrectYob(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res, err := h.Init(ctx, sym, input)
-	if err != nil {
-		return res, err
-	}
+	var res resource.Result
 
 	flag_incorrect_date_format, _ := h.flagManager.GetFlag("flag_incorrect_date_format")
 
@@ -605,10 +564,9 @@ func (h *Handlers) ResetIncorrectYob(ctx context.Context, sym string, input []by
 // CheckBalance retrieves the balance from the API using the "PublicKey" and sets
 // the balance as the result content
 func (h *Handlers) CheckBalance(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res, err := h.Init(ctx, sym, input)
-	if err != nil {
-		return res, err
-	}
+	var res resource.Result
+	var err error
+
 	// publicKey, err := h.db.Fetch([]byte(PublicKeyKey))
 
 	sessionId, ok := ctx.Value("SessionId").(string)
@@ -629,10 +587,8 @@ func (h *Handlers) CheckBalance(ctx context.Context, sym string, input []byte) (
 
 // ValidateRecipient validates that the given input is a valid phone number.
 func (h *Handlers) ValidateRecipient(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res, err := h.Init(ctx, sym, input)
-	if err != nil {
-		return res, err
-	}
+	var res resource.Result
+
 	recipient := string(input)
 
 	flag_invalid_recipient, _ := h.flagManager.GetFlag("flag_invalid_recipient")
@@ -659,10 +615,7 @@ func (h *Handlers) ValidateRecipient(ctx context.Context, sym string, input []by
 // TransactionReset resets the previous transaction data (Recipient and Amount)
 // as well as the invalid flags
 func (h *Handlers) TransactionReset(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res, err := h.Init(ctx, sym, input)
-	if err != nil {
-		return res, err
-	}
+	var res resource.Result
 
 	flag_invalid_recipient, _ := h.flagManager.GetFlag("flag_invalid_recipient")
 	flag_invalid_recipient_with_invite, _ := h.flagManager.GetFlag("flag_invalid_recipient_with_invite")
@@ -683,10 +636,7 @@ func (h *Handlers) TransactionReset(ctx context.Context, sym string, input []byt
 
 // ResetTransactionAmount resets the transaction amount and invalid flag
 func (h *Handlers) ResetTransactionAmount(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res, err := h.Init(ctx, sym, input)
-	if err != nil {
-		return res, err
-	}
+	var res resource.Result
 
 	flag_invalid_amount, _ := h.flagManager.GetFlag("flag_invalid_amount")
 
@@ -703,10 +653,9 @@ func (h *Handlers) ResetTransactionAmount(ctx context.Context, sym string, input
 // MaxAmount gets the current balance from the API and sets it as
 // the result content.
 func (h *Handlers) MaxAmount(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res, err := h.Init(ctx, sym, input)
-	if err != nil {
-		return res, err
-	}
+	var res resource.Result
+	var err error
+
 	// publicKey, err := h.db.Fetch([]byte(PublicKeyKey))
 	// if err != nil {
 	// 	return res, err
@@ -725,10 +674,8 @@ func (h *Handlers) MaxAmount(ctx context.Context, sym string, input []byte) (res
 // ValidateAmount ensures that the given input is a valid amount and that
 // it is not more than the current balance.
 func (h *Handlers) ValidateAmount(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res, err := h.Init(ctx, sym, input)
-	if err != nil {
-		return res, err
-	}
+	var res resource.Result
+	var err error
 
 	flag_invalid_amount, _ := h.flagManager.GetFlag("flag_invalid_amount")
 
@@ -792,10 +739,8 @@ func (h *Handlers) ValidateAmount(ctx context.Context, sym string, input []byte)
 
 // GetRecipient returns the transaction recipient from a JSON data file.
 func (h *Handlers) GetRecipient(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res, err := h.Init(ctx, sym, input)
-	if err != nil {
-		return res, err
-	}
+	var res resource.Result
+
 	// recipient, err := h.db.Fetch([]byte(Recipient))
 	// if err != nil {
 	// 	return res, err
@@ -808,10 +753,8 @@ func (h *Handlers) GetRecipient(ctx context.Context, sym string, input []byte) (
 
 // GetSender retrieves the public key from the Gdbm Db
 func (h *Handlers) GetSender(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res, err := h.Init(ctx, sym, input)
-	if err != nil {
-		return res, err
-	}
+	var res resource.Result
+
 	// publicKey, err := h.db.Fetch([]byte(PublicKeyKey))
 	// if err != nil {
 	// 	return res, err
@@ -824,10 +767,8 @@ func (h *Handlers) GetSender(ctx context.Context, sym string, input []byte) (res
 
 // GetAmount retrieves the amount from teh Gdbm Db
 func (h *Handlers) GetAmount(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res, err := h.Init(ctx, sym, input)
-	if err != nil {
-		return res, err
-	}
+	var res resource.Result
+
 	// amount, err := h.db.Fetch([]byte(Amount))
 	// if err != nil {
 	// 	return res, err
@@ -840,10 +781,8 @@ func (h *Handlers) GetAmount(ctx context.Context, sym string, input []byte) (res
 // QuickWithBalance retrieves the balance for a given public key from the custodial balance API endpoint before
 // gracefully exiting the session.
 func (h *Handlers) QuitWithBalance(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res, err := h.Init(ctx, sym, input)
-	if err != nil {
-		return res, err
-	}
+	var res resource.Result
+	var err error
 
 	flag_account_authorized, _ := h.flagManager.GetFlag("flag_account_authorized")
 
@@ -866,10 +805,9 @@ func (h *Handlers) QuitWithBalance(ctx context.Context, sym string, input []byte
 // InitiateTransaction returns a confirmation and resets the transaction data
 // on the JSON file.
 func (h *Handlers) InitiateTransaction(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res, err := h.Init(ctx, sym, input)
-	if err != nil {
-		return res, err
-	}
+	var res resource.Result
+	var err error
+
 	code := codeFromCtx(ctx)
 	l := gotext.NewLocale(translationDir, code)
 	l.AddDomain("default")
@@ -902,10 +840,7 @@ func (h *Handlers) InitiateTransaction(ctx context.Context, sym string, input []
 
 // GetProfileInfo retrieves and formats the profile information of a user from a Gdbm backed storage.
 func (h *Handlers) GetProfileInfo(ctx context.Context, sym string, input []byte) (resource.Result, error) {
-	res, err := h.Init(ctx, sym, input)
-	if err != nil {
-		return res, err
-	}
+	var res resource.Result
 
 	// Define default values
 	defaultValue := "Not provided"

From de8c7ce34afb6aae954a91c4f0151688bfbbf21a Mon Sep 17 00:00:00 2001
From: alfred-mk <alfredmwaik@gmail.com>
Date: Fri, 6 Sep 2024 08:35:01 +0300
Subject: [PATCH 14/47] Added user data to db.go util

---
 internal/utils/db.go | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/internal/utils/db.go b/internal/utils/db.go
index bfaf2e1..32fb804 100644
--- a/internal/utils/db.go
+++ b/internal/utils/db.go
@@ -16,6 +16,15 @@ const (
 	DATA_PUBLIC_KEY
 	DATA_CUSTODIAL_ID
 	DATA_ACCOUNT_PIN
+	DATA_ACCOUNT_STATUS
+	DATA_FIRST_NAME
+	DATA_FAMILY_NAME
+	DATA_YOB
+	DATA_LOCATION
+	DATA_GENDER
+	DATA_OFFERINGS
+	DATA_RECIPIENT
+	DATA_AMOUNT
 )
 
 func typToBytes(typ DataTyp) []byte {

From d001c5a7fc2b50a9f5b7c11a6d018c69b71021fe Mon Sep 17 00:00:00 2001
From: alfred-mk <alfredmwaik@gmail.com>
Date: Fri, 6 Sep 2024 09:33:39 +0300
Subject: [PATCH 15/47] Write and read data from gdbm

---
 internal/handlers/ussd/menuhandler.go | 325 +++++++++++++++-----------
 1 file changed, 184 insertions(+), 141 deletions(-)

diff --git a/internal/handlers/ussd/menuhandler.go b/internal/handlers/ussd/menuhandler.go
index 8b22753..6217921 100644
--- a/internal/handlers/ussd/menuhandler.go
+++ b/internal/handlers/ussd/menuhandler.go
@@ -29,23 +29,6 @@ var (
 	translationDir = path.Join(scriptDir, "locale")
 )
 
-const (
-	TrackingIdKey  = "TRACKINGID"
-	PublicKeyKey   = "PUBLICKEY"
-	CustodialIdKey = "CUSTODIALID"
-	AccountPin     = "ACCOUNTPIN"
-	AccountStatus  = "ACCOUNTSTATUS"
-	FirstName      = "FIRSTNAME"
-	FamilyName     = "FAMILYNAME"
-	YearOfBirth    = "YOB"
-	Location       = "LOCATION"
-	Gender         = "GENDER"
-	Offerings      = "OFFERINGS"
-	Recipient      = "RECIPIENT"
-	Amount         = "AMOUNT"
-	AccountCreated = "ACCOUNTCREATED"
-)
-
 type FSData struct {
 	Path string
 	St   *state.State
@@ -75,7 +58,7 @@ func (fm *FlagManager) GetFlag(label string) (uint32, error) {
 }
 
 type Handlers struct {
-	pe	*persist.Persister
+	pe                 *persist.Persister
 	st                 *state.State
 	ca                 cache.Memory
 	userdataStore      db.Db
@@ -92,7 +75,7 @@ func NewHandlers(appFlags *asm.FlagParser, pe *persist.Persister, userdataStore
 		return nil, fmt.Errorf("cannot create handler with nil userdata store")
 	}
 	h := &Handlers{
-		pe:	pe,
+		pe:                 pe,
 		userdataStore:      userdataStore,
 		flagManager:        appFlags,
 		accountFileHandler: utils.NewAccountFileHandler(userdataStore),
@@ -122,7 +105,7 @@ func (h *Handlers) Init(ctx context.Context, sym string, input []byte) (resource
 	if h.st == nil || h.ca == nil {
 		logg.ErrorCtxf(ctx, "perister fail in handler", "state", h.st, "cache", h.ca)
 		return r, fmt.Errorf("cannot get state and memory for handler")
-	}	
+	}
 	h.pe = nil
 
 	logg.DebugCtxf(ctx, "handler has been initialized", "state", h.st, "cache", h.ca)
@@ -208,7 +191,7 @@ func (h *Handlers) CreateAccount(ctx context.Context, sym string, input []byte)
 func (h *Handlers) SavePin(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 	var res resource.Result
 	var err error
-	
+
 	sessionId, ok := ctx.Value("SessionId").(string)
 	if !ok {
 		return res, fmt.Errorf("missing session")
@@ -236,7 +219,7 @@ func (h *Handlers) SavePin(ctx context.Context, sym string, input []byte) (resou
 // SetResetSingleEdit sets and resets  flags to allow gradual editing of profile information.
 func (h *Handlers) SetResetSingleEdit(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 	var res resource.Result
-	
+
 	menuOption := string(input)
 
 	flag_allow_update, _ := h.flagManager.GetFlag("flag_allow_update")
@@ -297,67 +280,94 @@ func codeFromCtx(ctx context.Context) string {
 	return code
 }
 
-// SaveFirstname updates the first name in a JSON data file with the provided input.
+// SaveFirstname updates the first name in the gdbm with the provided input.
 func (h *Handlers) SaveFirstname(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 	var res resource.Result
+	var err error
+	sessionId, ok := ctx.Value("SessionId").(string)
+	if !ok {
+		return res, fmt.Errorf("missing session")
+	}
 
 	if len(input) > 0 {
-		//name := string(input)
-		//key := []byte(FirstName)
-		//value := []byte(name)
-		//h.db.Store(key, value, true)
+		firstName := string(input)
+		err = utils.WriteEntry(ctx, h.userdataStore, sessionId, utils.DATA_FIRST_NAME, []byte(firstName))
+		if err != nil {
+			return res, nil
+		}
 	}
 
 	return res, nil
 }
 
-// SaveFamilyname updates the family name in a JSON data file with the provided input.
+// SaveFamilyname updates the family name in the gdbm with the provided input.
 func (h *Handlers) SaveFamilyname(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 	var res resource.Result
+	var err error
+	sessionId, ok := ctx.Value("SessionId").(string)
+	if !ok {
+		return res, fmt.Errorf("missing session")
+	}
 
 	if len(input) > 0 {
-		//secondname := string(input)
-		//key := []byte(FamilyName)
-		//value := []byte(secondname)
-		//h.db.Store(key, value, true)
+		familyName := string(input)
+		err = utils.WriteEntry(ctx, h.userdataStore, sessionId, utils.DATA_FAMILY_NAME, []byte(familyName))
+		if err != nil {
+			return res, nil
+		}
 	}
 
 	return res, nil
 }
 
-// SaveYOB updates the Year of Birth(YOB) in a JSON data file with the provided input.
+// SaveYOB updates the Year of Birth(YOB) in the gdbm with the provided input.
 func (h *Handlers) SaveYob(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 	var res resource.Result
+	var err error
+	sessionId, ok := ctx.Value("SessionId").(string)
+	if !ok {
+		return res, fmt.Errorf("missing session")
+	}
 
-	yob := string(input)
-	if len(yob) == 4 {
-		//yob := string(input)
-		//key := []byte(YearOfBirth)
-		//value := []byte(yob)
-		//h.db.Store(key, value, true)
+	if len(input) == 4 {
+		yob := string(input)
+		err = utils.WriteEntry(ctx, h.userdataStore, sessionId, utils.DATA_YOB, []byte(yob))
+		if err != nil {
+			return res, nil
+		}
 	}
 
 	return res, nil
 }
 
-// SaveLocation updates the location in a JSON data file with the provided input.
+// SaveLocation updates the location in the gdbm with the provided input.
 func (h *Handlers) SaveLocation(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 	var res resource.Result
+	var err error
+	sessionId, ok := ctx.Value("SessionId").(string)
+	if !ok {
+		return res, fmt.Errorf("missing session")
+	}
 
 	if len(input) > 0 {
-		//location := string(input)
-		//key := []byte(Location)
-		//value := []byte(location)
-
-		//h.db.Store(key, value, true)
+		location := string(input)
+		err = utils.WriteEntry(ctx, h.userdataStore, sessionId, utils.DATA_LOCATION, []byte(location))
+		if err != nil {
+			return res, nil
+		}
 	}
 
 	return res, nil
 }
 
-// SaveGender updates the gender in a JSON data file with the provided input.
+// SaveGender updates the gender in the gdbm with the provided input.
 func (h *Handlers) SaveGender(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 	var res resource.Result
+	var err error
+	sessionId, ok := ctx.Value("SessionId").(string)
+	if !ok {
+		return res, fmt.Errorf("missing session")
+	}
 
 	if len(input) > 0 {
 		gender := string(input)
@@ -369,23 +379,32 @@ func (h *Handlers) SaveGender(ctx context.Context, sym string, input []byte) (re
 		case "3":
 			gender = "Unspecified"
 		}
-		//key := []byte(Gender)
-		//value := []byte(gender)
-		//h.db.Store(key, value, true)
+		err = utils.WriteEntry(ctx, h.userdataStore, sessionId, utils.DATA_GENDER, []byte(gender))
+		if err != nil {
+			return res, nil
+		}
 	}
+
 	return res, nil
 }
 
-// SaveOfferings updates the offerings(goods and services provided by the user) in a JSON data file with the provided input.
+// SaveOfferings updates the offerings(goods and services provided by the user) in the gdbm with the provided input.
 func (h *Handlers) SaveOfferings(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 	var res resource.Result
+	var err error
+	sessionId, ok := ctx.Value("SessionId").(string)
+	if !ok {
+		return res, fmt.Errorf("missing session")
+	}
 
 	if len(input) > 0 {
-		//offerings := string(input)
-		//key := []byte(Offerings)
-		//value := []byte(offerings)
-		//h.db.Store(key, value, true)
+		offerings := string(input)
+		err = utils.WriteEntry(ctx, h.userdataStore, sessionId, utils.DATA_OFFERINGS, []byte(offerings))
+		if err != nil {
+			return res, nil
+		}
 	}
+
 	return res, nil
 }
 
@@ -413,11 +432,15 @@ func (h *Handlers) ResetAccountAuthorized(ctx context.Context, sym string, input
 func (h *Handlers) CheckIdentifier(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 	var res resource.Result
 
-	//publicKey, err := h.db.Fetch([]byte(PublicKeyKey))
-	// if err != nil {
-	// 	return res, err
-	// }
-	res.Content = "string(publicKey)"
+	sessionId, ok := ctx.Value("SessionId").(string)
+	if !ok {
+		return res, fmt.Errorf("missing session")
+	}
+
+	publicKey, _ := utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_PUBLIC_KEY)
+
+	res.Content = string(publicKey)
+
 	return res, nil
 }
 
@@ -427,13 +450,15 @@ func (h *Handlers) Authorize(ctx context.Context, sym string, input []byte) (res
 	var res resource.Result
 	var err error
 
-	flag_incorrect_pin, _ := h.flagManager.GetFlag("flag_incorrect_pin")
-	flag_account_authorized, _ := h.flagManager.GetFlag("flag_account_authorized")
-	flag_allow_update, _ := h.flagManager.GetFlag("flag_allow_update")
 	sessionId, ok := ctx.Value("SessionId").(string)
 	if !ok {
 		return res, fmt.Errorf("missing session")
 	}
+
+	flag_incorrect_pin, _ := h.flagManager.GetFlag("flag_incorrect_pin")
+	flag_account_authorized, _ := h.flagManager.GetFlag("flag_account_authorized")
+	flag_allow_update, _ := h.flagManager.GetFlag("flag_allow_update")
+
 	AccountPin, err := utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_ACCOUNT_PIN)
 
 	if err == nil {
@@ -485,22 +510,15 @@ func (h *Handlers) CheckAccountStatus(ctx context.Context, sym string, input []b
 	trackingId, _ := utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_TRACKING_ID)
 
 	status, err := h.accountService.CheckAccountStatus(string(trackingId))
-
 	if err != nil {
 		fmt.Println("Error checking account status:", err)
 		return res, err
-
 	}
 
-	// err = h.db.Store(toBytes(AccountStatus), toBytes(status), true)
-	// if err != nil {
-	// 	return res, nil
-	// }
-
-	// err = h.db.Store(toBytes(TrackingIdKey), toBytes(status), true)
-	// if err != nil {
-	// 	return res, nil
-	// }
+	err = utils.WriteEntry(ctx, h.userdataStore, sessionId, utils.DATA_ACCOUNT_STATUS, []byte(status))
+	if err != nil {
+		return res, nil
+	}
 
 	if status == "SUCCESS" {
 		res.FlagSet = append(res.FlagSet, flag_account_success)
@@ -567,8 +585,6 @@ func (h *Handlers) CheckBalance(ctx context.Context, sym string, input []byte) (
 	var res resource.Result
 	var err error
 
-	// publicKey, err := h.db.Fetch([]byte(PublicKeyKey))
-
 	sessionId, ok := ctx.Value("SessionId").(string)
 	if !ok {
 		return res, fmt.Errorf("missing session")
@@ -588,6 +604,12 @@ func (h *Handlers) CheckBalance(ctx context.Context, sym string, input []byte) (
 // ValidateRecipient validates that the given input is a valid phone number.
 func (h *Handlers) ValidateRecipient(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 	var res resource.Result
+	var err error
+
+	sessionId, ok := ctx.Value("SessionId").(string)
+	if !ok {
+		return res, fmt.Errorf("missing session")
+	}
 
 	recipient := string(input)
 
@@ -602,11 +624,10 @@ func (h *Handlers) ValidateRecipient(ctx context.Context, sym string, input []by
 			return res, nil
 		}
 
-		// accountData["Recipient"] = recipient
-		// key := []byte(Recipient)
-		// value := []byte(recipient)
-
-		// h.db.Store(key, value, true)
+		err = utils.WriteEntry(ctx, h.userdataStore, sessionId, utils.DATA_RECIPIENT, []byte(recipient))
+		if err != nil {
+			return res, nil
+		}
 	}
 
 	return res, nil
@@ -616,18 +637,25 @@ func (h *Handlers) ValidateRecipient(ctx context.Context, sym string, input []by
 // as well as the invalid flags
 func (h *Handlers) TransactionReset(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 	var res resource.Result
+	var err error
+
+	sessionId, ok := ctx.Value("SessionId").(string)
+	if !ok {
+		return res, fmt.Errorf("missing session")
+	}
 
 	flag_invalid_recipient, _ := h.flagManager.GetFlag("flag_invalid_recipient")
 	flag_invalid_recipient_with_invite, _ := h.flagManager.GetFlag("flag_invalid_recipient_with_invite")
 
-	// err := h.db.Delete([]byte(Amount))
-	// if err != nil && !errors.Is(err, gdbm.ErrItemNotFound) {
-	// 	return res, err
-	// }
-	// err = h.db.Delete([]byte(Recipient))
-	// if err != nil && !errors.Is(err, gdbm.ErrItemNotFound) {
-	// 	return res, err
-	// }
+	err = utils.WriteEntry(ctx, h.userdataStore, sessionId, utils.DATA_AMOUNT, []byte(""))
+	if err != nil {
+		return res, nil
+	}
+
+	err = utils.WriteEntry(ctx, h.userdataStore, sessionId, utils.DATA_RECIPIENT, []byte(""))
+	if err != nil {
+		return res, nil
+	}
 
 	res.FlagReset = append(res.FlagReset, flag_invalid_recipient, flag_invalid_recipient_with_invite)
 
@@ -637,13 +665,19 @@ func (h *Handlers) TransactionReset(ctx context.Context, sym string, input []byt
 // ResetTransactionAmount resets the transaction amount and invalid flag
 func (h *Handlers) ResetTransactionAmount(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 	var res resource.Result
+	var err error
+
+	sessionId, ok := ctx.Value("SessionId").(string)
+	if !ok {
+		return res, fmt.Errorf("missing session")
+	}
 
 	flag_invalid_amount, _ := h.flagManager.GetFlag("flag_invalid_amount")
 
-	// err := h.db.Delete([]byte(Amount))
-	// if err != nil && !errors.Is(err, gdbm.ErrItemNotFound) {
-	// 	return res, err
-	// }
+	err = utils.WriteEntry(ctx, h.userdataStore, sessionId, utils.DATA_AMOUNT, []byte(""))
+	if err != nil {
+		return res, nil
+	}
 
 	res.FlagReset = append(res.FlagReset, flag_invalid_amount)
 
@@ -656,12 +690,14 @@ func (h *Handlers) MaxAmount(ctx context.Context, sym string, input []byte) (res
 	var res resource.Result
 	var err error
 
-	// publicKey, err := h.db.Fetch([]byte(PublicKeyKey))
-	// if err != nil {
-	// 	return res, err
-	// }
+	sessionId, ok := ctx.Value("SessionId").(string)
+	if !ok {
+		return res, fmt.Errorf("missing session")
+	}
 
-	balance, err := h.accountService.CheckBalance(string("publicKey"))
+	publicKey, _ := utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_PUBLIC_KEY)
+
+	balance, err := h.accountService.CheckBalance(string(publicKey))
 	if err != nil {
 		return res, nil
 	}
@@ -677,16 +713,18 @@ func (h *Handlers) ValidateAmount(ctx context.Context, sym string, input []byte)
 	var res resource.Result
 	var err error
 
+	sessionId, ok := ctx.Value("SessionId").(string)
+	if !ok {
+		return res, fmt.Errorf("missing session")
+	}
+
 	flag_invalid_amount, _ := h.flagManager.GetFlag("flag_invalid_amount")
 
+	publicKey, _ := utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_PUBLIC_KEY)
+
 	amountStr := string(input)
-	// publicKey, err := h.db.Fetch([]byte(PublicKeyKey))
 
-	// if err != nil {
-	// 	return res, err
-	// }
-
-	balanceStr, err := h.accountService.CheckBalance(string("publicKey"))
+	balanceStr, err := h.accountService.CheckBalance(string(publicKey))
 
 	if err != nil {
 		return res, err
@@ -726,10 +764,8 @@ func (h *Handlers) ValidateAmount(ctx context.Context, sym string, input []byte)
 	}
 
 	res.Content = fmt.Sprintf("%.3f", inputAmount) // Format to 3 decimal places
-	// key := []byte(Amount)
-	// value := []byte(res.Content)
-	// h.db.Store(key, value, true)
 
+	err = utils.WriteEntry(ctx, h.userdataStore, sessionId, utils.DATA_AMOUNT, []byte(amountStr))
 	if err != nil {
 		return res, err
 	}
@@ -737,16 +773,18 @@ func (h *Handlers) ValidateAmount(ctx context.Context, sym string, input []byte)
 	return res, nil
 }
 
-// GetRecipient returns the transaction recipient from a JSON data file.
+// GetRecipient returns the transaction recipient from the gdbm.
 func (h *Handlers) GetRecipient(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 	var res resource.Result
 
-	// recipient, err := h.db.Fetch([]byte(Recipient))
-	// if err != nil {
-	// 	return res, err
-	// }
+	sessionId, ok := ctx.Value("SessionId").(string)
+	if !ok {
+		return res, fmt.Errorf("missing session")
+	}
 
-	res.Content = string("recipient")
+	recipient, _ := utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_RECIPIENT)
+
+	res.Content = string(recipient)
 
 	return res, nil
 }
@@ -755,12 +793,14 @@ func (h *Handlers) GetRecipient(ctx context.Context, sym string, input []byte) (
 func (h *Handlers) GetSender(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 	var res resource.Result
 
-	// publicKey, err := h.db.Fetch([]byte(PublicKeyKey))
-	// if err != nil {
-	// 	return res, err
-	// }
+	sessionId, ok := ctx.Value("SessionId").(string)
+	if !ok {
+		return res, fmt.Errorf("missing session")
+	}
 
-	res.Content = string("publicKey")
+	publicKey, _ := utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_PUBLIC_KEY)
+
+	res.Content = string(publicKey)
 
 	return res, nil
 }
@@ -769,11 +809,14 @@ func (h *Handlers) GetSender(ctx context.Context, sym string, input []byte) (res
 func (h *Handlers) GetAmount(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 	var res resource.Result
 
-	// amount, err := h.db.Fetch([]byte(Amount))
-	// if err != nil {
-	// 	return res, err
-	// }
-	res.Content = string("amount")
+	sessionId, ok := ctx.Value("SessionId").(string)
+	if !ok {
+		return res, fmt.Errorf("missing session")
+	}
+
+	amount, _ := utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_AMOUNT)
+
+	res.Content = string(amount)
 
 	return res, nil
 }
@@ -783,17 +826,20 @@ func (h *Handlers) GetAmount(ctx context.Context, sym string, input []byte) (res
 func (h *Handlers) QuitWithBalance(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 	var res resource.Result
 	var err error
+	sessionId, ok := ctx.Value("SessionId").(string)
+	if !ok {
+		return res, fmt.Errorf("missing session")
+	}
 
 	flag_account_authorized, _ := h.flagManager.GetFlag("flag_account_authorized")
 
 	code := codeFromCtx(ctx)
 	l := gotext.NewLocale(translationDir, code)
 	l.AddDomain("default")
-	// publicKey, err := h.db.Fetch([]byte(PublicKeyKey))
-	// if err != nil {
-	// 	return res, err
-	// }
-	balance, err := h.accountService.CheckBalance(string("publicKey"))
+
+	publicKey, _ := utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_PUBLIC_KEY)
+
+	balance, err := h.accountService.CheckBalance(string(publicKey))
 	if err != nil {
 		return res, nil
 	}
@@ -803,10 +849,14 @@ func (h *Handlers) QuitWithBalance(ctx context.Context, sym string, input []byte
 }
 
 // InitiateTransaction returns a confirmation and resets the transaction data
-// on the JSON file.
+// on the gdbm store.
 func (h *Handlers) InitiateTransaction(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 	var res resource.Result
 	var err error
+	sessionId, ok := ctx.Value("SessionId").(string)
+	if !ok {
+		return res, fmt.Errorf("missing session")
+	}
 
 	code := codeFromCtx(ctx)
 	l := gotext.NewLocale(translationDir, code)
@@ -814,20 +864,13 @@ func (h *Handlers) InitiateTransaction(ctx context.Context, sym string, input []
 	// TODO
 	// Use the amount, recipient and sender to call the API and initialize the transaction
 
-	// publicKey, err := h.db.Fetch([]byte(PublicKeyKey))
-	// if err != nil {
-	// 	return res, err
-	// }
-	// amount, err := h.db.Fetch([]byte(Amount))
-	// if err != nil {
-	// 	return res, err
-	// }
-	// recipient, err := h.db.Fetch([]byte(Recipient))
-	// if err != nil {
-	// 	return res, err
-	// }
+	publicKey, _ := utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_PUBLIC_KEY)
 
-	//res.Content = l.Get("Your request has been sent. %s will receive %s from %s.", string(recipient), string(amount), string(publicKey))
+	amount, _ := utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_AMOUNT)
+
+	recipient, _ := utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_RECIPIENT)
+
+	res.Content = l.Get("Your request has been sent. %s will receive %s from %s.", string(recipient), string(amount), string(publicKey))
 
 	account_authorized_flag, err := h.flagManager.GetFlag("flag_account_authorized")
 	if err != nil {

From 2cc85379cc09a20eaed1403b78f39ba21041989d Mon Sep 17 00:00:00 2001
From: Carlosokumu <carlosokumu254@gmail.com>
Date: Fri, 6 Sep 2024 11:02:33 +0300
Subject: [PATCH 16/47] update log

---
 internal/handlers/ussd/menuhandler.go | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/internal/handlers/ussd/menuhandler.go b/internal/handlers/ussd/menuhandler.go
index 6217921..3482f2a 100644
--- a/internal/handlers/ussd/menuhandler.go
+++ b/internal/handlers/ussd/menuhandler.go
@@ -172,7 +172,7 @@ func (h *Handlers) CreateAccount(ctx context.Context, sym string, input []byte)
 	_, err = utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_ACCOUNT_CREATED)
 	if err != nil {
 		if db.IsNotFound(err) {
-			fmt.Println("Creating an account because it doesn't exist")
+			logg.Printf(logging.LVL_INFO, "Creating an account because it doesn't exist")
 			err = h.createAccountNoExist(ctx, sessionId, &res)
 			if err != nil {
 				return res, err
@@ -315,6 +315,8 @@ func (h *Handlers) SaveFamilyname(ctx context.Context, sym string, input []byte)
 		if err != nil {
 			return res, nil
 		}
+	} else {
+		return res,fmt.Errorf("a family name cannot be less than one character")
 	}
 
 	return res, nil

From 6947b1e4a41ddca05c9a403787df10a18504ecb0 Mon Sep 17 00:00:00 2001
From: Carlosokumu <carlosokumu254@gmail.com>
Date: Fri, 6 Sep 2024 11:03:01 +0300
Subject: [PATCH 17/47] rename getflags to getparser

---
 cmd/main.go | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/cmd/main.go b/cmd/main.go
index a7f7174..906c4cc 100644
--- a/cmd/main.go
+++ b/cmd/main.go
@@ -23,7 +23,7 @@ var (
 	scriptDir = path.Join("services", "registration")
 )
 
-func getFlags(fp string, debug bool) (*asm.FlagParser, error) {
+func getParser(fp string, debug bool) (*asm.FlagParser, error) {
 	flagParser := asm.NewFlagParser().WithDebug()
 	_, err := flagParser.Load(fp)
 	if err != nil {
@@ -128,7 +128,7 @@ func main() {
 	ctx := context.Background()
 	ctx = context.WithValue(ctx, "SessionId",sessionId)
 	pfp := path.Join(scriptDir, "pp.csv")
-	flagParser, err := getFlags(pfp, true)
+	flagParser, err := getParser(pfp, true)
 
 	if err != nil {
 		os.Exit(1)

From 7a12588744099303d617ea6b18e0df86add361fc Mon Sep 17 00:00:00 2001
From: Carlosokumu <carlosokumu254@gmail.com>
Date: Fri, 6 Sep 2024 12:42:24 +0300
Subject: [PATCH 18/47] remove deprecated code

---
 internal/utils/account_utils.go | 39 +++------------------------------
 1 file changed, 3 insertions(+), 36 deletions(-)

diff --git a/internal/utils/account_utils.go b/internal/utils/account_utils.go
index 1ab34b8..b9fd1e3 100644
--- a/internal/utils/account_utils.go
+++ b/internal/utils/account_utils.go
@@ -8,38 +8,21 @@ import (
 )
 
 type AccountFileHandler struct {
-	//FilePath string
 	store db.Db
 }
 
-// func NewAccountFileHandler(path string) *AccountFileHandler {
-// 	return &AccountFileHandler{FilePath: path}
-// }
-
 func NewAccountFileHandler(store db.Db) *AccountFileHandler {
 	return &AccountFileHandler{
 		store: store,
 	}
 }
 
-// func (afh *AccountFileHandler) ReadAccountData() (map[string]string, error) {
-// 	jsonData, err := os.ReadFile(afh.FilePath)
-// 	if err != nil {
-// 		return nil, err
-// 	}
-
-// 	var accountData map[string]string
-// 	err = json.Unmarshal(jsonData, &accountData)
-// 	if err != nil {
-// 		return nil, err
-// 	}
-
-// 	return accountData, nil
-// }
-
 func (afh *AccountFileHandler) ReadAccountData(ctx context.Context, sessionId string) (map[string]string, error) {
 	var accountData map[string]string
 	jsonData, err := ReadEntry(ctx, afh.store, sessionId, DATA_ACCOUNT)
+	if err != nil {
+		return nil,err
+	}
 	err = json.Unmarshal(jsonData, &accountData)
 	if err != nil {
 		return nil, err
@@ -47,15 +30,6 @@ func (afh *AccountFileHandler) ReadAccountData(ctx context.Context, sessionId st
 	return accountData, nil
 }
 
-// func (afh *AccountFileHandler) WriteAccountData(accountData map[string]string) error {
-// 	jsonData, err := json.Marshal(accountData)
-// 	if err != nil {
-// 		return err
-// 	}
-
-// 	return os.WriteFile(afh.FilePath, jsonData, 0644)
-// }
-
 func (afh *AccountFileHandler) WriteAccountData(ctx context.Context, sessionId string, accountData map[string]string) error {
 	_, err := json.Marshal(accountData)
 	if err != nil {
@@ -65,13 +39,6 @@ func (afh *AccountFileHandler) WriteAccountData(ctx context.Context, sessionId s
 	return nil
 }
 
-//	func (afh *AccountFileHandler) EnsureFileExists() error {
-//		f, err := os.OpenFile(afh.FilePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
-//		if err != nil {
-//			return err
-//		}
-//		return f.Close()
-//	}
 func (afh *AccountFileHandler) EnsureFileExists() error {
 	return nil
 }

From eb9f470ac568473b72aa2a5ad61d8d4eec91018f Mon Sep 17 00:00:00 2001
From: alfred-mk <alfredmwaik@gmail.com>
Date: Fri, 6 Sep 2024 16:17:26 +0300
Subject: [PATCH 19/47] Update the GetProfileInfo to get data from gdbm

---
 internal/handlers/ussd/menuhandler.go | 73 ++++++++++++---------------
 1 file changed, 33 insertions(+), 40 deletions(-)

diff --git a/internal/handlers/ussd/menuhandler.go b/internal/handlers/ussd/menuhandler.go
index 3482f2a..c94a57c 100644
--- a/internal/handlers/ussd/menuhandler.go
+++ b/internal/handlers/ussd/menuhandler.go
@@ -316,7 +316,7 @@ func (h *Handlers) SaveFamilyname(ctx context.Context, sym string, input []byte)
 			return res, nil
 		}
 	} else {
-		return res,fmt.Errorf("a family name cannot be less than one character")
+		return res, fmt.Errorf("a family name cannot be less than one character")
 	}
 
 	return res, nil
@@ -886,62 +886,55 @@ func (h *Handlers) InitiateTransaction(ctx context.Context, sym string, input []
 // GetProfileInfo retrieves and formats the profile information of a user from a Gdbm backed storage.
 func (h *Handlers) GetProfileInfo(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 	var res resource.Result
+	sessionId, ok := ctx.Value("SessionId").(string)
+	if !ok {
+		return res, fmt.Errorf("missing session")
+	}
 
-	// Define default values
-	defaultValue := "Not provided"
-	name := defaultValue
-	familyName := defaultValue
-	yob := defaultValue
-	gender := defaultValue
-	location := defaultValue
-	offerings := defaultValue
+	// Default value when an entry is not found
+	defaultValue := "Not Provided"
 
-	// Fetch data using a map for better organization
-	// dataKeys := map[string]*string{
-	// 	FirstName:   &name,
-	// 	FamilyName:  &familyName,
-	// 	YearOfBirth: &yob,
-	// 	Location:    &location,
-	// 	Gender:      &gender,
-	// 	Offerings:   &offerings,
-	// }
+	// Helper function to handle nil byte slices and convert them to string
+	getEntryOrDefault := func(entry []byte, err error) string {
+		if err != nil || entry == nil {
+			return defaultValue
+		}
+		return string(entry)
+	}
 
-	// Iterate over keys and fetch values
-	//iter := h.db.Iterator()
-	// next := h.db.Iterator()
-	// //defer iter.Close() // Ensure the iterator is closed
-	// for key, err := next(); err == nil; key, err = next() {
-	// 	if valuePointer, ok := dataKeys[string(key)]; ok {
-	// 		// value, fetchErr := h.db.Fetch(key)
-	// 		// if fetchErr == nil {
-	// 		// 	*valuePointer = string(value)
-	// 		// }
-	// 	}
-	// }
+	// Retrieve user data as strings with fallback to defaultValue
+	firstName := getEntryOrDefault(utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_FIRST_NAME))
+	familyName := getEntryOrDefault(utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_FAMILY_NAME))
+	yob := getEntryOrDefault(utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_YOB))
+	gender := getEntryOrDefault(utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_GENDER))
+	location := getEntryOrDefault(utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_LOCATION))
+	offerings := getEntryOrDefault(utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_OFFERINGS))
 
 	// Construct the full name
+	name := defaultValue
 	if familyName != defaultValue {
-		if name == defaultValue {
+		if firstName == defaultValue {
 			name = familyName
 		} else {
-			name = name + " " + familyName
+			name = firstName + " " + familyName
 		}
 	}
 
 	// Calculate age from year of birth
-	var age string
+	age := defaultValue
 	if yob != defaultValue {
-		yobInt, err := strconv.Atoi(yob)
-		if err != nil {
+		if yobInt, err := strconv.Atoi(yob); err == nil {
+			age = strconv.Itoa(utils.CalculateAgeWithYOB(yobInt))
+		} else {
 			return res, fmt.Errorf("invalid year of birth: %v", err)
 		}
-		age = strconv.Itoa(utils.CalculateAgeWithYOB(yobInt))
-	} else {
-		age = defaultValue
 	}
 
 	// Format the result
-	formattedData := fmt.Sprintf("Name: %s\nGender: %s\nAge: %s\nLocation: %s\nYou provide: %s\n", name, gender, age, location, offerings)
-	res.Content = formattedData
+	res.Content = fmt.Sprintf(
+		"Name: %s\nGender: %s\nAge: %s\nLocation: %s\nYou provide: %s\n",
+		name, gender, age, location, offerings,
+	)
+
 	return res, nil
 }

From d7376a41961b23674658a0051635ed72988c3ccc Mon Sep 17 00:00:00 2001
From: Carlosokumu <carlosokumu254@gmail.com>
Date: Fri, 6 Sep 2024 16:53:22 +0300
Subject: [PATCH 20/47] format error

---
 internal/handlers/ussd/menuhandler.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/internal/handlers/ussd/menuhandler.go b/internal/handlers/ussd/menuhandler.go
index 3482f2a..5c25ded 100644
--- a/internal/handlers/ussd/menuhandler.go
+++ b/internal/handlers/ussd/menuhandler.go
@@ -316,7 +316,7 @@ func (h *Handlers) SaveFamilyname(ctx context.Context, sym string, input []byte)
 			return res, nil
 		}
 	} else {
-		return res,fmt.Errorf("a family name cannot be less than one character")
+		return res, fmt.Errorf("a family name cannot be less than one character")
 	}
 
 	return res, nil

From 8175d6ac129e877c6f616a191dd59733fc0127bd Mon Sep 17 00:00:00 2001
From: Carlosokumu <carlosokumu254@gmail.com>
Date: Fri, 6 Sep 2024 17:50:33 +0300
Subject: [PATCH 21/47] setup db mock

---
 internal/handlers/ussd/mocks/dbmock.go | 60 ++++++++++++++++++++++++++
 1 file changed, 60 insertions(+)
 create mode 100644 internal/handlers/ussd/mocks/dbmock.go

diff --git a/internal/handlers/ussd/mocks/dbmock.go b/internal/handlers/ussd/mocks/dbmock.go
new file mode 100644
index 0000000..71f7eca
--- /dev/null
+++ b/internal/handlers/ussd/mocks/dbmock.go
@@ -0,0 +1,60 @@
+package mocks
+
+import (
+	"context"
+
+	"git.defalsify.org/vise.git/lang"
+	"git.grassecon.net/urdt/ussd/internal/utils"
+	"github.com/stretchr/testify/mock"
+)
+
+type MockDb struct {
+	mock.Mock
+}
+
+func (m *MockDb) SetPrefix(prefix uint8) {
+	m.Called(utils.DATA_FAMILY_NAME)
+}
+
+func (m *MockDb) Prefix() uint8 {
+	args := m.Called()
+	return args.Get(0).(uint8)
+}
+
+func (m *MockDb) Safe() bool {
+	args := m.Called()
+	return args.Get(0).(bool)
+}
+
+func (m *MockDb) SetLanguage(language *lang.Language) {
+	m.Called(language)
+}
+
+func (m *MockDb) SetLock(uint8, bool) error {
+	args := m.Called()
+	return args.Error(0)
+}
+
+func (m *MockDb) Connect(ctx context.Context, connectionStr string) error {
+	args := m.Called(ctx, connectionStr)
+	return args.Error(0)
+}
+
+func (m *MockDb) SetSession(sessionId string) {
+	m.Called(sessionId)
+}
+
+func (m *MockDb) Put(ctx context.Context, key, value []byte) error {
+	args := m.Called(ctx, key, value)
+	return args.Error(0)
+}
+
+func (m *MockDb) Get(ctx context.Context, key []byte) ([]byte, error) {
+	args := m.Called(ctx, key)
+	return nil, args.Error(0)
+}
+
+func (m *MockDb) Close() error {
+	args := m.Called(nil)
+	return args.Error(0)
+}

From 175cbd1983a54521d8f7db6d0b3e60ae13794e7a Mon Sep 17 00:00:00 2001
From: Carlosokumu <carlosokumu254@gmail.com>
Date: Fri, 6 Sep 2024 17:51:07 +0300
Subject: [PATCH 22/47] setup template test

---
 internal/handlers/ussd/menuhandler_test.go | 1822 ++++++++++----------
 1 file changed, 937 insertions(+), 885 deletions(-)

diff --git a/internal/handlers/ussd/menuhandler_test.go b/internal/handlers/ussd/menuhandler_test.go
index 5bcf7c1..3c14a26 100644
--- a/internal/handlers/ussd/menuhandler_test.go
+++ b/internal/handlers/ussd/menuhandler_test.go
@@ -2,13 +2,8 @@ package ussd
 
 import (
 	"context"
-	"encoding/json"
-	"fmt"
-	"os"
-	"path/filepath"
 	"testing"
 
-	"git.defalsify.org/vise.git/resource"
 	"git.grassecon.net/urdt/ussd/internal/handlers/ussd/mocks"
 	"git.grassecon.net/urdt/ussd/internal/models"
 	"git.grassecon.net/urdt/ussd/internal/utils"
@@ -45,949 +40,1006 @@ func (m *MockAccountService) CheckAccountStatus(trackingId string) (string, erro
 	return args.String(0), args.Error(1)
 }
 
-func TestCreateAccount(t *testing.T) {
-	// Setup
-	tempDir, err := os.MkdirTemp("", "test_create_account")
-	if err != nil {
-		t.Fatalf("Failed to create temp directory: %v", err)
-	}
-	defer os.RemoveAll(tempDir) // Clean up after the test run
+// func TestCreateAccount(t *testing.T) {
+// 	// Setup
+// 	tempDir, err := os.MkdirTemp("", "test_create_account")
+// 	if err != nil {
+// 		t.Fatalf("Failed to create temp directory: %v", err)
+// 	}
+// 	defer os.RemoveAll(tempDir) // Clean up after the test run
 
-	sessionID := "07xxxxxxxx"
+// 	sessionID := "07xxxxxxxx"
 
-	// Set up the data file path using the session ID
-	accountFilePath := filepath.Join(tempDir, sessionID+"_data")
+// 	// Set up the data file path using the session ID
+// 	accountFilePath := filepath.Join(tempDir, sessionID+"_data")
 
-	// Initialize account file handler
-	accountFileHandler := utils.NewAccountFileHandler(accountFilePath)
+// 	// Initialize account file handler
+// 	accountFileHandler := utils.NewAccountFileHandler(accountFilePath)
 
-	// Create a mock account service
-	mockAccountService := &MockAccountService{}
-	mockAccountResponse := &models.AccountResponse{
-		Ok: true,
-		Result: struct {
-			CustodialId json.Number `json:"custodialId"`
-			PublicKey   string      `json:"publicKey"`
-			TrackingId  string      `json:"trackingId"`
-		}{
-			CustodialId: "test-custodial-id",
-			PublicKey:   "test-public-key",
-			TrackingId:  "test-tracking-id",
-		},
-	}
+// 	// Create a mock account service
+// 	mockAccountService := &MockAccountService{}
+// 	mockAccountResponse := &models.AccountResponse{
+// 		Ok: true,
+// 		Result: struct {
+// 			CustodialId json.Number `json:"custodialId"`
+// 			PublicKey   string      `json:"publicKey"`
+// 			TrackingId  string      `json:"trackingId"`
+// 		}{
+// 			CustodialId: "test-custodial-id",
+// 			PublicKey:   "test-public-key",
+// 			TrackingId:  "test-tracking-id",
+// 		},
+// 	}
 
-	// Set up expectations for the mock account service
-	mockAccountService.On("CreateAccount").Return(mockAccountResponse, nil)
+// 	// Set up expectations for the mock account service
+// 	mockAccountService.On("CreateAccount").Return(mockAccountResponse, nil)
 
-	mockParser := new(MockFlagParser)
+// 	mockParser := new(MockFlagParser)
 
-	flag_account_created := uint32(1)
-	flag_account_creation_failed := uint32(2)
+// 	flag_account_created := uint32(1)
+// 	flag_account_creation_failed := uint32(2)
 
-	mockParser.On("GetFlag", "flag_account_created").Return(flag_account_created, nil)
-	mockParser.On("GetFlag", "flag_account_creation_failed").Return(flag_account_creation_failed, nil)
+// 	mockParser.On("GetFlag", "flag_account_created").Return(flag_account_created, nil)
+// 	mockParser.On("GetFlag", "flag_account_creation_failed").Return(flag_account_creation_failed, nil)
 
-	// Initialize Handlers with mock account service
-	h := &Handlers{
-		fs:                 &FSData{Path: accountFilePath},
-		accountFileHandler: accountFileHandler,
-		accountService:     mockAccountService,
-		parser:             mockParser,
-	}
+// 	// Initialize Handlers with mock account service
+// 	h := &Handlers{
+// 		fs:                 &FSData{Path: accountFilePath},
+// 		accountFileHandler: accountFileHandler,
+// 		accountService:     mockAccountService,
+// 		parser:             mockParser,
+// 	}
 
-	tests := []struct {
-		name           string
-		existingData   map[string]string
-		expectedResult resource.Result
-		expectedData   map[string]string
-	}{
-		{
-			name:         "New account creation",
-			existingData: nil,
-			expectedResult: resource.Result{
-				FlagSet: []uint32{flag_account_created},
-			},
-			expectedData: map[string]string{
-				"TrackingId":  "test-tracking-id",
-				"PublicKey":   "test-public-key",
-				"CustodialId": "test-custodial-id",
-				"Status":      "PENDING",
-				"Gender":      "Not provided",
-				"YOB":         "Not provided",
-				"Location":    "Not provided",
-				"Offerings":   "Not provided",
-				"FirstName":   "Not provided",
-				"FamilyName":  "Not provided",
-			},
-		},
-		{
-			name: "Existing account",
-			existingData: map[string]string{
-				"TrackingId":  "test-tracking-id",
-				"PublicKey":   "test-public-key",
-				"CustodialId": "test-custodial-id",
-				"Status":      "PENDING",
-				"Gender":      "Not provided",
-				"YOB":         "Not provided",
-				"Location":    "Not provided",
-				"Offerings":   "Not provided",
-				"FirstName":   "Not provided",
-				"FamilyName":  "Not provided",
-			},
-			expectedResult: resource.Result{},
-			expectedData: map[string]string{
-				"TrackingId":  "test-tracking-id",
-				"PublicKey":   "test-public-key",
-				"CustodialId": "test-custodial-id",
-				"Status":      "PENDING",
-				"Gender":      "Not provided",
-				"YOB":         "Not provided",
-				"Location":    "Not provided",
-				"Offerings":   "Not provided",
-				"FirstName":   "Not provided",
-				"FamilyName":  "Not provided",
-			},
-		},
-	}
+// 	tests := []struct {
+// 		name           string
+// 		existingData   map[string]string
+// 		expectedResult resource.Result
+// 		expectedData   map[string]string
+// 	}{
+// 		{
+// 			name:         "New account creation",
+// 			existingData: nil,
+// 			expectedResult: resource.Result{
+// 				FlagSet: []uint32{flag_account_created},
+// 			},
+// 			expectedData: map[string]string{
+// 				"TrackingId":  "test-tracking-id",
+// 				"PublicKey":   "test-public-key",
+// 				"CustodialId": "test-custodial-id",
+// 				"Status":      "PENDING",
+// 				"Gender":      "Not provided",
+// 				"YOB":         "Not provided",
+// 				"Location":    "Not provided",
+// 				"Offerings":   "Not provided",
+// 				"FirstName":   "Not provided",
+// 				"FamilyName":  "Not provided",
+// 			},
+// 		},
+// 		{
+// 			name: "Existing account",
+// 			existingData: map[string]string{
+// 				"TrackingId":  "test-tracking-id",
+// 				"PublicKey":   "test-public-key",
+// 				"CustodialId": "test-custodial-id",
+// 				"Status":      "PENDING",
+// 				"Gender":      "Not provided",
+// 				"YOB":         "Not provided",
+// 				"Location":    "Not provided",
+// 				"Offerings":   "Not provided",
+// 				"FirstName":   "Not provided",
+// 				"FamilyName":  "Not provided",
+// 			},
+// 			expectedResult: resource.Result{},
+// 			expectedData: map[string]string{
+// 				"TrackingId":  "test-tracking-id",
+// 				"PublicKey":   "test-public-key",
+// 				"CustodialId": "test-custodial-id",
+// 				"Status":      "PENDING",
+// 				"Gender":      "Not provided",
+// 				"YOB":         "Not provided",
+// 				"Location":    "Not provided",
+// 				"Offerings":   "Not provided",
+// 				"FirstName":   "Not provided",
+// 				"FamilyName":  "Not provided",
+// 			},
+// 		},
+// 	}
 
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			// Set up the data file path using the session ID
-			accountFilePath := filepath.Join(tempDir, sessionID+"_data")
+// 	for _, tt := range tests {
+// 		t.Run(tt.name, func(t *testing.T) {
+// 			// Set up the data file path using the session ID
+// 			accountFilePath := filepath.Join(tempDir, sessionID+"_data")
 
-			// Setup existing data if any
-			if tt.existingData != nil {
-				data, _ := json.Marshal(tt.existingData)
-				err := os.WriteFile(accountFilePath, data, 0644)
-				if err != nil {
-					t.Fatalf("Failed to write existing data: %v", err)
-				}
-			}
+// 			// Setup existing data if any
+// 			if tt.existingData != nil {
+// 				data, _ := json.Marshal(tt.existingData)
+// 				err := os.WriteFile(accountFilePath, data, 0644)
+// 				if err != nil {
+// 					t.Fatalf("Failed to write existing data: %v", err)
+// 				}
+// 			}
 
-			// Call the function
-			result, err := h.CreateAccount(context.Background(), "", nil)
+// 			// Call the function
+// 			result, err := h.CreateAccount(context.Background(), "", nil)
 
-			// Check for errors
-			if err != nil {
-				t.Fatalf("CreateAccount returned an error: %v", err)
-			}
+// 			// Check for errors
+// 			if err != nil {
+// 				t.Fatalf("CreateAccount returned an error: %v", err)
+// 			}
 
-			// Check the result
-			if len(result.FlagSet) != len(tt.expectedResult.FlagSet) {
-				t.Errorf("Expected %d flags, got %d", len(tt.expectedResult.FlagSet), len(result.FlagSet))
-			}
-			for i, flag := range tt.expectedResult.FlagSet {
-				if result.FlagSet[i] != flag {
-					t.Errorf("Expected flag %d, got %d", flag, result.FlagSet[i])
-				}
-			}
+// 			// Check the result
+// 			if len(result.FlagSet) != len(tt.expectedResult.FlagSet) {
+// 				t.Errorf("Expected %d flags, got %d", len(tt.expectedResult.FlagSet), len(result.FlagSet))
+// 			}
+// 			for i, flag := range tt.expectedResult.FlagSet {
+// 				if result.FlagSet[i] != flag {
+// 					t.Errorf("Expected flag %d, got %d", flag, result.FlagSet[i])
+// 				}
+// 			}
 
-			// Check the stored data
-			data, err := os.ReadFile(accountFilePath)
-			if err != nil {
-				t.Fatalf("Failed to read account data file: %v", err)
-			}
+// 			// Check the stored data
+// 			data, err := os.ReadFile(accountFilePath)
+// 			if err != nil {
+// 				t.Fatalf("Failed to read account data file: %v", err)
+// 			}
 
-			var storedData map[string]string
-			err = json.Unmarshal(data, &storedData)
-			if err != nil {
-				t.Fatalf("Failed to unmarshal stored data: %v", err)
-			}
+// 			var storedData map[string]string
+// 			err = json.Unmarshal(data, &storedData)
+// 			if err != nil {
+// 				t.Fatalf("Failed to unmarshal stored data: %v", err)
+// 			}
 
-			for key, expectedValue := range tt.expectedData {
-				if storedValue, ok := storedData[key]; !ok || storedValue != expectedValue {
-					t.Errorf("Expected %s to be %s, got %s", key, expectedValue, storedValue)
-				}
-			}
-		})
-	}
-}
+// 			for key, expectedValue := range tt.expectedData {
+// 				if storedValue, ok := storedData[key]; !ok || storedValue != expectedValue {
+// 					t.Errorf("Expected %s to be %s, got %s", key, expectedValue, storedValue)
+// 				}
+// 			}
+// 		})
+// 	}
+// }
 
-func TestCreateAccount_Success(t *testing.T) {
-	mockAccountFileHandler := new(mocks.MockAccountFileHandler)
-	mockCreateAccountService := new(mocks.MockAccountService)
+// func TestCreateAccount_Success(t *testing.T) {
+// 	mockAccountFileHandler := new(mocks.MockAccountFileHandler)
+// 	mockCreateAccountService := new(mocks.MockAccountService)
 
-	mockAccountFileHandler.On("EnsureFileExists").Return(nil)
+// 	mockAccountFileHandler.On("EnsureFileExists").Return(nil)
 
-	// Mock that no account data exists
-	mockAccountFileHandler.On("ReadAccountData").Return(nil, nil)
+// 	// Mock that no account data exists
+// 	mockAccountFileHandler.On("ReadAccountData").Return(nil, nil)
 
-	// Define expected account response after api call
-	expectedAccountResp := &models.AccountResponse{
-		Ok: true,
-		Result: struct {
-			CustodialId json.Number `json:"custodialId"`
-			PublicKey   string      `json:"publicKey"`
-			TrackingId  string      `json:"trackingId"`
-		}{
-			CustodialId: "12",
-			PublicKey:   "0x8E0XSCSVA",
-			TrackingId:  "d95a7e83-196c-4fd0-866fSGAGA",
-		},
-	}
-	mockCreateAccountService.On("CreateAccount").Return(expectedAccountResp, nil)
+// 	// Define expected account response after api call
+// 	expectedAccountResp := &models.AccountResponse{
+// 		Ok: true,
+// 		Result: struct {
+// 			CustodialId json.Number `json:"custodialId"`
+// 			PublicKey   string      `json:"publicKey"`
+// 			TrackingId  string      `json:"trackingId"`
+// 		}{
+// 			CustodialId: "12",
+// 			PublicKey:   "0x8E0XSCSVA",
+// 			TrackingId:  "d95a7e83-196c-4fd0-866fSGAGA",
+// 		},
+// 	}
+// 	mockCreateAccountService.On("CreateAccount").Return(expectedAccountResp, nil)
 
-	// Mock WriteAccountData to not error
-	mockAccountFileHandler.On("WriteAccountData", mock.Anything).Return(nil)
+// 	// Mock WriteAccountData to not error
+// 	mockAccountFileHandler.On("WriteAccountData", mock.Anything).Return(nil)
 
-	handlers := &Handlers{
-		accountService: mockCreateAccountService,
-	}
+// 	handlers := &Handlers{
+// 		accountService: mockCreateAccountService,
+// 	}
 
-	actualResponse, err := handlers.accountService.CreateAccount()
+// 	actualResponse, err := handlers.accountService.CreateAccount()
 
-	// Assert results
-	assert.NoError(t, err)
-	assert.Equal(t, expectedAccountResp.Ok, true)
-	assert.Equal(t, expectedAccountResp, actualResponse)
-}
+// 	// Assert results
+// 	assert.NoError(t, err)
+// 	assert.Equal(t, expectedAccountResp.Ok, true)
+// 	assert.Equal(t, expectedAccountResp, actualResponse)
+// }
 
-func TestSavePin(t *testing.T) {
-	// Setup
-	tempDir, err := os.MkdirTemp("", "test_save_pin")
-	if err != nil {
-		t.Fatalf("Failed to create temp directory: %v", err)
-	}
-	defer os.RemoveAll(tempDir)
+// func TestSavePin(t *testing.T) {
+// 	// Setup
+// 	tempDir, err := os.MkdirTemp("", "test_save_pin")
+// 	if err != nil {
+// 		t.Fatalf("Failed to create temp directory: %v", err)
+// 	}
+// 	defer os.RemoveAll(tempDir)
 
-	sessionID := "07xxxxxxxx"
+// 	sessionID := "07xxxxxxxx"
 
-	// Set up the data file path using the session ID
-	accountFilePath := filepath.Join(tempDir, sessionID+"_data")
-	initialAccountData := map[string]string{
-		"TrackingId": "test-tracking-id",
-		"PublicKey":  "test-public-key",
-	}
-	data, _ := json.Marshal(initialAccountData)
-	err = os.WriteFile(accountFilePath, data, 0644)
-	if err != nil {
-		t.Fatalf("Failed to write initial account data: %v", err)
-	}
+// 	// Set up the data file path using the session ID
+// 	accountFilePath := filepath.Join(tempDir, sessionID+"_data")
+// 	initialAccountData := map[string]string{
+// 		"TrackingId": "test-tracking-id",
+// 		"PublicKey":  "test-public-key",
+// 	}
+// 	data, _ := json.Marshal(initialAccountData)
+// 	err = os.WriteFile(accountFilePath, data, 0644)
+// 	if err != nil {
+// 		t.Fatalf("Failed to write initial account data: %v", err)
+// 	}
 
-	// Create a new AccountFileHandler and set it in the Handlers struct
-	accountFileHandler := utils.NewAccountFileHandler(accountFilePath)
-	mockParser := new(MockFlagParser)
-	
-	h := &Handlers{
-		accountFileHandler: accountFileHandler,
-		parser:             mockParser,
-	}
+// 	// Create a new AccountFileHandler and set it in the Handlers struct
+// 	accountFileHandler := utils.NewAccountFileHandler(accountFilePath)
+// 	mockParser := new(MockFlagParser)
 
-	flag_incorrect_pin := uint32(1)
-	mockParser.On("GetFlag", "flag_incorrect_pin").Return(flag_incorrect_pin, nil)
+// 	h := &Handlers{
+// 		accountFileHandler: accountFileHandler,
+// 		parser:             mockParser,
+// 	}
 
-	tests := []struct {
-		name           string
-		input          []byte
-		expectedFlags  []uint32
-		expectedData   map[string]string
-		expectedErrors bool
-	}{
-		{
-			name:          "Valid PIN",
-			input:         []byte("1234"),
-			expectedFlags: []uint32{},
-			expectedData: map[string]string{
-				"TrackingId": "test-tracking-id",
-				"PublicKey":  "test-public-key",
-				"AccountPIN": "1234",
-			},
-		},
-		{
-			name:           "Invalid PIN - non-numeric",
-			input:          []byte("12ab"),
-			expectedFlags:  []uint32{flag_incorrect_pin},
-			expectedData:   initialAccountData, // No changes expected
-			expectedErrors: false,
-		},
-		{
-			name:           "Invalid PIN - less than 4 digits",
-			input:          []byte("123"),
-			expectedFlags:  []uint32{flag_incorrect_pin},
-			expectedData:   initialAccountData, // No changes expected
-			expectedErrors: false,
-		},
-		{
-			name:           "Invalid PIN - more than 4 digits",
-			input:          []byte("12345"),
-			expectedFlags:  []uint32{flag_incorrect_pin},
-			expectedData:   initialAccountData, // No changes expected
-			expectedErrors: false,
-		},
-	}
+// 	flag_incorrect_pin := uint32(1)
+// 	mockParser.On("GetFlag", "flag_incorrect_pin").Return(flag_incorrect_pin, nil)
 
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			err := accountFileHandler.EnsureFileExists()
-			if err != nil {
-				t.Fatalf("Failed to ensure account file exists: %v", err)
-			}
+// 	tests := []struct {
+// 		name           string
+// 		input          []byte
+// 		expectedFlags  []uint32
+// 		expectedData   map[string]string
+// 		expectedErrors bool
+// 	}{
+// 		{
+// 			name:          "Valid PIN",
+// 			input:         []byte("1234"),
+// 			expectedFlags: []uint32{},
+// 			expectedData: map[string]string{
+// 				"TrackingId": "test-tracking-id",
+// 				"PublicKey":  "test-public-key",
+// 				"AccountPIN": "1234",
+// 			},
+// 		},
+// 		{
+// 			name:           "Invalid PIN - non-numeric",
+// 			input:          []byte("12ab"),
+// 			expectedFlags:  []uint32{flag_incorrect_pin},
+// 			expectedData:   initialAccountData, // No changes expected
+// 			expectedErrors: false,
+// 		},
+// 		{
+// 			name:           "Invalid PIN - less than 4 digits",
+// 			input:          []byte("123"),
+// 			expectedFlags:  []uint32{flag_incorrect_pin},
+// 			expectedData:   initialAccountData, // No changes expected
+// 			expectedErrors: false,
+// 		},
+// 		{
+// 			name:           "Invalid PIN - more than 4 digits",
+// 			input:          []byte("12345"),
+// 			expectedFlags:  []uint32{flag_incorrect_pin},
+// 			expectedData:   initialAccountData, // No changes expected
+// 			expectedErrors: false,
+// 		},
+// 	}
 
-			result, err := h.SavePin(context.Background(), "", tt.input)
-			if err != nil && !tt.expectedErrors {
-				t.Fatalf("SavePin returned an unexpected error: %v", err)
-			}
+// 	for _, tt := range tests {
+// 		t.Run(tt.name, func(t *testing.T) {
+// 			err := accountFileHandler.EnsureFileExists()
+// 			if err != nil {
+// 				t.Fatalf("Failed to ensure account file exists: %v", err)
+// 			}
 
-			if len(result.FlagSet) != len(tt.expectedFlags) {
-				t.Errorf("Expected %d flags, got %d", len(tt.expectedFlags), len(result.FlagSet))
-			}
-			for i, flag := range tt.expectedFlags {
-				if result.FlagSet[i] != flag {
-					t.Errorf("Expected flag %d, got %d", flag, result.FlagSet[i])
-				}
-			}
+// 			result, err := h.SavePin(context.Background(), "", tt.input)
+// 			if err != nil && !tt.expectedErrors {
+// 				t.Fatalf("SavePin returned an unexpected error: %v", err)
+// 			}
 
-			data, err := os.ReadFile(accountFilePath)
-			if err != nil {
-				t.Fatalf("Failed to read account data file: %v", err)
-			}
+// 			if len(result.FlagSet) != len(tt.expectedFlags) {
+// 				t.Errorf("Expected %d flags, got %d", len(tt.expectedFlags), len(result.FlagSet))
+// 			}
+// 			for i, flag := range tt.expectedFlags {
+// 				if result.FlagSet[i] != flag {
+// 					t.Errorf("Expected flag %d, got %d", flag, result.FlagSet[i])
+// 				}
+// 			}
 
-			var storedData map[string]string
-			err = json.Unmarshal(data, &storedData)
-			if err != nil {
-				t.Fatalf("Failed to unmarshal stored data: %v", err)
-			}
+// 			data, err := os.ReadFile(accountFilePath)
+// 			if err != nil {
+// 				t.Fatalf("Failed to read account data file: %v", err)
+// 			}
 
-			for key, expectedValue := range tt.expectedData {
-				if storedValue, ok := storedData[key]; !ok || storedValue != expectedValue {
-					t.Errorf("Expected %s to be %s, got %s", key, expectedValue, storedValue)
-				}
-			}
-		})
-	}
-}
+// 			var storedData map[string]string
+// 			err = json.Unmarshal(data, &storedData)
+// 			if err != nil {
+// 				t.Fatalf("Failed to unmarshal stored data: %v", err)
+// 			}
 
-func TestSaveLocation(t *testing.T) {
-	// Create a new instance of MockAccountFileHandler
-	mockFileHandler := new(mocks.MockAccountFileHandler)
+// 			for key, expectedValue := range tt.expectedData {
+// 				if storedValue, ok := storedData[key]; !ok || storedValue != expectedValue {
+// 					t.Errorf("Expected %s to be %s, got %s", key, expectedValue, storedValue)
+// 				}
+// 			}
+// 		})
+// 	}
+// }
 
+// func TestSaveLocation(t *testing.T) {
+// 	// Create a new instance of MockAccountFileHandler
+// 	mockFileHandler := new(mocks.MockAccountFileHandler)
+
+// 	// Define test cases
+// 	tests := []struct {
+// 		name           string
+// 		input          []byte
+// 		existingData   map[string]string
+// 		writeError     error
+// 		expectedResult resource.Result
+// 		expectedError  error
+// 	}{
+// 		{
+// 			name:           "Successful Save",
+// 			input:          []byte("Mombasa"),
+// 			existingData:   map[string]string{"Location": "Mombasa"},
+// 			writeError:     nil,
+// 			expectedResult: resource.Result{},
+// 			expectedError:  nil,
+// 		},
+// 		{
+// 			name:           "Empty location input",
+// 			input:          []byte{},
+// 			existingData:   map[string]string{"OtherKey": "OtherValue"},
+// 			writeError:     nil,
+// 			expectedResult: resource.Result{},
+// 			expectedError:  nil,
+// 		},
+// 	}
+
+// 	for _, tt := range tests {
+// 		t.Run(tt.name, func(t *testing.T) {
+// 			// Set up the mock expectations
+// 			mockFileHandler.On("ReadAccountData").Return(tt.existingData, tt.expectedError)
+// 			if tt.expectedError == nil && len(tt.input) > 0 {
+// 				mockFileHandler.On("WriteAccountData", mock.MatchedBy(func(data map[string]string) bool {
+// 					return data["Location"] == string(tt.input)
+// 				})).Return(tt.writeError)
+// 			} else if len(tt.input) == 0 {
+// 				// For empty input, no WriteAccountData call should be made
+// 				mockFileHandler.On("WriteAccountData", mock.Anything).Maybe().Return(tt.writeError)
+// 				return
+// 			}
+
+// 			// Create the Handlers instance with the mock file handler
+// 			h := &Handlers{
+// 				accountFileHandler: mockFileHandler,
+// 			}
+
+// 			// Call Save Location
+// 			result, err := h.SaveLocation(context.Background(), "save_location", tt.input)
+
+// 			if err != nil {
+// 				t.Fatalf("Failed to save location with error: %v", err)
+// 			}
+
+// 			savedData, err := h.accountFileHandler.ReadAccountData()
+// 			if err == nil {
+// 				//Assert that the input provided is what was saved into the file
+// 				assert.Equal(t, string(tt.input), savedData["Location"])
+// 			}
+
+// 			// Assert the results
+// 			assert.Equal(t, tt.expectedResult, result)
+// 			assert.Equal(t, tt.expectedError, err)
+
+// 			// Assert all expectations were met
+// 			mockFileHandler.AssertExpectations(t)
+// 		})
+// 	}
+// }
+
+// func TestSaveFirstname(t *testing.T) {
+// 	// Create a new instance of MockAccountFileHandler
+// 	mockFileHandler := new(mocks.MockAccountFileHandler)
+
+// 	// Define test cases
+// 	tests := []struct {
+// 		name           string
+// 		input          []byte
+// 		existingData   map[string]string
+// 		writeError     error
+// 		expectedResult resource.Result
+// 		expectedError  error
+// 	}{
+// 		{
+// 			name:           "Successful Save",
+// 			input:          []byte("Joe"),
+// 			existingData:   map[string]string{"Name": "Joe"},
+// 			writeError:     nil,
+// 			expectedResult: resource.Result{},
+// 			expectedError:  nil,
+// 		},
+// 		{
+// 			name:          "Empty Input",
+// 			input:         []byte{},
+// 			existingData:  map[string]string{"OtherKey": "OtherValue"},
+// 			writeError:    nil,
+// 			expectedError: nil,
+// 		},
+// 	}
+
+// 	for _, tt := range tests {
+// 		t.Run(tt.name, func(t *testing.T) {
+// 			// Set up the mock expectations
+// 			mockFileHandler.On("ReadAccountData").Return(tt.existingData, tt.expectedError)
+// 			if tt.expectedError == nil && len(tt.input) > 0 {
+// 				mockFileHandler.On("WriteAccountData", mock.MatchedBy(func(data map[string]string) bool {
+// 					return data["FirstName"] == string(tt.input)
+// 				})).Return(tt.writeError)
+// 			} else if len(tt.input) == 0 {
+// 				// For empty input, no WriteAccountData call should be made
+// 				mockFileHandler.On("WriteAccountData", mock.Anything).Maybe().Return(tt.writeError)
+// 				return
+// 			}
+
+// 			// Create the Handlers instance with the mock file handler
+// 			h := &Handlers{
+// 				accountFileHandler: mockFileHandler,
+// 			}
+
+// 			// Call save location
+// 			result, err := h.SaveFirstname(context.Background(), "save_location", tt.input)
+
+// 			if err != nil {
+// 				t.Fatalf("Failed to save first name with error: %v", err)
+// 			}
+// 			savedData, err := h.accountFileHandler.ReadAccountData()
+// 			if err == nil {
+// 				//Assert that the input provided is what was saved into the file
+// 				assert.Equal(t, string(tt.input), savedData["FirstName"])
+// 			}
+
+// 			// Assert the results
+// 			assert.Equal(t, tt.expectedResult, result)
+// 			assert.Equal(t, tt.expectedError, err)
+
+// 			// Assert all expectations were met
+// 			mockFileHandler.AssertExpectations(t)
+// 		})
+// 	}
+// }
+
+// func TestSaveFamilyName(t *testing.T) {
+// 	// Create a new instance of MockAccountFileHandler
+// 	mockFileHandler := new(mocks.MockAccountFileHandler)
+
+// 	// Define test cases
+// 	tests := []struct {
+// 		name           string
+// 		input          []byte
+// 		existingData   map[string]string
+// 		writeError     error
+// 		expectedResult resource.Result
+// 		expectedError  error
+// 	}{
+// 		{
+// 			name:           "Successful Save",
+// 			input:          []byte("Doe"),
+// 			existingData:   map[string]string{"FamilyName": "Doe"},
+// 			writeError:     nil,
+// 			expectedResult: resource.Result{},
+// 			expectedError:  nil,
+// 		},
+// 		{
+// 			name:          "Empty Input",
+// 			input:         []byte{},
+// 			existingData:  map[string]string{"FamilyName": "Doe"},
+// 			writeError:    nil,
+// 			expectedError: nil,
+// 		},
+// 	}
+
+// 	for _, tt := range tests {
+// 		t.Run(tt.name, func(t *testing.T) {
+// 			// Set up the mock expectations
+// 			mockFileHandler.On("ReadAccountData").Return(tt.existingData, tt.expectedError)
+// 			if tt.expectedError == nil && len(tt.input) > 0 {
+// 				mockFileHandler.On("WriteAccountData", mock.MatchedBy(func(data map[string]string) bool {
+// 					return data["FamilyName"] == string(tt.input)
+// 				})).Return(tt.writeError)
+// 			} else if len(tt.input) == 0 {
+// 				// For empty input, no WriteAccountData call should be made
+// 				mockFileHandler.On("WriteAccountData", mock.Anything).Maybe().Return(tt.writeError)
+// 				return
+// 			}
+
+// 			// Create the Handlers instance with the mock file handler
+// 			h := &Handlers{
+// 				accountFileHandler: mockFileHandler,
+// 			}
+
+// 			// Call save familyname
+// 			result, err := h.SaveFamilyname(context.Background(), "save_familyname", tt.input)
+
+// 			if err != nil {
+// 				t.Fatalf("Failed to save family name with error: %v", err)
+// 			}
+// 			savedData, err := h.accountFileHandler.ReadAccountData()
+// 			if err == nil {
+// 				//Assert that the input provided is what was saved into the file
+// 				assert.Equal(t, string(tt.input), savedData["FamilyName"])
+// 			}
+
+// 			// Assert the results
+// 			assert.Equal(t, tt.expectedResult, result)
+// 			assert.Equal(t, tt.expectedError, err)
+
+// 			// Assert all expectations were met
+// 			mockFileHandler.AssertExpectations(t)
+// 		})
+// 	}
+// }
+
+// func TestSaveYOB(t *testing.T) {
+// 	// Create a new instance of MockAccountFileHandler
+// 	mockFileHandler := new(mocks.MockAccountFileHandler)
+
+// 	// Define test cases
+// 	tests := []struct {
+// 		name           string
+// 		input          []byte
+// 		existingData   map[string]string
+// 		writeError     error
+// 		expectedResult resource.Result
+// 		expectedError  error
+// 	}{
+// 		{
+// 			name:           "Successful Save",
+// 			input:          []byte("2006"),
+// 			existingData:   map[string]string{"": ""},
+// 			writeError:     nil,
+// 			expectedResult: resource.Result{},
+// 			expectedError:  nil,
+// 		},
+// 		{
+// 			name:          "YOB less than 4 digits(invalid date entry)",
+// 			input:         []byte{},
+// 			existingData:  map[string]string{"": ""},
+// 			writeError:    nil,
+// 			expectedError: nil,
+// 		},
+// 	}
+
+// 	for _, tt := range tests {
+// 		t.Run(tt.name, func(t *testing.T) {
+// 			// Set up the mock expectations
+// 			mockFileHandler.On("ReadAccountData").Return(tt.existingData, tt.expectedError)
+// 			if tt.expectedError == nil && len(tt.input) > 0 {
+// 				mockFileHandler.On("WriteAccountData", mock.MatchedBy(func(data map[string]string) bool {
+// 					return data["YOB"] == string(tt.input)
+// 				})).Return(tt.writeError)
+// 			} else if len(tt.input) != 4 {
+// 				// For input whose input is not a valid yob, no WriteAccountData call should be made
+// 				mockFileHandler.On("WriteAccountData", mock.Anything).Maybe().Return(tt.writeError)
+// 				return
+// 			}
+
+// 			// Create the Handlers instance with the mock file handler
+// 			h := &Handlers{
+// 				accountFileHandler: mockFileHandler,
+// 			}
+
+// 			// Call save yob
+// 			result, err := h.SaveYob(context.Background(), "save_yob", tt.input)
+
+// 			if err != nil {
+// 				t.Fatalf("Failed to save family name with error: %v", err)
+// 			}
+// 			savedData, err := h.accountFileHandler.ReadAccountData()
+// 			if err == nil {
+// 				//Assert that the input provided is what was saved into the file
+// 				assert.Equal(t, string(tt.input), savedData["YOB"])
+// 			}
+
+// 			// Assert the results
+// 			assert.Equal(t, tt.expectedResult, result)
+// 			assert.Equal(t, tt.expectedError, err)
+
+// 			// Assert all expectations were met
+// 			mockFileHandler.AssertExpectations(t)
+// 		})
+// 	}
+// }
+
+// func TestSaveOfferings(t *testing.T) {
+// 	// Create a new instance of MockAccountFileHandler
+// 	mockFileHandler := new(mocks.MockAccountFileHandler)
+
+// 	// Define test cases
+// 	tests := []struct {
+// 		name           string
+// 		input          []byte
+// 		existingData   map[string]string
+// 		writeError     error
+// 		expectedResult resource.Result
+// 		expectedError  error
+// 	}{
+// 		{
+// 			name:           "Successful Save",
+// 			input:          []byte("Bananas"),
+// 			existingData:   map[string]string{"": ""},
+// 			writeError:     nil,
+// 			expectedResult: resource.Result{},
+// 			expectedError:  nil,
+// 		},
+// 		{
+// 			name:          "Empty input",
+// 			input:         []byte{},
+// 			existingData:  map[string]string{"": ""},
+// 			writeError:    nil,
+// 			expectedError: nil,
+// 		},
+// 	}
+
+// 	for _, tt := range tests {
+// 		t.Run(tt.name, func(t *testing.T) {
+// 			// Set up the mock expectations
+// 			mockFileHandler.On("ReadAccountData").Return(tt.existingData, tt.expectedError)
+// 			if tt.expectedError == nil && len(tt.input) > 0 {
+// 				mockFileHandler.On("WriteAccountData", mock.MatchedBy(func(data map[string]string) bool {
+// 					return data["Offerings"] == string(tt.input)
+// 				})).Return(tt.writeError)
+// 			} else if len(tt.input) != 4 {
+// 				// For input whose input is not a valid yob, no WriteAccountData call should be made
+// 				mockFileHandler.On("WriteAccountData", mock.Anything).Maybe().Return(tt.writeError)
+// 				return
+// 			}
+
+// 			// Create the Handlers instance with the mock file handler
+// 			h := &Handlers{
+// 				accountFileHandler: mockFileHandler,
+// 			}
+
+// 			// Call save yob
+// 			result, err := h.SaveOfferings(context.Background(), "save_offerings", tt.input)
+
+// 			if err != nil {
+// 				t.Fatalf("Failed to save offerings with error: %v", err)
+// 			}
+// 			savedData, err := h.accountFileHandler.ReadAccountData()
+// 			if err == nil {
+// 				//Assert that the input provided is what was saved into the file
+// 				assert.Equal(t, string(tt.input), savedData["Offerings"])
+// 			}
+
+// 			// Assert the results
+// 			assert.Equal(t, tt.expectedResult, result)
+// 			assert.Equal(t, tt.expectedError, err)
+
+// 			// Assert all expectations were met
+// 			mockFileHandler.AssertExpectations(t)
+// 		})
+// 	}
+// }
+
+// func TestSaveGender(t *testing.T) {
+// 	// Create a new instance of MockAccountFileHandler
+// 	mockFileHandler := new(mocks.MockAccountFileHandler)
+
+// 	// Define test cases
+// 	tests := []struct {
+// 		name           string
+// 		input          []byte
+// 		existingData   map[string]string
+// 		writeError     error
+// 		expectedResult resource.Result
+// 		expectedError  error
+// 		expectedGender string
+// 	}{
+// 		{
+// 			name:           "Successful Save - Male",
+// 			input:          []byte("1"),
+// 			existingData:   map[string]string{"OtherKey": "OtherValue"},
+// 			writeError:     nil,
+// 			expectedResult: resource.Result{},
+// 			expectedError:  nil,
+// 			expectedGender: "Male",
+// 		},
+// 		{
+// 			name:           "Successful Save - Female",
+// 			input:          []byte("2"),
+// 			existingData:   map[string]string{"OtherKey": "OtherValue"},
+// 			writeError:     nil,
+// 			expectedResult: resource.Result{},
+// 			expectedError:  nil,
+// 			expectedGender: "Female",
+// 		},
+// 		{
+// 			name:           "Successful Save - Unspecified",
+// 			input:          []byte("3"),
+// 			existingData:   map[string]string{"OtherKey": "OtherValue"},
+// 			writeError:     nil,
+// 			expectedResult: resource.Result{},
+// 			expectedError:  nil,
+// 			expectedGender: "Unspecified",
+// 		},
+
+// 		{
+// 			name:           "Empty Input",
+// 			input:          []byte{},
+// 			existingData:   map[string]string{"OtherKey": "OtherValue"},
+// 			writeError:     nil,
+// 			expectedResult: resource.Result{},
+// 			expectedError:  nil,
+// 			expectedGender: "",
+// 		},
+// 	}
+
+// 	for _, tt := range tests {
+// 		t.Run(tt.name, func(t *testing.T) {
+// 			// Set up the mock expectations
+// 			mockFileHandler.On("ReadAccountData").Return(tt.existingData, tt.expectedError)
+// 			if tt.expectedError == nil && len(tt.input) > 0 {
+// 				mockFileHandler.On("WriteAccountData", mock.MatchedBy(func(data map[string]string) bool {
+// 					return data["Gender"] == tt.expectedGender
+// 				})).Return(tt.writeError)
+// 			} else if len(tt.input) == 0 {
+// 				// For empty input, no WriteAccountData call should be made
+// 				mockFileHandler.On("WriteAccountData", mock.Anything).Maybe().Return(tt.writeError)
+// 			}
+
+// 			// Create the Handlers instance with the mock file handler
+// 			h := &Handlers{
+// 				accountFileHandler: mockFileHandler,
+// 			}
+
+// 			// Call the method
+// 			result, err := h.SaveGender(context.Background(), "save_gender", tt.input)
+
+// 			// Assert the results
+// 			assert.Equal(t, tt.expectedResult, result)
+// 			assert.Equal(t, tt.expectedError, err)
+
+// 			// Verify WriteAccountData was called with the expected data
+// 			if len(tt.input) > 0 && tt.expectedError == nil {
+// 				mockFileHandler.AssertCalled(t, "WriteAccountData", mock.MatchedBy(func(data map[string]string) bool {
+// 					return data["Gender"] == tt.expectedGender
+// 				}))
+// 			}
+
+// 			// Assert all expectations were met
+// 			mockFileHandler.AssertExpectations(t)
+// 		})
+// 	}
+// }
+
+// func TestGetSender(t *testing.T) {
+// 	mockAccountFileHandler := new(mocks.MockAccountFileHandler)
+// 	h := &Handlers{
+// 		accountFileHandler: mockAccountFileHandler,
+// 	}
+
+// 	tests := []struct {
+// 		name           string
+// 		expectedResult resource.Result
+// 		accountData    map[string]string
+// 	}{
+// 		{
+// 			name: "Valid public key",
+// 			expectedResult: resource.Result{
+// 				Content: "test-public-key",
+// 			},
+// 			accountData: map[string]string{
+// 				"PublicKey": "test-public-key",
+// 			},
+// 		},
+// 		{
+// 			name: "Missing public key",
+// 			expectedResult: resource.Result{
+// 				Content: "",
+// 			},
+// 			accountData: map[string]string{},
+// 		},
+// 	}
+
+// 	for _, tt := range tests {
+// 		t.Run(tt.name, func(t *testing.T) {
+// 			// Reset the mock state
+// 			mockAccountFileHandler.Mock = mock.Mock{}
+
+// 			mockAccountFileHandler.On("ReadAccountData").Return(tt.accountData, nil)
+
+// 			result, err := h.GetSender(context.Background(), "", nil)
+
+// 			if err != nil {
+// 				t.Fatalf("Error occurred: %v", err)
+// 			}
+
+// 			assert.Equal(t, tt.expectedResult.Content, result.Content)
+// 			mockAccountFileHandler.AssertCalled(t, "ReadAccountData")
+// 		})
+// 	}
+// }
+
+// func TestGetAmount(t *testing.T) {
+// 	mockAccountFileHandler := new(mocks.MockAccountFileHandler)
+// 	h := &Handlers{
+// 		accountFileHandler: mockAccountFileHandler,
+// 	}
+
+// 	tests := []struct {
+// 		name           string
+// 		expectedResult resource.Result
+// 		accountData    map[string]string
+// 	}{
+// 		{
+// 			name: "Valid amount",
+// 			expectedResult: resource.Result{
+// 				Content: "0.003",
+// 			},
+// 			accountData: map[string]string{
+// 				"Amount": "0.003",
+// 			},
+// 		},
+// 		{
+// 			name:           "Missing amount",
+// 			expectedResult: resource.Result{},
+// 			accountData: map[string]string{
+// 				"Amount": "",
+// 			},
+// 		},
+// 	}
+
+// 	for _, tt := range tests {
+// 		t.Run(tt.name, func(t *testing.T) {
+// 			// Reset the mock state
+// 			mockAccountFileHandler.Mock = mock.Mock{}
+
+// 			mockAccountFileHandler.On("ReadAccountData").Return(tt.accountData, nil)
+
+// 			result, err := h.GetAmount(context.Background(), "", nil)
+
+// 			assert.NoError(t, err)
+// 			assert.Equal(t, tt.expectedResult.Content, result.Content)
+
+// 			mockAccountFileHandler.AssertCalled(t, "ReadAccountData")
+// 		})
+// 	}
+// }
+
+// func TestGetProfileInfo(t *testing.T) {
+// 	tests := []struct {
+// 		name           string
+// 		accountData    map[string]string
+// 		readError      error
+// 		expectedResult resource.Result
+// 		expectedError  error
+// 	}{
+// 		{
+// 			name: "Complete Profile",
+// 			accountData: map[string]string{
+// 				"FirstName":  "John",
+// 				"FamilyName": "Doe",
+// 				"Gender":     "Male",
+// 				"YOB":        "1980",
+// 				"Location":   "Mombasa",
+// 				"Offerings":  "Product A",
+// 			},
+// 			readError: nil,
+// 			expectedResult: resource.Result{
+// 				Content: fmt.Sprintf(
+// 					"Name: %s %s\nGender: %s\nAge: %d\nLocation: %s\nYou provide: %s\n",
+// 					"John", "Doe", "Male", 44, "Mombasa", "Product A",
+// 				),
+// 			},
+// 			expectedError: nil,
+// 		},
+// 		{
+// 			name: "Profile with Not Provided Fields",
+// 			accountData: map[string]string{
+// 				"FirstName":  "Not provided",
+// 				"FamilyName": "Doe",
+// 				"Gender":     "Female",
+// 				"YOB":        "1995",
+// 				"Location":   "Not provided",
+// 				"Offerings":  "Service B",
+// 			},
+// 			readError: nil,
+// 			expectedResult: resource.Result{
+// 				Content: fmt.Sprintf(
+// 					"Name: %s\nGender: %s\nAge: %d\nLocation: %s\nYou provide: %s\n",
+// 					"Not provided", "Female", 29, "Not provided", "Service B",
+// 				),
+// 			},
+// 			expectedError: nil,
+// 		},
+// 		{
+// 			name: "Profile with YOB as Not provided",
+// 			accountData: map[string]string{
+// 				"FirstName":  "Not provided",
+// 				"FamilyName": "Doe",
+// 				"Gender":     "Female",
+// 				"YOB":        "Not provided",
+// 				"Location":   "Not provided",
+// 				"Offerings":  "Service B",
+// 			},
+// 			readError: nil,
+// 			expectedResult: resource.Result{
+// 				Content: fmt.Sprintf(
+// 					"Name: %s\nGender: %s\nAge: %s\nLocation: %s\nYou provide: %s\n",
+// 					"Not provided", "Female", "Not provided", "Not provided", "Service B",
+// 				),
+// 			},
+// 			expectedError: nil,
+// 		},
+// 	}
+
+// 	for _, tt := range tests {
+// 		t.Run(tt.name, func(t *testing.T) {
+// 			// Create a new instance of MockAccountFileHandler
+// 			mockFileHandler := new(mocks.MockAccountFileHandler)
+
+// 			// Set up the mock expectations
+// 			mockFileHandler.On("ReadAccountData").Return(tt.accountData, tt.readError)
+
+// 			// Create the Handlers instance with the mock file handler
+// 			h := &Handlers{
+// 				accountFileHandler: mockFileHandler,
+// 			}
+
+// 			// Call the method
+// 			result, err := h.GetProfileInfo(context.Background(), "get_profile_info", nil)
+
+// 			// Assert the results
+// 			assert.Equal(t, tt.expectedResult, result)
+// 			assert.Equal(t, tt.expectedError, err)
+
+// 			// Assert all expectations were met
+// 			mockFileHandler.AssertExpectations(t)
+// 		})
+// 	}
+// }
+
+// Test SaveFirstname
+func TestSaveFirstName(t *testing.T) {
+	// Create a new instance of MockDb
+	mockDb := new(mocks.MockDb)
+	k := utils.PackKey(utils.DATA_FAMILY_NAME, []byte("session123"))
 	// Define test cases
 	tests := []struct {
-		name           string
-		input          []byte
-		existingData   map[string]string
-		writeError     error
-		expectedResult resource.Result
-		expectedError  error
+		name          string
+		ctxValue      string
+		input         []byte
+		mockPutError  error
+		expectedError error
+		expectedCalls []mock.Call
 	}{
 		{
-			name:           "Successful Save",
-			input:          []byte("Mombasa"),
-			existingData:   map[string]string{"Location": "Mombasa"},
-			writeError:     nil,
-			expectedResult: resource.Result{},
-			expectedError:  nil,
-		},
-		{
-			name:           "Empty location input",
-			input:          []byte{},
-			existingData:   map[string]string{"OtherKey": "OtherValue"},
-			writeError:     nil,
-			expectedResult: resource.Result{},
-			expectedError:  nil,
-		},
-	}
-
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			// Set up the mock expectations
-			mockFileHandler.On("ReadAccountData").Return(tt.existingData, tt.expectedError)
-			if tt.expectedError == nil && len(tt.input) > 0 {
-				mockFileHandler.On("WriteAccountData", mock.MatchedBy(func(data map[string]string) bool {
-					return data["Location"] == string(tt.input)
-				})).Return(tt.writeError)
-			} else if len(tt.input) == 0 {
-				// For empty input, no WriteAccountData call should be made
-				mockFileHandler.On("WriteAccountData", mock.Anything).Maybe().Return(tt.writeError)
-				return
-			}
-
-			// Create the Handlers instance with the mock file handler
-			h := &Handlers{
-				accountFileHandler: mockFileHandler,
-			}
-
-			// Call Save Location
-			result, err := h.SaveLocation(context.Background(), "save_location", tt.input)
-
-			if err != nil {
-				t.Fatalf("Failed to save location with error: %v", err)
-			}
-
-			savedData, err := h.accountFileHandler.ReadAccountData()
-			if err == nil {
-				//Assert that the input provided is what was saved into the file
-				assert.Equal(t, string(tt.input), savedData["Location"])
-			}
-
-			// Assert the results
-			assert.Equal(t, tt.expectedResult, result)
-			assert.Equal(t, tt.expectedError, err)
-
-			// Assert all expectations were met
-			mockFileHandler.AssertExpectations(t)
-		})
-	}
-}
-
-func TestSaveFirstname(t *testing.T) {
-	// Create a new instance of MockAccountFileHandler
-	mockFileHandler := new(mocks.MockAccountFileHandler)
-
-	// Define test cases
-	tests := []struct {
-		name           string
-		input          []byte
-		existingData   map[string]string
-		writeError     error
-		expectedResult resource.Result
-		expectedError  error
-	}{
-		{
-			name:           "Successful Save",
-			input:          []byte("Joe"),
-			existingData:   map[string]string{"Name": "Joe"},
-			writeError:     nil,
-			expectedResult: resource.Result{},
-			expectedError:  nil,
-		},
-		{
-			name:          "Empty Input",
-			input:         []byte{},
-			existingData:  map[string]string{"OtherKey": "OtherValue"},
-			writeError:    nil,
+			name:          "Successful save",
+			ctxValue:      "session123",
+			input:         []byte("John"),
+			mockPutError:  nil,
 			expectedError: nil,
+			expectedCalls: []mock.Call{
+				// Expect the SetPrefix and SetSession calls
+				*mockDb.On("SetPrefix", utils.DATA_FAMILY_NAME).Return(),
+				*mockDb.On("SetSession", "session123").Return(),
+				// Expect the Put call
+				*mockDb.On("Put", context.WithValue(context.Background(), "SessionId", "session123"), k, []byte("John")).Return(nil),
+			},
 		},
 	}
 
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
 			// Set up the mock expectations
-			mockFileHandler.On("ReadAccountData").Return(tt.existingData, tt.expectedError)
-			if tt.expectedError == nil && len(tt.input) > 0 {
-				mockFileHandler.On("WriteAccountData", mock.MatchedBy(func(data map[string]string) bool {
-					return data["FirstName"] == string(tt.input)
-				})).Return(tt.writeError)
-			} else if len(tt.input) == 0 {
-				// For empty input, no WriteAccountData call should be made
-				mockFileHandler.On("WriteAccountData", mock.Anything).Maybe().Return(tt.writeError)
-				return
+			for _, call := range tt.expectedCalls {
+				call.Run(func(args mock.Arguments) {})
 			}
 
-			// Create the Handlers instance with the mock file handler
+			// Create the Handlers instance with the mock db
 			h := &Handlers{
-				accountFileHandler: mockFileHandler,
+				userdataStore: mockDb,
 			}
 
-			// Call save location
-			result, err := h.SaveFirstname(context.Background(), "save_location", tt.input)
-
-			if err != nil {
-				t.Fatalf("Failed to save first name with error: %v", err)
-			}
-			savedData, err := h.accountFileHandler.ReadAccountData()
-			if err == nil {
-				//Assert that the input provided is what was saved into the file
-				assert.Equal(t, string(tt.input), savedData["FirstName"])
-			}
-
-			// Assert the results
-			assert.Equal(t, tt.expectedResult, result)
-			assert.Equal(t, tt.expectedError, err)
-
-			// Assert all expectations were met
-			mockFileHandler.AssertExpectations(t)
-		})
-	}
-}
-
-func TestSaveFamilyName(t *testing.T) {
-	// Create a new instance of MockAccountFileHandler
-	mockFileHandler := new(mocks.MockAccountFileHandler)
-
-	// Define test cases
-	tests := []struct {
-		name           string
-		input          []byte
-		existingData   map[string]string
-		writeError     error
-		expectedResult resource.Result
-		expectedError  error
-	}{
-		{
-			name:           "Successful Save",
-			input:          []byte("Doe"),
-			existingData:   map[string]string{"FamilyName": "Doe"},
-			writeError:     nil,
-			expectedResult: resource.Result{},
-			expectedError:  nil,
-		},
-		{
-			name:          "Empty Input",
-			input:         []byte{},
-			existingData:  map[string]string{"FamilyName": "Doe"},
-			writeError:    nil,
-			expectedError: nil,
-		},
-	}
-
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			// Set up the mock expectations
-			mockFileHandler.On("ReadAccountData").Return(tt.existingData, tt.expectedError)
-			if tt.expectedError == nil && len(tt.input) > 0 {
-				mockFileHandler.On("WriteAccountData", mock.MatchedBy(func(data map[string]string) bool {
-					return data["FamilyName"] == string(tt.input)
-				})).Return(tt.writeError)
-			} else if len(tt.input) == 0 {
-				// For empty input, no WriteAccountData call should be made
-				mockFileHandler.On("WriteAccountData", mock.Anything).Maybe().Return(tt.writeError)
-				return
-			}
-
-			// Create the Handlers instance with the mock file handler
-			h := &Handlers{
-				accountFileHandler: mockFileHandler,
-			}
-
-			// Call save familyname
-			result, err := h.SaveFamilyname(context.Background(), "save_familyname", tt.input)
-
-			if err != nil {
-				t.Fatalf("Failed to save family name with error: %v", err)
-			}
-			savedData, err := h.accountFileHandler.ReadAccountData()
-			if err == nil {
-				//Assert that the input provided is what was saved into the file
-				assert.Equal(t, string(tt.input), savedData["FamilyName"])
-			}
-
-			// Assert the results
-			assert.Equal(t, tt.expectedResult, result)
-			assert.Equal(t, tt.expectedError, err)
-
-			// Assert all expectations were met
-			mockFileHandler.AssertExpectations(t)
-		})
-	}
-}
-
-func TestSaveYOB(t *testing.T) {
-	// Create a new instance of MockAccountFileHandler
-	mockFileHandler := new(mocks.MockAccountFileHandler)
-
-	// Define test cases
-	tests := []struct {
-		name           string
-		input          []byte
-		existingData   map[string]string
-		writeError     error
-		expectedResult resource.Result
-		expectedError  error
-	}{
-		{
-			name:           "Successful Save",
-			input:          []byte("2006"),
-			existingData:   map[string]string{"": ""},
-			writeError:     nil,
-			expectedResult: resource.Result{},
-			expectedError:  nil,
-		},
-		{
-			name:          "YOB less than 4 digits(invalid date entry)",
-			input:         []byte{},
-			existingData:  map[string]string{"": ""},
-			writeError:    nil,
-			expectedError: nil,
-		},
-	}
-
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			// Set up the mock expectations
-			mockFileHandler.On("ReadAccountData").Return(tt.existingData, tt.expectedError)
-			if tt.expectedError == nil && len(tt.input) > 0 {
-				mockFileHandler.On("WriteAccountData", mock.MatchedBy(func(data map[string]string) bool {
-					return data["YOB"] == string(tt.input)
-				})).Return(tt.writeError)
-			} else if len(tt.input) != 4 {
-				// For input whose input is not a valid yob, no WriteAccountData call should be made
-				mockFileHandler.On("WriteAccountData", mock.Anything).Maybe().Return(tt.writeError)
-				return
-			}
-
-			// Create the Handlers instance with the mock file handler
-			h := &Handlers{
-				accountFileHandler: mockFileHandler,
-			}
-
-			// Call save yob
-			result, err := h.SaveYob(context.Background(), "save_yob", tt.input)
-
-			if err != nil {
-				t.Fatalf("Failed to save family name with error: %v", err)
-			}
-			savedData, err := h.accountFileHandler.ReadAccountData()
-			if err == nil {
-				//Assert that the input provided is what was saved into the file
-				assert.Equal(t, string(tt.input), savedData["YOB"])
-			}
-
-			// Assert the results
-			assert.Equal(t, tt.expectedResult, result)
-			assert.Equal(t, tt.expectedError, err)
-
-			// Assert all expectations were met
-			mockFileHandler.AssertExpectations(t)
-		})
-	}
-}
-
-func TestSaveOfferings(t *testing.T) {
-	// Create a new instance of MockAccountFileHandler
-	mockFileHandler := new(mocks.MockAccountFileHandler)
-
-	// Define test cases
-	tests := []struct {
-		name           string
-		input          []byte
-		existingData   map[string]string
-		writeError     error
-		expectedResult resource.Result
-		expectedError  error
-	}{
-		{
-			name:           "Successful Save",
-			input:          []byte("Bananas"),
-			existingData:   map[string]string{"": ""},
-			writeError:     nil,
-			expectedResult: resource.Result{},
-			expectedError:  nil,
-		},
-		{
-			name:          "Empty input",
-			input:         []byte{},
-			existingData:  map[string]string{"": ""},
-			writeError:    nil,
-			expectedError: nil,
-		},
-	}
-
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			// Set up the mock expectations
-			mockFileHandler.On("ReadAccountData").Return(tt.existingData, tt.expectedError)
-			if tt.expectedError == nil && len(tt.input) > 0 {
-				mockFileHandler.On("WriteAccountData", mock.MatchedBy(func(data map[string]string) bool {
-					return data["Offerings"] == string(tt.input)
-				})).Return(tt.writeError)
-			} else if len(tt.input) != 4 {
-				// For input whose input is not a valid yob, no WriteAccountData call should be made
-				mockFileHandler.On("WriteAccountData", mock.Anything).Maybe().Return(tt.writeError)
-				return
-			}
-
-			// Create the Handlers instance with the mock file handler
-			h := &Handlers{
-				accountFileHandler: mockFileHandler,
-			}
-
-			// Call save yob
-			result, err := h.SaveOfferings(context.Background(), "save_offerings", tt.input)
-
-			if err != nil {
-				t.Fatalf("Failed to save offerings with error: %v", err)
-			}
-			savedData, err := h.accountFileHandler.ReadAccountData()
-			if err == nil {
-				//Assert that the input provided is what was saved into the file
-				assert.Equal(t, string(tt.input), savedData["Offerings"])
-			}
-
-			// Assert the results
-			assert.Equal(t, tt.expectedResult, result)
-			assert.Equal(t, tt.expectedError, err)
-
-			// Assert all expectations were met
-			mockFileHandler.AssertExpectations(t)
-		})
-	}
-}
-
-func TestSaveGender(t *testing.T) {
-	// Create a new instance of MockAccountFileHandler
-	mockFileHandler := new(mocks.MockAccountFileHandler)
-
-	// Define test cases
-	tests := []struct {
-		name           string
-		input          []byte
-		existingData   map[string]string
-		writeError     error
-		expectedResult resource.Result
-		expectedError  error
-		expectedGender string
-	}{
-		{
-			name:           "Successful Save - Male",
-			input:          []byte("1"),
-			existingData:   map[string]string{"OtherKey": "OtherValue"},
-			writeError:     nil,
-			expectedResult: resource.Result{},
-			expectedError:  nil,
-			expectedGender: "Male",
-		},
-		{
-			name:           "Successful Save - Female",
-			input:          []byte("2"),
-			existingData:   map[string]string{"OtherKey": "OtherValue"},
-			writeError:     nil,
-			expectedResult: resource.Result{},
-			expectedError:  nil,
-			expectedGender: "Female",
-		},
-		{
-			name:           "Successful Save - Unspecified",
-			input:          []byte("3"),
-			existingData:   map[string]string{"OtherKey": "OtherValue"},
-			writeError:     nil,
-			expectedResult: resource.Result{},
-			expectedError:  nil,
-			expectedGender: "Unspecified",
-		},
-
-		{
-			name:           "Empty Input",
-			input:          []byte{},
-			existingData:   map[string]string{"OtherKey": "OtherValue"},
-			writeError:     nil,
-			expectedResult: resource.Result{},
-			expectedError:  nil,
-			expectedGender: "",
-		},
-	}
-
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			// Set up the mock expectations
-			mockFileHandler.On("ReadAccountData").Return(tt.existingData, tt.expectedError)
-			if tt.expectedError == nil && len(tt.input) > 0 {
-				mockFileHandler.On("WriteAccountData", mock.MatchedBy(func(data map[string]string) bool {
-					return data["Gender"] == tt.expectedGender
-				})).Return(tt.writeError)
-			} else if len(tt.input) == 0 {
-				// For empty input, no WriteAccountData call should be made
-				mockFileHandler.On("WriteAccountData", mock.Anything).Maybe().Return(tt.writeError)
-			}
-
-			// Create the Handlers instance with the mock file handler
-			h := &Handlers{
-				accountFileHandler: mockFileHandler,
-			}
+			// Create the context with the session ID
+			ctx := context.WithValue(context.Background(), "SessionId", tt.ctxValue)
 
 			// Call the method
-			result, err := h.SaveGender(context.Background(), "save_gender", tt.input)
+			_, err := h.SaveFamilyname(ctx, "save_familyname", []byte("John"))
 
 			// Assert the results
-			assert.Equal(t, tt.expectedResult, result)
-			assert.Equal(t, tt.expectedError, err)
-
-			// Verify WriteAccountData was called with the expected data
-			if len(tt.input) > 0 && tt.expectedError == nil {
-				mockFileHandler.AssertCalled(t, "WriteAccountData", mock.MatchedBy(func(data map[string]string) bool {
-					return data["Gender"] == tt.expectedGender
-				}))
-			}
-
-			// Assert all expectations were met
-			mockFileHandler.AssertExpectations(t)
-		})
-	}
-}
-
-func TestGetSender(t *testing.T) {
-	mockAccountFileHandler := new(mocks.MockAccountFileHandler)
-	h := &Handlers{
-		accountFileHandler: mockAccountFileHandler,
-	}
-
-	tests := []struct {
-		name           string
-		expectedResult resource.Result
-		accountData    map[string]string
-	}{
-		{
-			name: "Valid public key",
-			expectedResult: resource.Result{
-				Content: "test-public-key",
-			},
-			accountData: map[string]string{
-				"PublicKey": "test-public-key",
-			},
-		},
-		{
-			name: "Missing public key",
-			expectedResult: resource.Result{
-				Content: "",
-			},
-			accountData: map[string]string{},
-		},
-	}
-
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			// Reset the mock state
-			mockAccountFileHandler.Mock = mock.Mock{}
-
-			mockAccountFileHandler.On("ReadAccountData").Return(tt.accountData, nil)
-
-			result, err := h.GetSender(context.Background(), "", nil)
-
-			if err != nil {
-				t.Fatalf("Error occurred: %v", err)
-			}
-
-			assert.Equal(t, tt.expectedResult.Content, result.Content)
-			mockAccountFileHandler.AssertCalled(t, "ReadAccountData")
-		})
-	}
-}
-
-func TestGetAmount(t *testing.T) {
-	mockAccountFileHandler := new(mocks.MockAccountFileHandler)
-	h := &Handlers{
-		accountFileHandler: mockAccountFileHandler,
-	}
-
-	tests := []struct {
-		name           string
-		expectedResult resource.Result
-		accountData    map[string]string
-	}{
-		{
-			name: "Valid amount",
-			expectedResult: resource.Result{
-				Content: "0.003",
-			},
-			accountData: map[string]string{
-				"Amount": "0.003",
-			},
-		},
-		{
-			name:           "Missing amount",
-			expectedResult: resource.Result{},
-			accountData: map[string]string{
-				"Amount": "",
-			},
-		},
-	}
-
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			// Reset the mock state
-			mockAccountFileHandler.Mock = mock.Mock{}
-
-			mockAccountFileHandler.On("ReadAccountData").Return(tt.accountData, nil)
-
-			result, err := h.GetAmount(context.Background(), "", nil)
-
-			assert.NoError(t, err)
-			assert.Equal(t, tt.expectedResult.Content, result.Content)
-
-			mockAccountFileHandler.AssertCalled(t, "ReadAccountData")
-		})
-	}
-}
-
-func TestGetProfileInfo(t *testing.T) {
-	tests := []struct {
-		name           string
-		accountData    map[string]string
-		readError      error
-		expectedResult resource.Result
-		expectedError  error
-	}{
-		{
-			name: "Complete Profile",
-			accountData: map[string]string{
-				"FirstName":  "John",
-				"FamilyName": "Doe",
-				"Gender":     "Male",
-				"YOB":        "1980",
-				"Location":   "Mombasa",
-				"Offerings":  "Product A",
-			},
-			readError: nil,
-			expectedResult: resource.Result{
-				Content: fmt.Sprintf(
-					"Name: %s %s\nGender: %s\nAge: %d\nLocation: %s\nYou provide: %s\n",
-					"John", "Doe", "Male", 44, "Mombasa", "Product A",
-				),
-			},
-			expectedError: nil,
-		},
-		{
-			name: "Profile with Not Provided Fields",
-			accountData: map[string]string{
-				"FirstName":  "Not provided",
-				"FamilyName": "Doe",
-				"Gender":     "Female",
-				"YOB":        "1995",
-				"Location":   "Not provided",
-				"Offerings":  "Service B",
-			},
-			readError: nil,
-			expectedResult: resource.Result{
-				Content: fmt.Sprintf(
-					"Name: %s\nGender: %s\nAge: %d\nLocation: %s\nYou provide: %s\n",
-					"Not provided", "Female", 29, "Not provided", "Service B",
-				),
-			},
-			expectedError: nil,
-		},
-		{
-			name: "Profile with YOB as Not provided",
-			accountData: map[string]string{
-				"FirstName":  "Not provided",
-				"FamilyName": "Doe",
-				"Gender":     "Female",
-				"YOB":        "Not provided",
-				"Location":   "Not provided",
-				"Offerings":  "Service B",
-			},
-			readError: nil,
-			expectedResult: resource.Result{
-				Content: fmt.Sprintf(
-					"Name: %s\nGender: %s\nAge: %s\nLocation: %s\nYou provide: %s\n",
-					"Not provided", "Female", "Not provided", "Not provided", "Service B",
-				),
-			},
-			expectedError: nil,
-		},
-	}
-
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			// Create a new instance of MockAccountFileHandler
-			mockFileHandler := new(mocks.MockAccountFileHandler)
-
-			// Set up the mock expectations
-			mockFileHandler.On("ReadAccountData").Return(tt.accountData, tt.readError)
-
-			// Create the Handlers instance with the mock file handler
-			h := &Handlers{
-				accountFileHandler: mockFileHandler,
-			}
-
-			// Call the method
-			result, err := h.GetProfileInfo(context.Background(), "get_profile_info", nil)
-
-			// Assert the results
-			assert.Equal(t, tt.expectedResult, result)
 			assert.Equal(t, tt.expectedError, err)
 
 			// Assert all expectations were met
-			mockFileHandler.AssertExpectations(t)
+			mockDb.AssertExpectations(t)
 		})
 	}
 }

From de24ca0648fe88a5be88336a75cfa91915649e5a Mon Sep 17 00:00:00 2001
From: alfred-mk <alfredmwaik@gmail.com>
Date: Sat, 7 Sep 2024 09:30:20 +0300
Subject: [PATCH 23/47] Mock the gdm nd updated the TestSaveFirstname and
 TestSaveFamilyname

---
 internal/handlers/ussd/menuhandler_test.go | 348 +++++++++------------
 1 file changed, 154 insertions(+), 194 deletions(-)

diff --git a/internal/handlers/ussd/menuhandler_test.go b/internal/handlers/ussd/menuhandler_test.go
index 3c14a26..b13da16 100644
--- a/internal/handlers/ussd/menuhandler_test.go
+++ b/internal/handlers/ussd/menuhandler_test.go
@@ -4,9 +4,9 @@ import (
 	"context"
 	"testing"
 
-	"git.grassecon.net/urdt/ussd/internal/handlers/ussd/mocks"
+	"git.defalsify.org/vise.git/lang"
 	"git.grassecon.net/urdt/ussd/internal/models"
-	"git.grassecon.net/urdt/ussd/internal/utils"
+
 	"github.com/alecthomas/assert/v2"
 	"github.com/stretchr/testify/mock"
 )
@@ -16,15 +16,6 @@ type MockAccountService struct {
 	mock.Mock
 }
 
-type MockFlagParser struct {
-	mock.Mock
-}
-
-func (m *MockFlagParser) GetFlag(key string) (uint32, error) {
-	args := m.Called(key)
-	return args.Get(0).(uint32), args.Error(1)
-}
-
 func (m *MockAccountService) CreateAccount() (*models.AccountResponse, error) {
 	args := m.Called()
 	return args.Get(0).(*models.AccountResponse), args.Error(1)
@@ -40,6 +31,58 @@ func (m *MockAccountService) CheckAccountStatus(trackingId string) (string, erro
 	return args.String(0), args.Error(1)
 }
 
+// MockDb is a mock implementation of the db.Db interface
+type MockDb struct {
+	mock.Mock
+}
+
+func (m *MockDb) SetPrefix(prefix uint8) {
+	m.Called(prefix)
+}
+
+func (m *MockDb) Prefix() uint8 {
+	args := m.Called()
+	return args.Get(0).(uint8)
+}
+
+func (m *MockDb) Safe() bool {
+	args := m.Called()
+	return args.Get(0).(bool)
+}
+
+func (m *MockDb) SetLanguage(language *lang.Language) {
+	m.Called(language)
+}
+
+func (m *MockDb) SetLock(uint8, bool) error {
+	args := m.Called()
+	return args.Error(0)
+}
+
+func (m *MockDb) Connect(ctx context.Context, connectionStr string) error {
+	args := m.Called(ctx, connectionStr)
+	return args.Error(0)
+}
+
+func (m *MockDb) SetSession(sessionId string) {
+	m.Called(sessionId)
+}
+
+func (m *MockDb) Put(ctx context.Context, key, value []byte) error {
+	args := m.Called(ctx, key, value)
+	return args.Error(0)
+}
+
+func (m *MockDb) Get(ctx context.Context, key []byte) ([]byte, error) {
+	args := m.Called(ctx, key)
+	return nil, args.Error(0)
+}
+
+func (m *MockDb) Close() error {
+	args := m.Called(nil)
+	return args.Error(0)
+}
+
 // func TestCreateAccount(t *testing.T) {
 // 	// Setup
 // 	tempDir, err := os.MkdirTemp("", "test_create_account")
@@ -425,147 +468,121 @@ func (m *MockAccountService) CheckAccountStatus(trackingId string) (string, erro
 // 	}
 // }
 
-// func TestSaveFirstname(t *testing.T) {
-// 	// Create a new instance of MockAccountFileHandler
-// 	mockFileHandler := new(mocks.MockAccountFileHandler)
+func TestSaveFirstname(t *testing.T) {
+	// Create a mock database
+	mockDb := new(MockDb)
 
-// 	// Define test cases
-// 	tests := []struct {
-// 		name           string
-// 		input          []byte
-// 		existingData   map[string]string
-// 		writeError     error
-// 		expectedResult resource.Result
-// 		expectedError  error
-// 	}{
-// 		{
-// 			name:           "Successful Save",
-// 			input:          []byte("Joe"),
-// 			existingData:   map[string]string{"Name": "Joe"},
-// 			writeError:     nil,
-// 			expectedResult: resource.Result{},
-// 			expectedError:  nil,
-// 		},
-// 		{
-// 			name:          "Empty Input",
-// 			input:         []byte{},
-// 			existingData:  map[string]string{"OtherKey": "OtherValue"},
-// 			writeError:    nil,
-// 			expectedError: nil,
-// 		},
-// 	}
+	// Create a Handlers instance with the mock database
+	h := &Handlers{
+		userdataStore: mockDb,
+	}
 
-// 	for _, tt := range tests {
-// 		t.Run(tt.name, func(t *testing.T) {
-// 			// Set up the mock expectations
-// 			mockFileHandler.On("ReadAccountData").Return(tt.existingData, tt.expectedError)
-// 			if tt.expectedError == nil && len(tt.input) > 0 {
-// 				mockFileHandler.On("WriteAccountData", mock.MatchedBy(func(data map[string]string) bool {
-// 					return data["FirstName"] == string(tt.input)
-// 				})).Return(tt.writeError)
-// 			} else if len(tt.input) == 0 {
-// 				// For empty input, no WriteAccountData call should be made
-// 				mockFileHandler.On("WriteAccountData", mock.Anything).Maybe().Return(tt.writeError)
-// 				return
-// 			}
+	// Create a context with a session ID
+	ctx := context.WithValue(context.Background(), "SessionId", "test-session")
 
-// 			// Create the Handlers instance with the mock file handler
-// 			h := &Handlers{
-// 				accountFileHandler: mockFileHandler,
-// 			}
+	tests := []struct {
+		name        string
+		input       []byte
+		expectError bool
+		setupMock   func(*MockDb)
+	}{
+		{
+			name:        "Valid first name",
+			input:       []byte("John"),
+			expectError: false,
+			setupMock: func(m *MockDb) {
+				m.On("SetPrefix", uint8(0x20)).Return(nil)
+				m.On("SetSession", "test-session").Return(nil)
+				m.On("Put", mock.Anything, mock.Anything, []byte("John")).Return(nil)
+			},
+		},
+		{
+			name:        "Empty first name",
+			input:       []byte{},
+			expectError: false, // Note: The function doesn't return an error for empty input
+			setupMock:   func(m *MockDb) {},
+		},
+	}
 
-// 			// Call save location
-// 			result, err := h.SaveFirstname(context.Background(), "save_location", tt.input)
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			// Setup mock expectations
+			tt.setupMock(mockDb)
 
-// 			if err != nil {
-// 				t.Fatalf("Failed to save first name with error: %v", err)
-// 			}
-// 			savedData, err := h.accountFileHandler.ReadAccountData()
-// 			if err == nil {
-// 				//Assert that the input provided is what was saved into the file
-// 				assert.Equal(t, string(tt.input), savedData["FirstName"])
-// 			}
+			// Call the function
+			_, err := h.SaveFirstname(ctx, "", tt.input)
 
-// 			// Assert the results
-// 			assert.Equal(t, tt.expectedResult, result)
-// 			assert.Equal(t, tt.expectedError, err)
+			if tt.expectError {
+				assert.Error(t, err)
+			} else {
+				assert.NoError(t, err)
+				mockDb.AssertExpectations(t)
+			}
 
-// 			// Assert all expectations were met
-// 			mockFileHandler.AssertExpectations(t)
-// 		})
-// 	}
-// }
+			// Clear mock for the next test
+			mockDb.ExpectedCalls = nil
+			mockDb.Calls = nil
+		})
+	}
+}
 
-// func TestSaveFamilyName(t *testing.T) {
-// 	// Create a new instance of MockAccountFileHandler
-// 	mockFileHandler := new(mocks.MockAccountFileHandler)
+func TestSaveFamilyname(t *testing.T) {
+	// Create a mock database
+	mockDb := new(MockDb)
 
-// 	// Define test cases
-// 	tests := []struct {
-// 		name           string
-// 		input          []byte
-// 		existingData   map[string]string
-// 		writeError     error
-// 		expectedResult resource.Result
-// 		expectedError  error
-// 	}{
-// 		{
-// 			name:           "Successful Save",
-// 			input:          []byte("Doe"),
-// 			existingData:   map[string]string{"FamilyName": "Doe"},
-// 			writeError:     nil,
-// 			expectedResult: resource.Result{},
-// 			expectedError:  nil,
-// 		},
-// 		{
-// 			name:          "Empty Input",
-// 			input:         []byte{},
-// 			existingData:  map[string]string{"FamilyName": "Doe"},
-// 			writeError:    nil,
-// 			expectedError: nil,
-// 		},
-// 	}
+	// Create a Handlers instance with the mock database
+	h := &Handlers{
+		userdataStore: mockDb,
+	}
 
-// 	for _, tt := range tests {
-// 		t.Run(tt.name, func(t *testing.T) {
-// 			// Set up the mock expectations
-// 			mockFileHandler.On("ReadAccountData").Return(tt.existingData, tt.expectedError)
-// 			if tt.expectedError == nil && len(tt.input) > 0 {
-// 				mockFileHandler.On("WriteAccountData", mock.MatchedBy(func(data map[string]string) bool {
-// 					return data["FamilyName"] == string(tt.input)
-// 				})).Return(tt.writeError)
-// 			} else if len(tt.input) == 0 {
-// 				// For empty input, no WriteAccountData call should be made
-// 				mockFileHandler.On("WriteAccountData", mock.Anything).Maybe().Return(tt.writeError)
-// 				return
-// 			}
+	// Create a context with a session ID
+	ctx := context.WithValue(context.Background(), "SessionId", "test-session")
 
-// 			// Create the Handlers instance with the mock file handler
-// 			h := &Handlers{
-// 				accountFileHandler: mockFileHandler,
-// 			}
+	tests := []struct {
+		name        string
+		input       []byte
+		expectError bool
+		setupMock   func(*MockDb)
+	}{
+		{
+			name:        "Valid family name",
+			input:       []byte("Smith"),
+			expectError: false,
+			setupMock: func(m *MockDb) {
+				m.On("SetPrefix", uint8(0x20)).Return(nil)
+				m.On("SetSession", "test-session").Return(nil)
+				m.On("Put", mock.Anything, mock.Anything, []byte("Smith")).Return(nil)
+			},
+		},
+		{
+			name:        "Empty family name",
+			input:       []byte{},
+			expectError: true,
+			setupMock:   func(m *MockDb) {},
+		},
+	}
 
-// 			// Call save familyname
-// 			result, err := h.SaveFamilyname(context.Background(), "save_familyname", tt.input)
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			// Setup mock expectations
+			tt.setupMock(mockDb)
 
-// 			if err != nil {
-// 				t.Fatalf("Failed to save family name with error: %v", err)
-// 			}
-// 			savedData, err := h.accountFileHandler.ReadAccountData()
-// 			if err == nil {
-// 				//Assert that the input provided is what was saved into the file
-// 				assert.Equal(t, string(tt.input), savedData["FamilyName"])
-// 			}
+			// Call the function
+			_, err := h.SaveFamilyname(ctx, "", tt.input)
 
-// 			// Assert the results
-// 			assert.Equal(t, tt.expectedResult, result)
-// 			assert.Equal(t, tt.expectedError, err)
+			if tt.expectError {
+				assert.Error(t, err)
+			} else {
+				assert.NoError(t, err)
+				mockDb.AssertExpectations(t)
+			}
 
-// 			// Assert all expectations were met
-// 			mockFileHandler.AssertExpectations(t)
-// 		})
-// 	}
-// }
+			// Clear mock for the next test
+			mockDb.ExpectedCalls = nil
+			mockDb.Calls = nil
+		})
+	}
+}
 
 // func TestSaveYOB(t *testing.T) {
 // 	// Create a new instance of MockAccountFileHandler
@@ -986,60 +1003,3 @@ func (m *MockAccountService) CheckAccountStatus(trackingId string) (string, erro
 // 		})
 // 	}
 // }
-
-// Test SaveFirstname
-func TestSaveFirstName(t *testing.T) {
-	// Create a new instance of MockDb
-	mockDb := new(mocks.MockDb)
-	k := utils.PackKey(utils.DATA_FAMILY_NAME, []byte("session123"))
-	// Define test cases
-	tests := []struct {
-		name          string
-		ctxValue      string
-		input         []byte
-		mockPutError  error
-		expectedError error
-		expectedCalls []mock.Call
-	}{
-		{
-			name:          "Successful save",
-			ctxValue:      "session123",
-			input:         []byte("John"),
-			mockPutError:  nil,
-			expectedError: nil,
-			expectedCalls: []mock.Call{
-				// Expect the SetPrefix and SetSession calls
-				*mockDb.On("SetPrefix", utils.DATA_FAMILY_NAME).Return(),
-				*mockDb.On("SetSession", "session123").Return(),
-				// Expect the Put call
-				*mockDb.On("Put", context.WithValue(context.Background(), "SessionId", "session123"), k, []byte("John")).Return(nil),
-			},
-		},
-	}
-
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			// Set up the mock expectations
-			for _, call := range tt.expectedCalls {
-				call.Run(func(args mock.Arguments) {})
-			}
-
-			// Create the Handlers instance with the mock db
-			h := &Handlers{
-				userdataStore: mockDb,
-			}
-
-			// Create the context with the session ID
-			ctx := context.WithValue(context.Background(), "SessionId", tt.ctxValue)
-
-			// Call the method
-			_, err := h.SaveFamilyname(ctx, "save_familyname", []byte("John"))
-
-			// Assert the results
-			assert.Equal(t, tt.expectedError, err)
-
-			// Assert all expectations were met
-			mockDb.AssertExpectations(t)
-		})
-	}
-}

From 421fbe5543b44faee9ec14b7672144e581c26490 Mon Sep 17 00:00:00 2001
From: Carlosokumu <carlosokumu254@gmail.com>
Date: Sat, 7 Sep 2024 09:55:00 +0300
Subject: [PATCH 24/47] setup mock for the acccount service

---
 internal/handlers/ussd/mocks/servicemock.go | 26 +++++++++++++++++++++
 1 file changed, 26 insertions(+)
 create mode 100644 internal/handlers/ussd/mocks/servicemock.go

diff --git a/internal/handlers/ussd/mocks/servicemock.go b/internal/handlers/ussd/mocks/servicemock.go
new file mode 100644
index 0000000..9fb6d3e
--- /dev/null
+++ b/internal/handlers/ussd/mocks/servicemock.go
@@ -0,0 +1,26 @@
+package mocks
+
+import (
+	"git.grassecon.net/urdt/ussd/internal/models"
+	"github.com/stretchr/testify/mock"
+)
+
+// MockAccountService implements AccountServiceInterface for testing
+type MockAccountService struct {
+	mock.Mock
+}
+
+func (m *MockAccountService) CreateAccount() (*models.AccountResponse, error) {
+	args := m.Called()
+	return args.Get(0).(*models.AccountResponse), args.Error(1)
+}
+
+func (m *MockAccountService) CheckBalance(publicKey string) (string, error) {
+	args := m.Called(publicKey)
+	return args.String(0), args.Error(1)
+}
+
+func (m *MockAccountService) CheckAccountStatus(trackingId string) (string, error) {
+	args := m.Called(trackingId)
+	return args.String(0), args.Error(1)
+}
\ No newline at end of file

From 57225523954e8028a8e7de1190548d65929ec04b Mon Sep 17 00:00:00 2001
From: Carlosokumu <carlosokumu254@gmail.com>
Date: Sat, 7 Sep 2024 09:55:13 +0300
Subject: [PATCH 25/47] remove old mocks

---
 internal/handlers/ussd/mocks/mocks.go | 44 ---------------------------
 1 file changed, 44 deletions(-)
 delete mode 100644 internal/handlers/ussd/mocks/mocks.go

diff --git a/internal/handlers/ussd/mocks/mocks.go b/internal/handlers/ussd/mocks/mocks.go
deleted file mode 100644
index 3c7eb1e..0000000
--- a/internal/handlers/ussd/mocks/mocks.go
+++ /dev/null
@@ -1,44 +0,0 @@
-package mocks
-
-import (
-	"git.grassecon.net/urdt/ussd/internal/models"
-	"github.com/stretchr/testify/mock"
-)
-
-type MockAccountFileHandler struct {
-	mock.Mock
-}
-
-func (m *MockAccountFileHandler) EnsureFileExists() error {
-	args := m.Called()
-	return args.Error(0)
-}
-
-func (m *MockAccountFileHandler) ReadAccountData() (map[string]string, error) {
-	args := m.Called()
-	return args.Get(0).(map[string]string), args.Error(1)
-}
-
-func (m *MockAccountFileHandler) WriteAccountData(data map[string]string) error {
-	args := m.Called(data)
-	return args.Error(0)
-}
-
-type MockAccountService struct {
-	mock.Mock
-}
-
-func (m *MockAccountService) CreateAccount() (*models.AccountResponse, error) {
-	args := m.Called()
-	return args.Get(0).(*models.AccountResponse), args.Error(1)
-}
-
-func (m *MockAccountService) CheckAccountStatus(TrackingId string) (string, error) {
-	args := m.Called()
-	return args.Get(0).(string), args.Error(1)
-}
-
-func (m *MockAccountService) CheckBalance(PublicKey string) (string, error) {
-	args := m.Called()
-	return args.Get(0).(string), args.Error(1)
-}

From 04ea11dd6d3c3d9af6d65a9e95924c4bd976587c Mon Sep 17 00:00:00 2001
From: Carlosokumu <carlosokumu254@gmail.com>
Date: Sat, 7 Sep 2024 09:55:47 +0300
Subject: [PATCH 26/47] setup db mock

---
 internal/handlers/ussd/mocks/dbmock.go | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/internal/handlers/ussd/mocks/dbmock.go b/internal/handlers/ussd/mocks/dbmock.go
index 71f7eca..0b40eab 100644
--- a/internal/handlers/ussd/mocks/dbmock.go
+++ b/internal/handlers/ussd/mocks/dbmock.go
@@ -4,7 +4,6 @@ import (
 	"context"
 
 	"git.defalsify.org/vise.git/lang"
-	"git.grassecon.net/urdt/ussd/internal/utils"
 	"github.com/stretchr/testify/mock"
 )
 
@@ -13,7 +12,7 @@ type MockDb struct {
 }
 
 func (m *MockDb) SetPrefix(prefix uint8) {
-	m.Called(utils.DATA_FAMILY_NAME)
+	m.Called(prefix)
 }
 
 func (m *MockDb) Prefix() uint8 {

From d1d5c897d1e0ad724a303c8517ca6f6fdb0430fe Mon Sep 17 00:00:00 2001
From: Carlosokumu <carlosokumu254@gmail.com>
Date: Sat, 7 Sep 2024 09:55:59 +0300
Subject: [PATCH 27/47] refactor

---
 internal/handlers/ussd/menuhandler_test.go | 120 +++++++++------------
 1 file changed, 49 insertions(+), 71 deletions(-)

diff --git a/internal/handlers/ussd/menuhandler_test.go b/internal/handlers/ussd/menuhandler_test.go
index b13da16..e496773 100644
--- a/internal/handlers/ussd/menuhandler_test.go
+++ b/internal/handlers/ussd/menuhandler_test.go
@@ -4,84 +4,62 @@ import (
 	"context"
 	"testing"
 
-	"git.defalsify.org/vise.git/lang"
-	"git.grassecon.net/urdt/ussd/internal/models"
-
+	"git.grassecon.net/urdt/ussd/internal/handlers/ussd/mocks"
 	"github.com/alecthomas/assert/v2"
 	"github.com/stretchr/testify/mock"
 )
 
-// MockAccountService implements AccountServiceInterface for testing
-type MockAccountService struct {
-	mock.Mock
-}
-
-func (m *MockAccountService) CreateAccount() (*models.AccountResponse, error) {
-	args := m.Called()
-	return args.Get(0).(*models.AccountResponse), args.Error(1)
-}
-
-func (m *MockAccountService) CheckBalance(publicKey string) (string, error) {
-	args := m.Called(publicKey)
-	return args.String(0), args.Error(1)
-}
-
-func (m *MockAccountService) CheckAccountStatus(trackingId string) (string, error) {
-	args := m.Called(trackingId)
-	return args.String(0), args.Error(1)
-}
-
 // MockDb is a mock implementation of the db.Db interface
-type MockDb struct {
-	mock.Mock
-}
+//type MockDb struct {
+// 	mock.Mock
+// }
 
-func (m *MockDb) SetPrefix(prefix uint8) {
-	m.Called(prefix)
-}
+// func (m *MockDb) SetPrefix(prefix uint8) {
+// 	m.Called(prefix)
+// }
 
-func (m *MockDb) Prefix() uint8 {
-	args := m.Called()
-	return args.Get(0).(uint8)
-}
+// func (m *MockDb) Prefix() uint8 {
+// 	args := m.Called()
+// 	return args.Get(0).(uint8)
+// }
 
-func (m *MockDb) Safe() bool {
-	args := m.Called()
-	return args.Get(0).(bool)
-}
+// func (m *MockDb) Safe() bool {
+// 	args := m.Called()
+// 	return args.Get(0).(bool)
+// }
 
-func (m *MockDb) SetLanguage(language *lang.Language) {
-	m.Called(language)
-}
+// func (m *MockDb) SetLanguage(language *lang.Language) {
+// 	m.Called(language)
+// }
 
-func (m *MockDb) SetLock(uint8, bool) error {
-	args := m.Called()
-	return args.Error(0)
-}
+// func (m *MockDb) SetLock(uint8, bool) error {
+// 	args := m.Called()
+// 	return args.Error(0)
+// }
 
-func (m *MockDb) Connect(ctx context.Context, connectionStr string) error {
-	args := m.Called(ctx, connectionStr)
-	return args.Error(0)
-}
+// func (m *MockDb) Connect(ctx context.Context, connectionStr string) error {
+// 	args := m.Called(ctx, connectionStr)
+// 	return args.Error(0)
+// }
 
-func (m *MockDb) SetSession(sessionId string) {
-	m.Called(sessionId)
-}
+// func (m *MockDb) SetSession(sessionId string) {
+// 	m.Called(sessionId)
+// }
 
-func (m *MockDb) Put(ctx context.Context, key, value []byte) error {
-	args := m.Called(ctx, key, value)
-	return args.Error(0)
-}
+// func (m *MockDb) Put(ctx context.Context, key, value []byte) error {
+// 	args := m.Called(ctx, key, value)
+// 	return args.Error(0)
+// }
 
-func (m *MockDb) Get(ctx context.Context, key []byte) ([]byte, error) {
-	args := m.Called(ctx, key)
-	return nil, args.Error(0)
-}
+// func (m *MockDb) Get(ctx context.Context, key []byte) ([]byte, error) {
+// 	args := m.Called(ctx, key)
+// 	return nil, args.Error(0)
+// }
 
-func (m *MockDb) Close() error {
-	args := m.Called(nil)
-	return args.Error(0)
-}
+// func (m *MockDb) Close() error {
+// 	args := m.Called(nil)
+// 	return args.Error(0)
+// }
 
 // func TestCreateAccount(t *testing.T) {
 // 	// Setup
@@ -470,7 +448,7 @@ func (m *MockDb) Close() error {
 
 func TestSaveFirstname(t *testing.T) {
 	// Create a mock database
-	mockDb := new(MockDb)
+	mockDb := new(mocks.MockDb)
 
 	// Create a Handlers instance with the mock database
 	h := &Handlers{
@@ -484,13 +462,13 @@ func TestSaveFirstname(t *testing.T) {
 		name        string
 		input       []byte
 		expectError bool
-		setupMock   func(*MockDb)
+		setupMock   func(*mocks.MockDb)
 	}{
 		{
 			name:        "Valid first name",
 			input:       []byte("John"),
 			expectError: false,
-			setupMock: func(m *MockDb) {
+			setupMock: func(m *mocks.MockDb) {
 				m.On("SetPrefix", uint8(0x20)).Return(nil)
 				m.On("SetSession", "test-session").Return(nil)
 				m.On("Put", mock.Anything, mock.Anything, []byte("John")).Return(nil)
@@ -500,7 +478,7 @@ func TestSaveFirstname(t *testing.T) {
 			name:        "Empty first name",
 			input:       []byte{},
 			expectError: false, // Note: The function doesn't return an error for empty input
-			setupMock:   func(m *MockDb) {},
+			setupMock:   func(m *mocks.MockDb) {},
 		},
 	}
 
@@ -528,7 +506,7 @@ func TestSaveFirstname(t *testing.T) {
 
 func TestSaveFamilyname(t *testing.T) {
 	// Create a mock database
-	mockDb := new(MockDb)
+	mockDb := new(mocks.MockDb)
 
 	// Create a Handlers instance with the mock database
 	h := &Handlers{
@@ -542,13 +520,13 @@ func TestSaveFamilyname(t *testing.T) {
 		name        string
 		input       []byte
 		expectError bool
-		setupMock   func(*MockDb)
+		setupMock   func(*mocks.MockDb)
 	}{
 		{
 			name:        "Valid family name",
 			input:       []byte("Smith"),
 			expectError: false,
-			setupMock: func(m *MockDb) {
+			setupMock: func(m *mocks.MockDb) {
 				m.On("SetPrefix", uint8(0x20)).Return(nil)
 				m.On("SetSession", "test-session").Return(nil)
 				m.On("Put", mock.Anything, mock.Anything, []byte("Smith")).Return(nil)
@@ -558,7 +536,7 @@ func TestSaveFamilyname(t *testing.T) {
 			name:        "Empty family name",
 			input:       []byte{},
 			expectError: true,
-			setupMock:   func(m *MockDb) {},
+			setupMock:   func(m *mocks.MockDb) {},
 		},
 	}
 

From 4c3f63a48fb733c2b479668888754638976cd10f Mon Sep 17 00:00:00 2001
From: Carlosokumu <carlosokumu254@gmail.com>
Date: Sat, 7 Sep 2024 10:36:00 +0300
Subject: [PATCH 28/47] create an account only if not found in gdbm

---
 internal/handlers/ussd/menuhandler.go | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/internal/handlers/ussd/menuhandler.go b/internal/handlers/ussd/menuhandler.go
index c94a57c..89fc6c6 100644
--- a/internal/handlers/ussd/menuhandler.go
+++ b/internal/handlers/ussd/menuhandler.go
@@ -177,12 +177,7 @@ func (h *Handlers) CreateAccount(ctx context.Context, sym string, input []byte)
 			if err != nil {
 				return res, err
 			}
-		} else {
-			err = h.createAccountNoExist(ctx, sessionId, &res)
-			if err != nil {
-				return res, err
-			}
-		}
+		} 
 	}
 	return res, nil
 }

From be33b7458fbe0bfae2ca5d15b12e6b67a5596094 Mon Sep 17 00:00:00 2001
From: Carlosokumu <carlosokumu254@gmail.com>
Date: Sat, 7 Sep 2024 16:22:08 +0300
Subject: [PATCH 29/47] cleanup code

---
 internal/handlers/ussd/menuhandler.go | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/internal/handlers/ussd/menuhandler.go b/internal/handlers/ussd/menuhandler.go
index 89fc6c6..27af8f4 100644
--- a/internal/handlers/ussd/menuhandler.go
+++ b/internal/handlers/ussd/menuhandler.go
@@ -145,7 +145,6 @@ func (h *Handlers) createAccountNoExist(ctx context.Context, sessionId string, r
 		utils.DATA_PUBLIC_KEY:   accountResp.Result.PublicKey,
 		utils.DATA_CUSTODIAL_ID: accountResp.Result.CustodialId.String(),
 	}
-
 	for key, value := range data {
 		err := utils.WriteEntry(ctx, h.userdataStore, sessionId, key, []byte(value))
 		if err != nil {
@@ -164,7 +163,6 @@ func (h *Handlers) createAccountNoExist(ctx context.Context, sessionId string, r
 func (h *Handlers) CreateAccount(ctx context.Context, sym string, input []byte) (resource.Result, error) {
 	var res resource.Result
 	var err error
-
 	sessionId, ok := ctx.Value("SessionId").(string)
 	if !ok {
 		return res, fmt.Errorf("missing session")
@@ -177,7 +175,7 @@ func (h *Handlers) CreateAccount(ctx context.Context, sym string, input []byte)
 			if err != nil {
 				return res, err
 			}
-		} 
+		}
 	}
 	return res, nil
 }

From dd975318613034ef6acf70ceba6a1b4e2e65ee99 Mon Sep 17 00:00:00 2001
From: Carlosokumu <carlosokumu254@gmail.com>
Date: Sat, 7 Sep 2024 16:24:37 +0300
Subject: [PATCH 30/47] remove uimplemented tests

---
 internal/handlers/ussd/menuhandler_test.go | 888 +--------------------
 1 file changed, 36 insertions(+), 852 deletions(-)

diff --git a/internal/handlers/ussd/menuhandler_test.go b/internal/handlers/ussd/menuhandler_test.go
index e496773..4ab3046 100644
--- a/internal/handlers/ussd/menuhandler_test.go
+++ b/internal/handlers/ussd/menuhandler_test.go
@@ -2,449 +2,53 @@ package ussd
 
 import (
 	"context"
+	"encoding/json"
 	"testing"
 
+	"git.defalsify.org/vise.git/db"
 	"git.grassecon.net/urdt/ussd/internal/handlers/ussd/mocks"
+	"git.grassecon.net/urdt/ussd/internal/models"
+	"git.grassecon.net/urdt/ussd/internal/utils"
 	"github.com/alecthomas/assert/v2"
 	"github.com/stretchr/testify/mock"
 )
 
-// MockDb is a mock implementation of the db.Db interface
-//type MockDb struct {
-// 	mock.Mock
-// }
+func TestCreateAccount_Success(t *testing.T) {
+	mockCreateAccountService := new(mocks.MockAccountService)
+	mockUserDataStore := new(mocks.MockDb)
 
-// func (m *MockDb) SetPrefix(prefix uint8) {
-// 	m.Called(prefix)
-// }
+	h := &Handlers{
+		userdataStore:  mockUserDataStore,
+		accountService: mockCreateAccountService,
+	}
+	ctx := context.WithValue(context.Background(), "SessionId", "test-session-12345")
+	k := utils.PackKey(utils.DATA_ACCOUNT_CREATED, []byte("test-session-12345"))
+	mockUserDataStore.On("SetPrefix", uint8(0x20)).Return(nil)
+	mockUserDataStore.On("SetSession", "test-session-12345").Return(nil)
+	mockUserDataStore.On("Get", ctx, k).
+		Return(nil, db.ErrNotFound{})
 
-// func (m *MockDb) Prefix() uint8 {
-// 	args := m.Called()
-// 	return args.Get(0).(uint8)
-// }
+	// Define expected account response after api call
+	expectedAccountResp := &models.AccountResponse{
+		Ok: true,
+		Result: struct {
+			CustodialId json.Number `json:"custodialId"`
+			PublicKey   string      `json:"publicKey"`
+			TrackingId  string      `json:"trackingId"`
+		}{
+			CustodialId: "12",
+			PublicKey:   "0x8E0XSCSVA",
+			TrackingId:  "d95a7e83-196c-4fd0-866fSGAGA",
+		},
+	}
+	mockCreateAccountService.On("CreateAccount").Return(expectedAccountResp, nil)
 
-// func (m *MockDb) Safe() bool {
-// 	args := m.Called()
-// 	return args.Get(0).(bool)
-// }
+	_, err := h.CreateAccount(ctx, "create_account", []byte("create_account"))
 
-// func (m *MockDb) SetLanguage(language *lang.Language) {
-// 	m.Called(language)
-// }
-
-// func (m *MockDb) SetLock(uint8, bool) error {
-// 	args := m.Called()
-// 	return args.Error(0)
-// }
-
-// func (m *MockDb) Connect(ctx context.Context, connectionStr string) error {
-// 	args := m.Called(ctx, connectionStr)
-// 	return args.Error(0)
-// }
-
-// func (m *MockDb) SetSession(sessionId string) {
-// 	m.Called(sessionId)
-// }
-
-// func (m *MockDb) Put(ctx context.Context, key, value []byte) error {
-// 	args := m.Called(ctx, key, value)
-// 	return args.Error(0)
-// }
-
-// func (m *MockDb) Get(ctx context.Context, key []byte) ([]byte, error) {
-// 	args := m.Called(ctx, key)
-// 	return nil, args.Error(0)
-// }
-
-// func (m *MockDb) Close() error {
-// 	args := m.Called(nil)
-// 	return args.Error(0)
-// }
-
-// func TestCreateAccount(t *testing.T) {
-// 	// Setup
-// 	tempDir, err := os.MkdirTemp("", "test_create_account")
-// 	if err != nil {
-// 		t.Fatalf("Failed to create temp directory: %v", err)
-// 	}
-// 	defer os.RemoveAll(tempDir) // Clean up after the test run
-
-// 	sessionID := "07xxxxxxxx"
-
-// 	// Set up the data file path using the session ID
-// 	accountFilePath := filepath.Join(tempDir, sessionID+"_data")
-
-// 	// Initialize account file handler
-// 	accountFileHandler := utils.NewAccountFileHandler(accountFilePath)
-
-// 	// Create a mock account service
-// 	mockAccountService := &MockAccountService{}
-// 	mockAccountResponse := &models.AccountResponse{
-// 		Ok: true,
-// 		Result: struct {
-// 			CustodialId json.Number `json:"custodialId"`
-// 			PublicKey   string      `json:"publicKey"`
-// 			TrackingId  string      `json:"trackingId"`
-// 		}{
-// 			CustodialId: "test-custodial-id",
-// 			PublicKey:   "test-public-key",
-// 			TrackingId:  "test-tracking-id",
-// 		},
-// 	}
-
-// 	// Set up expectations for the mock account service
-// 	mockAccountService.On("CreateAccount").Return(mockAccountResponse, nil)
-
-// 	mockParser := new(MockFlagParser)
-
-// 	flag_account_created := uint32(1)
-// 	flag_account_creation_failed := uint32(2)
-
-// 	mockParser.On("GetFlag", "flag_account_created").Return(flag_account_created, nil)
-// 	mockParser.On("GetFlag", "flag_account_creation_failed").Return(flag_account_creation_failed, nil)
-
-// 	// Initialize Handlers with mock account service
-// 	h := &Handlers{
-// 		fs:                 &FSData{Path: accountFilePath},
-// 		accountFileHandler: accountFileHandler,
-// 		accountService:     mockAccountService,
-// 		parser:             mockParser,
-// 	}
-
-// 	tests := []struct {
-// 		name           string
-// 		existingData   map[string]string
-// 		expectedResult resource.Result
-// 		expectedData   map[string]string
-// 	}{
-// 		{
-// 			name:         "New account creation",
-// 			existingData: nil,
-// 			expectedResult: resource.Result{
-// 				FlagSet: []uint32{flag_account_created},
-// 			},
-// 			expectedData: map[string]string{
-// 				"TrackingId":  "test-tracking-id",
-// 				"PublicKey":   "test-public-key",
-// 				"CustodialId": "test-custodial-id",
-// 				"Status":      "PENDING",
-// 				"Gender":      "Not provided",
-// 				"YOB":         "Not provided",
-// 				"Location":    "Not provided",
-// 				"Offerings":   "Not provided",
-// 				"FirstName":   "Not provided",
-// 				"FamilyName":  "Not provided",
-// 			},
-// 		},
-// 		{
-// 			name: "Existing account",
-// 			existingData: map[string]string{
-// 				"TrackingId":  "test-tracking-id",
-// 				"PublicKey":   "test-public-key",
-// 				"CustodialId": "test-custodial-id",
-// 				"Status":      "PENDING",
-// 				"Gender":      "Not provided",
-// 				"YOB":         "Not provided",
-// 				"Location":    "Not provided",
-// 				"Offerings":   "Not provided",
-// 				"FirstName":   "Not provided",
-// 				"FamilyName":  "Not provided",
-// 			},
-// 			expectedResult: resource.Result{},
-// 			expectedData: map[string]string{
-// 				"TrackingId":  "test-tracking-id",
-// 				"PublicKey":   "test-public-key",
-// 				"CustodialId": "test-custodial-id",
-// 				"Status":      "PENDING",
-// 				"Gender":      "Not provided",
-// 				"YOB":         "Not provided",
-// 				"Location":    "Not provided",
-// 				"Offerings":   "Not provided",
-// 				"FirstName":   "Not provided",
-// 				"FamilyName":  "Not provided",
-// 			},
-// 		},
-// 	}
-
-// 	for _, tt := range tests {
-// 		t.Run(tt.name, func(t *testing.T) {
-// 			// Set up the data file path using the session ID
-// 			accountFilePath := filepath.Join(tempDir, sessionID+"_data")
-
-// 			// Setup existing data if any
-// 			if tt.existingData != nil {
-// 				data, _ := json.Marshal(tt.existingData)
-// 				err := os.WriteFile(accountFilePath, data, 0644)
-// 				if err != nil {
-// 					t.Fatalf("Failed to write existing data: %v", err)
-// 				}
-// 			}
-
-// 			// Call the function
-// 			result, err := h.CreateAccount(context.Background(), "", nil)
-
-// 			// Check for errors
-// 			if err != nil {
-// 				t.Fatalf("CreateAccount returned an error: %v", err)
-// 			}
-
-// 			// Check the result
-// 			if len(result.FlagSet) != len(tt.expectedResult.FlagSet) {
-// 				t.Errorf("Expected %d flags, got %d", len(tt.expectedResult.FlagSet), len(result.FlagSet))
-// 			}
-// 			for i, flag := range tt.expectedResult.FlagSet {
-// 				if result.FlagSet[i] != flag {
-// 					t.Errorf("Expected flag %d, got %d", flag, result.FlagSet[i])
-// 				}
-// 			}
-
-// 			// Check the stored data
-// 			data, err := os.ReadFile(accountFilePath)
-// 			if err != nil {
-// 				t.Fatalf("Failed to read account data file: %v", err)
-// 			}
-
-// 			var storedData map[string]string
-// 			err = json.Unmarshal(data, &storedData)
-// 			if err != nil {
-// 				t.Fatalf("Failed to unmarshal stored data: %v", err)
-// 			}
-
-// 			for key, expectedValue := range tt.expectedData {
-// 				if storedValue, ok := storedData[key]; !ok || storedValue != expectedValue {
-// 					t.Errorf("Expected %s to be %s, got %s", key, expectedValue, storedValue)
-// 				}
-// 			}
-// 		})
-// 	}
-// }
-
-// func TestCreateAccount_Success(t *testing.T) {
-// 	mockAccountFileHandler := new(mocks.MockAccountFileHandler)
-// 	mockCreateAccountService := new(mocks.MockAccountService)
-
-// 	mockAccountFileHandler.On("EnsureFileExists").Return(nil)
-
-// 	// Mock that no account data exists
-// 	mockAccountFileHandler.On("ReadAccountData").Return(nil, nil)
-
-// 	// Define expected account response after api call
-// 	expectedAccountResp := &models.AccountResponse{
-// 		Ok: true,
-// 		Result: struct {
-// 			CustodialId json.Number `json:"custodialId"`
-// 			PublicKey   string      `json:"publicKey"`
-// 			TrackingId  string      `json:"trackingId"`
-// 		}{
-// 			CustodialId: "12",
-// 			PublicKey:   "0x8E0XSCSVA",
-// 			TrackingId:  "d95a7e83-196c-4fd0-866fSGAGA",
-// 		},
-// 	}
-// 	mockCreateAccountService.On("CreateAccount").Return(expectedAccountResp, nil)
-
-// 	// Mock WriteAccountData to not error
-// 	mockAccountFileHandler.On("WriteAccountData", mock.Anything).Return(nil)
-
-// 	handlers := &Handlers{
-// 		accountService: mockCreateAccountService,
-// 	}
-
-// 	actualResponse, err := handlers.accountService.CreateAccount()
-
-// 	// Assert results
-// 	assert.NoError(t, err)
-// 	assert.Equal(t, expectedAccountResp.Ok, true)
-// 	assert.Equal(t, expectedAccountResp, actualResponse)
-// }
-
-// func TestSavePin(t *testing.T) {
-// 	// Setup
-// 	tempDir, err := os.MkdirTemp("", "test_save_pin")
-// 	if err != nil {
-// 		t.Fatalf("Failed to create temp directory: %v", err)
-// 	}
-// 	defer os.RemoveAll(tempDir)
-
-// 	sessionID := "07xxxxxxxx"
-
-// 	// Set up the data file path using the session ID
-// 	accountFilePath := filepath.Join(tempDir, sessionID+"_data")
-// 	initialAccountData := map[string]string{
-// 		"TrackingId": "test-tracking-id",
-// 		"PublicKey":  "test-public-key",
-// 	}
-// 	data, _ := json.Marshal(initialAccountData)
-// 	err = os.WriteFile(accountFilePath, data, 0644)
-// 	if err != nil {
-// 		t.Fatalf("Failed to write initial account data: %v", err)
-// 	}
-
-// 	// Create a new AccountFileHandler and set it in the Handlers struct
-// 	accountFileHandler := utils.NewAccountFileHandler(accountFilePath)
-// 	mockParser := new(MockFlagParser)
-
-// 	h := &Handlers{
-// 		accountFileHandler: accountFileHandler,
-// 		parser:             mockParser,
-// 	}
-
-// 	flag_incorrect_pin := uint32(1)
-// 	mockParser.On("GetFlag", "flag_incorrect_pin").Return(flag_incorrect_pin, nil)
-
-// 	tests := []struct {
-// 		name           string
-// 		input          []byte
-// 		expectedFlags  []uint32
-// 		expectedData   map[string]string
-// 		expectedErrors bool
-// 	}{
-// 		{
-// 			name:          "Valid PIN",
-// 			input:         []byte("1234"),
-// 			expectedFlags: []uint32{},
-// 			expectedData: map[string]string{
-// 				"TrackingId": "test-tracking-id",
-// 				"PublicKey":  "test-public-key",
-// 				"AccountPIN": "1234",
-// 			},
-// 		},
-// 		{
-// 			name:           "Invalid PIN - non-numeric",
-// 			input:          []byte("12ab"),
-// 			expectedFlags:  []uint32{flag_incorrect_pin},
-// 			expectedData:   initialAccountData, // No changes expected
-// 			expectedErrors: false,
-// 		},
-// 		{
-// 			name:           "Invalid PIN - less than 4 digits",
-// 			input:          []byte("123"),
-// 			expectedFlags:  []uint32{flag_incorrect_pin},
-// 			expectedData:   initialAccountData, // No changes expected
-// 			expectedErrors: false,
-// 		},
-// 		{
-// 			name:           "Invalid PIN - more than 4 digits",
-// 			input:          []byte("12345"),
-// 			expectedFlags:  []uint32{flag_incorrect_pin},
-// 			expectedData:   initialAccountData, // No changes expected
-// 			expectedErrors: false,
-// 		},
-// 	}
-
-// 	for _, tt := range tests {
-// 		t.Run(tt.name, func(t *testing.T) {
-// 			err := accountFileHandler.EnsureFileExists()
-// 			if err != nil {
-// 				t.Fatalf("Failed to ensure account file exists: %v", err)
-// 			}
-
-// 			result, err := h.SavePin(context.Background(), "", tt.input)
-// 			if err != nil && !tt.expectedErrors {
-// 				t.Fatalf("SavePin returned an unexpected error: %v", err)
-// 			}
-
-// 			if len(result.FlagSet) != len(tt.expectedFlags) {
-// 				t.Errorf("Expected %d flags, got %d", len(tt.expectedFlags), len(result.FlagSet))
-// 			}
-// 			for i, flag := range tt.expectedFlags {
-// 				if result.FlagSet[i] != flag {
-// 					t.Errorf("Expected flag %d, got %d", flag, result.FlagSet[i])
-// 				}
-// 			}
-
-// 			data, err := os.ReadFile(accountFilePath)
-// 			if err != nil {
-// 				t.Fatalf("Failed to read account data file: %v", err)
-// 			}
-
-// 			var storedData map[string]string
-// 			err = json.Unmarshal(data, &storedData)
-// 			if err != nil {
-// 				t.Fatalf("Failed to unmarshal stored data: %v", err)
-// 			}
-
-// 			for key, expectedValue := range tt.expectedData {
-// 				if storedValue, ok := storedData[key]; !ok || storedValue != expectedValue {
-// 					t.Errorf("Expected %s to be %s, got %s", key, expectedValue, storedValue)
-// 				}
-// 			}
-// 		})
-// 	}
-// }
-
-// func TestSaveLocation(t *testing.T) {
-// 	// Create a new instance of MockAccountFileHandler
-// 	mockFileHandler := new(mocks.MockAccountFileHandler)
-
-// 	// Define test cases
-// 	tests := []struct {
-// 		name           string
-// 		input          []byte
-// 		existingData   map[string]string
-// 		writeError     error
-// 		expectedResult resource.Result
-// 		expectedError  error
-// 	}{
-// 		{
-// 			name:           "Successful Save",
-// 			input:          []byte("Mombasa"),
-// 			existingData:   map[string]string{"Location": "Mombasa"},
-// 			writeError:     nil,
-// 			expectedResult: resource.Result{},
-// 			expectedError:  nil,
-// 		},
-// 		{
-// 			name:           "Empty location input",
-// 			input:          []byte{},
-// 			existingData:   map[string]string{"OtherKey": "OtherValue"},
-// 			writeError:     nil,
-// 			expectedResult: resource.Result{},
-// 			expectedError:  nil,
-// 		},
-// 	}
-
-// 	for _, tt := range tests {
-// 		t.Run(tt.name, func(t *testing.T) {
-// 			// Set up the mock expectations
-// 			mockFileHandler.On("ReadAccountData").Return(tt.existingData, tt.expectedError)
-// 			if tt.expectedError == nil && len(tt.input) > 0 {
-// 				mockFileHandler.On("WriteAccountData", mock.MatchedBy(func(data map[string]string) bool {
-// 					return data["Location"] == string(tt.input)
-// 				})).Return(tt.writeError)
-// 			} else if len(tt.input) == 0 {
-// 				// For empty input, no WriteAccountData call should be made
-// 				mockFileHandler.On("WriteAccountData", mock.Anything).Maybe().Return(tt.writeError)
-// 				return
-// 			}
-
-// 			// Create the Handlers instance with the mock file handler
-// 			h := &Handlers{
-// 				accountFileHandler: mockFileHandler,
-// 			}
-
-// 			// Call Save Location
-// 			result, err := h.SaveLocation(context.Background(), "save_location", tt.input)
-
-// 			if err != nil {
-// 				t.Fatalf("Failed to save location with error: %v", err)
-// 			}
-
-// 			savedData, err := h.accountFileHandler.ReadAccountData()
-// 			if err == nil {
-// 				//Assert that the input provided is what was saved into the file
-// 				assert.Equal(t, string(tt.input), savedData["Location"])
-// 			}
-
-// 			// Assert the results
-// 			assert.Equal(t, tt.expectedResult, result)
-// 			assert.Equal(t, tt.expectedError, err)
-
-// 			// Assert all expectations were met
-// 			mockFileHandler.AssertExpectations(t)
-// 		})
-// 	}
-// }
+	// Assert results
+	assert.NoError(t, err)
+	assert.Equal(t, expectedAccountResp.Ok, true)
+}
 
 func TestSaveFirstname(t *testing.T) {
 	// Create a mock database
@@ -561,423 +165,3 @@ func TestSaveFamilyname(t *testing.T) {
 		})
 	}
 }
-
-// func TestSaveYOB(t *testing.T) {
-// 	// Create a new instance of MockAccountFileHandler
-// 	mockFileHandler := new(mocks.MockAccountFileHandler)
-
-// 	// Define test cases
-// 	tests := []struct {
-// 		name           string
-// 		input          []byte
-// 		existingData   map[string]string
-// 		writeError     error
-// 		expectedResult resource.Result
-// 		expectedError  error
-// 	}{
-// 		{
-// 			name:           "Successful Save",
-// 			input:          []byte("2006"),
-// 			existingData:   map[string]string{"": ""},
-// 			writeError:     nil,
-// 			expectedResult: resource.Result{},
-// 			expectedError:  nil,
-// 		},
-// 		{
-// 			name:          "YOB less than 4 digits(invalid date entry)",
-// 			input:         []byte{},
-// 			existingData:  map[string]string{"": ""},
-// 			writeError:    nil,
-// 			expectedError: nil,
-// 		},
-// 	}
-
-// 	for _, tt := range tests {
-// 		t.Run(tt.name, func(t *testing.T) {
-// 			// Set up the mock expectations
-// 			mockFileHandler.On("ReadAccountData").Return(tt.existingData, tt.expectedError)
-// 			if tt.expectedError == nil && len(tt.input) > 0 {
-// 				mockFileHandler.On("WriteAccountData", mock.MatchedBy(func(data map[string]string) bool {
-// 					return data["YOB"] == string(tt.input)
-// 				})).Return(tt.writeError)
-// 			} else if len(tt.input) != 4 {
-// 				// For input whose input is not a valid yob, no WriteAccountData call should be made
-// 				mockFileHandler.On("WriteAccountData", mock.Anything).Maybe().Return(tt.writeError)
-// 				return
-// 			}
-
-// 			// Create the Handlers instance with the mock file handler
-// 			h := &Handlers{
-// 				accountFileHandler: mockFileHandler,
-// 			}
-
-// 			// Call save yob
-// 			result, err := h.SaveYob(context.Background(), "save_yob", tt.input)
-
-// 			if err != nil {
-// 				t.Fatalf("Failed to save family name with error: %v", err)
-// 			}
-// 			savedData, err := h.accountFileHandler.ReadAccountData()
-// 			if err == nil {
-// 				//Assert that the input provided is what was saved into the file
-// 				assert.Equal(t, string(tt.input), savedData["YOB"])
-// 			}
-
-// 			// Assert the results
-// 			assert.Equal(t, tt.expectedResult, result)
-// 			assert.Equal(t, tt.expectedError, err)
-
-// 			// Assert all expectations were met
-// 			mockFileHandler.AssertExpectations(t)
-// 		})
-// 	}
-// }
-
-// func TestSaveOfferings(t *testing.T) {
-// 	// Create a new instance of MockAccountFileHandler
-// 	mockFileHandler := new(mocks.MockAccountFileHandler)
-
-// 	// Define test cases
-// 	tests := []struct {
-// 		name           string
-// 		input          []byte
-// 		existingData   map[string]string
-// 		writeError     error
-// 		expectedResult resource.Result
-// 		expectedError  error
-// 	}{
-// 		{
-// 			name:           "Successful Save",
-// 			input:          []byte("Bananas"),
-// 			existingData:   map[string]string{"": ""},
-// 			writeError:     nil,
-// 			expectedResult: resource.Result{},
-// 			expectedError:  nil,
-// 		},
-// 		{
-// 			name:          "Empty input",
-// 			input:         []byte{},
-// 			existingData:  map[string]string{"": ""},
-// 			writeError:    nil,
-// 			expectedError: nil,
-// 		},
-// 	}
-
-// 	for _, tt := range tests {
-// 		t.Run(tt.name, func(t *testing.T) {
-// 			// Set up the mock expectations
-// 			mockFileHandler.On("ReadAccountData").Return(tt.existingData, tt.expectedError)
-// 			if tt.expectedError == nil && len(tt.input) > 0 {
-// 				mockFileHandler.On("WriteAccountData", mock.MatchedBy(func(data map[string]string) bool {
-// 					return data["Offerings"] == string(tt.input)
-// 				})).Return(tt.writeError)
-// 			} else if len(tt.input) != 4 {
-// 				// For input whose input is not a valid yob, no WriteAccountData call should be made
-// 				mockFileHandler.On("WriteAccountData", mock.Anything).Maybe().Return(tt.writeError)
-// 				return
-// 			}
-
-// 			// Create the Handlers instance with the mock file handler
-// 			h := &Handlers{
-// 				accountFileHandler: mockFileHandler,
-// 			}
-
-// 			// Call save yob
-// 			result, err := h.SaveOfferings(context.Background(), "save_offerings", tt.input)
-
-// 			if err != nil {
-// 				t.Fatalf("Failed to save offerings with error: %v", err)
-// 			}
-// 			savedData, err := h.accountFileHandler.ReadAccountData()
-// 			if err == nil {
-// 				//Assert that the input provided is what was saved into the file
-// 				assert.Equal(t, string(tt.input), savedData["Offerings"])
-// 			}
-
-// 			// Assert the results
-// 			assert.Equal(t, tt.expectedResult, result)
-// 			assert.Equal(t, tt.expectedError, err)
-
-// 			// Assert all expectations were met
-// 			mockFileHandler.AssertExpectations(t)
-// 		})
-// 	}
-// }
-
-// func TestSaveGender(t *testing.T) {
-// 	// Create a new instance of MockAccountFileHandler
-// 	mockFileHandler := new(mocks.MockAccountFileHandler)
-
-// 	// Define test cases
-// 	tests := []struct {
-// 		name           string
-// 		input          []byte
-// 		existingData   map[string]string
-// 		writeError     error
-// 		expectedResult resource.Result
-// 		expectedError  error
-// 		expectedGender string
-// 	}{
-// 		{
-// 			name:           "Successful Save - Male",
-// 			input:          []byte("1"),
-// 			existingData:   map[string]string{"OtherKey": "OtherValue"},
-// 			writeError:     nil,
-// 			expectedResult: resource.Result{},
-// 			expectedError:  nil,
-// 			expectedGender: "Male",
-// 		},
-// 		{
-// 			name:           "Successful Save - Female",
-// 			input:          []byte("2"),
-// 			existingData:   map[string]string{"OtherKey": "OtherValue"},
-// 			writeError:     nil,
-// 			expectedResult: resource.Result{},
-// 			expectedError:  nil,
-// 			expectedGender: "Female",
-// 		},
-// 		{
-// 			name:           "Successful Save - Unspecified",
-// 			input:          []byte("3"),
-// 			existingData:   map[string]string{"OtherKey": "OtherValue"},
-// 			writeError:     nil,
-// 			expectedResult: resource.Result{},
-// 			expectedError:  nil,
-// 			expectedGender: "Unspecified",
-// 		},
-
-// 		{
-// 			name:           "Empty Input",
-// 			input:          []byte{},
-// 			existingData:   map[string]string{"OtherKey": "OtherValue"},
-// 			writeError:     nil,
-// 			expectedResult: resource.Result{},
-// 			expectedError:  nil,
-// 			expectedGender: "",
-// 		},
-// 	}
-
-// 	for _, tt := range tests {
-// 		t.Run(tt.name, func(t *testing.T) {
-// 			// Set up the mock expectations
-// 			mockFileHandler.On("ReadAccountData").Return(tt.existingData, tt.expectedError)
-// 			if tt.expectedError == nil && len(tt.input) > 0 {
-// 				mockFileHandler.On("WriteAccountData", mock.MatchedBy(func(data map[string]string) bool {
-// 					return data["Gender"] == tt.expectedGender
-// 				})).Return(tt.writeError)
-// 			} else if len(tt.input) == 0 {
-// 				// For empty input, no WriteAccountData call should be made
-// 				mockFileHandler.On("WriteAccountData", mock.Anything).Maybe().Return(tt.writeError)
-// 			}
-
-// 			// Create the Handlers instance with the mock file handler
-// 			h := &Handlers{
-// 				accountFileHandler: mockFileHandler,
-// 			}
-
-// 			// Call the method
-// 			result, err := h.SaveGender(context.Background(), "save_gender", tt.input)
-
-// 			// Assert the results
-// 			assert.Equal(t, tt.expectedResult, result)
-// 			assert.Equal(t, tt.expectedError, err)
-
-// 			// Verify WriteAccountData was called with the expected data
-// 			if len(tt.input) > 0 && tt.expectedError == nil {
-// 				mockFileHandler.AssertCalled(t, "WriteAccountData", mock.MatchedBy(func(data map[string]string) bool {
-// 					return data["Gender"] == tt.expectedGender
-// 				}))
-// 			}
-
-// 			// Assert all expectations were met
-// 			mockFileHandler.AssertExpectations(t)
-// 		})
-// 	}
-// }
-
-// func TestGetSender(t *testing.T) {
-// 	mockAccountFileHandler := new(mocks.MockAccountFileHandler)
-// 	h := &Handlers{
-// 		accountFileHandler: mockAccountFileHandler,
-// 	}
-
-// 	tests := []struct {
-// 		name           string
-// 		expectedResult resource.Result
-// 		accountData    map[string]string
-// 	}{
-// 		{
-// 			name: "Valid public key",
-// 			expectedResult: resource.Result{
-// 				Content: "test-public-key",
-// 			},
-// 			accountData: map[string]string{
-// 				"PublicKey": "test-public-key",
-// 			},
-// 		},
-// 		{
-// 			name: "Missing public key",
-// 			expectedResult: resource.Result{
-// 				Content: "",
-// 			},
-// 			accountData: map[string]string{},
-// 		},
-// 	}
-
-// 	for _, tt := range tests {
-// 		t.Run(tt.name, func(t *testing.T) {
-// 			// Reset the mock state
-// 			mockAccountFileHandler.Mock = mock.Mock{}
-
-// 			mockAccountFileHandler.On("ReadAccountData").Return(tt.accountData, nil)
-
-// 			result, err := h.GetSender(context.Background(), "", nil)
-
-// 			if err != nil {
-// 				t.Fatalf("Error occurred: %v", err)
-// 			}
-
-// 			assert.Equal(t, tt.expectedResult.Content, result.Content)
-// 			mockAccountFileHandler.AssertCalled(t, "ReadAccountData")
-// 		})
-// 	}
-// }
-
-// func TestGetAmount(t *testing.T) {
-// 	mockAccountFileHandler := new(mocks.MockAccountFileHandler)
-// 	h := &Handlers{
-// 		accountFileHandler: mockAccountFileHandler,
-// 	}
-
-// 	tests := []struct {
-// 		name           string
-// 		expectedResult resource.Result
-// 		accountData    map[string]string
-// 	}{
-// 		{
-// 			name: "Valid amount",
-// 			expectedResult: resource.Result{
-// 				Content: "0.003",
-// 			},
-// 			accountData: map[string]string{
-// 				"Amount": "0.003",
-// 			},
-// 		},
-// 		{
-// 			name:           "Missing amount",
-// 			expectedResult: resource.Result{},
-// 			accountData: map[string]string{
-// 				"Amount": "",
-// 			},
-// 		},
-// 	}
-
-// 	for _, tt := range tests {
-// 		t.Run(tt.name, func(t *testing.T) {
-// 			// Reset the mock state
-// 			mockAccountFileHandler.Mock = mock.Mock{}
-
-// 			mockAccountFileHandler.On("ReadAccountData").Return(tt.accountData, nil)
-
-// 			result, err := h.GetAmount(context.Background(), "", nil)
-
-// 			assert.NoError(t, err)
-// 			assert.Equal(t, tt.expectedResult.Content, result.Content)
-
-// 			mockAccountFileHandler.AssertCalled(t, "ReadAccountData")
-// 		})
-// 	}
-// }
-
-// func TestGetProfileInfo(t *testing.T) {
-// 	tests := []struct {
-// 		name           string
-// 		accountData    map[string]string
-// 		readError      error
-// 		expectedResult resource.Result
-// 		expectedError  error
-// 	}{
-// 		{
-// 			name: "Complete Profile",
-// 			accountData: map[string]string{
-// 				"FirstName":  "John",
-// 				"FamilyName": "Doe",
-// 				"Gender":     "Male",
-// 				"YOB":        "1980",
-// 				"Location":   "Mombasa",
-// 				"Offerings":  "Product A",
-// 			},
-// 			readError: nil,
-// 			expectedResult: resource.Result{
-// 				Content: fmt.Sprintf(
-// 					"Name: %s %s\nGender: %s\nAge: %d\nLocation: %s\nYou provide: %s\n",
-// 					"John", "Doe", "Male", 44, "Mombasa", "Product A",
-// 				),
-// 			},
-// 			expectedError: nil,
-// 		},
-// 		{
-// 			name: "Profile with Not Provided Fields",
-// 			accountData: map[string]string{
-// 				"FirstName":  "Not provided",
-// 				"FamilyName": "Doe",
-// 				"Gender":     "Female",
-// 				"YOB":        "1995",
-// 				"Location":   "Not provided",
-// 				"Offerings":  "Service B",
-// 			},
-// 			readError: nil,
-// 			expectedResult: resource.Result{
-// 				Content: fmt.Sprintf(
-// 					"Name: %s\nGender: %s\nAge: %d\nLocation: %s\nYou provide: %s\n",
-// 					"Not provided", "Female", 29, "Not provided", "Service B",
-// 				),
-// 			},
-// 			expectedError: nil,
-// 		},
-// 		{
-// 			name: "Profile with YOB as Not provided",
-// 			accountData: map[string]string{
-// 				"FirstName":  "Not provided",
-// 				"FamilyName": "Doe",
-// 				"Gender":     "Female",
-// 				"YOB":        "Not provided",
-// 				"Location":   "Not provided",
-// 				"Offerings":  "Service B",
-// 			},
-// 			readError: nil,
-// 			expectedResult: resource.Result{
-// 				Content: fmt.Sprintf(
-// 					"Name: %s\nGender: %s\nAge: %s\nLocation: %s\nYou provide: %s\n",
-// 					"Not provided", "Female", "Not provided", "Not provided", "Service B",
-// 				),
-// 			},
-// 			expectedError: nil,
-// 		},
-// 	}
-
-// 	for _, tt := range tests {
-// 		t.Run(tt.name, func(t *testing.T) {
-// 			// Create a new instance of MockAccountFileHandler
-// 			mockFileHandler := new(mocks.MockAccountFileHandler)
-
-// 			// Set up the mock expectations
-// 			mockFileHandler.On("ReadAccountData").Return(tt.accountData, tt.readError)
-
-// 			// Create the Handlers instance with the mock file handler
-// 			h := &Handlers{
-// 				accountFileHandler: mockFileHandler,
-// 			}
-
-// 			// Call the method
-// 			result, err := h.GetProfileInfo(context.Background(), "get_profile_info", nil)
-
-// 			// Assert the results
-// 			assert.Equal(t, tt.expectedResult, result)
-// 			assert.Equal(t, tt.expectedError, err)
-
-// 			// Assert all expectations were met
-// 			mockFileHandler.AssertExpectations(t)
-// 		})
-// 	}
-// }

From 01c13ec581b029add5bcb6eb432d84f9e4897a55 Mon Sep 17 00:00:00 2001
From: Carlosokumu <carlosokumu254@gmail.com>
Date: Sat, 7 Sep 2024 16:25:29 +0300
Subject: [PATCH 31/47] make packKey accessible from tests

---
 internal/utils/db.go | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/internal/utils/db.go b/internal/utils/db.go
index 32fb804..5b128f6 100644
--- a/internal/utils/db.go
+++ b/internal/utils/db.go
@@ -33,15 +33,16 @@ func typToBytes(typ DataTyp) []byte {
 	return b[:]
 }
 
-func packKey(typ DataTyp, data []byte) []byte {
+func PackKey(typ DataTyp, data []byte) []byte {
 	v := typToBytes(typ)
 	return append(v, data...)
 }
 
 func ReadEntry(ctx context.Context, store db.Db, sessionId string, typ DataTyp) ([]byte, error) {
+
 	store.SetPrefix(db.DATATYPE_USERDATA)
 	store.SetSession(sessionId)
-	k := packKey(typ, []byte(sessionId))
+	k := PackKey(typ, []byte(sessionId))
 	b, err := store.Get(ctx, k)
 	if err != nil {
 		return nil, err
@@ -52,6 +53,6 @@ func ReadEntry(ctx context.Context, store db.Db, sessionId string, typ DataTyp)
 func WriteEntry(ctx context.Context, store db.Db, sessionId string, typ DataTyp, value []byte) error {
 	store.SetPrefix(db.DATATYPE_USERDATA)
 	store.SetSession(sessionId)
-	k := packKey(typ, []byte(sessionId))
+	k := PackKey(typ, []byte(sessionId))
 	return store.Put(ctx, k, value)
 }

From e14fd5e496d7efe1660994bbe6e0dd260a146d51 Mon Sep 17 00:00:00 2001
From: alfred-mk <alfredmwaik@gmail.com>
Date: Sat, 7 Sep 2024 17:41:05 +0300
Subject: [PATCH 32/47] Return the response and the error

---
 internal/handlers/ussd/menuhandler.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/internal/handlers/ussd/menuhandler.go b/internal/handlers/ussd/menuhandler.go
index 27af8f4..066eef2 100644
--- a/internal/handlers/ussd/menuhandler.go
+++ b/internal/handlers/ussd/menuhandler.go
@@ -203,7 +203,7 @@ func (h *Handlers) SavePin(ctx context.Context, sym string, input []byte) (resou
 
 	err = utils.WriteEntry(ctx, h.userdataStore, sessionId, utils.DATA_ACCOUNT_PIN, []byte(accountPIN))
 	if err != nil {
-		return res, nil
+		return res, err
 	}
 
 	return res, nil

From deb4706b1d05f3670172ba64992696565c042eb4 Mon Sep 17 00:00:00 2001
From: alfred-mk <alfredmwaik@gmail.com>
Date: Sat, 7 Sep 2024 17:51:30 +0300
Subject: [PATCH 33/47] Test commit

---
 internal/handlers/ussd/menuhandler_test.go | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/internal/handlers/ussd/menuhandler_test.go b/internal/handlers/ussd/menuhandler_test.go
index 4ab3046..4f26e12 100644
--- a/internal/handlers/ussd/menuhandler_test.go
+++ b/internal/handlers/ussd/menuhandler_test.go
@@ -165,3 +165,7 @@ func TestSaveFamilyname(t *testing.T) {
 		})
 	}
 }
+
+func testSavePin () {
+	
+}
\ No newline at end of file

From 6d02ea79ecdf25d277f5b930577bf3fdb3d519f7 Mon Sep 17 00:00:00 2001
From: Carlosokumu <carlosokumu254@gmail.com>
Date: Sat, 7 Sep 2024 18:09:13 +0300
Subject: [PATCH 34/47] add go-vise

---
 go.sum | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/go.sum b/go.sum
index f203383..2624d07 100644
--- a/go.sum
+++ b/go.sum
@@ -1,2 +1,36 @@
+git.defalsify.org/vise.git v0.1.0-rc.1.0.20240906020635-400f69d01a89 h1:YyQODhMwSM5YD9yKHM5jCF0HC0RQtE3MkVXcTnOhXJo=
+git.defalsify.org/vise.git v0.1.0-rc.1.0.20240906020635-400f69d01a89/go.mod h1:JDguWmcoWBdsnpw7PUjVZAEpdC/ubBmjdUBy3tjP63M=
+github.com/alecthomas/assert/v2 v2.2.2 h1:Z/iVC0xZfWTaFNE6bA3z07T86hd45Xe2eLt6WVy2bbk=
+github.com/alecthomas/assert/v2 v2.2.2/go.mod h1:pXcQ2Asjp247dahGEmsZ6ru0UVwnkhktn7S0bBDLxvQ=
+github.com/alecthomas/participle/v2 v2.0.0 h1:Fgrq+MbuSsJwIkw3fEj9h75vDP0Er5JzepJ0/HNHv0g=
+github.com/alecthomas/participle/v2 v2.0.0/go.mod h1:rAKZdJldHu8084ojcWevWAL8KmEU+AT+Olodb+WoN2Y=
+github.com/alecthomas/repr v0.2.0 h1:HAzS41CIzNW5syS8Mf9UwXhNH1J9aix/BvDRf1Ml2Yk=
+github.com/alecthomas/repr v0.2.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
+github.com/barbashov/iso639-3 v0.0.0-20211020172741-1f4ffb2d8d1c h1:H9Nm+I7Cg/YVPpEV1RzU3Wq2pjamPc/UtHDgItcb7lE=
+github.com/barbashov/iso639-3 v0.0.0-20211020172741-1f4ffb2d8d1c/go.mod h1:rGod7o6KPeJ+hyBpHfhi4v7blx9sf+QsHsA7KAsdN6U=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/fxamacker/cbor/v2 v2.4.0 h1:ri0ArlOR+5XunOP8CRUowT0pSJOwhW098ZCUyskZD88=
+github.com/fxamacker/cbor/v2 v2.4.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
+github.com/graygnuorg/go-gdbm v0.0.0-20220711140707-71387d66dce4 h1:U4kkNYryi/qfbBF8gh7Vsbuz+cVmhf5kt6pE9bYYyLo=
+github.com/graygnuorg/go-gdbm v0.0.0-20220711140707-71387d66dce4/go.mod h1:zpZDgZFzeq9s0MIeB1P50NIEWDFFHSFBohI/NbaTD/Y=
+github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
+github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
+github.com/mattn/kinako v0.0.0-20170717041458-332c0a7e205a h1:0Q3H0YXzMHiciXtRcM+j0jiCe8WKPQHoRgQiRTnfcLY=
+github.com/mattn/kinako v0.0.0-20170717041458-332c0a7e205a/go.mod h1:CdTTBOYzS5E4mWS1N8NWP6AHI19MP0A2B18n3hLzRMk=
+github.com/peteole/testdata-loader v0.3.0 h1:8jckE9KcyNHgyv/VPoaljvKZE0Rqr8+dPVYH6rfNr9I=
+github.com/peteole/testdata-loader v0.3.0/go.mod h1:Mt0ZbRtb56u8SLJpNP+BnQbENljMorYBpqlvt3cS83U=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
+github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
 github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
 github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
+github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
+github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/leonelquinteros/gotext.v1 v1.3.1 h1:8d9/fdTG0kn/B7NNGV1BsEyvektXFAbkMsTZS2sFSCc=
+gopkg.in/leonelquinteros/gotext.v1 v1.3.1/go.mod h1:X1WlGDeAFIYsW6GjgMm4VwUwZ2XjI7Zan2InxSUQWrU=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

From 16a56ef29d1a5db62e4c0980a517d04e1292fdc2 Mon Sep 17 00:00:00 2001
From: Carlosokumu <carlosokumu254@gmail.com>
Date: Sat, 7 Sep 2024 18:09:55 +0300
Subject: [PATCH 35/47] add go-vise

---
 go.mod | 22 +++++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/go.mod b/go.mod
index de33912..e2aff05 100644
--- a/go.mod
+++ b/go.mod
@@ -2,4 +2,24 @@ module git.grassecon.net/urdt/ussd
 
 go 1.22.6
 
-require github.com/stretchr/testify v1.9.0 // indirect
+require (
+	github.com/alecthomas/participle/v2 v2.0.0 // indirect
+	github.com/alecthomas/repr v0.2.0 // indirect
+	github.com/barbashov/iso639-3 v0.0.0-20211020172741-1f4ffb2d8d1c // indirect
+	github.com/davecgh/go-spew v1.1.1 // indirect
+	github.com/fxamacker/cbor/v2 v2.4.0 // indirect
+	github.com/graygnuorg/go-gdbm v0.0.0-20220711140707-71387d66dce4 // indirect
+	github.com/hexops/gotextdiff v1.0.3 // indirect
+	github.com/mattn/kinako v0.0.0-20170717041458-332c0a7e205a // indirect
+	github.com/pmezard/go-difflib v1.0.0 // indirect
+	github.com/stretchr/objx v0.5.2 // indirect
+	github.com/stretchr/testify v1.9.0
+	github.com/x448/float16 v0.8.4 // indirect
+	gopkg.in/yaml.v3 v3.0.1 // indirect
+)
+
+require (
+	git.defalsify.org/vise.git v0.1.0-rc.1.0.20240906020635-400f69d01a89
+	github.com/alecthomas/assert/v2 v2.2.2
+	gopkg.in/leonelquinteros/gotext.v1 v1.3.1
+)

From 2c059afa7d4358958db2e15a7cfc21da2375012a Mon Sep 17 00:00:00 2001
From: Carlosokumu <carlosokumu254@gmail.com>
Date: Sat, 7 Sep 2024 22:05:09 +0300
Subject: [PATCH 36/47] resolve

---
 cmd/main.go | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/cmd/main.go b/cmd/main.go
index 906c4cc..c2878a9 100644
--- a/cmd/main.go
+++ b/cmd/main.go
@@ -12,14 +12,14 @@ import (
 	fsdb "git.defalsify.org/vise.git/db/fs"
 	gdbmdb "git.defalsify.org/vise.git/db/gdbm"
 	"git.defalsify.org/vise.git/engine"
+	"git.defalsify.org/vise.git/logging"
 	"git.defalsify.org/vise.git/persist"
 	"git.defalsify.org/vise.git/resource"
-	"git.defalsify.org/vise.git/logging"
 	"git.grassecon.net/urdt/ussd/internal/handlers/ussd"
 )
 
 var (
-	logg = logging.NewVanilla()
+	logg      = logging.NewVanilla()
 	scriptDir = path.Join("services", "registration")
 )
 
@@ -90,7 +90,7 @@ func getUserdataDb(dbDir string, ctx context.Context) db.Db {
 	store := gdbmdb.NewGdbmDb()
 	storeFile := path.Join(dbDir, "userdata.gdbm")
 	store.Connect(ctx, storeFile)
-	
+
 	return store
 }
 
@@ -123,10 +123,10 @@ func main() {
 	flag.UintVar(&size, "s", 160, "max size of output")
 	flag.Parse()
 
-	logg.Infof("start command", "dbdir", dbDir, "resourcedir", resourceDir,  "outputsize", size)
+	logg.Infof("start command", "dbdir", dbDir, "resourcedir", resourceDir, "outputsize", size)
 
 	ctx := context.Background()
-	ctx = context.WithValue(ctx, "SessionId",sessionId)
+	ctx = context.WithValue(ctx, "SessionId", sessionId)
 	pfp := path.Join(scriptDir, "pp.csv")
 	flagParser, err := getParser(pfp, true)
 

From c2564a9b8f8ba6acf2822effdb643df319547ac4 Mon Sep 17 00:00:00 2001
From: Carlosokumu <carlosokumu254@gmail.com>
Date: Mon, 9 Sep 2024 10:12:29 +0300
Subject: [PATCH 37/47] remove go-vise subdirectory

---
 go-vise | 1 -
 1 file changed, 1 deletion(-)
 delete mode 160000 go-vise

diff --git a/go-vise b/go-vise
deleted file mode 160000
index 2bddc36..0000000
--- a/go-vise
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 2bddc363f20210ab019eec29d8ba4104d147e9b7

From da93444d3f195cafb6b36ab0af761972f7d7dfb9 Mon Sep 17 00:00:00 2001
From: Carlosokumu <carlosokumu254@gmail.com>
Date: Mon, 9 Sep 2024 10:14:40 +0300
Subject: [PATCH 38/47] remove deprecated code

---
 cmd/main.go | 1 -
 1 file changed, 1 deletion(-)

diff --git a/cmd/main.go b/cmd/main.go
index 86b569e..c2878a9 100644
--- a/cmd/main.go
+++ b/cmd/main.go
@@ -4,7 +4,6 @@ import (
 	"context"
 	"flag"
 	"fmt"
-	"log"
 	"os"
 	"path"
 

From ca655b0cdc4cb9a548cec2d65fcfe84040a7fdb3 Mon Sep 17 00:00:00 2001
From: Carlosokumu <carlosokumu254@gmail.com>
Date: Mon, 9 Sep 2024 17:15:04 +0300
Subject: [PATCH 39/47] add tests

---
 internal/handlers/ussd/menuhandler_test.go | 458 +++++++++++++++------
 1 file changed, 331 insertions(+), 127 deletions(-)

diff --git a/internal/handlers/ussd/menuhandler_test.go b/internal/handlers/ussd/menuhandler_test.go
index 4f26e12..7dd2094 100644
--- a/internal/handlers/ussd/menuhandler_test.go
+++ b/internal/handlers/ussd/menuhandler_test.go
@@ -2,170 +2,374 @@ package ussd
 
 import (
 	"context"
-	"encoding/json"
 	"testing"
 
-	"git.defalsify.org/vise.git/db"
+	"git.defalsify.org/vise.git/resource"
 	"git.grassecon.net/urdt/ussd/internal/handlers/ussd/mocks"
-	"git.grassecon.net/urdt/ussd/internal/models"
 	"git.grassecon.net/urdt/ussd/internal/utils"
 	"github.com/alecthomas/assert/v2"
-	"github.com/stretchr/testify/mock"
 )
 
-func TestCreateAccount_Success(t *testing.T) {
-	mockCreateAccountService := new(mocks.MockAccountService)
-	mockUserDataStore := new(mocks.MockDb)
+// func TestCreateAccount(t *testing.T) {
+// 	// Create a new instance of MockMyDataStore
+// 	mockDataStore := new(mocks.MockMyDataStore)
+// 	mockCreateAccountService := new(mocks.MockAccountService)
 
+// 	// Define session ID and mock data
+// 	sessionId := "session123"
+// 	typ := utils.DATA_ACCOUNT_CREATED
+// 	fakeError := db.ErrNotFound{}
+// 	// Create context with session ID
+// 	ctx := context.WithValue(context.Background(), "SessionId", sessionId)
+
+// 	// Define expected interactions with the mock
+// 	mockDataStore.On("ReadEntry", ctx, sessionId, typ).Return([]byte("123"), fakeError)
+// 	expectedAccountResp := &models.AccountResponse{
+// 		Ok: true,
+// 		Result: struct {
+// 			CustodialId json.Number `json:"custodialId"`
+// 			PublicKey   string      `json:"publicKey"`
+// 			TrackingId  string      `json:"trackingId"`
+// 		}{
+// 			CustodialId: "12",
+// 			PublicKey:   "0x8E0XSCSVA",
+// 			TrackingId:  "d95a7e83-196c-4fd0-866fSGAGA",
+// 		},
+// 	}
+// 	mockCreateAccountService.On("CreateAccount").Return(expectedAccountResp, nil)
+// 	data := map[utils.DataTyp]string{
+// 		utils.DATA_TRACKING_ID:  expectedAccountResp.Result.TrackingId,
+// 		utils.DATA_PUBLIC_KEY:   expectedAccountResp.Result.PublicKey,
+// 		utils.DATA_CUSTODIAL_ID: expectedAccountResp.Result.CustodialId.String(),
+// 	}
+
+// 	for key, value := range data {
+// 		//err := utils.WriteEntry(ctx, h.userdataStore, sessionId, key, []byte(value))
+// 		mockDataStore.On("WriteEntry", ctx, sessionId, key, []byte(value)).Return(nil)
+// 	}
+// 	//mockDataStore.On("WriteEntry", mock.Anything, sessionId, mock.Anything, mock.Anything).Return(nil)
+
+// 	// Create a Handlers instance with the mock data store
+// 	h := &Handlers{
+// 		userdataStore:  mockDataStore,
+// 		accountService: mockCreateAccountService,
+// 	}
+
+// 	// Call the method you want to test
+// 	_, err := h.CreateAccount(ctx, "some-symbol", []byte("some-input"))
+
+// 	// Assert that no errors occurred
+// 	assert.NoError(t, err)
+
+// 	// Assert that expectations were met
+// 	mockDataStore.AssertExpectations(t)
+// }
+
+func TestSaveFirstname(t *testing.T) {
+	// Create a new instance of MockMyDataStore
+	mockStore := new(mocks.MockUserDataStore)
+
+	// Define test data
+	sessionId := "session123"
+	firstName := "John"
+	ctx := context.WithValue(context.Background(), "SessionId", sessionId)
+
+	// Set up the expected behavior of the mock
+	mockStore.On("WriteEntry", ctx, sessionId, utils.DATA_FIRST_NAME, []byte(firstName)).Return(nil)
+
+	// Create the Handlers instance with the mock store
 	h := &Handlers{
-		userdataStore:  mockUserDataStore,
-		accountService: mockCreateAccountService,
+		userdataStore: mockStore,
 	}
-	ctx := context.WithValue(context.Background(), "SessionId", "test-session-12345")
-	k := utils.PackKey(utils.DATA_ACCOUNT_CREATED, []byte("test-session-12345"))
-	mockUserDataStore.On("SetPrefix", uint8(0x20)).Return(nil)
-	mockUserDataStore.On("SetSession", "test-session-12345").Return(nil)
-	mockUserDataStore.On("Get", ctx, k).
-		Return(nil, db.ErrNotFound{})
 
-	// Define expected account response after api call
-	expectedAccountResp := &models.AccountResponse{
-		Ok: true,
-		Result: struct {
-			CustodialId json.Number `json:"custodialId"`
-			PublicKey   string      `json:"publicKey"`
-			TrackingId  string      `json:"trackingId"`
-		}{
-			CustodialId: "12",
-			PublicKey:   "0x8E0XSCSVA",
-			TrackingId:  "d95a7e83-196c-4fd0-866fSGAGA",
-		},
-	}
-	mockCreateAccountService.On("CreateAccount").Return(expectedAccountResp, nil)
-
-	_, err := h.CreateAccount(ctx, "create_account", []byte("create_account"))
+	// Call the method
+	res, err := h.SaveFirstname(ctx, "save_firstname", []byte(firstName))
 
 	// Assert results
 	assert.NoError(t, err)
-	assert.Equal(t, expectedAccountResp.Ok, true)
-}
+	assert.Equal(t, resource.Result{}, res)
 
-func TestSaveFirstname(t *testing.T) {
-	// Create a mock database
-	mockDb := new(mocks.MockDb)
-
-	// Create a Handlers instance with the mock database
-	h := &Handlers{
-		userdataStore: mockDb,
-	}
-
-	// Create a context with a session ID
-	ctx := context.WithValue(context.Background(), "SessionId", "test-session")
-
-	tests := []struct {
-		name        string
-		input       []byte
-		expectError bool
-		setupMock   func(*mocks.MockDb)
-	}{
-		{
-			name:        "Valid first name",
-			input:       []byte("John"),
-			expectError: false,
-			setupMock: func(m *mocks.MockDb) {
-				m.On("SetPrefix", uint8(0x20)).Return(nil)
-				m.On("SetSession", "test-session").Return(nil)
-				m.On("Put", mock.Anything, mock.Anything, []byte("John")).Return(nil)
-			},
-		},
-		{
-			name:        "Empty first name",
-			input:       []byte{},
-			expectError: false, // Note: The function doesn't return an error for empty input
-			setupMock:   func(m *mocks.MockDb) {},
-		},
-	}
-
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			// Setup mock expectations
-			tt.setupMock(mockDb)
-
-			// Call the function
-			_, err := h.SaveFirstname(ctx, "", tt.input)
-
-			if tt.expectError {
-				assert.Error(t, err)
-			} else {
-				assert.NoError(t, err)
-				mockDb.AssertExpectations(t)
-			}
-
-			// Clear mock for the next test
-			mockDb.ExpectedCalls = nil
-			mockDb.Calls = nil
-		})
-	}
+	// Assert all expectations were met
+	mockStore.AssertExpectations(t)
 }
 
 func TestSaveFamilyname(t *testing.T) {
-	// Create a mock database
-	mockDb := new(mocks.MockDb)
+	// Create a new instance of MockMyDataStore
+	mockStore := new(mocks.MockUserDataStore)
 
-	// Create a Handlers instance with the mock database
+	// Define test data
+	sessionId := "session123"
+	familyName := "Doeee"
+	ctx := context.WithValue(context.Background(), "SessionId", sessionId)
+
+	// Set up the expected behavior of the mock
+	mockStore.On("WriteEntry", ctx, sessionId, utils.DATA_FAMILY_NAME, []byte(familyName)).Return(nil)
+
+	// Create the Handlers instance with the mock store
 	h := &Handlers{
-		userdataStore: mockDb,
+		userdataStore: mockStore,
 	}
 
-	// Create a context with a session ID
-	ctx := context.WithValue(context.Background(), "SessionId", "test-session")
+	// Call the method
+	res, err := h.SaveFamilyname(ctx, "save_familyname", []byte(familyName))
 
+	// Assert results
+	assert.NoError(t, err)
+	assert.Equal(t, resource.Result{}, res)
+
+	// Assert all expectations were met
+	mockStore.AssertExpectations(t)
+}
+
+func TestSaveYoB(t *testing.T) {
+	// Create a new instance of MockMyDataStore
+	mockStore := new(mocks.MockUserDataStore)
+
+	// Define test data
+	sessionId := "session123"
+	yob := "1980"
+	ctx := context.WithValue(context.Background(), "SessionId", sessionId)
+
+	// Set up the expected behavior of the mock
+	mockStore.On("WriteEntry", ctx, sessionId, utils.DATA_YOB, []byte(yob)).Return(nil)
+
+	// Create the Handlers instance with the mock store
+	h := &Handlers{
+		userdataStore: mockStore,
+	}
+
+	// Call the method
+	res, err := h.SaveYob(ctx, "save_yob", []byte(yob))
+
+	// Assert results
+	assert.NoError(t, err)
+	assert.Equal(t, resource.Result{}, res)
+
+	// Assert all expectations were met
+	mockStore.AssertExpectations(t)
+}
+
+func TestSaveLocation(t *testing.T) {
+	// Create a new instance of MockMyDataStore
+	mockStore := new(mocks.MockUserDataStore)
+
+	// Define test data
+	sessionId := "session123"
+	yob := "Kilifi"
+	ctx := context.WithValue(context.Background(), "SessionId", sessionId)
+
+	// Set up the expected behavior of the mock
+	mockStore.On("WriteEntry", ctx, sessionId, utils.DATA_LOCATION, []byte(yob)).Return(nil)
+
+	// Create the Handlers instance with the mock store
+	h := &Handlers{
+		userdataStore: mockStore,
+	}
+
+	// Call the method
+	res, err := h.SaveLocation(ctx, "save_location", []byte(yob))
+
+	// Assert results
+	assert.NoError(t, err)
+	assert.Equal(t, resource.Result{}, res)
+
+	// Assert all expectations were met
+	mockStore.AssertExpectations(t)
+}
+
+func TestSaveGender(t *testing.T) {
+	// Create a new instance of MockMyDataStore
+	mockStore := new(mocks.MockUserDataStore)
+
+	// Define the session ID and context
+	sessionId := "session123"
+	ctx := context.WithValue(context.Background(), "SessionId", sessionId)
+
+	// Define test cases
 	tests := []struct {
-		name        string
-		input       []byte
-		expectError bool
-		setupMock   func(*mocks.MockDb)
+		name           string
+		input          []byte
+		expectedGender string
+		expectCall     bool
 	}{
 		{
-			name:        "Valid family name",
-			input:       []byte("Smith"),
-			expectError: false,
-			setupMock: func(m *mocks.MockDb) {
-				m.On("SetPrefix", uint8(0x20)).Return(nil)
-				m.On("SetSession", "test-session").Return(nil)
-				m.On("Put", mock.Anything, mock.Anything, []byte("Smith")).Return(nil)
-			},
+			name:           "Valid Male Input",
+			input:          []byte("1"),
+			expectedGender: "Male",
+			expectCall:     true,
 		},
 		{
-			name:        "Empty family name",
-			input:       []byte{},
-			expectError: true,
-			setupMock:   func(m *mocks.MockDb) {},
+			name:           "Valid Female Input",
+			input:          []byte("2"),
+			expectedGender: "Female",
+			expectCall:     true,
+		},
+		{
+			name:           "Valid Unspecified Input",
+			input:          []byte("3"),
+			expectedGender: "Unspecified",
+			expectCall:     true,
+		},
+		{
+			name:           "Empty Input",
+			input:          []byte(""),
+			expectedGender: "",
+			expectCall:     false,
 		},
 	}
 
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			// Setup mock expectations
-			tt.setupMock(mockDb)
-
-			// Call the function
-			_, err := h.SaveFamilyname(ctx, "", tt.input)
-
-			if tt.expectError {
-				assert.Error(t, err)
+			// Set up expectations for the mock database
+			if tt.expectCall {
+				expectedKey := utils.DATA_GENDER
+				mockStore.On("WriteEntry", ctx, sessionId, expectedKey, []byte(tt.expectedGender)).Return(nil)
 			} else {
-				assert.NoError(t, err)
-				mockDb.AssertExpectations(t)
+				mockStore.On("WriteEntry", ctx, sessionId, utils.DATA_GENDER, []byte(tt.expectedGender)).Return(nil)
 			}
 
-			// Clear mock for the next test
-			mockDb.ExpectedCalls = nil
-			mockDb.Calls = nil
+			// Create the Handlers instance with the mock store
+			h := &Handlers{
+				userdataStore: mockStore,
+			}
+
+			// Call the method
+			_, err := h.SaveGender(ctx, "someSym", tt.input)
+
+			// Assert no error
+			assert.NoError(t, err)
+
+			// Verify expectations
+			if tt.expectCall {
+				mockStore.AssertCalled(t, "WriteEntry", ctx, sessionId, utils.DATA_GENDER, []byte(tt.expectedGender))
+			} else {
+				mockStore.AssertNotCalled(t, "WriteEntry", ctx, sessionId, utils.DATA_GENDER, []byte(tt.expectedGender))
+			}
 		})
 	}
 }
 
-func testSavePin () {
-	
-}
\ No newline at end of file
+func TestCheckIdentifier(t *testing.T) {
+	// Create a new instance of MockMyDataStore
+	mockStore := new(mocks.MockUserDataStore)
+
+	// Define the session ID and context
+	sessionId := "session123"
+	ctx := context.WithValue(context.Background(), "SessionId", sessionId)
+
+	// Define test cases
+	tests := []struct {
+		name            string
+		mockPublicKey   []byte
+		mockErr         error
+		expectedContent string
+		expectError     bool
+	}{
+		{
+			name:            "Saved public Key",
+			mockPublicKey:   []byte("0xa8363"),
+			mockErr:         nil,
+			expectedContent: "0xa8363",
+			expectError:     false,
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			// Set up expectations for the mock database
+			mockStore.On("ReadEntry", ctx, sessionId, utils.DATA_PUBLIC_KEY).Return(tt.mockPublicKey, tt.mockErr)
+
+			// Create the Handlers instance with the mock store
+			h := &Handlers{
+				userdataStore: mockStore,
+			}
+
+			// Call the method
+			res, err := h.CheckIdentifier(ctx, "check_identifier", nil)
+
+			// Assert results
+
+			assert.NoError(t, err)
+			assert.Equal(t, tt.expectedContent, res.Content)
+
+			// Verify expectations
+			mockStore.AssertExpectations(t)
+		})
+	}
+}
+
+func TestMaxAmount(t *testing.T) {
+	mockStore := new(mocks.MockUserDataStore)
+	mockCreateAccountService := new(mocks.MockAccountService)
+
+	// Define test data
+	sessionId := "session123"
+	ctx := context.WithValue(context.Background(), "SessionId", sessionId)
+	publicKey := "0xcasgatweksalw1018221"
+	expectedBalance := "0.003CELO"
+
+	// Set up the expected behavior of the mock
+	mockStore.On("ReadEntry", ctx, sessionId, utils.DATA_PUBLIC_KEY).Return([]byte(publicKey), nil)
+	mockCreateAccountService.On("CheckBalance", publicKey).Return(expectedBalance, nil)
+
+	// Create the Handlers instance with the mock store
+	h := &Handlers{
+		userdataStore:  mockStore,
+		accountService: mockCreateAccountService,
+	}
+
+	// Call the method
+	res, _ := h.MaxAmount(ctx, "max_amount", []byte("check_balance"))
+
+	//Assert that the balance that was set as the result content is what was returned by  Check Balance
+	assert.Equal(t, expectedBalance, res.Content)
+
+}
+
+func TestGetSender(t *testing.T) {
+	mockStore := new(mocks.MockUserDataStore)
+
+	// Define test data
+	sessionId := "session123"
+	ctx := context.WithValue(context.Background(), "SessionId", sessionId)
+	publicKey := "0xcasgatweksalw1018221"
+
+	// Set up the expected behavior of the mock
+	mockStore.On("ReadEntry", ctx, sessionId, utils.DATA_PUBLIC_KEY).Return([]byte(publicKey), nil)
+
+	// Create the Handlers instance with the mock store
+	h := &Handlers{
+		userdataStore: mockStore,
+	}
+
+	// Call the method
+	res, _ := h.GetSender(ctx, "max_amount", []byte("check_balance"))
+
+	//Assert that the public key from readentry operation  is what was set as the result content.
+	assert.Equal(t, publicKey, res.Content)
+
+}
+
+func TestGetAmount(t *testing.T) {
+	mockStore := new(mocks.MockUserDataStore)
+
+	// Define test data
+	sessionId := "session123"
+	ctx := context.WithValue(context.Background(), "SessionId", sessionId)
+	Amount := "0.03CELO"
+
+	// Set up the expected behavior of the mock
+	mockStore.On("ReadEntry", ctx, sessionId, utils.DATA_AMOUNT).Return([]byte(Amount), nil)
+
+	// Create the Handlers instance with the mock store
+	h := &Handlers{
+		userdataStore: mockStore,
+	}
+
+	// Call the method
+	res, _ := h.GetAmount(ctx, "get_amount", []byte("Getting amount..."))
+
+	//Assert that the retrieved amount is what was set as the content
+	assert.Equal(t, Amount, res.Content)
+
+}

From 0cdb23fbea9b821bdf70a8fb6e6d2a154955ee98 Mon Sep 17 00:00:00 2001
From: Carlosokumu <carlosokumu254@gmail.com>
Date: Mon, 9 Sep 2024 17:15:35 +0300
Subject: [PATCH 40/47] setupmock for user datastore

---
 internal/handlers/ussd/mocks/userdbmock.go | 69 ++++++++++++++++++++++
 1 file changed, 69 insertions(+)
 create mode 100644 internal/handlers/ussd/mocks/userdbmock.go

diff --git a/internal/handlers/ussd/mocks/userdbmock.go b/internal/handlers/ussd/mocks/userdbmock.go
new file mode 100644
index 0000000..f1e4b57
--- /dev/null
+++ b/internal/handlers/ussd/mocks/userdbmock.go
@@ -0,0 +1,69 @@
+package mocks
+
+import (
+	"context"
+
+	"git.defalsify.org/vise.git/lang"
+	"git.grassecon.net/urdt/ussd/internal/utils"
+	"github.com/stretchr/testify/mock"
+)
+
+type MockUserDataStore struct {
+	mock.Mock
+}
+
+func (m *MockUserDataStore) SetPrefix(prefix uint8) {
+	m.Called(prefix)
+}
+
+func (m *MockUserDataStore) SetSession(sessionId string) {
+	m.Called(sessionId)
+}
+
+func (m *MockUserDataStore) Get(ctx context.Context, key []byte) ([]byte, error) {
+	args := m.Called(ctx, key)
+	return args.Get(0).([]byte), args.Error(1)
+}
+
+func (m *MockUserDataStore) ReadEntry(ctx context.Context, sessionId string, typ utils.DataTyp) ([]byte, error) {
+	args := m.Called(ctx, sessionId, typ)
+	return args.Get(0).([]byte), args.Error(1)
+}
+
+func (m *MockUserDataStore) WriteEntry(ctx context.Context, sessionId string, typ utils.DataTyp, value []byte) error {
+	args := m.Called(ctx, sessionId, typ, value)
+	return args.Error(0)
+}
+
+func (m *MockUserDataStore) Prefix() uint8 {
+	args := m.Called()
+	return args.Get(0).(uint8)
+}
+
+func (m *MockUserDataStore) Safe() bool {
+	args := m.Called()
+	return args.Get(0).(bool)
+}
+
+func (m *MockUserDataStore) SetLanguage(language *lang.Language) {
+	m.Called(language)
+}
+
+func (m *MockUserDataStore) SetLock(uint8, bool) error {
+	args := m.Called()
+	return args.Error(0)
+}
+
+func (m *MockUserDataStore) Connect(ctx context.Context, connectionStr string) error {
+	args := m.Called(ctx, connectionStr)
+	return args.Error(0)
+}
+
+func (m *MockUserDataStore) Put(ctx context.Context, key, value []byte) error {
+	args := m.Called(ctx, key, value)
+	return args.Error(0)
+}
+func (m *MockUserDataStore) Close() error {
+	args := m.Called(nil)
+	return args.Error(0)
+}

From 134aa96194b36401bc6b40cb6eba9ae6e36185f8 Mon Sep 17 00:00:00 2001
From: Carlosokumu <carlosokumu254@gmail.com>
Date: Mon, 9 Sep 2024 17:16:08 +0300
Subject: [PATCH 41/47] implement db for user datastore

---
 internal/utils/userStore.go | 81 +++++++++++++++++++++++++++++++++++++
 1 file changed, 81 insertions(+)
 create mode 100644 internal/utils/userStore.go

diff --git a/internal/utils/userStore.go b/internal/utils/userStore.go
new file mode 100644
index 0000000..e8fbbf4
--- /dev/null
+++ b/internal/utils/userStore.go
@@ -0,0 +1,81 @@
+package utils
+
+import (
+	"context"
+
+	"git.defalsify.org/vise.git/db"
+	"git.defalsify.org/vise.git/lang"
+)
+
+type DataStore interface {
+	SetPrefix(prefix uint8)
+	SetSession(sessionId string)
+	Get(ctx context.Context, key []byte) ([]byte, error)
+	ReadEntry(ctx context.Context, sessionId string, typ DataTyp) ([]byte, error)
+	WriteEntry(ctx context.Context, sessionId string, typ DataTyp, value []byte) error
+	Connect(ctx context.Context, connStr string) error
+	SetLanguage(*lang.Language)
+	Close() error
+	Prefix() uint8
+	Put(ctx context.Context, key []byte, val []byte) error
+	Safe() bool
+	SetLock(typ uint8, locked bool) error
+}
+
+type UserDataStore struct {
+	Store db.Db
+}
+
+func (store UserDataStore) SetPrefix(prefix uint8) {
+	store.Store.SetPrefix(prefix)
+}
+
+func (store UserDataStore) SetLanguage(lang *lang.Language) {
+	store.Store.SetLanguage(lang)
+}
+
+func (store UserDataStore) SetLock(typ uint8, locked bool) error {
+	return store.Store.SetLock(typ, locked)
+}
+func (store UserDataStore) Safe() bool {
+	return store.Store.Safe()
+}
+
+func (store UserDataStore) Put(ctx context.Context, key []byte, val []byte) error {
+	return store.Store.Put(ctx, key, val)
+}
+
+func (store UserDataStore) Connect(ctx context.Context, connectionStr string) error {
+	return store.Store.Connect(ctx, connectionStr)
+}
+
+func (store UserDataStore) Close() error {
+	return store.Store.Close()
+}
+
+func (store UserDataStore) Prefix() uint8 {
+	return store.Store.Prefix()
+}
+
+func (store UserDataStore) SetSession(sessionId string) {
+	store.Store.SetSession(sessionId)
+}
+
+func (store UserDataStore) Get(ctx context.Context, key []byte) ([]byte, error) {
+	return store.Store.Get(ctx, key)
+}
+
+// ReadEntry retrieves an entry from the store based on the provided parameters.
+func (store UserDataStore) ReadEntry(ctx context.Context, sessionId string, typ DataTyp) ([]byte, error) {
+	store.Store.SetPrefix(db.DATATYPE_USERDATA)
+	store.Store.SetSession(sessionId)
+	k := PackKey(typ, []byte(sessionId))
+	return store.Get(ctx, k)
+}
+
+func (store UserDataStore) WriteEntry(ctx context.Context, sessionId string, typ DataTyp, value []byte) error {
+	store.Store.SetPrefix(db.DATATYPE_USERDATA)
+	store.Store.SetSession(sessionId)
+	k := PackKey(typ, []byte(sessionId))
+	return store.Store.Put(ctx, k, value)
+}

From f5f1cbaabaecd08d93224bf117cbe501feb304c4 Mon Sep 17 00:00:00 2001
From: Carlosokumu <carlosokumu254@gmail.com>
Date: Mon, 9 Sep 2024 17:18:07 +0300
Subject: [PATCH 42/47] cleanup

---
 internal/handlers/ussd/menuhandler.go | 159 ++++++++++++++++----------
 1 file changed, 96 insertions(+), 63 deletions(-)

diff --git a/internal/handlers/ussd/menuhandler.go b/internal/handlers/ussd/menuhandler.go
index 066eef2..1b34b74 100644
--- a/internal/handlers/ussd/menuhandler.go
+++ b/internal/handlers/ussd/menuhandler.go
@@ -58,16 +58,18 @@ func (fm *FlagManager) GetFlag(label string) (uint32, error) {
 }
 
 type Handlers struct {
-	pe                 *persist.Persister
-	st                 *state.State
-	ca                 cache.Memory
-	userdataStore      db.Db
-	flagManager        *asm.FlagParser
-	accountFileHandler *utils.AccountFileHandler
-	accountService     server.AccountServiceInterface
+	pe             *persist.Persister
+	st             *state.State
+	ca             cache.Memory
+	userdataStore  utils.DataStore
+	flagManager    *asm.FlagParser
+	accountService server.AccountServiceInterface
 }
 
-func NewHandlers(appFlags *asm.FlagParser, pe *persist.Persister, userdataStore db.Db) (*Handlers, error) {
+func NewHandlers(parser *asm.FlagParser, pe *persist.Persister, userdataStore db.Db) (*Handlers, error) {
+	userDb := utils.UserDataStore{
+		Store: userdataStore,
+	}
 	if pe == nil {
 		return nil, fmt.Errorf("cannot create handler with nil persister")
 	}
@@ -75,11 +77,10 @@ func NewHandlers(appFlags *asm.FlagParser, pe *persist.Persister, userdataStore
 		return nil, fmt.Errorf("cannot create handler with nil userdata store")
 	}
 	h := &Handlers{
-		pe:                 pe,
-		userdataStore:      userdataStore,
-		flagManager:        appFlags,
-		accountFileHandler: utils.NewAccountFileHandler(userdataStore),
-		accountService:     &server.AccountService{},
+		pe:             pe,
+		userdataStore:  userDb,
+		flagManager:    parser,
+		accountService: &server.AccountService{},
 	}
 	return h, nil
 }
@@ -145,8 +146,10 @@ func (h *Handlers) createAccountNoExist(ctx context.Context, sessionId string, r
 		utils.DATA_PUBLIC_KEY:   accountResp.Result.PublicKey,
 		utils.DATA_CUSTODIAL_ID: accountResp.Result.CustodialId.String(),
 	}
+
 	for key, value := range data {
-		err := utils.WriteEntry(ctx, h.userdataStore, sessionId, key, []byte(value))
+		store := h.userdataStore
+		err := store.WriteEntry(ctx, sessionId, key, []byte(value))
 		if err != nil {
 			return err
 		}
@@ -167,7 +170,8 @@ func (h *Handlers) CreateAccount(ctx context.Context, sym string, input []byte)
 	if !ok {
 		return res, fmt.Errorf("missing session")
 	}
-	_, err = utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_ACCOUNT_CREATED)
+	store := h.userdataStore
+	_, err = store.ReadEntry(ctx, sessionId, utils.DATA_ACCOUNT_CREATED)
 	if err != nil {
 		if db.IsNotFound(err) {
 			logg.Printf(logging.LVL_INFO, "Creating an account because it doesn't exist")
@@ -200,12 +204,11 @@ func (h *Handlers) SavePin(ctx context.Context, sym string, input []byte) (resou
 	}
 
 	res.FlagReset = append(res.FlagReset, flag_incorrect_pin)
-
-	err = utils.WriteEntry(ctx, h.userdataStore, sessionId, utils.DATA_ACCOUNT_PIN, []byte(accountPIN))
+	store := h.userdataStore
+	err = store.WriteEntry(ctx, sessionId, utils.DATA_ACCOUNT_PIN, []byte(accountPIN))
 	if err != nil {
 		return res, err
 	}
-
 	return res, nil
 }
 
@@ -250,7 +253,12 @@ func (h *Handlers) VerifyPin(ctx context.Context, sym string, input []byte) (res
 		return res, fmt.Errorf("missing session")
 	}
 
-	AccountPin, _ := utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_ACCOUNT_PIN)
+	//AccountPin, _ := utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_ACCOUNT_PIN)
+	store := h.userdataStore.(utils.UserDataStore)
+	AccountPin, err := store.ReadEntry(ctx, sessionId, utils.DATA_ACCOUNT_PIN)
+	if err != nil {
+		return res, err
+	}
 
 	if bytes.Equal(input, AccountPin) {
 		res.FlagSet = []uint32{flag_valid_pin}
@@ -284,9 +292,10 @@ func (h *Handlers) SaveFirstname(ctx context.Context, sym string, input []byte)
 
 	if len(input) > 0 {
 		firstName := string(input)
-		err = utils.WriteEntry(ctx, h.userdataStore, sessionId, utils.DATA_FIRST_NAME, []byte(firstName))
+		store := h.userdataStore
+		err = store.WriteEntry(ctx, sessionId, utils.DATA_FIRST_NAME, []byte(firstName))
 		if err != nil {
-			return res, nil
+			return res, err
 		}
 	}
 
@@ -304,7 +313,11 @@ func (h *Handlers) SaveFamilyname(ctx context.Context, sym string, input []byte)
 
 	if len(input) > 0 {
 		familyName := string(input)
-		err = utils.WriteEntry(ctx, h.userdataStore, sessionId, utils.DATA_FAMILY_NAME, []byte(familyName))
+		store := h.userdataStore
+		err = store.WriteEntry(ctx, sessionId, utils.DATA_FAMILY_NAME, []byte(familyName))
+		if err != nil {
+			return res, err
+		}
 		if err != nil {
 			return res, nil
 		}
@@ -326,9 +339,10 @@ func (h *Handlers) SaveYob(ctx context.Context, sym string, input []byte) (resou
 
 	if len(input) == 4 {
 		yob := string(input)
-		err = utils.WriteEntry(ctx, h.userdataStore, sessionId, utils.DATA_YOB, []byte(yob))
+		store := h.userdataStore
+		err = store.WriteEntry(ctx, sessionId, utils.DATA_YOB, []byte(yob))
 		if err != nil {
-			return res, nil
+			return res, err
 		}
 	}
 
@@ -346,9 +360,10 @@ func (h *Handlers) SaveLocation(ctx context.Context, sym string, input []byte) (
 
 	if len(input) > 0 {
 		location := string(input)
-		err = utils.WriteEntry(ctx, h.userdataStore, sessionId, utils.DATA_LOCATION, []byte(location))
+		store := h.userdataStore
+		err = store.WriteEntry(ctx, sessionId, utils.DATA_LOCATION, []byte(location))
 		if err != nil {
-			return res, nil
+			return res, err
 		}
 	}
 
@@ -374,7 +389,8 @@ func (h *Handlers) SaveGender(ctx context.Context, sym string, input []byte) (re
 		case "3":
 			gender = "Unspecified"
 		}
-		err = utils.WriteEntry(ctx, h.userdataStore, sessionId, utils.DATA_GENDER, []byte(gender))
+		store := h.userdataStore
+		err = store.WriteEntry(ctx, sessionId, utils.DATA_GENDER, []byte(gender))
 		if err != nil {
 			return res, nil
 		}
@@ -394,7 +410,8 @@ func (h *Handlers) SaveOfferings(ctx context.Context, sym string, input []byte)
 
 	if len(input) > 0 {
 		offerings := string(input)
-		err = utils.WriteEntry(ctx, h.userdataStore, sessionId, utils.DATA_OFFERINGS, []byte(offerings))
+		store := h.userdataStore
+		err = store.WriteEntry(ctx, sessionId, utils.DATA_OFFERINGS, []byte(offerings))
 		if err != nil {
 			return res, nil
 		}
@@ -432,7 +449,8 @@ func (h *Handlers) CheckIdentifier(ctx context.Context, sym string, input []byte
 		return res, fmt.Errorf("missing session")
 	}
 
-	publicKey, _ := utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_PUBLIC_KEY)
+	store := h.userdataStore
+	publicKey, _ := store.ReadEntry(ctx, sessionId, utils.DATA_PUBLIC_KEY)
 
 	res.Content = string(publicKey)
 
@@ -454,7 +472,11 @@ func (h *Handlers) Authorize(ctx context.Context, sym string, input []byte) (res
 	flag_account_authorized, _ := h.flagManager.GetFlag("flag_account_authorized")
 	flag_allow_update, _ := h.flagManager.GetFlag("flag_allow_update")
 
-	AccountPin, err := utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_ACCOUNT_PIN)
+	store := h.userdataStore
+	AccountPin, err := store.ReadEntry(ctx, sessionId, utils.DATA_ACCOUNT_PIN)
+	if err != nil {
+		return res, err
+	}
 
 	if err == nil {
 		if len(input) == 4 {
@@ -501,8 +523,11 @@ func (h *Handlers) CheckAccountStatus(ctx context.Context, sym string, input []b
 	if !ok {
 		return res, fmt.Errorf("missing session")
 	}
-
-	trackingId, _ := utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_TRACKING_ID)
+	store := h.userdataStore.(utils.UserDataStore)
+	trackingId, err := store.ReadEntry(ctx, sessionId, utils.DATA_TRACKING_ID)
+	if err != nil {
+		return res, err
+	}
 
 	status, err := h.accountService.CheckAccountStatus(string(trackingId))
 	if err != nil {
@@ -510,7 +535,7 @@ func (h *Handlers) CheckAccountStatus(ctx context.Context, sym string, input []b
 		return res, err
 	}
 
-	err = utils.WriteEntry(ctx, h.userdataStore, sessionId, utils.DATA_ACCOUNT_STATUS, []byte(status))
+	err = store.WriteEntry(ctx, sessionId, utils.DATA_ACCOUNT_STATUS, []byte(status))
 	if err != nil {
 		return res, nil
 	}
@@ -585,7 +610,11 @@ func (h *Handlers) CheckBalance(ctx context.Context, sym string, input []byte) (
 		return res, fmt.Errorf("missing session")
 	}
 
-	publicKey, _ := utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_PUBLIC_KEY)
+	store := h.userdataStore.(utils.UserDataStore)
+	publicKey, err := store.ReadEntry(ctx, sessionId, utils.DATA_PUBLIC_KEY)
+	if err != nil {
+		return res, err
+	}
 
 	balance, err := h.accountService.CheckBalance(string(publicKey))
 	if err != nil {
@@ -618,8 +647,8 @@ func (h *Handlers) ValidateRecipient(ctx context.Context, sym string, input []by
 
 			return res, nil
 		}
-
-		err = utils.WriteEntry(ctx, h.userdataStore, sessionId, utils.DATA_RECIPIENT, []byte(recipient))
+		store := h.userdataStore
+		err = store.WriteEntry(ctx, sessionId, utils.DATA_RECIPIENT, []byte(recipient))
 		if err != nil {
 			return res, nil
 		}
@@ -641,13 +670,13 @@ func (h *Handlers) TransactionReset(ctx context.Context, sym string, input []byt
 
 	flag_invalid_recipient, _ := h.flagManager.GetFlag("flag_invalid_recipient")
 	flag_invalid_recipient_with_invite, _ := h.flagManager.GetFlag("flag_invalid_recipient_with_invite")
-
-	err = utils.WriteEntry(ctx, h.userdataStore, sessionId, utils.DATA_AMOUNT, []byte(""))
+	store := h.userdataStore
+	err = store.WriteEntry(ctx, sessionId, utils.DATA_AMOUNT, []byte(""))
 	if err != nil {
 		return res, nil
 	}
 
-	err = utils.WriteEntry(ctx, h.userdataStore, sessionId, utils.DATA_RECIPIENT, []byte(""))
+	err = store.WriteEntry(ctx, sessionId, utils.DATA_RECIPIENT, []byte(""))
 	if err != nil {
 		return res, nil
 	}
@@ -668,8 +697,8 @@ func (h *Handlers) ResetTransactionAmount(ctx context.Context, sym string, input
 	}
 
 	flag_invalid_amount, _ := h.flagManager.GetFlag("flag_invalid_amount")
-
-	err = utils.WriteEntry(ctx, h.userdataStore, sessionId, utils.DATA_AMOUNT, []byte(""))
+	store := h.userdataStore
+	err = store.WriteEntry(ctx, sessionId, utils.DATA_AMOUNT, []byte(""))
 	if err != nil {
 		return res, nil
 	}
@@ -689,8 +718,8 @@ func (h *Handlers) MaxAmount(ctx context.Context, sym string, input []byte) (res
 	if !ok {
 		return res, fmt.Errorf("missing session")
 	}
-
-	publicKey, _ := utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_PUBLIC_KEY)
+	store := h.userdataStore
+	publicKey, _ := store.ReadEntry(ctx, sessionId, utils.DATA_PUBLIC_KEY)
 
 	balance, err := h.accountService.CheckBalance(string(publicKey))
 	if err != nil {
@@ -759,8 +788,8 @@ func (h *Handlers) ValidateAmount(ctx context.Context, sym string, input []byte)
 	}
 
 	res.Content = fmt.Sprintf("%.3f", inputAmount) // Format to 3 decimal places
-
-	err = utils.WriteEntry(ctx, h.userdataStore, sessionId, utils.DATA_AMOUNT, []byte(amountStr))
+	store := h.userdataStore
+	err = store.WriteEntry(ctx, sessionId, utils.DATA_AMOUNT, []byte(amountStr))
 	if err != nil {
 		return res, err
 	}
@@ -776,8 +805,8 @@ func (h *Handlers) GetRecipient(ctx context.Context, sym string, input []byte) (
 	if !ok {
 		return res, fmt.Errorf("missing session")
 	}
-
-	recipient, _ := utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_RECIPIENT)
+	store := h.userdataStore
+	recipient, _ := store.ReadEntry(ctx, sessionId, utils.DATA_RECIPIENT)
 
 	res.Content = string(recipient)
 
@@ -793,7 +822,8 @@ func (h *Handlers) GetSender(ctx context.Context, sym string, input []byte) (res
 		return res, fmt.Errorf("missing session")
 	}
 
-	publicKey, _ := utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_PUBLIC_KEY)
+	store := h.userdataStore
+	publicKey, _ := store.ReadEntry(ctx, sessionId, utils.DATA_PUBLIC_KEY)
 
 	res.Content = string(publicKey)
 
@@ -808,8 +838,8 @@ func (h *Handlers) GetAmount(ctx context.Context, sym string, input []byte) (res
 	if !ok {
 		return res, fmt.Errorf("missing session")
 	}
-
-	amount, _ := utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_AMOUNT)
+	store := h.userdataStore
+	amount, _ := store.ReadEntry(ctx, sessionId, utils.DATA_AMOUNT)
 
 	res.Content = string(amount)
 
@@ -832,8 +862,11 @@ func (h *Handlers) QuitWithBalance(ctx context.Context, sym string, input []byte
 	l := gotext.NewLocale(translationDir, code)
 	l.AddDomain("default")
 
-	publicKey, _ := utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_PUBLIC_KEY)
-
+	store := h.userdataStore.(utils.UserDataStore)
+	publicKey, err := store.ReadEntry(ctx, sessionId, utils.DATA_PUBLIC_KEY)
+	if err != nil {
+		return res, err
+	}
 	balance, err := h.accountService.CheckBalance(string(publicKey))
 	if err != nil {
 		return res, nil
@@ -858,12 +891,12 @@ func (h *Handlers) InitiateTransaction(ctx context.Context, sym string, input []
 	l.AddDomain("default")
 	// TODO
 	// Use the amount, recipient and sender to call the API and initialize the transaction
+	store := h.userdataStore
+	publicKey, _ := store.ReadEntry(ctx, sessionId, utils.DATA_PUBLIC_KEY)
 
-	publicKey, _ := utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_PUBLIC_KEY)
+	amount, _ := store.ReadEntry(ctx, sessionId, utils.DATA_AMOUNT)
 
-	amount, _ := utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_AMOUNT)
-
-	recipient, _ := utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_RECIPIENT)
+	recipient, _ := store.ReadEntry(ctx, sessionId, utils.DATA_RECIPIENT)
 
 	res.Content = l.Get("Your request has been sent. %s will receive %s from %s.", string(recipient), string(amount), string(publicKey))
 
@@ -894,14 +927,14 @@ func (h *Handlers) GetProfileInfo(ctx context.Context, sym string, input []byte)
 		}
 		return string(entry)
 	}
-
+	store := h.userdataStore
 	// Retrieve user data as strings with fallback to defaultValue
-	firstName := getEntryOrDefault(utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_FIRST_NAME))
-	familyName := getEntryOrDefault(utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_FAMILY_NAME))
-	yob := getEntryOrDefault(utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_YOB))
-	gender := getEntryOrDefault(utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_GENDER))
-	location := getEntryOrDefault(utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_LOCATION))
-	offerings := getEntryOrDefault(utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_OFFERINGS))
+	firstName := getEntryOrDefault(store.ReadEntry(ctx, sessionId, utils.DATA_FIRST_NAME))
+	familyName := getEntryOrDefault(store.ReadEntry(ctx, sessionId, utils.DATA_FAMILY_NAME))
+	yob := getEntryOrDefault(store.ReadEntry(ctx, sessionId, utils.DATA_YOB))
+	gender := getEntryOrDefault(store.ReadEntry(ctx, sessionId, utils.DATA_GENDER))
+	location := getEntryOrDefault(store.ReadEntry(ctx, sessionId, utils.DATA_LOCATION))
+	offerings := getEntryOrDefault(store.ReadEntry(ctx, sessionId, utils.DATA_OFFERINGS))
 
 	// Construct the full name
 	name := defaultValue

From 47d39a1c6fb2c2fb74772107d9a3e55efaa9681d Mon Sep 17 00:00:00 2001
From: Carlosokumu <carlosokumu254@gmail.com>
Date: Mon, 9 Sep 2024 17:24:43 +0300
Subject: [PATCH 43/47] remove commented test

---
 internal/handlers/ussd/menuhandler_test.go | 57 +---------------------
 1 file changed, 1 insertion(+), 56 deletions(-)

diff --git a/internal/handlers/ussd/menuhandler_test.go b/internal/handlers/ussd/menuhandler_test.go
index 7dd2094..0a6aedb 100644
--- a/internal/handlers/ussd/menuhandler_test.go
+++ b/internal/handlers/ussd/menuhandler_test.go
@@ -10,61 +10,6 @@ import (
 	"github.com/alecthomas/assert/v2"
 )
 
-// func TestCreateAccount(t *testing.T) {
-// 	// Create a new instance of MockMyDataStore
-// 	mockDataStore := new(mocks.MockMyDataStore)
-// 	mockCreateAccountService := new(mocks.MockAccountService)
-
-// 	// Define session ID and mock data
-// 	sessionId := "session123"
-// 	typ := utils.DATA_ACCOUNT_CREATED
-// 	fakeError := db.ErrNotFound{}
-// 	// Create context with session ID
-// 	ctx := context.WithValue(context.Background(), "SessionId", sessionId)
-
-// 	// Define expected interactions with the mock
-// 	mockDataStore.On("ReadEntry", ctx, sessionId, typ).Return([]byte("123"), fakeError)
-// 	expectedAccountResp := &models.AccountResponse{
-// 		Ok: true,
-// 		Result: struct {
-// 			CustodialId json.Number `json:"custodialId"`
-// 			PublicKey   string      `json:"publicKey"`
-// 			TrackingId  string      `json:"trackingId"`
-// 		}{
-// 			CustodialId: "12",
-// 			PublicKey:   "0x8E0XSCSVA",
-// 			TrackingId:  "d95a7e83-196c-4fd0-866fSGAGA",
-// 		},
-// 	}
-// 	mockCreateAccountService.On("CreateAccount").Return(expectedAccountResp, nil)
-// 	data := map[utils.DataTyp]string{
-// 		utils.DATA_TRACKING_ID:  expectedAccountResp.Result.TrackingId,
-// 		utils.DATA_PUBLIC_KEY:   expectedAccountResp.Result.PublicKey,
-// 		utils.DATA_CUSTODIAL_ID: expectedAccountResp.Result.CustodialId.String(),
-// 	}
-
-// 	for key, value := range data {
-// 		//err := utils.WriteEntry(ctx, h.userdataStore, sessionId, key, []byte(value))
-// 		mockDataStore.On("WriteEntry", ctx, sessionId, key, []byte(value)).Return(nil)
-// 	}
-// 	//mockDataStore.On("WriteEntry", mock.Anything, sessionId, mock.Anything, mock.Anything).Return(nil)
-
-// 	// Create a Handlers instance with the mock data store
-// 	h := &Handlers{
-// 		userdataStore:  mockDataStore,
-// 		accountService: mockCreateAccountService,
-// 	}
-
-// 	// Call the method you want to test
-// 	_, err := h.CreateAccount(ctx, "some-symbol", []byte("some-input"))
-
-// 	// Assert that no errors occurred
-// 	assert.NoError(t, err)
-
-// 	// Assert that expectations were met
-// 	mockDataStore.AssertExpectations(t)
-// }
-
 func TestSaveFirstname(t *testing.T) {
 	// Create a new instance of MockMyDataStore
 	mockStore := new(mocks.MockUserDataStore)
@@ -94,7 +39,7 @@ func TestSaveFirstname(t *testing.T) {
 }
 
 func TestSaveFamilyname(t *testing.T) {
-	// Create a new instance of MockMyDataStore
+	// Create a new instance of UserDataStore
 	mockStore := new(mocks.MockUserDataStore)
 
 	// Define test data

From a3dffdf4e90b0ba9be83898baf220f4d9e54b6c3 Mon Sep 17 00:00:00 2001
From: Carlosokumu <carlosokumu254@gmail.com>
Date: Tue, 10 Sep 2024 11:23:25 +0300
Subject: [PATCH 44/47] match code refactor

---
 internal/handlers/ussd/menuhandler.go | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/internal/handlers/ussd/menuhandler.go b/internal/handlers/ussd/menuhandler.go
index 1b34b74..3b441c2 100644
--- a/internal/handlers/ussd/menuhandler.go
+++ b/internal/handlers/ussd/menuhandler.go
@@ -68,7 +68,7 @@ type Handlers struct {
 
 func NewHandlers(parser *asm.FlagParser, pe *persist.Persister, userdataStore db.Db) (*Handlers, error) {
 	userDb := utils.UserDataStore{
-		Store: userdataStore,
+		Db: userdataStore,
 	}
 	if pe == nil {
 		return nil, fmt.Errorf("cannot create handler with nil persister")
@@ -78,7 +78,7 @@ func NewHandlers(parser *asm.FlagParser, pe *persist.Persister, userdataStore db
 	}
 	h := &Handlers{
 		pe:             pe,
-		userdataStore:  userDb,
+		userdataStore:  &userDb,
 		flagManager:    parser,
 		accountService: &server.AccountService{},
 	}
@@ -254,7 +254,7 @@ func (h *Handlers) VerifyPin(ctx context.Context, sym string, input []byte) (res
 	}
 
 	//AccountPin, _ := utils.ReadEntry(ctx, h.userdataStore, sessionId, utils.DATA_ACCOUNT_PIN)
-	store := h.userdataStore.(utils.UserDataStore)
+	store := h.userdataStore
 	AccountPin, err := store.ReadEntry(ctx, sessionId, utils.DATA_ACCOUNT_PIN)
 	if err != nil {
 		return res, err
@@ -523,7 +523,7 @@ func (h *Handlers) CheckAccountStatus(ctx context.Context, sym string, input []b
 	if !ok {
 		return res, fmt.Errorf("missing session")
 	}
-	store := h.userdataStore.(utils.UserDataStore)
+	store := h.userdataStore
 	trackingId, err := store.ReadEntry(ctx, sessionId, utils.DATA_TRACKING_ID)
 	if err != nil {
 		return res, err
@@ -610,7 +610,7 @@ func (h *Handlers) CheckBalance(ctx context.Context, sym string, input []byte) (
 		return res, fmt.Errorf("missing session")
 	}
 
-	store := h.userdataStore.(utils.UserDataStore)
+	store := h.userdataStore
 	publicKey, err := store.ReadEntry(ctx, sessionId, utils.DATA_PUBLIC_KEY)
 	if err != nil {
 		return res, err
@@ -862,7 +862,7 @@ func (h *Handlers) QuitWithBalance(ctx context.Context, sym string, input []byte
 	l := gotext.NewLocale(translationDir, code)
 	l.AddDomain("default")
 
-	store := h.userdataStore.(utils.UserDataStore)
+	store := h.userdataStore
 	publicKey, err := store.ReadEntry(ctx, sessionId, utils.DATA_PUBLIC_KEY)
 	if err != nil {
 		return res, err

From c0a3ad7e2bd735343e7a8703459ad333c80b2258 Mon Sep 17 00:00:00 2001
From: Carlosokumu <carlosokumu254@gmail.com>
Date: Tue, 10 Sep 2024 11:23:41 +0300
Subject: [PATCH 45/47] delete deprecated code

---
 internal/utils/account_utils.go | 44 ---------------------------------
 1 file changed, 44 deletions(-)
 delete mode 100644 internal/utils/account_utils.go

diff --git a/internal/utils/account_utils.go b/internal/utils/account_utils.go
deleted file mode 100644
index b9fd1e3..0000000
--- a/internal/utils/account_utils.go
+++ /dev/null
@@ -1,44 +0,0 @@
-package utils
-
-import (
-	"context"
-	"encoding/json"
-
-	"git.defalsify.org/vise.git/db"
-)
-
-type AccountFileHandler struct {
-	store db.Db
-}
-
-func NewAccountFileHandler(store db.Db) *AccountFileHandler {
-	return &AccountFileHandler{
-		store: store,
-	}
-}
-
-func (afh *AccountFileHandler) ReadAccountData(ctx context.Context, sessionId string) (map[string]string, error) {
-	var accountData map[string]string
-	jsonData, err := ReadEntry(ctx, afh.store, sessionId, DATA_ACCOUNT)
-	if err != nil {
-		return nil,err
-	}
-	err = json.Unmarshal(jsonData, &accountData)
-	if err != nil {
-		return nil, err
-	}
-	return accountData, nil
-}
-
-func (afh *AccountFileHandler) WriteAccountData(ctx context.Context, sessionId string, accountData map[string]string) error {
-	_, err := json.Marshal(accountData)
-	if err != nil {
-		return err
-	}
-
-	return nil
-}
-
-func (afh *AccountFileHandler) EnsureFileExists() error {
-	return nil
-}

From ad48890a9fa61c5ffe473f35d96275988582d7f4 Mon Sep 17 00:00:00 2001
From: Carlosokumu <carlosokumu254@gmail.com>
Date: Tue, 10 Sep 2024 11:24:09 +0300
Subject: [PATCH 46/47] remove deprecated code

---
 internal/handlers/ussd/mocks/userdbmock.go | 49 +---------------
 internal/utils/userStore.go                | 67 +++-------------------
 2 files changed, 11 insertions(+), 105 deletions(-)

diff --git a/internal/handlers/ussd/mocks/userdbmock.go b/internal/handlers/ussd/mocks/userdbmock.go
index f1e4b57..ff3f18d 100644
--- a/internal/handlers/ussd/mocks/userdbmock.go
+++ b/internal/handlers/ussd/mocks/userdbmock.go
@@ -3,28 +3,16 @@ package mocks
 import (
 	"context"
 
-	"git.defalsify.org/vise.git/lang"
+	"git.defalsify.org/vise.git/db"
 	"git.grassecon.net/urdt/ussd/internal/utils"
 	"github.com/stretchr/testify/mock"
 )
 
 type MockUserDataStore struct {
+	db.Db
 	mock.Mock
 }
 
-func (m *MockUserDataStore) SetPrefix(prefix uint8) {
-	m.Called(prefix)
-}
-
-func (m *MockUserDataStore) SetSession(sessionId string) {
-	m.Called(sessionId)
-}
-
-func (m *MockUserDataStore) Get(ctx context.Context, key []byte) ([]byte, error) {
-	args := m.Called(ctx, key)
-	return args.Get(0).([]byte), args.Error(1)
-}
-
 func (m *MockUserDataStore) ReadEntry(ctx context.Context, sessionId string, typ utils.DataTyp) ([]byte, error) {
 	args := m.Called(ctx, sessionId, typ)
 	return args.Get(0).([]byte), args.Error(1)
@@ -34,36 +22,3 @@ func (m *MockUserDataStore) WriteEntry(ctx context.Context, sessionId string, ty
 	args := m.Called(ctx, sessionId, typ, value)
 	return args.Error(0)
 }
-
-func (m *MockUserDataStore) Prefix() uint8 {
-	args := m.Called()
-	return args.Get(0).(uint8)
-}
-
-func (m *MockUserDataStore) Safe() bool {
-	args := m.Called()
-	return args.Get(0).(bool)
-}
-
-func (m *MockUserDataStore) SetLanguage(language *lang.Language) {
-	m.Called(language)
-}
-
-func (m *MockUserDataStore) SetLock(uint8, bool) error {
-	args := m.Called()
-	return args.Error(0)
-}
-
-func (m *MockUserDataStore) Connect(ctx context.Context, connectionStr string) error {
-	args := m.Called(ctx, connectionStr)
-	return args.Error(0)
-}
-
-func (m *MockUserDataStore) Put(ctx context.Context, key, value []byte) error {
-	args := m.Called(ctx, key, value)
-	return args.Error(0)
-}
-func (m *MockUserDataStore) Close() error {
-	args := m.Called(nil)
-	return args.Error(0)
-}
diff --git a/internal/utils/userStore.go b/internal/utils/userStore.go
index e8fbbf4..a1485b1 100644
--- a/internal/utils/userStore.go
+++ b/internal/utils/userStore.go
@@ -4,78 +4,29 @@ import (
 	"context"
 
 	"git.defalsify.org/vise.git/db"
-	"git.defalsify.org/vise.git/lang"
 )
 
 type DataStore interface {
-	SetPrefix(prefix uint8)
-	SetSession(sessionId string)
-	Get(ctx context.Context, key []byte) ([]byte, error)
+	db.Db
 	ReadEntry(ctx context.Context, sessionId string, typ DataTyp) ([]byte, error)
 	WriteEntry(ctx context.Context, sessionId string, typ DataTyp, value []byte) error
-	Connect(ctx context.Context, connStr string) error
-	SetLanguage(*lang.Language)
-	Close() error
-	Prefix() uint8
-	Put(ctx context.Context, key []byte, val []byte) error
-	Safe() bool
-	SetLock(typ uint8, locked bool) error
 }
 
 type UserDataStore struct {
-	Store db.Db
-}
-
-func (store UserDataStore) SetPrefix(prefix uint8) {
-	store.Store.SetPrefix(prefix)
-}
-
-func (store UserDataStore) SetLanguage(lang *lang.Language) {
-	store.Store.SetLanguage(lang)
-}
-
-func (store UserDataStore) SetLock(typ uint8, locked bool) error {
-	return store.Store.SetLock(typ, locked)
-}
-func (store UserDataStore) Safe() bool {
-	return store.Store.Safe()
-}
-
-func (store UserDataStore) Put(ctx context.Context, key []byte, val []byte) error {
-	return store.Store.Put(ctx, key, val)
-}
-
-func (store UserDataStore) Connect(ctx context.Context, connectionStr string) error {
-	return store.Store.Connect(ctx, connectionStr)
-}
-
-func (store UserDataStore) Close() error {
-	return store.Store.Close()
-}
-
-func (store UserDataStore) Prefix() uint8 {
-	return store.Store.Prefix()
-}
-
-func (store UserDataStore) SetSession(sessionId string) {
-	store.Store.SetSession(sessionId)
-}
-
-func (store UserDataStore) Get(ctx context.Context, key []byte) ([]byte, error) {
-	return store.Store.Get(ctx, key)
+	db.Db
 }
 
 // ReadEntry retrieves an entry from the store based on the provided parameters.
-func (store UserDataStore) ReadEntry(ctx context.Context, sessionId string, typ DataTyp) ([]byte, error) {
-	store.Store.SetPrefix(db.DATATYPE_USERDATA)
-	store.Store.SetSession(sessionId)
+func (store *UserDataStore) ReadEntry(ctx context.Context, sessionId string, typ DataTyp) ([]byte, error) {
+	store.SetPrefix(db.DATATYPE_USERDATA)
+	store.SetSession(sessionId)
 	k := PackKey(typ, []byte(sessionId))
 	return store.Get(ctx, k)
 }
 
-func (store UserDataStore) WriteEntry(ctx context.Context, sessionId string, typ DataTyp, value []byte) error {
-	store.Store.SetPrefix(db.DATATYPE_USERDATA)
-	store.Store.SetSession(sessionId)
+func (store *UserDataStore) WriteEntry(ctx context.Context, sessionId string, typ DataTyp, value []byte) error {
+	store.SetPrefix(db.DATATYPE_USERDATA)
+	store.SetSession(sessionId)
 	k := PackKey(typ, []byte(sessionId))
-	return store.Store.Put(ctx, k, value)
+	return store.Put(ctx, k, value)
 }

From 9f034967b5032a43f287d5c6ef1479420c0437a4 Mon Sep 17 00:00:00 2001
From: Carlosokumu <carlosokumu254@gmail.com>
Date: Tue, 10 Sep 2024 12:32:19 +0300
Subject: [PATCH 47/47] remove resource directory

---
 cmd/main.go | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/cmd/main.go b/cmd/main.go
index c2878a9..fc734d4 100644
--- a/cmd/main.go
+++ b/cmd/main.go
@@ -112,18 +112,16 @@ func getEngine(cfg engine.Config, rs resource.Resource, pr *persist.Persister) *
 
 func main() {
 	var dbDir string
-	var resourceDir string
 	var size uint
 	var sessionId string
 	var debug bool
 	flag.StringVar(&sessionId, "session-id", "075xx2123", "session id")
 	flag.StringVar(&dbDir, "dbdir", ".state", "database dir to read from")
-	flag.StringVar(&resourceDir, "resourcedir", path.Join("services", "registration"), "resource dir")
 	flag.BoolVar(&debug, "d", false, "use engine debug output")
 	flag.UintVar(&size, "s", 160, "max size of output")
 	flag.Parse()
 
-	logg.Infof("start command", "dbdir", dbDir, "resourcedir", resourceDir, "outputsize", size)
+	logg.Infof("start command", "dbdir", dbDir, "outputsize", size)
 
 	ctx := context.Background()
 	ctx = context.WithValue(ctx, "SessionId", sessionId)
@@ -141,7 +139,7 @@ func main() {
 		FlagCount:  uint32(16),
 	}
 
-	rs, err := getResource(resourceDir, ctx)
+	rs, err := getResource(scriptDir, ctx)
 	if err != nil {
 		fmt.Fprintf(os.Stderr, err.Error())
 		os.Exit(1)