Commit graph

7 commits

Author SHA1 Message Date
932655e4c6 add placeholder tasks.png tile
Generated 256x256 checkmark on indigo. Fixes the 404 on
/tasks/static/image/tasks.png observed in lnbits logs. Real branding
to come.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 20:08:14 +02:00
daf352c136 bump version to 0.0.1 for first tagged release v0.0.1
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 19:47:33 +02:00
7362592880 make tasks migration idempotent and fix sqlite index syntax
m001 was leaving partial state on first boot: CREATE TABLE succeeded
but `CREATE UNIQUE INDEX ... ON tasks.tasks (...)` failed silently in
sqlite (schema prefix on the target table, not the index name, is not
what sqlite expects for ATTACHed databases). Because LNbits never
recorded the migration version, every restart retried m001 and crashed
on `CREATE TABLE tasks already exists`.

Two fixes:
- Use IF NOT EXISTS on every CREATE so a partial run is safe to re-run.
- Schema-prefix the index *name*, not the target table:
  `CREATE INDEX tasks.idx ON tbl (...)` instead of `CREATE INDEX idx ON tasks.tbl (...)`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 13:33:35 +02:00
48a63c0338 add API routes, admin UI, and SPA bootstrap
views_api wires the full task lifecycle: create / update / delete /
list (per-wallet, public, admin-all) and the completion flow (claim /
start / complete via POST, unclaim via DELETE, plus a "mine" lookup
for the current user's claim on a task or specific occurrence).

Auth model: tasks are owned by an LNbits wallet but signed with the
wallet owner's account.pubkey — _wallet_pubkey resolves that pubkey at
create time and refuses to create tasks for accounts that haven't
generated a keypair yet, so we never publish a task we can't sign.

Completions optimistically insert with a local hash, publish to Nostr,
then re-insert under the actual event id so a later delete can find it.

Static SPA: Quasar-UMD index.vue / index.js mirroring the events
extension layout — wallet picker, task table, create/edit dialog with
optional daily/weekly recurrence, plus an admin-only public_listing
toggle. /tasks/:id and display.vue intentionally left out until the
public task page lands.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 11:43:59 +02:00
24acbe6674 add Nostr publishing and bidirectional sync
- nostr/ vendors NostrEvent + the nostrclient WebSocket bridge from
  the events extension, retagged [TASKS] / subscription-id "tasks-*".
- nostr_publisher builds kind 31922 with the `event-type: task` tag
  (per aiolabs/webapp#25 — disambiguates from kind-31922 activities on
  shared relays), kind 31925 with task-status / occurrence /
  completed_at, and kind 5 deletions for both.
- nostr_hooks bridges task/completion mutations to the publisher and
  persists the resulting nostr_event_id back onto the local row.
- nostr_sync subscribes to {31922, 31925, 5/#k} and filters 31922
  client-side on `event-type: task` because most relays don't index
  custom single-letter tags.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 11:38:42 +02:00
6fbb6d4a42 add models, migrations, and CRUD
Schema mirrors the webapp tasks module's ScheduledEvent + EventCompletion
shape:

- tasks.tasks (NIP-52 kind 31922 cache): (pubkey, d_tag) is the
  parameterized-replaceable key. JSON-encoded participants / categories
  / recurrence columns are decoded on read via _parse_task_row so each
  model can keep clean field validators.
- tasks.completions (kind 31925 cache): unique on
  (task_address, pubkey, occurrence). occurrence is NULL for one-shot
  tasks; create_completion deletes any prior claim for the same triple
  so the latest event wins.
- tasks.settings: singleton row with public_listing toggle.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 11:36:13 +02:00
bc88b421b6 scaffold tasks extension
Empty skeleton mirroring the events extension layout: config/manifest,
pyproject + Makefile + ruff/mypy config, FastAPI routers wired into
tasks_ext, NostrClient bootstrap stubs, and an empty static/routes.json.

Models, migrations, CRUD, Nostr publisher/sync, and the API/template
layers land in follow-up commits.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 11:34:04 +02:00