# TIEASY — Pre-Implementation Inventory

**Status:** Analysis only. No application code written. Waiting for approval before Phase 1.

**Authorities**
- UI / visual: finalized Figma prototype (Tieasy Design File, page `159:1414`, starting node `350:6392`)
- Functional / technical: TIEASY Cursor Master Build Specification v1.0

---

## 1. Complete screen inventory

Wireframe screens that were actually opened in the prototype are marked **Seen**. Screens required by the spec but not present/wired in the prototype are marked **Missing in prototype (spec-required)**. Wireframe-only extras are marked **Wireframe extra**.

### 1.1 Authentication and onboarding

| ID | Screen | Wireframe title / copy | Prototype | Notes |
|---|---|---|---|---|
| S01 | Sign In | Heading **Sign In**. Field **Phone Number \***. Placeholder `+91 (555) 555 - 5555`. Button **Continue**. Link **Back to Home**. Hero illustration (person at window with calendar/mail). | Seen | Spec replaces Phone with Email. Keep this layout. |
| S02 | OTP Verification | Heading **OTP Verification**. Banner **OTP Sent Successfully** / `An OTP has been sent to +91 ******2345 for verification.` Label **Enter OTP**. **4** digit boxes. **Didn't receive the OTP? Resend**. Button **Continue**. Back chevron. Hero illustration (person + lock/keypad). | Seen | Spec: 6-digit email OTP, cooldown copy, email wording. |
| S03 | Profile onboarding | Heading **Let us serve you better!** Fields: Profile Name, Age Group, Gender, Occupation, Email. Buttons **Continue** and **Skip**. | Seen | No Phone field. Email is an editable input in the wireframe. Spec: Email read-only from verified login; add Phone. |
| S03a | Age Group dropdown | Under 16; 16-25; 25-35; 35-45; 45 Above | Seen | Spec uses a different list (see mismatches). |
| S03b | Gender dropdown | Male; Female; Other | Seen | Spec adds Non-binary and Prefer not to say. |

### 1.2 Dashboard and task lists

| ID | Screen | Wireframe title / copy | Prototype | Notes |
|---|---|---|---|---|
| S04 | Dashboard — empty cards | 2×2 Eisenhower cards with illustration + instructional copy + **+** on each card. Search **Search Tasks**. Filter chips **Today**, **Pending**, **All**. Header icons: calendar, list, grid. Bottom nav: Home, Analytics, Hamburger, **+**. | Seen | This is the empty/no-task card state. |
| S05 | Dashboard — populated | Same chrome. Each card header is colored with a chevron. Task rows show an AI attribution label + title. Footer **+ Add Task** per card. | Seen | AI label wording varies across frames (`Segregated by AI` / `Suggested by AI` / `Highlighted by AI*`). Spec removes it and requires Category • Date • Time then Title. |
| S06 | Priority detail / single-quadrant list | Header **Important & Urgent** (red). Same search + filters. Task rows, swipe complete/delete, **+ Add Task**. Kebab **Actions**. | Seen for Important & Urgent. Other three priorities are the same layout, not all hotspots wired. | Spec: do not repeat Priority on each row in this view. |
| S07 | Search results | Same list/card style as S06, heading = search text, rows include Priority. | **Missing in prototype (spec-required)** | Search field exists; results screen is not wired. |
| S08 | Edit Task | Same fields as Add Task. | **Missing in prototype** (Quick Guide says tap pending task to edit; tapping a row currently completes it in the prototype) | Spec Phase 5 includes Create/Edit. |

### 1.3 Create / recurrence

