Roadmap
Eight phases, built in order (including 2b, Cases). Phase 1 is a useful CRM on its own (contacts, companies, segments, forms and the Newsletter element feeding it), and each later phase adds a module on top of the same contact record and activity timeline. Phase 1 starts by renaming the Newsletter / Subscriber CRM to CRM and reorganizing it: its working parts (the email builder, campaigns, the sender, lists, tags and segments) carry over, and everything that pointed at the old name moves in the same release.
Verified against the extension source on 2026-10-15.
Phase 1 · Contacts and companiesDone
23/23The record everything else hangs on. A contact is a person with an owner, a lifecycle stage, custom fields and a timeline, linked to companies, sorted by lists, tags and rule-based segments. Privacy, consent and team roles are built in here, once, so no later module can skip them.
- Rename to CRM and reorganize — Done
The Newsletter / Subscriber CRM becomes the CRM: folder
newsletter-crmbecomescrm, with its repository, settings, hooks and connector tool names renamed to match (no data to migrate; its tables are alreadyfw_crm_*). Its working parts are kept and moved into the new layout rather than rewritten: the email builder, campaigns and the batched sender, lists, tags and segments, double opt-in and the preference page, the contact form action, the Newsletter element listener, the privacy tools and the AI connector tools. Everything that pointed at the old name moves in the same release: the Site Converter, Visitor Insights, theforms-addtool and the CRM website generator. - CRM app shell — Done
The CRM gets its own interface inside wp-admin: a CRM sidebar (Home, Contacts, Companies, Calendar, Deals, Tasks, Campaigns, Automations, Reports, Settings) and a top bar with search and quick add. Opening the CRM folds the WordPress menu to its icons; a focus mode hides it with a Back to WordPress link, and a sales rep can land there straight after logging in.
- Extension scaffold — Done
manifest.php, the extension class and a settings screen under Unyson+ → CRM. Ships inactive; downloaded from the Extensions manager. - Tables and migrations — Done
Contacts, companies, contact-company links, custom field values, tags and lists, segment definitions and the activity log, each indexed for the screens that read them. Versioned installer with
migrate(); tables are never dropped on deactivation. Every later change to the tables goes through a numbered migration, so sites update in place. The busiest values (owner, company, lifecycle stage, source, timezone, score, lifetime value, last activity) are real columns on the contact row, so segments stay simple, fast queries. - Modules — Done
A small core that is always on, and modules switched on from a Modules screen of cards: companies, sales pipeline, calendar, email conversations, email marketing, audit log and webhooks, with automations, scoring and cases to come. A module that is off loads no code and adds no menu; a new site is asked what it will use the CRM for and starts with only that. Other plugins can add their own module.
- Contacts — Done
The subscriber record grows into a contact: an owner, a lifecycle stage (subscriber, lead, customer…), phone and address, companies and custom fields, with subscription status kept as one part of it. A list with search, filters and bulk actions, and a profile page with details, consent, companies, tags, lists and the timeline. Duplicate detection by email.
- Companies — Done
Companies (accounts) with their own fields, owner and timeline; a contact can belong to several.
- Custom fields — Done
Typed fields for contacts, companies and deals, defined on one screen and grouped into sections: text, number, date, choice, money, URL, plus a lookup (a link to another record), auto-number, address and calculated fields. Values live in their own table so lists can sort and filter by them.
- Tags and lists — Done
Lists are audiences people join (and leave); tags are labels. Both are the building blocks of segments, automations and membership rules. Carried over from the Newsletter / Subscriber CRM and reworked for the new layout.
- Subscription status per list — Done
Whether someone may be emailed (pending, subscribed, unsubscribed, bounced, complained) is kept per contact and list, with timestamps, separately from the lifecycle stage. Double opt-in, preferences and bounces all depend on it.
- Relations between records — Done
One table of labelled, two-way links between any two records (contact ↔ company, contact ↔ deal, deal ↔ case, a membership ↔ contact), so new record types attach without a schema change.
- Activity timeline — Done
One event log for every contact and company: form submissions, emails, notes, tasks, deal changes, tag changes. Every module writes to it; the profile page reads it.
- Rule-based segments — Done
Segments today hold one filter each (status, list, tag or search). They become saved, live segments built from AND / OR rules over fields, tags, lists, lifecycle stage, activity and dates, feeding campaigns, automations and reports. One filter engine serves list views, segments, campaign audiences, automation conditions and, later, Membership's access rules, so there is one rule language everywhere. Segment counts are cached.
- Import and export — Done
CSV import with column mapping, duplicate handling and a dry run; export of any segment. Carried over from the Newsletter / Subscriber CRM and reworked for the new layout. Every import is a batch that can be rolled back, with saved column mappings; large imports run in the background with a progress bar.
- Merge duplicates — Done
Duplicates suggested on import and on matching email or phone; merging moves tags, lists, deals, notes, the timeline and automation progress onto one record.
- Bin and restore — Done
Deleted records go to a bin first and can be restored; emptying the bin is a separate, explicit step.
- Leads from forms — Done
A contact or booking form adds its senders as contacts: each answer goes to a contact field, an existing custom field or a new one the CRM creates from the form field, the whole submission lands on the timeline, and a booking can become a deal or a meeting. Subscribing still needs a ticked consent box.
- Newsletter signup element — Done
The Newsletter element (in Shortcodes) announces a signup through
fw_newsletter_subscribe, and the CRM keeps listening to store the contact, with double opt-in when the email module is on. Carried over, so signups never go unsaved during the rename. - Privacy and consent — Done
A consent log per contact (what, when, from which form), the WordPress personal data exporter and eraser, and retention settings. Carried over from the Newsletter / Subscriber CRM and reworked for the new layout.
- Consent log — Done
What each person agreed to, the exact wording they saw, when, and from which form or page.
- Audit log — Done
Who changed what and when, for admins, built on the same change events every module emits.
- Team roles — Done
CRM capabilities and two roles: a CRM manager sees everything; a sales rep sees and edits only the contacts, companies and deals they own. Every query passes through one permission layer, and creating or linking a WordPress user checks capabilities first.
- REST API and AI connector tools — Done
The REST API grows to every record type, and the AI connector tools (today: describe the set-up, save lists and tags, save segments, settings, draft campaigns) grow to fields, companies and pipelines. No tool returns a contact's personal details.
Phase 2 · Sales pipelineDone
14/14Deals on a board. Several pipelines, each with its own stages; deals carry a value, an owner and a close date, and move by drag and drop. Tasks and notes keep the follow-up from slipping.
- Pipelines and stages — Done
Any number of pipelines (sales, onboarding, hiring…), each with ordered stages and a win probability per stage.
- Deals — Done
A deal has a title, value and currency, owner, contacts, company, stage, expected close date and custom fields. Won and lost, with a lost reason. Lost reasons, a per-deal probability that can override the stage's, and stalled-deal alerts when a deal sits in one stage too long.
- Pipeline board — Done
Columns per stage with totals; drag a deal to move it, to won or to lost. Filters by owner, value and date.
- Deal page — Done
Details, contacts, company, tasks, notes and the deal's timeline on one screen.
- Tasks and reminders — Done
Calls, meetings, emails and to-dos with due dates and owners, on contacts, companies and deals; a My Tasks view and email reminders.
- Notes — Done
Notes on any record, shown on its timeline.
- REST API for deals, pipelines and tasks — Done
Pipelines, deals (move, win, lose, the bin, linked contacts, the timeline), tasks and notes through the CRM's REST API, with the same rules as the screens: a sales rep reaches only their own deals and tasks.
- Calls, meetings and calendar — Done
Log calls (outcome, duration, notes) and schedule meetings with a time, attendees and a reminder; a calendar view of everything due.
- Files on records — Done
Attach files from the media library to contacts, companies and deals.
- Products and line items — Done
Optional: line items on deals from a simple product list, or from WooCommerce products when it is active. A line item copies the price, so later price changes do not rewrite old deals.
- One-to-one email — Done
Write to a contact from their profile or a deal; the email is sent through the Mailer and logged on the timeline.
- Replies on the timeline — Done
Replies reach the contact's timeline through a BCC address or a connected mailbox, which also lets an automation stop when someone answers.
- Sales reports — Done
Pipeline value by stage, a forecast weighted by stage probability, won and lost over time, and performance per owner.
- CRM home dashboard — Done
Counts, tasks due today, deals by stage, recent activity, list growth and the health of the sending queue, as cards you can rearrange.
Phase 2b · CasesPlanned
0/3Support requests tracked like deals. A case belongs to a contact and company, moves through statuses, has a priority and an owner, and keeps every reply and note on the timeline.
- Cases — Planned
A light support-ticket record that reuses the pipeline engine for its statuses (new, open, waiting, solved), with a priority, an owner and a due date.
- Case list and board — Planned
A list and a board by status, filtered by owner, priority and age.
- Cases from forms and email — Planned
A contact form action and the inbound email address can open a case.
Phase 3 · Email marketingIn progress
3/10Campaigns that reach the inbox. Designed in a block email builder from a template gallery, sent in batches through SMTP or an email service, and measured with opens and clicks.
- Sending queue — Done
Campaigns are queued and sent in small batches by the scheduler, so a big send never hits a host's time limit, with per-hour limits to respect shared hosting. Carried over from the Newsletter / Subscriber CRM and reworked for the new layout. One queue row per recipient, claimed atomically so no email is ever sent twice; a sending-rate cap with presets per kind of host; a per-campaign speed limit so opens and clicks cannot flood the site; the per-recipient send log cleared after a retention period while each campaign's totals are kept.
- Email services — Planned
The provider layer already exists (local sending through the Mailer). It gains email services sent directly through their API, for speed, deliverability and bounce handling.
- Email builder — Planned
Drag-and-drop blocks (text, image, button, columns, social, divider) compiled to email-safe HTML, with personalization tags and a live preview. Carried over from the Newsletter / Subscriber CRM and reworked for the new layout.
- Template gallery — Planned
Ready-made basic and designed templates (newsletter, announcement, welcome, follow-up, offer), plus saving your own.
- Campaigns — Done
Pick an audience (list, tag or segment), design, test, schedule and send. Campaigns that have started can no longer be edited, so everyone gets the same email. Carried over from the Newsletter / Subscriber CRM and reworked for the new layout.
- Double opt-in and preferences — Planned
Confirmation emails, a preference page where people choose their lists, and one-click unsubscribe in every email. Carried over from the Newsletter / Subscriber CRM and reworked for the new layout.
- Opens, clicks and bounces — Done
Open and click tracking (switchable, for privacy), bounce and complaint handling, and campaign reports. Clicks from corporate link scanners are filtered out, and tracked links are stored once in a short-link table.
- Sender profiles — Planned
Several From names and addresses, and transactional email (receipts, confirmations) kept apart from marketing email.
- Smart links and post digests — Planned
Links that add a tag when clicked, and a recurring email of the latest posts.
- Message channels — Planned
Email is the first channel of a channel registry, so SMS and messaging apps can be added later without changing campaigns or automations.
Phase 4 · AutomationsPlanned
0/11The CRM working on its own. An automation starts on a trigger and runs steps: send an email, wait, branch on a condition, change tags, move a deal, create a task, call a webhook. Built to run reliably on ordinary shared hosting.
- Automation engine — Planned
Each contact's progress through an automation is a row with a next-run time; the runner processes due rows in small batches. Waits of minutes or months cost nothing while they wait.
- Reliable scheduling — Planned
A health check that shows whether the scheduler is running on time, and the exact cron line for a real server cron job (cPanel and similar), replacing WordPress's visit-triggered scheduler.
- Triggers — Planned
Form submitted, list joined or left, tag added or removed, field changed, date reached (birthdays, renewals), deal stage changed, email opened or clicked, purchase made.
- Actions — Planned
Send an email, wait, if / else, add or remove tags and lists, update a field, create or move a deal, create a task, notify the team, call a webhook, start or end another automation.
- Goals and exit conditions — Planned
Jump ahead when a contact reaches a goal (buys, books, replies), and leave an automation when a condition stops being true.
- Automation editor — Planned
A visual flow editor: triggers at the top, steps in between, branches side by side, with a count of contacts at each step.
- Ready-made automations — Planned
Welcome series, lead nurture, quote or booking follow-up, re-engagement and deal follow-up, ready to switch on and edit.
- Run log and contact progress — Planned
Each run is logged as succeeded, partly done or failed with the reason, and every contact shows which automations they are in and at which step.
- Safe automations — Planned
A loop guard so automations cannot set each other off endlessly, a once-per-contact option, edits staged on live automations so people already inside are not broken, and a test run for one contact.
- More conditions and steps — Planned
Changed to / changed from conditions, date and birthday triggers, a random split, and round-robin owner assignment.
- Command line — Planned
WP-CLI commands to run the sending queue and automations, the scaling path on a VPS.
Phase 5 · Scoring and site activityPlanned
0/3Know who is ready to buy. Points for what contacts do, and which pages known contacts read, so the team calls the warmest leads first.
- Lead scoring — Planned
Rules that add or remove points for opens, clicks, page visits, form submissions and fields; scores that fade over time; segments and automations by score. Several named scores per contact (by product or interest) and a score on deals.
- Site activity for known contacts — Planned
Pages a contact visits after they identify themselves (a form or an email click), with consent, on their timeline and as an automation trigger.
- Events — Planned
One events table for anything a contact does (custom events from code, clicks on marked elements, logins, purchases), usable in segments, scores and automations.
Phase 6 · Integrations and the extension APIIn progress
1/9Other extensions build on the CRM without reaching into its tables. A documented, versioned PHP API, events and REST endpoints let the Membership extension, WooCommerce and anything written later read and change contacts, tags and deals, and react when they change.
- Public PHP API — Planned
One entry point,
fw_crm(), for finding, creating and updating contacts, companies and deals, adding and removing tags and lists, checking membership of a tag, list or segment, and writing to the timeline. Versioned and documented; the tables behind it stay private. - Events catalogue — Planned
A documented action for every change (contact created, tag added, list joined, deal moved, email clicked…), each with the same payload shape, so integrations and automations listen to one stream.
- Outbound webhooks — Done
Send CRM events (new contacts, tags, subscriptions, deals won, tasks done, email opens, clicks and bounces) to other apps as signed JSON the moment they happen, retried in the background and logged, with a test button and a REST API to manage them. Other extensions add their own events.
- Integrations registry — Planned
Extensions register themselves as CRM integrations: their own triggers and actions appear in Automations, their own fields on the contact page, and their activity on the timeline. The CRM never needs to know about them in advance.
- WooCommerce — Planned
Customers become contacts; orders, totals and products land on the timeline and become segment rules and automation triggers (purchased, refunded, abandoned cart).
- Ready for the Membership extension — Planned
Membership is its own extension. The CRM gives it what it needs: a contact linked to a WordPress user only when someone must log in, tag, list and segment checks for access rules, and membership events (joined, renewed, expired) on the timeline and in Automations.
- Dashboard widget registry — Planned
Other extensions add their own cards to the CRM home dashboard.
- Purchase summaries — Planned
Each store or membership provider keeps a summary per contact (orders, total spent, plan and status), so segments and automations can use it without reaching into other extensions' tables.
- Custom objects — Planned
An API for registering new record types (with fields, relations, the timeline and permissions), with an admin screen later.
Phase 7 · Built with AIPlanned
0/2The whole CRM can be set up by an AI app through the connector, and the CRM website generator builds sites on it.
- Connector tools for every module — Planned
Pipelines and stages, campaigns and templates, automations from recipes, scoring rules and access rules, each as an AI Assistant tool. Setting things up, never reading or contacting the people in the CRM.
- CRM website generator on the CRM — Planned
The generator's prompts build on the CRM: a real pipeline instead of stage tags, and a welcome automation instead of a single welcome email.
Order of work
- Rename and reorganize, then contacts and companies. The data model, privacy, team roles, the contact form action and the Newsletter element.
- Sales pipeline. Deals, the board, tasks and notes.
- Email marketing. Much of it exists already (the builder, campaigns, the queue, opt-in); this phase adds the template gallery, email services and tracking.
- Automations. The engine and its scheduler check first, then triggers, actions, the editor and ready-made recipes.
- Scoring and site activity.
- Integrations and the extension API. The public API, events and integrations registry that the Membership extension, WooCommerce and future extensions connect through.
- AI connector tools for every module, and the CRM website generator moved onto the CRM.
How this page stays current
Status is not ticked by hand. src/data/crm-roadmap.json lists every task with a detect block naming the
files (and, where needed, code symbols) that make it real, and scripts/gen-roadmap.mjs checks them against
the extension's source tree:
| Result | Status |
|---|---|
| Every file and symbol found | Done |
| Some found, some missing | In progress |
| None found | Planned |
npm run roadmap:crm # scan and rewrite the JSON
npm run roadmap:crm -- --dry # report only, write nothing
npm run roadmap:crm -- --check # exit 1 if stale
The detect paths double as the extension's agreed file layout, decided before the code is written: core
classes in includes/, and each switchable module in modules/<module>/, which is not loaded unless the
module is on.