Compare commits
4 Commits
Author | SHA1 | Date | |
---|---|---|---|
d4b7833a5e | |||
f338aea288 | |||
a1103f0974 | |||
7e9d876297 |
@ -1,3 +1,6 @@
|
|||||||
|
// Package config handles the configuration aspects of the KetoTrack application.
|
||||||
|
// It includes definitions and routines necessary for setting up and retrieving
|
||||||
|
// application configuration settings, such as data storage paths.
|
||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -5,15 +8,23 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// AppConfig holds configuration details for the application. It currently
|
||||||
|
// only includes the path to the data storage location.
|
||||||
type AppConfig struct {
|
type AppConfig struct {
|
||||||
DataPath string
|
DataPath string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load initializes the application configuration by ensuring the required
|
||||||
|
// directories exist and setting the path for data storage. It creates a
|
||||||
|
// directory named ".ketotrack" in the user's home directory if it does not already
|
||||||
|
// exist, and sets the data path to "records.json" within this directory.
|
||||||
|
// The function loads these settings into an AppConfig instance and returns it.
|
||||||
func Load() AppConfig {
|
func Load() AppConfig {
|
||||||
// TODO: Handle os.MkdirAll error gracefully
|
// TODO: Handle os.UserHomeDir errors
|
||||||
|
// TODO: Handle os.MkdirAll errors
|
||||||
homeDir, _ := os.UserHomeDir()
|
homeDir, _ := os.UserHomeDir()
|
||||||
ketotrackDir := filepath.Join(homeDir, ".ketotrack")
|
ketotrackDir := filepath.Join(homeDir, ".ketotrack")
|
||||||
os.MkdirAll(ketotrackDir, 0770) // handle error appropriately
|
os.MkdirAll(ketotrackDir, 0770)
|
||||||
return AppConfig{
|
return AppConfig{
|
||||||
DataPath: filepath.Join(ketotrackDir, "records.json"),
|
DataPath: filepath.Join(ketotrackDir, "records.json"),
|
||||||
}
|
}
|
||||||
|
25
data/data.go
25
data/data.go
@ -1,3 +1,7 @@
|
|||||||
|
// Package data manages the loading, saving, and manipulation of application data
|
||||||
|
// pertaining to health tracking. It provides an abstraction layer over the storage
|
||||||
|
// mechanism used for persisting records and offers convenient methods to interact
|
||||||
|
// with the data.
|
||||||
package data
|
package data
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -6,12 +10,17 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
// AppContext is the application data store that holds Records
|
// AppContext represents the application's data context, encapsulating the storage
|
||||||
|
// and management of health-related records. It provides mechanisms to load and save
|
||||||
|
// these records from a persistent storage.
|
||||||
type AppContext struct {
|
type AppContext struct {
|
||||||
Records []model.Record
|
Records []model.Record
|
||||||
dataPath string
|
dataPath string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewContext initializes a new application data context with the specified data
|
||||||
|
// path. It attempts to load existing records from the provided data path, or
|
||||||
|
// initializes an empty context if the records do not exist.
|
||||||
func NewContext(dataPath string) (AppContext, error) {
|
func NewContext(dataPath string) (AppContext, error) {
|
||||||
ctx := AppContext{dataPath: dataPath}
|
ctx := AppContext{dataPath: dataPath}
|
||||||
err := ctx.LoadRecords()
|
err := ctx.LoadRecords()
|
||||||
@ -21,7 +30,9 @@ func NewContext(dataPath string) (AppContext, error) {
|
|||||||
return ctx, nil
|
return ctx, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadRecords will load records from file
|
// LoadRecords loads the records from the data file specified in the AppContext.
|
||||||
|
// If the records file does not exist, it initializes an empty record list and
|
||||||
|
// saves it to create the file.
|
||||||
func (ctx *AppContext) LoadRecords() error {
|
func (ctx *AppContext) LoadRecords() error {
|
||||||
data, err := os.ReadFile(ctx.dataPath)
|
data, err := os.ReadFile(ctx.dataPath)
|
||||||
|
|
||||||
@ -37,7 +48,9 @@ func (ctx *AppContext) LoadRecords() error {
|
|||||||
return json.Unmarshal(data, &ctx.Records)
|
return json.Unmarshal(data, &ctx.Records)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SaveRecords will save records to a file
|
// SaveRecords serializes the current records to JSON and writes them to the
|
||||||
|
// data path specified in the AppContext. It ensures data persistence with
|
||||||
|
// appropriate access permissions.
|
||||||
func (ctx *AppContext) SaveRecords() error {
|
func (ctx *AppContext) SaveRecords() error {
|
||||||
jsonData, err := json.Marshal(ctx.Records)
|
jsonData, err := json.Marshal(ctx.Records)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -46,12 +59,14 @@ func (ctx *AppContext) SaveRecords() error {
|
|||||||
return os.WriteFile(ctx.dataPath, jsonData, 0660)
|
return os.WriteFile(ctx.dataPath, jsonData, 0660)
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddReading will add a Reading to the AppContext
|
// AddReading appends a new Reading record to the AppContext. It updates the
|
||||||
|
// application context's records with the latest readings data.
|
||||||
func (ctx *AppContext) AddReading(reading model.Reading) {
|
func (ctx *AppContext) AddReading(reading model.Reading) {
|
||||||
ctx.Records = append(ctx.Records, model.Record{Reading: &reading})
|
ctx.Records = append(ctx.Records, model.Record{Reading: &reading})
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddNote will a add a Note to the AppContext
|
// AddNote appends a new Note record to the AppContext. It updates the
|
||||||
|
// application context's records with the newly added note.
|
||||||
func (ctx *AppContext) AddNote(note model.Note) {
|
func (ctx *AppContext) AddNote(note model.Note) {
|
||||||
ctx.Records = append(ctx.Records, model.Record{Note: ¬e})
|
ctx.Records = append(ctx.Records, model.Record{Note: ¬e})
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,22 @@
|
|||||||
|
// Package model defines the data structures and associated functions used to represent
|
||||||
|
// and manipulate the health data in the application. This includes defining formats for data entries,
|
||||||
|
// calculations relevant to the metabolic tracking, and utilities for creating and handling these data
|
||||||
|
// structures. This package serves as the central definition point for all data used in the application.
|
||||||
package model
|
package model
|
||||||
|
|
||||||
import "time"
|
import "time"
|
||||||
|
|
||||||
// Note holds a text note along with the time the note was taken.
|
// Note represents a text note marked with the time it was taken.
|
||||||
|
// This structure can be used to store and retrieve anecdotal information that
|
||||||
|
// may be relevant to the health data being tracked.
|
||||||
type Note struct {
|
type Note struct {
|
||||||
Time time.Time `json:"time"`
|
Time time.Time `json:"time"`
|
||||||
Text string `json:"text"`
|
Text string `json:"text"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewNote returns a new Note
|
// NewNote creates a new Note instance with the current time and the provided text.
|
||||||
|
// The function is a constructor for Note type, allowing quick instantiation with
|
||||||
|
// automated timestamping.
|
||||||
func NewNote(text string) Note {
|
func NewNote(text string) Note {
|
||||||
return Note{
|
return Note{
|
||||||
Time: time.Now(),
|
Time: time.Now(),
|
||||||
@ -16,16 +24,20 @@ func NewNote(text string) Note {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reading holds the glucose and ketone level measurements along with the time the measurements were taken.
|
// Reading contains measurements for glucose and ketone levels taken at a specific time.
|
||||||
|
// Each Reading instance also calculates the Glucose Ketone Index (GKI),
|
||||||
|
// a key metric for managing metabolic health.
|
||||||
type Reading struct {
|
type Reading struct {
|
||||||
Time time.Time `json:"time"`
|
Time time.Time `json:"time"`
|
||||||
Glucose float64 `json:"glucose"`
|
Glucose float64 `json:"glucose"`
|
||||||
Ketone float64 `json:"ketone"`
|
Ketone float64 `json:"ketone"`
|
||||||
GKI float64 `json:"GKI"`
|
GKI float64 `json:"gki"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewReading creates and returns a new Reading instance with the provided glucose and ketone levels, and records
|
// NewReading creates a new Reading instance capturing the current time, glucose level,
|
||||||
// the current time. The glucose value should be provided in mg/dL, while the ketone level should be in mmol/L.
|
// and ketone level. It also calculates the Glucose Ketone Index (GKI) based on the provided
|
||||||
|
// measurements. Glucose values should be in mg/dL and ketone levels in mmol/L.
|
||||||
|
// If the ketone level is zero, the GKI is set to zero to prevent division by zero.
|
||||||
func NewReading(glucose, ketone float64) Reading {
|
func NewReading(glucose, ketone float64) Reading {
|
||||||
var gki float64
|
var gki float64
|
||||||
if ketone == 0 {
|
if ketone == 0 {
|
||||||
@ -42,7 +54,10 @@ func NewReading(glucose, ketone float64) Reading {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Record holds a pointer to a Reading or Note.
|
// Record represents a container that can hold either a Reading or a Note, but not both.
|
||||||
|
// This type is used to conglomerate different types of entries in a unified format.
|
||||||
|
// Each Record uses JSON tags to properly encode or decode either a Reading or a Note,
|
||||||
|
// with omitted fields left out of the serialized form.
|
||||||
type Record struct {
|
type Record struct {
|
||||||
Reading *Reading `json:"reading,omitempty"`
|
Reading *Reading `json:"reading,omitempty"`
|
||||||
Note *Note `json:"note,omitempty"`
|
Note *Note `json:"note,omitempty"`
|
||||||
|
Loading…
Reference in New Issue
Block a user