| ID | Screen | Wireframe title / copy | Prototype | Notes |
|---|---|---|---|---|
| S09 | Add Task | Title **Add Task**, close **X**. Task Title \* + mic. Due Date `dd/mm/yyyy`. Due Time `hh:mm`. Helper: *If left blank, the system sets the due date for today and due time for 23:59 of the present day.* Checkbox **Select to mark as recurring task**. Priority 2×2. Category dropdown (label misspelled **Cateogory**). **Save & Continue** / **Cancel**. | Seen | Spec: due date nullable; do not invent today/23:59. Priority and Category required; no AI auto-select. |
| S09a | Recurring — Daily | Daily / Weekly / Monthly pills. Copy: **Occurs on a daily basis.** | Seen | Spec requires every N days. Interval UI is missing on Daily. |
| S09b | Recurring — Weekly | Repeat every `[N]` week. Repeat on Mon–Sun (wireframe shows a duplicate **Sat** instead of **Sun**). Repeat at (time) `hh:mm`. Summary e.g. **Occurs every 2 weeks on Wednesday.** | Seen | Matches spec weekly model. |
| S09c | Recurring — Monthly | Repeat every `[N]` month. Repeat on: Day `[N]`; **Last day of the month**; **First** + weekday. Repeat at (time). Summary line. | Seen | Spec: day-of-month + weekday-position. “Last day of the month” is extra. No end-date control. |

### 1.4 Filters and overlays

| ID | Screen | Wireframe title / copy | Prototype | Notes |
|---|---|---|---|---|
| S10 | Date filter popover | Title **Due Date**. All Dates; Today (checked); This Week; Next 7 Days; This Month; Custom Date(s). | Seen | Spec also requires **Tomorrow**. Spec Custom Date = From + To. |
| S11 | Status filter popover | Title **Status**. All; Pending (checked); Completed. | Seen | Header **list** icon. Matches spec. |
| S12 | Category filter popover | Title **Categories**. All (checked); Home; Office. | Seen | Header **grid** icon. Spec: All Categories + user categories. |
| S13 | Custom date picker | From / To. | **Missing in prototype** (option exists, picker not wired) | Must be implemented. |
| S14 | Quadrant Actions menu | Title **Actions**. Delete All Tasks; Sort by End Date; Sort by Creation. | Seen | **Wireframe extra** — not in spec. |
| S15 | Hamburger (logged out) | Notifications; Category Manager; Settings; Contact Support; **Sign In** button + personalization helper text. | Seen | |
| S16 | Hamburger (logged in) | Same four items; button **Sign Out** (not “Logout”). | Seen | Spec requires **Logout**. |
| S17 | Swipe Complete | Checkmark revealed on task row. | Seen | Spec: complete this occurrence only. |
| S18 | Swipe Delete | Trash revealed on task row. | Seen | Spec: confirm; recurring gets two delete modes. |
| S19 | Recurring delete chooser | Delete this occurrence / Delete this and future occurrences. | **Missing in prototype (spec-required)** | |
| S20 | Non-recurring delete confirm | Confirm delete. | **Missing in prototype (spec-required)** | |

### 1.5 Analytics, notifications, categories, settings, support

| ID | Screen | Wireframe title / copy | Prototype | Notes |
|---|---|---|---|---|
| S21 | Analytics | Title **Analytics**. Intro: *View at a glance how you've been keeping up with completing tasks in hand. Click pies to see the list of tasks.* Filter chip **Today**. Insight carousel. Donut **Completed vs Pending Tasks**. Donut **Tasks by Priority**. Donut **Tasks by Cateogory**. Calendar date filter. | Seen | Spec requires the three charts with counts + percentages. Insight carousel and pie-click-to-list are extras. |
| S22 | Notifications list | In-app list, read/unread. | **Missing in prototype (spec-required)** | Menu item exists, not wired. Spec also adds a header bell. |
| S23 | Category Manager | Title **Manage Categories**. Intro copy. Rows: Home (System, edit only); Office (System, edit only); Lifestyle (User, edit + delete). Reorder icon. **Add New Category**. | Seen | Spec does not define System vs User categories. |
| S24 | Add / Edit Category sheet | **Add New Category**. Category Title \* + mic. **Save** / **Cancel**. | Seen | |
| S25 | Delete category alert | Title **Alert**. *There are 45 tasks associated with this category.* Radios: Delete all associated tasks; Move tasks in another category. Category picker. Helper about **Unknown**. **Yes** / **Go Back**. | Seen | **Wireframe extra** vs spec (spec only requires user-scoped delete). |
| S26 | Settings | Title **Settings**. Profile Information (Name, Age Group, Gender, Occupation, Email — no Phone). Settings / Personalization: View Mode Compact↔Full; Completed Task Behavior; Pending Task Reminder; **Quick Guide**. | Seen | Spec profile fields + Phone; Email read-only. Personalization block is extra. |
| S27 | Quick Guide modal | **Tieasy Quick Guide**. Eisenhower explanation, footer map, search/filter, swipe/long-press/drag/mic instructions. **Continue**. | Seen | **Wireframe extra**. |
| S28 | Contact Support | Title **Contact Support**. Intro copy. Profile Name \*; Email \*; Phone Number (optional); How can we help? \*; Message \*. **Submit Support Request**. | Seen | Spec: saved Name/Phone read-only when present; Email always read-only. |
| S28a | Support category dropdown | Technical Issue; Feature Request; Account Issue; General Inquiry; Feedback; Other | Seen | Spec seed list differs (see mismatches). |
| S29 | Support success | Confirmation after submit. | **Missing in prototype** | Add a minimal success/error state. |

