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>
13 KiB
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
Duepill - 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 375px–428px 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
addcommand 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:
visualViewportAPI for keyboard-aware positioning- iOS Safari's quirks with
position: fixedand 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