# AOLL — Task Backlog

Running list of everything still to do, so nothing is missed. Grouped by area and
roughly ordered. `[ ]` = pending, `[x]` = done. See [ARCHITECTURE.md](ARCHITECTURE.md)
for the full design, [USER_MANAGEMENT_PLAN.md](USER_MANAGEMENT_PLAN.md) for the
approved identity/roles/seats plan, and [README.md](../README.md) for current structure.

Legend: **P0** blocker · **P1** important · **P2** nice-to-have.

---

## ✅ Done so far (for context)
- [x] CI4 foundation: `.env`, clean URLs, asset porting to `public/assets`
- [x] Layouts (site / dashboard / auth) + server-rendered partials (nav, footer, sidebar, header)
- [x] All 31 front-end views ported from the design prototype (marketing, auth, dashboard)
- [x] Web controllers (`MarketingController`, `AuthPageController`, `DashboardController`)
- [x] Dynamic data layer: repository interfaces + Mock providers + fixtures, bound in `Config\Services`
- [x] REST API skeleton under `/api/v1` (read endpoints off Mock providers, JSON envelope, 501 writes)
- [x] Tab active-state (search / signals) driven by `?tab`
- [x] Full 34-page visual diff vs prototype (all within antialiasing tolerance)
- [x] php-cs-fixer configured + codebase conformant
- [x] Port the 5 design email templates into CI4 views (`Views/email/`) + 2 user-facing
      acknowledgement templates (contact-thanks, demo-thanks); welcome wired to
      signup + Google social register, contact/demo thanks wired to their submit endpoints

---

## 1. Front-end polish (Part A finish)
- [ ] **P1** Bind views to provider data (replace prototype's hardcoded rows with loops over
      `$companies`, `$brands`, `$agencies`, `$feed`, `$signals`, `$topics`, `$alerts`,
      `$workflows`, `$integrations`, `$plans`, `$users`, `$searches`). Per screen:
  - [ ] Home feed + intent rail (`dashboard`)
  - [ ] Advanced Search tables — companies / brands / agencies (`dashboard/search`)
  - [ ] Company detail — make dynamic by `id` (currently always Amazon) (`dashboard/company/(:num)`)
  - [ ] Signal Explorer + My Topics (`dashboard/signals`)
  - [ ] Saved searches + saved feed (`dashboard/saved`)
  - [ ] Alerts + email alerts (`dashboard/alerts`)
  - [ ] Workflows list + builder (`dashboard/workflows`)
  - [ ] Connectors catalog (`dashboard/connectors`)
  - [ ] Plan & Billing + comparison (`dashboard/plan`), Manage subscription (`dashboard/subscription`)
  - [ ] Users table (`dashboard/users`), Settings (`dashboard/settings`)
- [ ] **P2** Blog detail dynamic by slug (currently ignores the slug)
- [ ] **P2** Port the alternate landing page (`landing/landing.php`) — no route yet
- [ ] **P2** Universal search bar is currently decorative — wire to a search results view/endpoint
- [ ] **P2** Decide front-end data mode: keep server-side provider calls, or have page JS
      `fetch()` from `/api/v1` (the decoupled model). Wire whichever is chosen.

---

## 2. API — complete the REST surface (Part B)
- [ ] **P0** Implement write verbs (create / update / delete) — currently return 501
- [ ] **P1** Add remaining controllers: `Auth`, `Contact`, `Search`, `Subscription`,
      `Invoice`, `Setting`, `Connections`, `PaymentMethod`, `Ai`, `Webhook`
- [ ] **P1** List-endpoint pagination, filtering, sorting (query params → provider)
- [ ] **P1** Global JSON exception handler for `/api/*` (uncaught errors → JSON envelope)
- [ ] **P2** OpenAPI / API docs for the public (Enterprise "API Access") surface
- [ ] **P2** API rate limiting (`RateLimitFilter`) + throttling

---

## 3. Data & persistence (Part B)
- [ ] **P0** Decide data source (placeholder now) — Admedia feed / third-party / ingested (arch **D2**)
- [ ] **P0** MySQL schema: migrations for all tables (see ARCHITECTURE §6)
- [ ] **P0** Seeds: reference data (plans, integrations, intent topics) + demo dataset
- [ ] **P1** CI4 Models (one per table/aggregate) + typed Entities (Company, Contact, Signal, Plan, …)
- [ ] **P0** Swap Mock providers → `Api*`/DB providers in `Config\Services` (one line per domain)
- [ ] **P2** Data ingestion pipeline (if a real source is chosen)

---

## 4. Auth, tenancy & roles (Part B)

Plan: [USER_MANAGEMENT_PLAN.md](USER_MANAGEMENT_PLAN.md) — self-signup → **limited**
preview → **platform superadmin approve** → solo **workspace admin**; **1 seat** on
Starter/Professional/Intelligence; **team management** (Users UI, invites, roles) on
**Enterprise only**.

### Sprint UM-1 — Schema + Shield + signup
- [ ] **P0** Install & configure CodeIgniter Shield *(blocked: composer dev-deps; using extended `aoll_users` for now)*
- [x] **P0** Schema SQL: `aoll_organizations`, user `account_status` + `role`, `aoll_audit_logs` (`docs/sql/`)
- [x] **P0** Signup creates org + user (`limited`, `role=admin`, org `seat_limit=1`)
- [x] **P0** Session: `org_id`, `role`, `account_status`, `plan_tier`, `can_manage_team`
- [ ] **P1** Migrate existing `aoll_users` → orgs *(manual SQL backfill in `docs/sql/` when needed)*