### 1.6 Empty / error / loading states to add (least visual change)

| ID | State | Why |
|---|---|---|
| E01 | Unauthenticated default = Sign In, never Dashboard | Spec §3.1 |
| E02 | OTP errors | Incorrect / expired / too many attempts / resend too soon / send failure |
| E03 | Resend cooldown | `Resend OTP in 00:42` |
| E04 | Dashboard empty cards | Already in wireframe (S04) |
| E05 | Empty search results | Spec search screen with no matches |
| E06 | Empty notifications | Spec notifications |
| E07 | Empty category list | After user has no categories (if we do not seed System categories) |
| E08 | Validation errors on Add Task / Support / Profile | Required fields, CSRF, ownership |
| E09 | Email send failure | Spec OTP errors table |

---

## 2. Route inventory

Public (no session / no valid persistent token):

| Method | Route | Controller | Screen |
|---|---|---|---|
| GET | `/sign-in` | AuthController::index | S01 |
| POST | `/auth/send-otp` | AuthController::sendOtp | S01 → S02 |
| GET | `/auth/verify-otp` | AuthController::verifyForm | S02 |
| POST | `/auth/verify-otp` | AuthController::verifyOtp | S02 → S03 or S05 |
| POST | `/auth/resend-otp` | AuthController::resendOtp | S02 |
| GET | `/logout` | AuthController::logout | → S01 |

Authenticated:

| Method | Route | Controller | Screen |
|---|---|---|---|
| GET | `/` | redirect | unauth → `/sign-in`; new user → onboarding; else → `/dashboard` |
| GET/POST | `/profile/onboarding` | SettingsController::onboarding | S03 |
| GET | `/dashboard` | DashboardController::index | S04 / S05 |
| GET/POST | `/dashboard/filter` | DashboardController::filter (AJAX) | S04 / S05 |
| GET | `/tasks/search` | TaskController::search | S07 |
| GET | `/tasks/priority/{1-4}` | TaskController::byPriority | S06 |
| GET/POST | `/tasks/create` | TaskController::create | S09 |
| GET/POST | `/tasks/{id}/edit` | TaskController::edit | S08 |
| POST | `/tasks/occurrences/{id}/complete` | TaskController::complete (AJAX) | S17 |
| POST | `/tasks/occurrences/{id}/restore` | TaskController::restore (AJAX) | Quick Guide extra — defer unless approved |
| POST | `/tasks/occurrences/{id}/delete` | TaskController::deleteOccurrence | S19 / S20 |
| POST | `/tasks/{id}/delete-future` | TaskController::deleteThisAndFuture | S19 |
| GET | `/categories` | CategoryController::index | S23 |
| POST | `/categories` | CategoryController::store | S24 |
| POST | `/categories/{id}` | CategoryController::update | S24 |
| POST | `/categories/{id}/delete` | CategoryController::delete | S25 (simplified unless extra approved) |
| GET | `/analytics` | AnalyticsController::index | S21 |
| GET | `/notifications` | NotificationController::index | S22 |
| POST | `/notifications/{id}/read` | NotificationController::markRead (AJAX) | S22 |
| GET/POST | `/support` | SupportController::index/submit | S28 |
| GET | `/settings` | SettingsController::index | S26 |
| POST | `/settings/profile` | SettingsController::updateProfile | S26 |

