172 lines
7.4 KiB
C
172 lines
7.4 KiB
C
/* Trainlog Sleep Diary V1 domain API. */
|
|
#ifndef TRAINLOG_SLEEP_DIARY_H
|
|
#define TRAINLOG_SLEEP_DIARY_H
|
|
|
|
#include <stdbool.h>
|
|
#include <stddef.h>
|
|
|
|
#include "trainlog/database.h"
|
|
#include "trainlog/status.h"
|
|
|
|
#define TRAINLOG_SLEEP_EVENTS_MAX 64U
|
|
#define TRAINLOG_SLEEP_INTAKES_MAX 32U
|
|
#define TRAINLOG_SLEEP_NOTES_MAX 16384U
|
|
#define TRAINLOG_SLEEP_ENTRY_ID_CAPACITY 40U
|
|
#define TRAINLOG_SLEEP_REVISION_ID_CAPACITY 41U
|
|
#define TRAINLOG_SLEEP_EVENT_ID_CAPACITY 41U
|
|
#define TRAINLOG_SLEEP_TIMESTAMP_CAPACITY 64U
|
|
#define TRAINLOG_MEDICATION_NAME_CAPACITY 161U
|
|
#define TRAINLOG_MEDICATION_UNIT_CAPACITY 33U
|
|
#define TRAINLOG_MEDICATION_FORM_CAPACITY 65U
|
|
#define TRAINLOG_MEDICATION_NOTE_CAPACITY 513U
|
|
|
|
typedef struct TrainlogMedication {
|
|
char medication_id[41];
|
|
char revision_id[42];
|
|
char parent_revision_id[42];
|
|
char created_at[TRAINLOG_SLEEP_TIMESTAMP_CAPACITY];
|
|
char updated_at[TRAINLOG_SLEEP_TIMESTAMP_CAPACITY];
|
|
char name[TRAINLOG_MEDICATION_NAME_CAPACITY];
|
|
bool has_default_dose;
|
|
double default_dose_value;
|
|
char default_dose_unit[TRAINLOG_MEDICATION_UNIT_CAPACITY];
|
|
char form[TRAINLOG_MEDICATION_FORM_CAPACITY];
|
|
char note[TRAINLOG_MEDICATION_NOTE_CAPACITY];
|
|
bool active;
|
|
bool deleted;
|
|
} TrainlogMedication;
|
|
|
|
typedef struct TrainlogMedicationIntake {
|
|
char intake_id[42];
|
|
char medication_id[41];
|
|
char medication_name[TRAINLOG_MEDICATION_NAME_CAPACITY];
|
|
char taken_at[TRAINLOG_SLEEP_TIMESTAMP_CAPACITY];
|
|
bool has_dose;
|
|
double dose_value;
|
|
char dose_unit[TRAINLOG_MEDICATION_UNIT_CAPACITY];
|
|
unsigned int quantity;
|
|
char note[TRAINLOG_MEDICATION_NOTE_CAPACITY];
|
|
char created_at[TRAINLOG_SLEEP_TIMESTAMP_CAPACITY];
|
|
} TrainlogMedicationIntake;
|
|
|
|
typedef enum TrainlogSleepQuality {
|
|
TRAINLOG_SLEEP_QUALITY_UNSET = 0,
|
|
TRAINLOG_SLEEP_QUALITY_TB,
|
|
TRAINLOG_SLEEP_QUALITY_B,
|
|
TRAINLOG_SLEEP_QUALITY_MOY,
|
|
TRAINLOG_SLEEP_QUALITY_M,
|
|
TRAINLOG_SLEEP_QUALITY_TM
|
|
} TrainlogSleepQuality;
|
|
|
|
typedef enum TrainlogSleepEventType {
|
|
TRAINLOG_SLEEP_EVENT_BED_TIME = 0,
|
|
TRAINLOG_SLEEP_EVENT_FINAL_GET_UP,
|
|
TRAINLOG_SLEEP_EVENT_NIGHT_GET_UP,
|
|
TRAINLOG_SLEEP_EVENT_SLEEP,
|
|
TRAINLOG_SLEEP_EVENT_NAP,
|
|
TRAINLOG_SLEEP_EVENT_LONG_AWAKE,
|
|
TRAINLOG_SLEEP_EVENT_HALF_SLEEP,
|
|
TRAINLOG_SLEEP_EVENT_DAYTIME_SLEEPINESS
|
|
} TrainlogSleepEventType;
|
|
|
|
typedef enum TrainlogSleepPublicationStatus {
|
|
TRAINLOG_SLEEP_PUBLICATION_DRAFT = 0,
|
|
TRAINLOG_SLEEP_PUBLICATION_READY,
|
|
TRAINLOG_SLEEP_PUBLICATION_SYNCHRONIZED,
|
|
TRAINLOG_SLEEP_PUBLICATION_MODIFIED
|
|
} TrainlogSleepPublicationStatus;
|
|
|
|
typedef struct TrainlogSleepEvent {
|
|
char event_id[TRAINLOG_SLEEP_EVENT_ID_CAPACITY];
|
|
TrainlogSleepEventType type;
|
|
char start_at[TRAINLOG_SLEEP_TIMESTAMP_CAPACITY];
|
|
char end_at[TRAINLOG_SLEEP_TIMESTAMP_CAPACITY];
|
|
} TrainlogSleepEvent;
|
|
|
|
typedef struct TrainlogSleepDiaryEntry {
|
|
char entry_id[TRAINLOG_SLEEP_ENTRY_ID_CAPACITY];
|
|
char night_start_date[11];
|
|
char night_end_date[11];
|
|
char created_at[TRAINLOG_SLEEP_TIMESTAMP_CAPACITY];
|
|
char updated_at[TRAINLOG_SLEEP_TIMESTAMP_CAPACITY];
|
|
char revision_id[TRAINLOG_SLEEP_REVISION_ID_CAPACITY];
|
|
char parent_revision_id[TRAINLOG_SLEEP_REVISION_ID_CAPACITY];
|
|
TrainlogSleepQuality sleep_quality;
|
|
TrainlogSleepQuality wake_quality;
|
|
TrainlogSleepQuality day_form;
|
|
char treatment_and_notes[TRAINLOG_SLEEP_NOTES_MAX + 1U];
|
|
TrainlogSleepEvent events[TRAINLOG_SLEEP_EVENTS_MAX];
|
|
size_t event_count;
|
|
TrainlogMedicationIntake intakes[TRAINLOG_SLEEP_INTAKES_MAX];
|
|
size_t intake_count;
|
|
char validated_revision_id[TRAINLOG_SLEEP_REVISION_ID_CAPACITY];
|
|
char acknowledged_revision_id[TRAINLOG_SLEEP_REVISION_ID_CAPACITY];
|
|
TrainlogSleepPublicationStatus publication_status;
|
|
bool deleted;
|
|
} TrainlogSleepDiaryEntry;
|
|
|
|
typedef TrainlogStatus (*TrainlogSleepDiaryVisitor)(void *context,
|
|
const TrainlogSleepDiaryEntry *entry);
|
|
|
|
/* CONTRACT: timestamps are ISO-8601 instants carrying Z or a numeric offset.
|
|
* Intervals are ordered by absolute time, never lexically or by HH:MM. */
|
|
bool trainlog_sleep_diary_validate(const TrainlogSleepDiaryEntry *entry);
|
|
|
|
/* Creates one stable identity and initial immutable revision transactionally. */
|
|
TrainlogStatus trainlog_sleep_diary_create(TrainlogDatabase *database,
|
|
TrainlogSleepDiaryEntry *entry);
|
|
|
|
/* Replaces the complete current snapshot iff expected_revision is current.
|
|
* Exact replay of an already-current resulting revision is idempotent. */
|
|
TrainlogStatus trainlog_sleep_diary_update(TrainlogDatabase *database,
|
|
const char *expected_revision,
|
|
TrainlogSleepDiaryEntry *entry);
|
|
|
|
TrainlogStatus trainlog_sleep_diary_get(TrainlogDatabase *database,
|
|
const char *entry_id,
|
|
bool include_deleted,
|
|
TrainlogSleepDiaryEntry *output);
|
|
|
|
/* Dates are inclusive YYYY-MM-DD bounds; NULL means unbounded. */
|
|
TrainlogStatus trainlog_sleep_diary_list(TrainlogDatabase *database,
|
|
const char *start_date,
|
|
const char *end_date,
|
|
size_t limit,
|
|
TrainlogSleepDiaryVisitor visitor,
|
|
void *context);
|
|
|
|
/* Logical deletion is revision guarded and retained for sync replay safety. */
|
|
TrainlogStatus
|
|
trainlog_sleep_diary_delete(TrainlogDatabase *database,
|
|
const char *entry_id,
|
|
const char *expected_revision,
|
|
const char *deleted_at,
|
|
char output_revision[TRAINLOG_SLEEP_REVISION_ID_CAPACITY]);
|
|
|
|
/* Marks the guarded current revision as complete enough for the existing
|
|
* full-generation publisher. It remains editable and no transport is started. */
|
|
TrainlogStatus trainlog_sleep_diary_validate_revision(TrainlogDatabase *database,
|
|
const char *entry_id,
|
|
const char *expected_revision,
|
|
const char *validated_at);
|
|
|
|
typedef TrainlogStatus (*TrainlogMedicationVisitor)(void *context,
|
|
const TrainlogMedication *medication);
|
|
|
|
bool trainlog_medication_validate(const TrainlogMedication *medication);
|
|
TrainlogStatus trainlog_medication_create(TrainlogDatabase *database,
|
|
TrainlogMedication *medication);
|
|
TrainlogStatus trainlog_medication_update(TrainlogDatabase *database,
|
|
const char *expected_revision,
|
|
TrainlogMedication *medication);
|
|
TrainlogStatus trainlog_medication_get(TrainlogDatabase *database,
|
|
const char *medication_id,
|
|
bool include_deleted,
|
|
TrainlogMedication *output);
|
|
TrainlogStatus trainlog_medication_list(TrainlogDatabase *database,
|
|
bool include_inactive,
|
|
size_t limit,
|
|
TrainlogMedicationVisitor visitor,
|
|
void *context);
|
|
|
|
#endif
|