# 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 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 `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