Guards: `AuthFilter` on all authenticated routes. Unauthenticated hits redirect to `/sign-in`. After OTP, if `profile_onboarding_completed = 0`, force `/profile/onboarding`. Persistent token restores session then continues to Dashboard (or onboarding if still incomplete).

---

## 3. Click / action inventory

### Global chrome (authenticated)

| Control | Action |
|---|---|
| Bottom nav icon 1 (clipboard / home) | Open `/dashboard` |
| Bottom nav icon 2 (bar chart) | Open `/analytics` |
| Bottom nav icon 3 (hamburger) | Open overlay S15/S16 |
| Bottom nav icon 4 (**+** FAB) | Open Add Task with no preselected priority |
| Search field **Search Tasks** | Submit → `/tasks/search?q=` (cross-priority). Does **not** open a single priority. |
| Header calendar icon | Open Date filter S10 |
| Header list icon | Open Status filter S11 |
| Header grid icon | Open Category filter S12 |
| Filter chip **X** | Remove that filter; remaining filters stay combined |
| Header bell (spec add; not in wireframe) | Open `/notifications`; unread badge |

### Hamburger

| Item | Action |
|---|---|
| Notifications | `/notifications` |
| Category Manager | `/categories` |
| Settings | `/settings` |
| Contact Support | `/support` |
| Sign In (logged-out chrome only) | `/sign-in` |
| Logout (spec; wireframe label **Sign Out**) | Destroy session, revoke token/cookie, `/sign-in`. Back button must not show protected pages. |

### Auth

| Control | Action |
|---|---|
| Sign In **Continue** | Validate email, send 6-digit OTP, show S02 |
| **Back to Home** | Spec: unauthenticated home **is** Sign In. Treat as stay/refresh Sign In, or hide if it implies a public marketing page that does not exist. |
| OTP **Continue** | Verify hash, attempts, expiry. New user → S03. Onboarded user → S05. |
| **Resend** | Backend cooldown 60s, invalidate previous OTP, rate-limit ~5 / 30 min |
| Profile **Continue** / **Skip** | Set `profile_onboarding_completed = 1`, go Dashboard. Fields optional. |

### Dashboard / lists

| Control | Action |
|---|---|
| Quadrant header / chevron | Open that priority’s S06 |
| Card **+ Add Task** | Open S09 with that priority preselected |
| Task row tap | Open Edit Task (Quick Guide; implement as real edit, not complete-on-tap) |
| Swipe complete | Complete **this occurrence** only; drop from Pending immediately |
| Swipe delete | Confirm; if recurring, S19 two options |

### Add Task

| Control | Action |
|---|---|
| **X** / **Cancel** | Close without save |
| Mic | Wireframe extra — defer unless approved |
| Recurring checkbox | Reveal Daily / Weekly / Monthly |
| Daily / Weekly / Monthly | Show rule fields; generate parent + rule + ~90 days of occurrences |
| **Save & Continue** | Validate title, required priority + category; due time only if due date set |

### Categories / support / settings

| Control | Action |
|---|---|
| Add New Category | S24; unique per user |
| Edit pencil | S24 edit |
| Delete trash | Spec: user-scoped delete. Wireframe S25 extra unless approved |
| Support Submit | Snapshot Name/Email/Phone/category/message. **Do not** write back to `users` |
| Settings profile save | Update Name, Age Group, Gender, Occupation, Phone. Email stays read-only |

---

## 4. Mismatches: wireframe vs specification

### 4.1 Spec wins (keep the visual, change the behavior)

These are not redesigns. Spec §26: preserve visual design, follow the document for functional behavior.

