From e69e93f536dece0325202cb7c94f0ee2887e0a9b Mon Sep 17 00:00:00 2001 From: Barrett Ruth Date: Wed, 25 Feb 2026 13:03:40 -0500 Subject: [PATCH] feat(store): add recur and recur_mode task fields Problem: the task schema has no fields for storing recurrence rules. Solution: add recur and recur_mode to the Task class, known_fields, task_to_table, table_to_task, and the add() signature. --- lua/pending/store.lua | 16 +++++++++++++++- spec/store_spec.lua | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/lua/pending/store.lua b/lua/pending/store.lua index 5838414..4f3d2f1 100644 --- a/lua/pending/store.lua +++ b/lua/pending/store.lua @@ -7,6 +7,8 @@ local config = require('pending.config') ---@field category? string ---@field priority integer ---@field due? string +---@field recur? string +---@field recur_mode? 'scheduled'|'completion' ---@field entry string ---@field modified string ---@field end? string @@ -56,6 +58,8 @@ local known_fields = { category = true, priority = true, due = true, + recur = true, + recur_mode = true, entry = true, modified = true, ['end'] = true, @@ -81,6 +85,12 @@ local function task_to_table(task) if task.due then t.due = task.due end + if task.recur then + t.recur = task.recur + end + if task.recur_mode then + t.recur_mode = task.recur_mode + end if task['end'] then t['end'] = task['end'] end @@ -105,6 +115,8 @@ local function table_to_task(t) category = t.category, priority = t.priority or 0, due = t.due, + recur = t.recur, + recur_mode = t.recur_mode, entry = t.entry, modified = t.modified, ['end'] = t['end'], @@ -224,7 +236,7 @@ function M.get(id) return nil end ----@param fields { description: string, status?: string, category?: string, priority?: integer, due?: string, order?: integer, _extra?: table } +---@param fields { description: string, status?: string, category?: string, priority?: integer, due?: string, recur?: string, recur_mode?: string, order?: integer, _extra?: table } ---@return pending.Task function M.add(fields) local data = M.data() @@ -236,6 +248,8 @@ function M.add(fields) category = fields.category or config.get().default_category, priority = fields.priority or 0, due = fields.due, + recur = fields.recur, + recur_mode = fields.recur_mode, entry = now, modified = now, ['end'] = nil, diff --git a/spec/store_spec.lua b/spec/store_spec.lua index bb6266d..ebe4da1 100644 --- a/spec/store_spec.lua +++ b/spec/store_spec.lua @@ -196,6 +196,41 @@ describe('store', function() end) end) + describe('recurrence fields', function() + it('persists recur and recur_mode through round-trip', function() + store.load() + store.add({ description = 'Recurring', recur = 'weekly', recur_mode = 'scheduled' }) + store.save() + store.unload() + store.load() + local task = store.get(1) + assert.are.equal('weekly', task.recur) + assert.are.equal('scheduled', task.recur_mode) + end) + + it('persists recur without recur_mode', function() + store.load() + store.add({ description = 'Simple recur', recur = 'daily' }) + store.save() + store.unload() + store.load() + local task = store.get(1) + assert.are.equal('daily', task.recur) + assert.is_nil(task.recur_mode) + end) + + it('omits recur fields when not set', function() + store.load() + store.add({ description = 'No recur' }) + store.save() + store.unload() + store.load() + local task = store.get(1) + assert.is_nil(task.recur) + assert.is_nil(task.recur_mode) + end) + end) + describe('active_tasks', function() it('excludes deleted tasks', function() store.load()