### Sprint UM-2 — Limited access + superadmin approval
- [x] **P0** `AccountStatusFilter` — preview caps while `account_status=limited`
- [x] **P0** Platform superadmin approval queue (admin console)
- [x] **P0** Approve → `active` + notification email; reject → `inactive`
- [x] **P1** Limited-dashboard banner; block billing/search/export until approved
- [x] **P1** Audit log for superadmin approve/reject
- [x] **P1** Notify superadmin on new signup (email to platform superadmins)

### Sprint UM-3 — Auth hardening + filters *(deferred — web-only phase)*
- [ ] **P1** REST `/api/v1` + filters (`ApiAuth`, `Tenant`, `Role`, CORS, Bearer tokens)
- [ ] **P0** Shield integration *(deferred — custom auth)*
- [ ] **P1** Work-email blocklist; bcrypt; reset token hardening *(deferred)*

### Sprint UM-4 — Entitlements + seat limits
- [x] **P0** `EntitlementService` feature map includes `team_management` (Enterprise only)
- [x] **P0** `EntitlementFilter` — route map in `Config/EntitlementRoutes.php`; 402 JSON / redirect to plan
- [ ] **P0** Enforce `seat_limit=1` on S/P/I — block `POST /api/v1/users`
- [x] **P1** Hide `/dashboard/users` nav unless Enterprise (+ upgrade CTA via locked nav)
- [ ] **P1** Domain dedup on signup (same `@company.com` → existing org rules)
- [ ] **P1** Checkout/billing only when `account_status=active` (with Stripe sprint)

### Sprint UM-5 — Enterprise team management
- [x] **P1** `user_invitations` + invite accept flow
- [ ] **P1** `/api/v1/users` CRUD (Enterprise admin only)
- [x] **P1** Wire `/dashboard/users` — roles Admin/Manager/Member/Viewer
- [x] **P1** Seat limit on invite; protect last admin from deletion
- [ ] **P1** PHPUnit: approval flow, seat gate, Enterprise-only team API

---

## 5. Entitlements & billing (Part B)
- [x] **P1** `EntitlementService` + plan → feature map (free-vs-paid tiering table)
- [x] **P1** `EntitlementFilter` — gate tier-locked endpoints, return 402 + upgrade hint
- [x] **P1** `UsageService` + `usage_counters` SQL (`docs/sql/2026-07-29_usage_counters_and_plan_limits.sql`)
- [x] **P1** Sticky.io billing Phase 1 — subscribe/cancel, mock gateway, checkout UI (`docs/BILLING_STICKY.md`)
- [x] **P1** Billing Phase 1 polish — emails, upgrade/downgrade, promos, webhooks, demo banner
- [ ] **P1** Sticky live: set HTTP creds + `planOffers` in `StickyBilling.php`, replace placeholder campaign ids, `mockMode = false`
- [ ] **P1** Sticky webhooks — signature verification + production IPN credentials
- [ ] **P2** Plan change at next billing cycle; dunning / failed-payment flow

---

## 6. Integrations, workflows, alerts, email (Part B)
- [ ] **P1** Connectors: real Salesforce / HubSpot / webhook push; OAuth connect; encrypted token storage
- [ ] **P1** `WorkflowEngine` + scheduled runner (`spark tasks:run` via cron) + `workflow_runs` log
- [ ] **P1** `AlertService` + `NotificationService` (in-app + email); email alerts from saved-search alerts
- [ ] **P1** Email: CI4 Email + transactional sends — welcome / contact-thanks / demo-thanks
      wired; still to wire: payment ok, payment failed, subscription reactivated, signup-no-subscription
- [ ] **P1** AI provider decision (Claude assumed — arch **D4**)
- [ ] **P1** `AiInsightService`: AI opportunity insights + outreach generation (Intelligence tier, gated)

---

## 7. Quality, infra & ops
- [ ] **P1** PHPUnit tests: controllers, services, API endpoints (envelope + status codes)
- [ ] **P2** CI pipeline (lint + tests + cs-fixer check)
- [ ] **P1** Production `.env` + deploy config; point web server at `public/`
- [ ] **P2** Security review (CSRF for web forms, API auth, input validation, secrets handling)
- [ ] **P2** CORS config if front-end is served from a different origin
- [ ] **P2** Logging / error monitoring in production

---

## 8. Open decisions (from ARCHITECTURE §12)
- [ ] **D2** Data source (placeholder now) — **P0** before real data work
- [ ] **D3** Payments provider (Stripe assumed)
- [ ] **D4** AI provider (Claude assumed)
- [ ] **D6** Module packaging — standard `app/` tree (current) vs full HMVC modules
- [x] **D1** Front-end shape — resolved: server-rendered CI4 pages
- [x] **D5** Tenancy scope — resolved: saved searches / workflows / alerts shared across org
- [x] **D7** User lifecycle — resolved: signup → limited → superadmin approve → solo admin
- [x] **D8** Seats & team UI — resolved: S/P/I = 1 seat; team management = Enterprise only

---

## Notes / watch-list
- Views are **faithful static ports**; the data layer is wired but most screens don't
  consume it yet (see §1). This is intentional for the front-end phase.
- All forms are **UI-only** (no submit handling) — matches the prototype; real handling is Part B.
- IDE shows PEAR-style docblock / `<?=` warnings from a linter that is **not** this
  project's standard; php-cs-fixer (the real standard) reports clean.