| # | Topic | Wireframe | Spec | Implementation |
|---|---|---|---|---|
| M01 | Default entry | Prototype starts on Dashboard / Support depending on URL | Unauthenticated app **must** open Sign In | Correct entry |
| M02 | Sign-in identifier | Phone Number | Email Address | Same field chrome, Email label/placeholder |
| M03 | OTP channel copy | SMS / `+91 ******2345` | Email wording | Replace copy only |
| M04 | OTP length | 4 boxes | 6-digit | **Flagged** — 6 boxes in the same row (smallest visual change) |
| M05 | Resend | Link only, no timer | 60s countdown + backend limit | Add countdown under Resend |
| M06 | Profile Email | Editable input | Verified, read-only | Read-only field, same placement |
| M07 | Profile Phone | Absent | Optional, no phone OTP | Add field under Occupation with least disturbance |
| M08 | Age groups | Under 16; 16-25; 25-35; 35-45; 45 Above | Under 15; 15–24; 25–34; 35–44; 45–54; 55–64; 65+ | Spec list |
| M09 | Gender | Male, Female, Other | Male, Female, Non-binary, Prefer not to say, Other | Spec list |
| M10 | Hamburger auth action | Sign In / Sign Out | Logout when authenticated | Same button slot, label **Logout** (or keep **Sign Out** visually if you prefer — needs a one-word decision) |
| M11 | AI badges | Segregated / Suggested / Highlighted by AI | Remove completely | Remove |
| M12 | Task row metadata | AI label + title only | `Category • Due Date • Due Time` then Title; omit missing pieces; no empty separators | Spec layout inside existing card |
| M13 | Search rows | Not designed | Same as above **plus Priority** | Spec |
| M14 | Priority detail rows | No priority on row (good) | Do not repeat Priority | Matches |
| M15 | Due date blank | Defaults to today 23:59 | Nullable; never invent a date; no time without date | Remove/replace helper text |
| M16 | Priority / Category blank | AI picks or Unknown | Both **required** | Required; drop AI helper copy |
| M17 | Date filter | No Tomorrow; has All Dates | Today, Tomorrow, This Week, Next 7 Days, This Month, Custom From–To | Keep **All Dates** (spec allows an all-inclusive state for undated tasks). Add **Tomorrow**. |
| M18 | Notifications UI | Menu item only | Menu + small header bell + unread badge | Add bell unobtrusively top-right |
| M19 | Support field lock | All fields look editable | Saved Name/Phone read-only; Email always read-only | Same form, lock rules |
| M20 | Support categories | Feature Request, Account Issue, General Inquiry, Feedback | Technical Issue, Account/Login Issue, Task Management, Notification Issue, Feedback/Suggestion, Other | Spec seed (dropdown still database-driven) |
| M21 | Daily recurrence | “Occurs on a daily basis” only | Every N days | Add interval control when Daily is selected |
| M22 | Footer | Four icons, no labels | Exactly those four actions | Match |
| M23 | Mobile on desktop | iPhone frame | Mobile-app presentation on desktop | Centered phone-width shell |

### 4.2 Missing in wireframe (add with least visual disturbance)

| # | Missing | Plan |
|---|---|---|
| G01 | Notifications list + empty + read/unread | New screen using Settings/list visual language |
| G02 | Search results screen | Reuse S06 list; heading = query text |
| G03 | Recurring delete two-option dialog | New overlay |
| G04 | Non-recurring delete confirm | Simple confirm overlay |
| G05 | Custom From–To date picker | Overlay from S10 |
| G06 | OTP error messages + cooldown | Inline under OTP boxes |
| G07 | Header bell | Next to search/filter icons |
| G08 | Edit Task | Reuse Add Task chrome, prefilled |
| G09 | Empty search / notifications / support success | Minimal |
| G10 | Phone on onboarding and Settings | Extra field |

### 4.3 Wireframe extras — proposed DEFER unless you say otherwise

Clickable in the prototype or described in Quick Guide, but **not** in the Master Build Specification. Spec item 38: implement or explicitly defer.

| Extra | Recommendation |
|---|---|
| AI auto-priority / auto-category / Unknown fallback | **Defer** (conflicts with required fields and “no dummy AI”) |
| Voice / mic on title and category | **Defer** |
| Insight carousel on Analytics | **Defer** (charts still ship) |
| Click pie → task list | **Defer** |
| Compact / Full view mode | **Defer** |
| Move completed tasks to bottom | **Defer** (Completed filter already handles visibility) |
| Pending Task Reminder toggle | **Defer** (in-app due notifications still ship via cron) |
| Quick Guide | **Defer** |
| Delete All Tasks / Sort by End Date / Sort by Creation | **Defer** |
| Drag-and-drop / multi-select / long-press quadrant menu | **Defer** |
| Swipe-left restore completed → pending | **Defer** (spec complete is one-way except viewing Completed) |
| Calendar as a third *view* | **N/A** — header calendar is the Date **filter**, not a calendar page |
| System categories Home/Office (non-deletable) | **Needs your decision** — spec is user-scoped categories only, no system set |
| Category delete: delete-all vs move-to-another / Unknown | **Needs your decision** — spec only says delete category |
| Monthly “Last day of the month” | **Include** — small, fits monthly model, already drawn |
| Weekly duplicate Sat vs Sun | **Fix to Sun** — wireframe typo |
| “Cateogory” spelling | **Fix to Category** in UI copy |
| Sign In **Back to Home** | **Treat as no-op / stay on Sign In** unless you have a marketing page |

