Skip to main content

Database Schema

The Convex backend defines 10 tables organized around a domain-driven design. Each table includes extensive indexing for high-performance queries.

Core Tables

tasks

The master commitment definitions. Each task represents a recurring accountability contract created by a user.
Indexes: by_assignee_id, by_assigner_id, by_created_at, by_updated_at

taskInstances

Individual occurrences of commitments. Generated from recurrence rules and snapshotted with the parent task’s penalty/waiver configuration at creation time.
Immutable Snapshots: The penalty and penalty_waiver fields on instances are FROZEN copies from the parent task. They are never updated, even if the user later edits the task. This prevents retroactive contract manipulation (e.g., setting ₹500 penalty → failing → quickly editing to ₹10).
Key fields: Indexes: by_task, by_task_end, by_assignee, by_assignee_start, by_status, by_task_status, by_assignee_status, by_start, by_end

The Steel Vault (Strict Mode)

When strict_until is set on an instance, the backend rejects all mutations (edits, deletions) until that timestamp passes:

Waiver Lifecycle

The waiver_state object tracks the progression of a second-chance challenge: The penalty_job_id field stores the ID of a Convex durable scheduled function — the “bomb” that fires the penalty when the waiver deadline expires. The only way to defuse it is by completing the waiver challenge, which calls ctx.scheduler.cancel(waiver_state.penalty_job_id).

Preset Tables

accountabilityPresets

Persistent “contract templates” that remember a user’s preferred penalty and waiver settings. Used for zero-friction task creation.

locationPresets

Saved locations with GPS coordinates and radius. Indexed by recency and popularity for smart suggestions.

digitalCommitmentPresets

Saved app/website blocking lists. Named presets like “Social Media Block” for quick reuse.

behavioralRulePresets

Saved verification configurations (check-in style, alarm timing, grace periods).

Security Tables

userDevices

Maps authenticated users to physical device signatures (Android SSAID). Prevents “Account Switching” bypass attempts:

auditLogs

Central ledger for all user events — successes, failures, executed penalties. Powers the frontend notification feed and history dashboard.

files

Unified asset registry for all binary files (photos, videos). Single-table design for unified security, performance, and garbage collection.

Backend Architecture

Domain-Driven Structure

Self-Healing Watchdog

A hourly cron job scans all tasks and detects “orphaned” instances — those with status: pending but no linked scheduled_job_id. When found, it automatically re-links them to a new durable scheduled function: