Files
gems/opal-web/REQUIREMENTS.md
T
joakim 78881e1b07 feat: add parse endpoint, refactor recurring tasks, and improve web task completion
Extract CreateRecurringTask into engine package for reuse by both CLI
and API. Add POST /tasks/parse endpoint for CLI-style input parsing.
Remove FK constraint on change_log to preserve history after task
deletion. Update web frontend to filter completed tasks from view and
add mock mode support for development.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 23:49:20 +01:00

13 KiB
Raw Blame History

Opal Web — PWA Requirements

1. Problem Statement

The current opal-web PWA uses a conventional form-based UI for task management. This is misaligned with how opal actually works — opal is a CLI-first tool with a rich, expressive text syntax for creating, filtering, and modifying tasks.

The new design replaces the form-based approach with a CLI-passthrough interface: a single text input that accepts the same syntax as the opal CLI, making the web UI a thin, mobile-friendly shell over the existing command language.

Target users: Existing opal CLI users who want quick mobile/web access without learning a separate UI paradigm.


2. User Stories

US-1: Quick-add a task from mobile

As a user, I want to type Buy groceries due:tomorrow +errand into the input and have it create a task, so that I can capture tasks as fast as I do from the terminal.

Acceptance Criteria:

  • Given the input is focused and I type a description with modifiers
  • When I submit (Enter / tap send)
  • Then the raw input string is sent to the API, which parses it server-side
  • And a task is created with the parsed description, due date, and tags
  • And the input clears
  • And the new task appears in the list

US-2: Use property pills to build a command

As a user, I want to tap a Due pill above the input to insert due: at my cursor position, so that I don't have to remember every modifier name on mobile.

Acceptance Criteria:

  • Given the input is focused
  • When I tap the Due pill
  • Then due: is inserted at the cursor position in the input
  • And the keyboard stays open / input retains focus
  • And the cursor is placed immediately after the inserted text

US-3: View my pending tasks

As a user, I want to see my pending tasks in a list above the input, so that I have context for what I'm working on.

Acceptance Criteria:

  • Given I open the app
  • When the task list loads
  • Then I see pending tasks displayed in a compact list, sorted by urgency
  • And each task shows its description with inline metadata (project, priority, due date, tags) using subtle color coding

US-4: Complete a task via swipe

As a user, I want to swipe a task to the right to mark it done, so that I can quickly clear completed work.

Acceptance Criteria:

  • Given I see a task in the list
  • When I swipe the task to the right
  • Then a green background with a checkmark is revealed during the swipe
  • And on release past the threshold, the task is marked as completed
  • And the task animates out of the list

US-5: Complete a task via checkbox

As a user, I want to tap a checkbox on a task to mark it done, so that I have a familiar fallback when swiping is inconvenient.

Acceptance Criteria:

  • Given I see a task in the list
  • When I tap the checkbox/circle on the left side of the task
  • Then the task is marked as completed and animates out of the list

US-6: Filter tasks by report

As a user, I want to switch between different task views (pending, next, active, overdue, completed, etc.), so that I can focus on what's relevant.

Acceptance Criteria:

  • Given I am on the main task view
  • When I tap the filter/report button
  • Then a dropdown opens showing available reports
  • And selecting a report filters the task list accordingly

US-7: Access settings

As a user, I want to access a settings page, so that I can configure API connection, view sync status, and log out.

Acceptance Criteria:

  • Given I am on the main task view
  • When I tap the gear icon in the top-right corner
  • Then I navigate to a settings page
  • And I can navigate back to the task list

3. Functional Requirements

App Structure

ID Priority Requirement
F-00 MUST The app is a single-screen design: one main view with task list + input bar
F-01 MUST A separate settings page is accessible via a gear icon in the top-right corner
F-02 MUST No bottom navigation bar — the input bar occupies the bottom of the screen

Header

ID Priority Requirement
F-05 MUST The header contains the current report name (e.g., "Pending", "Next", "Overdue")
F-06 MUST The header contains a filter/report button that opens a dropdown of available reports
F-07 MUST The header contains a gear icon (top-right) linking to the settings page

Report Picker

ID Priority Requirement
F-08 MUST A dropdown/popover triggered by the filter button in the header
F-09 MUST Lists all available reports (see table below)
F-0A MUST Selecting a report reloads the task list with the corresponding filter
F-0B MUST The currently active report is visually indicated in the dropdown
F-0C SHOULD Default report on app open is "Pending"

Reports (all CLI reports):

Report Description
Pending All pending tasks (default)
Next Most urgent ready tasks (top N)
Active Currently started tasks
Ready Tasks with no future wait/scheduled date
Overdue Tasks past their due date
Completed Completed tasks
Waiting Tasks hidden until their wait date
Recurring Pending recurring task instances
Template Recurring template tasks
Newest Most recently created pending tasks
Oldest Oldest pending tasks

Input Bar

ID Priority Requirement
F-10 MUST A single-line text input is fixed to the bottom of the visible viewport, always visible
F-11 MUST The input accepts opal CLI syntax for the add command: description words, +tag, project:, due:, priority:, scheduled:, wait:, until:, recur:
F-12 MUST Submitting the input sends the raw string to the API for server-side parsing and task creation
F-13 MUST The input clears after successful submission
F-14 SHOULD The input bar remains above the mobile keyboard when the keyboard is open
F-15 MUST The input is add-only — it does not parse other CLI commands (done, modify, delete, etc.)

Property Pills

ID Priority Requirement
F-20 MUST When the input is focused, a row of tappable pills appears directly above the input
F-21 MUST Tapping a pill inserts its text at the current cursor position in the input
F-22 MUST After inserting, the input retains focus and the cursor is placed after the inserted text
F-23 MUST Pills disappear when the input loses focus
F-24 SHOULD The pill row is horizontally scrollable if it overflows

Pills (display order):

Pill label Inserts Notes
Due due: Date: tomorrow, mon, eod, 2025-03-15, 3d, etc.
Pri priority: H, M, L
Project project: Project name
Tag + Tag prefix — user types tag name after
Recur recur: Duration: 1d, 1w, 2w, 1m, daily, weekly, etc.
Scheduled scheduled: Same date format as due:
Wait wait: Same date format as due:
Until until: Same date format as due:

Task List

ID Priority Requirement
F-30 MUST The main view displays a scrollable list of tasks above the input bar, filtered by the active report
F-31 MUST Each task row shows: description, and inline metadata where set (project, priority, due date, tags)
F-32 MUST Task rows are compact — hybrid density with subtle color coding for priority and due dates, no full cards
F-33 MUST Swiping a task to the right marks it as completed
F-34 MUST Each task has a small checkbox/circle on the left that also completes the task on tap
F-35 MUST Swipe-to-complete reveals a green background with a checkmark icon during the swipe
F-36 SHOULD Tasks are sorted by urgency (matching the CLI's urgency calculation)
F-37 SHOULD Overdue due dates are visually distinct (red/warm color)
F-38 SHOULD Completed tasks animate out of the list (brief fade/slide)
F-39 COULD Pull-to-refresh to reload task list

4. Non-Functional Requirements

ID Category Requirement
NF-01 Mobile-first The UI must work well on 375px428px viewport widths (iPhone SE through Pro Max)
NF-02 Performance Task list should render within 100ms of data availability
NF-03 PWA The app must remain installable as a PWA with offline shell caching
NF-04 Keyboard The input bar must not be obscured by the mobile keyboard
NF-05 Touch Swipe gestures must have clear thresholds (no accidental triggers from scrolling)

5. Constraints & Assumptions

Constraints

  • Must use the existing SvelteKit + Vite + static adapter stack
  • Must work with the existing opal REST API (or mock mode for dev)
  • The opal API can be extended or reworked during the design phase to better support the new functionality

Assumptions

  • Users are familiar with opal CLI syntax or will learn it through the pills
  • The add command is the only command handled by the input bar
  • Parsing happens server-side — the frontend sends the raw input string to a new or updated API endpoint; no client-side replication of the opal parser
  • Completion is handled via swipe gesture or checkbox, not via the input bar

6. Open Questions

All previously open questions have been resolved:

# Question Resolution
Q1 How should the task list handle filtering/views? Reports are available via a filter button/dropdown in the header
Q2 Where should the settings link live? Top-right gear icon
Q3 Should swipe-to-complete show a visual indicator? Yes — green background with checkmark revealed during swipe
Q4 Should completed tasks be viewable? Yes — included as a report option in the filter dropdown
Q5 Which reports should the API support? All CLI reports (see Report Picker section)

Open for Design Phase

# Question Impact
Q6 What new API endpoint is needed for raw-string task creation? e.g., POST /tasks/parse accepting { "input": "Buy groceries due:tomorrow +errand" }. Affects backend and frontend contract
Q7 How should the API expose report-based queries? e.g., GET /tasks?report=next vs. dedicated endpoints per report. Some reports (next, ready, overdue) require server-side urgency/date logic. Affects API design

7. Design Notes

Items for the design phase to pay attention to:

Swipe vs. Scroll Conflict

Horizontal swipe-to-complete on a vertically scrolling list is a known UX challenge on mobile. The designer should define a clear gesture model:

  • Minimum horizontal displacement before the swipe "locks in" (vs. being interpreted as a scroll)
  • Whether the swipe requires a threshold to trigger, or if releasing mid-swipe cancels it
  • Consider a slight delay or angle detection to disambiguate

Input Bar and Mobile Keyboard

When the mobile keyboard opens, the input bar must stay visible above it. This is notoriously inconsistent across browsers/OS versions. Design should account for:

  • visualViewport API for keyboard-aware positioning
  • iOS Safari's quirks with position: fixed and the virtual keyboard
  • Whether the task list should shrink or scroll when the keyboard opens

Error Feedback from Parse Endpoint

If the server rejects the raw input string (e.g., invalid date due:neverday), how is the error communicated? Options:

  • Inline error message below the input bar (toast-style or persistent)
  • The input should NOT clear on failure (so the user can fix and retry)

Empty States

Each report may return zero results. Design should define empty states for:

  • First-time use (no tasks at all — should guide user toward the input)
  • Report with no matches (e.g., "No overdue tasks" — brief, non-alarming)

Report Picker Density

With 11 reports in the dropdown, the designer should consider whether all fit comfortably on a mobile screen without scrolling, or if grouping/sectioning is needed (e.g., "Active views" vs. "Archive views").


8. Out of Scope

  • OAuth/authentication flow redesign (handled separately; mock mode for dev)
  • Sync infrastructure changes
  • Offline task creation queue (existing implementation stays as-is)
  • Full CLI command passthrough (modify, delete, start, stop — add-only for now)
  • Task detail/edit view
  • Projects and Tags dedicated pages