### 4.4 Genuine conflicts that need your yes/no

1. **OTP input: 4 boxes vs 6 digits.** Proposal: 6 boxes, same OTP screen.
2. **Hamburger button copy: Sign Out vs Logout.** Proposal: **Logout** (spec).
3. **System categories Home / Office.** Proposal: **do not seed system categories**; every user creates their own; first-run empty category manager with Add.
4. **Category delete when tasks exist.** Proposal: **block delete** if the category still has tasks, with a short message to recategorize first — unless you want the wireframe move/delete-all dialog.
5. **Wireframe extras list in §4.3.** Proposal: **defer all of them** except monthly last-day and typo fixes.
6. **Settings personalization block.** Proposal: **omit** Compact/Full, completed-to-bottom, reminder toggle, and Quick Guide in V1 so Settings is Profile only (plus the spec Phone field).

---

## 5. Proposed CI4 project / file structure

```
app/
  Config/
    Routes.php
    Filters.php
    Email.php
    App.php
  Controllers/
    AuthController.php
    DashboardController.php
    TaskController.php
    CategoryController.php
    AnalyticsController.php
    NotificationController.php
    SupportController.php
    SettingsController.php
  Models/
    UserModel.php
    EmailOtpModel.php
    UserLoginTokenModel.php
    CategoryModel.php
    TaskModel.php
    TaskRecurrenceModel.php
    TaskOccurrenceModel.php
    NotificationModel.php
    SupportCategoryModel.php
    SupportRequestModel.php
  Services/
    OtpService.php
    PersistentLoginService.php
    RecurrenceService.php
    NotificationService.php
  Filters/
    AuthFilter.php
    GuestFilter.php
  Views/
    layouts/
      mobile.php              # phone-width shell, header, footer
      guest.php               # Sign In / OTP / onboarding chrome
    auth/
      sign_in.php
      verify_otp.php
    profile/
      onboarding.php
    dashboard/
      index.php               # 4 cards empty + populated
      _task_row.php           # shared row partial
      _filter_bar.php
    tasks/
      priority.php            # single-quadrant list
      search.php              # cross-priority list
      create.php              # Add / Edit modal or page
      _recurrence_fields.php
      _delete_recurring.php
    categories/
      index.php
      _form.php
    analytics/
      index.php
    notifications/
      index.php
    support/
      index.php
    settings/
      index.php
  Database/
    Migrations/
      2026-xx-xx-create-users.php
      2026-xx-xx-create-email-otps.php
      2026-xx-xx-create-user-login-tokens.php
      2026-xx-xx-create-categories.php
      2026-xx-xx-create-tasks.php
      2026-xx-xx-create-task-recurrence-rules.php
      2026-xx-xx-create-task-occurrences.php
      2026-xx-xx-create-notifications.php
      2026-xx-xx-create-support-categories.php
      2026-xx-xx-create-support-requests.php
    Seeds/
      SupportCategorySeeder.php
    Commands/
      GenerateTaskOccurrences.php   # php spark tasks:generate-occurrences
      GenerateTaskNotifications.php # php spark tasks:notifications
public/
  index.php
  assets/
    css/app.css
    js/app.js                   # AJAX filters, swipe, search, CSRF
    js/analytics.js             # Chart.js
    img/
writable/
.env.example
composer.json
README.md
```

Stack (locked): CodeIgniter 4, PHP 8.2+, MySQL 8+, Bootstrap 5 where useful, vanilla JS/AJAX, Chart.js. **No React/Vue/Angular.**

Schema: exactly spec §18 (`users`, `email_otps`, `user_login_tokens`, `categories`, `tasks`, `task_recurrence_rules`, `task_occurrences`, `notifications`, `support_categories`, `support_requests`).

