@fayz-ai/plugin-marketing 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +49 -0
- package/dist/index.cjs +46 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +46 -2
- package/dist/index.js.map +1 -1
- package/dist/registries.d.ts +7 -0
- package/dist/registries.d.ts.map +1 -0
- package/package.json +4 -4
- package/src/index.ts +13 -1
- package/src/registries.ts +48 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Faya Labs
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# @fayz-ai/plugin-marketing
|
|
2
|
+
|
|
3
|
+
> One acquisition & conversion engine — every channel, every vertical.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@fayz-ai/plugin-marketing)
|
|
6
|
+
[](https://github.com/FayaLabs/fayz-sdk/blob/main/LICENSE)
|
|
7
|
+
|
|
8
|
+
Marketing analytics are always the same shape — channels, campaigns, a funnel, landing-page CVR — but what counts as a "conversion" changes per business. A salon converts a booking, a store converts an order, an agency converts a lead. `plugin-marketing` is one plugin that adapts to all of them: pick a `domain` preset (or pass an explicit conversion model + channels) and the funnel, channel performance, and cost-per-acquisition are computed generically on top of it.
|
|
9
|
+
|
|
10
|
+
It ships a vertical-flavored mock today so the surface is real from the first install. Real attribution arrives through clean DI seams — an `AttributionBridge` to read conversions from CRM/agenda/orders, and a `SitesPerformanceBridge` to read landing-page numbers from your sites — so you wire reality in without rewriting the plugin. Campaigns and channels are first-class, and the whole thing exposes AI tools so your assistant can answer "which channel converts best?" out loud.
|
|
11
|
+
|
|
12
|
+
## What's inside
|
|
13
|
+
- A `/marketing` workspace: overview, channels (list + detail), campaigns (list + composer), funnel, and landing pages
|
|
14
|
+
- `domain` presets that set the conversion model + acquisition channels per vertical (defaults to `agency`)
|
|
15
|
+
- Generic channel performance (reach, conversions, CVR, spend, CPA), funnel, and campaign CVR
|
|
16
|
+
- DI seams: `attributionBridge` and `sitesBridge` to feed real data when it's ready
|
|
17
|
+
- Domain events: `marketing.conversion.tracked`, `campaign.created`, `campaign.updated`, `channel.synced`
|
|
18
|
+
- AI tools: `channelPerformance`, `topChannels`, `campaignCvr`, and `createCampaign`
|
|
19
|
+
- Dashboard widgets, a central Settings tab, currency formatting, and full i18n
|
|
20
|
+
- Exported `MARKETING_PRESETS` and a mock provider for local development
|
|
21
|
+
|
|
22
|
+
## Install
|
|
23
|
+
```bash
|
|
24
|
+
npm install @fayz-ai/plugin-marketing
|
|
25
|
+
```
|
|
26
|
+
Peer deps: `@fayz-ai/core`, `@fayz-ai/ui`, `@fayz-ai/saas`, plus `react` / `react-dom`.
|
|
27
|
+
|
|
28
|
+
## Usage
|
|
29
|
+
```tsx
|
|
30
|
+
import { defineSaas } from '@fayz-ai/saas'
|
|
31
|
+
import { createMarketingPlugin } from '@fayz-ai/plugin-marketing'
|
|
32
|
+
|
|
33
|
+
export const app = defineSaas({
|
|
34
|
+
// ...
|
|
35
|
+
plugins: [
|
|
36
|
+
createMarketingPlugin({
|
|
37
|
+
domain: 'beauty', // conversion model + channels from the preset
|
|
38
|
+
currency: { code: 'BRL' },
|
|
39
|
+
// attributionBridge / sitesBridge wire real data in later
|
|
40
|
+
}),
|
|
41
|
+
],
|
|
42
|
+
})
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Part of the Fayz SDK
|
|
46
|
+
The acquisition half of growth. Pairs with `plugin-crm` (the leads and deals it converts into), `plugin-conversations` (broadcast replies land in the inbox), and `plugin-reputation` (social proof that lifts CVR).
|
|
47
|
+
|
|
48
|
+
## Roadmap & contributing
|
|
49
|
+
Built and evolving in the open. See the [Fayz SDK roadmap](../../docs/ROADMAP.md#plugin-marketing) for current gaps, missing features, and good first issues.
|
package/dist/index.cjs
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
var React4 = require('react');
|
|
4
4
|
var core = require('@fayz-ai/core');
|
|
5
|
-
var ui = require('@fayz-ai/ui');
|
|
6
5
|
var saas = require('@fayz-ai/saas');
|
|
6
|
+
var ui = require('@fayz-ai/ui');
|
|
7
7
|
var jsxRuntime = require('react/jsx-runtime');
|
|
8
8
|
var lucideReact = require('lucide-react');
|
|
9
9
|
var vanilla = require('zustand/vanilla');
|
|
@@ -583,6 +583,42 @@ function SettingsView() {
|
|
|
583
583
|
] })
|
|
584
584
|
] });
|
|
585
585
|
}
|
|
586
|
+
|
|
587
|
+
// src/registries.ts
|
|
588
|
+
var KIND_OPTIONS = [
|
|
589
|
+
{ value: "paid", label: "Paid" },
|
|
590
|
+
{ value: "organic", label: "Organic" },
|
|
591
|
+
{ value: "social", label: "Social" },
|
|
592
|
+
{ value: "referral", label: "Referral" },
|
|
593
|
+
{ value: "direct", label: "Direct" },
|
|
594
|
+
{ value: "outbound", label: "Outbound" }
|
|
595
|
+
];
|
|
596
|
+
var channelEntity = {
|
|
597
|
+
name: "Channel",
|
|
598
|
+
namePlural: "Channels",
|
|
599
|
+
icon: "Radio",
|
|
600
|
+
displayField: "label",
|
|
601
|
+
defaultSort: "label",
|
|
602
|
+
fields: [
|
|
603
|
+
{ key: "label", label: "Channel", type: "text", required: true, showInTable: true, searchable: true },
|
|
604
|
+
{ key: "kind", label: "Type", type: "select", options: KIND_OPTIONS, showInTable: true },
|
|
605
|
+
{ key: "icon", label: "Icon", type: "text", showInTable: true }
|
|
606
|
+
],
|
|
607
|
+
facets: [{ field: "kind" }]
|
|
608
|
+
};
|
|
609
|
+
function buildMarketingRegistries(channels) {
|
|
610
|
+
return [
|
|
611
|
+
{
|
|
612
|
+
id: "channels",
|
|
613
|
+
entity: channelEntity,
|
|
614
|
+
icon: "Radio",
|
|
615
|
+
description: "Acquisition channels tracked for this workspace",
|
|
616
|
+
display: "table",
|
|
617
|
+
readOnly: true,
|
|
618
|
+
seedData: channels.map((c) => ({ id: c.id, label: c.label, kind: c.kind, icon: c.icon }))
|
|
619
|
+
}
|
|
620
|
+
];
|
|
621
|
+
}
|
|
586
622
|
function useEnsureMarketingData() {
|
|
587
623
|
const overview = useMarketingStore((s) => s.overview);
|
|
588
624
|
const loading = useMarketingStore((s) => s.loading);
|
|
@@ -1234,10 +1270,17 @@ function createMarketingPlugin(options) {
|
|
|
1234
1270
|
React4__default.default.createElement(MarketingPage, { config, provider, store })
|
|
1235
1271
|
);
|
|
1236
1272
|
PageComponent.displayName = "MarketingPage";
|
|
1273
|
+
const marketingRegistries = buildMarketingRegistries(config.channels);
|
|
1237
1274
|
const SettingsComponent = () => React4__default.default.createElement(
|
|
1238
1275
|
MarketingContextProvider,
|
|
1239
1276
|
{ config, provider, store },
|
|
1240
|
-
React4__default.default.createElement(
|
|
1277
|
+
React4__default.default.createElement(saas.PluginSettingsPanel, {
|
|
1278
|
+
title: config.labels.settings ?? config.labels.pageTitle,
|
|
1279
|
+
subtitle: config.labels.pageSubtitle,
|
|
1280
|
+
generalSettings: React4__default.default.createElement(SettingsView),
|
|
1281
|
+
registries: marketingRegistries,
|
|
1282
|
+
routeBase: "/settings/marketing"
|
|
1283
|
+
})
|
|
1241
1284
|
);
|
|
1242
1285
|
SettingsComponent.displayName = "MarketingSettings";
|
|
1243
1286
|
return {
|
|
@@ -1333,6 +1376,7 @@ function createMarketingPlugin(options) {
|
|
|
1333
1376
|
permission: { feature: "marketing", action: "create" }
|
|
1334
1377
|
}
|
|
1335
1378
|
],
|
|
1379
|
+
registries: marketingRegistries,
|
|
1336
1380
|
settings: [
|
|
1337
1381
|
{
|
|
1338
1382
|
id: "marketing",
|