Build order: spec §24 phases 1–12.

---

## 6. Confirmation of rules

I will not redesign the UI. Wireframe owns layout, color, type, icons, and structure. Spec owns behavior. Where they clash, visual stays, behavior follows the spec, except the six decisions in §4.4.

### Recurrence
- Parent task + one recurrence rule + generated `task_occurrences`. No duplicate master tasks.
- Daily: every N days. Weekly: every N weeks + ≥1 weekday (1=Mon … 7=Sun). Monthly: day-of-month **or** First/Second/Third/Fourth/Last + weekday.
- Recurrence time optional; if absent, date-only occurrences.
- Generate ~90 days ahead; daily Spark command extends; skip duplicates. Non-recurring tasks get one occurrence.
- Completing one occurrence does **not** complete the series.
- Delete: (1) this occurrence; (2) this and future — keep history, set stop date, remove future generated rows.

### Search
- Does **not** open a single priority.
- Same list/card screen; heading is the query text.
- Case-insensitive partial match on Task Title, all four priorities, current user only.
- Honors active Date + Status + Category filters unless you later specify a clear-on-search flow (wireframe does not).
- Rows: Category • Date • Time, Title, **and Priority**.

### Authentication
- Email OTP, not phone. 6-digit, hashed, 10-minute expiry, 5 attempts, then resend.
- Resend invalidates the old OTP, 60s cooldown, ~5 sends / 30 minutes, enforced on the server.
- New user → optional Profile onboarding (Skip or Save both set `profile_onboarding_completed = 1`) → Dashboard.
- Returning onboarded user → Dashboard.
- All profile fields optional. Email read-only. Phone stored, not OTP-verified in V1.

### Persistent session
- CI4 session **plus** hashed long-lived token in HttpOnly cookie (Secure on HTTPS, SameSite).
- Not an immortal PHP session ID. Nothing secret in localStorage.
- If session is gone but cookie token is valid: restore session, open Dashboard.
- Logout: destroy session, revoke token, clear cookie, Sign In. Server-side auth on every protected URL. Back after logout does not reveal data.

### Task display
- Dashboard default: **Today + Pending + All Categories**.
- Four cards: 1 Important & Urgent; 2 Important, Not Urgent; 3 Not Important, Urgent; 4 Not Important, Not Urgent. Wireframe labels (`Important but Not Urgent`, `Not Important or Urgent`, etc.) stay as painted.
- No task counts unless the wireframe already shows them (it does not).
- Remove all “Suggested/Segregated/Highlighted by AI” copy.
- Normal card / priority detail: `Category • Due Date • Due Time` then Title; only pieces that exist; never empty bullets. Priority is **not** repeated in a single-priority view.
- Undated tasks are not given a fake date. Today/Tomorrow exclude them. **All Dates** may include them.
- Date, Status, and Category filters combine. AJAX where practical, still CSRF + ownership checked.
- Swipe Complete / Delete as specified.

---

## 7. Phase checklist (not started)

| Phase | Work | Status |
|---|---|---|
| 0. Inventory | This document | [Completed] |
| 1. Foundation | CI4, .env.example, DB, migrations, models, mobile layout, AuthFilter | [Completed] |
| 2. Authentication | Email OTP, resend, persistent login, logout | [Pending] |
| 3. Profile | Onboarding, Skip, Settings/Profile | [Pending] |
| 4. Categories | List/Add/Edit/Delete | [Pending] |
| 5. Tasks | Create/Edit, optional due date/time, priority, category | [Pending] |
| 6. Recurrence | Rules, occurrences, complete, both deletes | [Pending] |
| 7. Dashboard | Four cards, metadata, filters, remove AI copy | [Pending] |
| 8. Search | Cross-priority results + priority on rows | [Pending] |
| 9. Analytics | Three Chart.js sections | [Pending] |
| 10. Notifications | Bell, list, read, due cron | [Pending] |
| 11. Support/Settings | Categories, form snapshot, settings | [Pending] |
| 12. Audit | Wireframe-to-route + functional acceptance | [Pending] |

Waiting for approval of this inventory (especially §4.4) before Phase 1.
