@endora-commerce/mod-linkedin-ads 0.100.0
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 +58 -0
- package/dist/admin/api/linkedin-ads-client.d.ts +32 -0
- package/dist/admin/api/linkedin-ads-client.d.ts.map +1 -0
- package/dist/admin/api/linkedin-ads-client.js +34 -0
- package/dist/admin/api/linkedin-ads-client.js.map +1 -0
- package/dist/admin/index.d.ts +32 -0
- package/dist/admin/index.d.ts.map +1 -0
- package/dist/admin/index.js +64 -0
- package/dist/admin/index.js.map +1 -0
- package/dist/admin/pages/ConversionMappingEditPage.d.ts +4 -0
- package/dist/admin/pages/ConversionMappingEditPage.d.ts.map +1 -0
- package/dist/admin/pages/ConversionMappingEditPage.js +89 -0
- package/dist/admin/pages/ConversionMappingEditPage.js.map +1 -0
- package/dist/admin/pages/ConversionMappingsListPage.d.ts +7 -0
- package/dist/admin/pages/ConversionMappingsListPage.d.ts.map +1 -0
- package/dist/admin/pages/ConversionMappingsListPage.js +84 -0
- package/dist/admin/pages/ConversionMappingsListPage.js.map +1 -0
- package/dist/backend/entities/linkedin-conversion-mapping.entity.d.ts +30 -0
- package/dist/backend/entities/linkedin-conversion-mapping.entity.d.ts.map +1 -0
- package/dist/backend/entities/linkedin-conversion-mapping.entity.js +85 -0
- package/dist/backend/entities/linkedin-conversion-mapping.entity.js.map +1 -0
- package/dist/backend/index.d.ts +58 -0
- package/dist/backend/index.d.ts.map +1 -0
- package/dist/backend/index.js +60 -0
- package/dist/backend/index.js.map +1 -0
- package/dist/backend/routes.admin.d.ts +16 -0
- package/dist/backend/routes.admin.d.ts.map +1 -0
- package/dist/backend/routes.admin.js +31 -0
- package/dist/backend/routes.admin.js.map +1 -0
- package/dist/backend/routes.storefront.d.ts +12 -0
- package/dist/backend/routes.storefront.d.ts.map +1 -0
- package/dist/backend/routes.storefront.js +15 -0
- package/dist/backend/routes.storefront.js.map +1 -0
- package/dist/backend/services/conversion-mappings.service.d.ts +51 -0
- package/dist/backend/services/conversion-mappings.service.d.ts.map +1 -0
- package/dist/backend/services/conversion-mappings.service.js +155 -0
- package/dist/backend/services/conversion-mappings.service.js.map +1 -0
- package/dist/backend/services/linkedin-config.service.d.ts +27 -0
- package/dist/backend/services/linkedin-config.service.d.ts.map +1 -0
- package/dist/backend/services/linkedin-config.service.js +57 -0
- package/dist/backend/services/linkedin-config.service.js.map +1 -0
- package/dist/manifest.d.ts +195 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +119 -0
- package/dist/manifest.js.map +1 -0
- package/dist/migrations/20260727T233211_linkedin_ads_init.d.ts +12 -0
- package/dist/migrations/20260727T233211_linkedin_ads_init.d.ts.map +1 -0
- package/dist/migrations/20260727T233211_linkedin_ads_init.js +36 -0
- package/dist/migrations/20260727T233211_linkedin_ads_init.js.map +1 -0
- package/dist/migrations/index.d.ts +27 -0
- package/dist/migrations/index.d.ts.map +1 -0
- package/dist/migrations/index.js +29 -0
- package/dist/migrations/index.js.map +1 -0
- package/docs/linkedin-ads.md +73 -0
- package/i18n/en.json +35 -0
- package/i18n/pl.json +35 -0
- package/package.json +92 -0
- package/tailwind.css +14 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Endora sp. z o.o. and the Endora Commerce contributors
|
|
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,58 @@
|
|
|
1
|
+
<!-- Generated by `pnpm --filter backend run manifests:generate`. Delete this line to take the file over; a README without it is never regenerated. -->
|
|
2
|
+
|
|
3
|
+
# @endora-commerce/mod-linkedin-ads
|
|
4
|
+
|
|
5
|
+
LinkedIn Ads integration: per-sales-channel Insight Tag, consent-gated tracking, configurable conversion mappings, and optional server-side reporting through the Conversions API.
|
|
6
|
+
|
|
7
|
+
## What this is
|
|
8
|
+
|
|
9
|
+
An **Endora Commerce module package**. Its module id is `linkedin_ads` — the identity of record in the platform's registries, in its migrations and in its setting, permission and translation codes.
|
|
10
|
+
|
|
11
|
+
A module is not imported by application code. The platform discovers the extension packages an instance has installed, reads the manifest on the root subpath and composes the module from it, so installing this package and starting the instance is the whole integration.
|
|
12
|
+
|
|
13
|
+
## Entry points
|
|
14
|
+
|
|
15
|
+
| Import | Contents |
|
|
16
|
+
| --- | --- |
|
|
17
|
+
| `@endora-commerce/mod-linkedin-ads` | the module manifest — its id, version, dependencies, settings and activation |
|
|
18
|
+
| `@endora-commerce/mod-linkedin-ads/admin` | the Admin UI contribution: the screens, navigation and palette actions it adds |
|
|
19
|
+
| `@endora-commerce/mod-linkedin-ads/backend` | the composition root the platform calls, with the entities, services, routes and workers it registers |
|
|
20
|
+
| `@endora-commerce/mod-linkedin-ads/migrations` | the module’s own schema migrations, in the order the platform runs them |
|
|
21
|
+
| `@endora-commerce/mod-linkedin-ads/tailwind.css` | the Tailwind source declaration for the admin code above |
|
|
22
|
+
|
|
23
|
+
## Depends on
|
|
24
|
+
|
|
25
|
+
Everything below is a **peer** dependency, so the application resolves exactly one copy of each — two copies of a host or of React are a runtime failure rather than a type error. An entry marked *optional* is needed only by the layers that use it.
|
|
26
|
+
|
|
27
|
+
**Endora packages**
|
|
28
|
+
|
|
29
|
+
- `@endora-commerce/admin-kit` — *optional*
|
|
30
|
+
- `@endora-commerce/contracts`
|
|
31
|
+
- `@endora-commerce/platform`
|
|
32
|
+
|
|
33
|
+
**Third-party**
|
|
34
|
+
|
|
35
|
+
- `@mikro-orm/core` ^6
|
|
36
|
+
- `@mikro-orm/migrations` ^6
|
|
37
|
+
- `@mikro-orm/postgresql` ^6
|
|
38
|
+
- `fastify` ^5
|
|
39
|
+
- `react` ^19 — *optional*
|
|
40
|
+
- `react-router-dom` ^7 — *optional*
|
|
41
|
+
- `zod` ^4
|
|
42
|
+
|
|
43
|
+
## What the tarball carries
|
|
44
|
+
|
|
45
|
+
- `dist/` — the compiled JavaScript and its type declarations
|
|
46
|
+
- `i18n/` — the translation bundles this package ships (`en`, `pl`), loaded by the platform
|
|
47
|
+
- `docs/` — the package’s own pages in the Endora Commerce documentation site
|
|
48
|
+
- `tailwind.css` — the Tailwind source declaration
|
|
49
|
+
|
|
50
|
+
## Install
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
pnpm add @endora-commerce/mod-linkedin-ads
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Licence
|
|
57
|
+
|
|
58
|
+
MIT — the text is in `LICENSE`, beside this file.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { CreateLinkedInConversionMapping, LinkedInConversionMapping, LinkedInTriggerAction, SalesChannelListResponse, UpdateLinkedInConversionMapping } from '@endora-commerce/contracts';
|
|
2
|
+
/** Typed admin client for the LinkedIn Ads module (feature 063). */
|
|
3
|
+
export declare const linkedInAdsClient: {
|
|
4
|
+
actionCatalogue: () => Promise<LinkedInTriggerAction[]>;
|
|
5
|
+
list: () => Promise<LinkedInConversionMapping[]>;
|
|
6
|
+
get: (id: string) => Promise<LinkedInConversionMapping>;
|
|
7
|
+
create: (body: CreateLinkedInConversionMapping) => Promise<LinkedInConversionMapping>;
|
|
8
|
+
update: (id: string, body: UpdateLinkedInConversionMapping) => Promise<LinkedInConversionMapping>;
|
|
9
|
+
remove: (id: string) => Promise<void>;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* The sales channels this module's two screens label a mapping's channel with.
|
|
13
|
+
*
|
|
14
|
+
* **This is a drained cross-module reach, not a convenience** (feature 091,
|
|
15
|
+
* Phase 4 batch three). Both screens used to import `salesChannelsClient` from
|
|
16
|
+
* `@/modules/sales_channels/api/sales-channels-client`, which
|
|
17
|
+
* `backend/scripts/ledgers/cross-module-imports/linkedin_ads.ts` recorded as a
|
|
18
|
+
* boundary reach before any admin directory moved. That entry named the exit
|
|
19
|
+
* taken here: *"the reach is the client module, not the HTTP call — the request
|
|
20
|
+
* and response shapes are already in `@endora-commerce/contracts`, which both
|
|
21
|
+
* sides compile"*, so the caller builds the request itself and no module names
|
|
22
|
+
* a file another module owns. Rewriting the specifier as a package subpath was
|
|
23
|
+
* the exit the entry refuses: it is the same coupling under a supported name.
|
|
24
|
+
*
|
|
25
|
+
* It is duplicated in `meta_ads`' client rather than shared, and that is the
|
|
26
|
+
* design and not an oversight. The only place two modules could share it is
|
|
27
|
+
* `@endora-commerce/admin-kit`, and the kit holds no module knowledge (R6) —
|
|
28
|
+
* `/api/v1/admin/sales-channels` is `sales_channels`' knowledge. Two callers of
|
|
29
|
+
* one published HTTP route is what an API boundary is for.
|
|
30
|
+
*/
|
|
31
|
+
export declare const listSalesChannels: () => Promise<SalesChannelListResponse>;
|
|
32
|
+
//# sourceMappingURL=linkedin-ads-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"linkedin-ads-client.d.ts","sourceRoot":"","sources":["../../../src/admin/api/linkedin-ads-client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,+BAA+B,EAC/B,yBAAyB,EACzB,qBAAqB,EACrB,wBAAwB,EACxB,+BAA+B,EAChC,MAAM,4BAA4B,CAAC;AAMpC,oEAAoE;AACpE,eAAO,MAAM,iBAAiB;2BACP,OAAO,CAAC,qBAAqB,EAAE,CAAC;gBAG3C,OAAO,CAAC,yBAAyB,EAAE,CAAC;cAGpC,MAAM,KAAG,OAAO,CAAC,yBAAyB,CAAC;mBAGtC,+BAA+B,KAAG,OAAO,CAAC,yBAAyB,CAAC;iBAM7E,MAAM,QACJ,+BAA+B,KACpC,OAAO,CAAC,yBAAyB,CAAC;iBAQxB,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;CACpC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,iBAAiB,QAAO,OAAO,CAAC,wBAAwB,CAGlE,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { apiClient } from '@endora-commerce/admin-kit/lib';
|
|
2
|
+
const unwrap = (p) => p.then((r) => r.data);
|
|
3
|
+
const BASE = '/api/v1/admin/linkedin-ads';
|
|
4
|
+
/** Typed admin client for the LinkedIn Ads module (feature 063). */
|
|
5
|
+
export const linkedInAdsClient = {
|
|
6
|
+
actionCatalogue: () => unwrap(apiClient.get(`${BASE}/action-catalogue`)),
|
|
7
|
+
list: () => unwrap(apiClient.get(`${BASE}/conversion-mappings`)),
|
|
8
|
+
get: (id) => unwrap(apiClient.get(`${BASE}/conversion-mappings/${id}`)),
|
|
9
|
+
create: (body) => unwrap(apiClient.post(`${BASE}/conversion-mappings`, body)),
|
|
10
|
+
update: (id, body) => unwrap(apiClient.patch(`${BASE}/conversion-mappings/${id}`, body)),
|
|
11
|
+
remove: (id) => apiClient.delete(`${BASE}/conversion-mappings/${id}`),
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* The sales channels this module's two screens label a mapping's channel with.
|
|
15
|
+
*
|
|
16
|
+
* **This is a drained cross-module reach, not a convenience** (feature 091,
|
|
17
|
+
* Phase 4 batch three). Both screens used to import `salesChannelsClient` from
|
|
18
|
+
* `@/modules/sales_channels/api/sales-channels-client`, which
|
|
19
|
+
* `backend/scripts/ledgers/cross-module-imports/linkedin_ads.ts` recorded as a
|
|
20
|
+
* boundary reach before any admin directory moved. That entry named the exit
|
|
21
|
+
* taken here: *"the reach is the client module, not the HTTP call — the request
|
|
22
|
+
* and response shapes are already in `@endora-commerce/contracts`, which both
|
|
23
|
+
* sides compile"*, so the caller builds the request itself and no module names
|
|
24
|
+
* a file another module owns. Rewriting the specifier as a package subpath was
|
|
25
|
+
* the exit the entry refuses: it is the same coupling under a supported name.
|
|
26
|
+
*
|
|
27
|
+
* It is duplicated in `meta_ads`' client rather than shared, and that is the
|
|
28
|
+
* design and not an oversight. The only place two modules could share it is
|
|
29
|
+
* `@endora-commerce/admin-kit`, and the kit holds no module knowledge (R6) —
|
|
30
|
+
* `/api/v1/admin/sales-channels` is `sales_channels`' knowledge. Two callers of
|
|
31
|
+
* one published HTTP route is what an API boundary is for.
|
|
32
|
+
*/
|
|
33
|
+
export const listSalesChannels = () => apiClient.get('/api/v1/admin/sales-channels?activeOnly=false&pageSize=100');
|
|
34
|
+
//# sourceMappingURL=linkedin-ads-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"linkedin-ads-client.js","sourceRoot":"","sources":["../../../src/admin/api/linkedin-ads-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAC;AAU3D,MAAM,MAAM,GAAG,CAAI,CAAmB,EAAc,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AAC7E,MAAM,IAAI,GAAG,4BAA4B,CAAC;AAE1C,oEAAoE;AACpE,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,eAAe,EAAE,GAAqC,EAAE,CACtD,MAAM,CAAC,SAAS,CAAC,GAAG,CAAgC,GAAG,IAAI,mBAAmB,CAAC,CAAC;IAElF,IAAI,EAAE,GAAyC,EAAE,CAC/C,MAAM,CAAC,SAAS,CAAC,GAAG,CAAoC,GAAG,IAAI,sBAAsB,CAAC,CAAC;IAEzF,GAAG,EAAE,CAAC,EAAU,EAAsC,EAAE,CACtD,MAAM,CAAC,SAAS,CAAC,GAAG,CAAkC,GAAG,IAAI,wBAAwB,EAAE,EAAE,CAAC,CAAC;IAE7F,MAAM,EAAE,CAAC,IAAqC,EAAsC,EAAE,CACpF,MAAM,CACJ,SAAS,CAAC,IAAI,CAAkC,GAAG,IAAI,sBAAsB,EAAE,IAAI,CAAC,CACrF;IAEH,MAAM,EAAE,CACN,EAAU,EACV,IAAqC,EACD,EAAE,CACtC,MAAM,CACJ,SAAS,CAAC,KAAK,CACb,GAAG,IAAI,wBAAwB,EAAE,EAAE,EACnC,IAAI,CACL,CACF;IAEH,MAAM,EAAE,CAAC,EAAU,EAAiB,EAAE,CAAC,SAAS,CAAC,MAAM,CAAO,GAAG,IAAI,wBAAwB,EAAE,EAAE,CAAC;CACnG,CAAC;AAEF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAsC,EAAE,CACvE,SAAS,CAAC,GAAG,CACX,4DAA4D,CAC7D,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `linkedin_ads`' admin surface — three routes and one sidebar entry, declared
|
|
3
|
+
* by the module that owns them (feature 091, Phase 4;
|
|
4
|
+
* `specs/091-module-owned-admin-surfaces/contracts/admin-contribution.md`).
|
|
5
|
+
*
|
|
6
|
+
* **This is the third batch of the drain, and it is the first that pays a
|
|
7
|
+
* boundary debt rather than finding none.** Batches one and two took modules
|
|
8
|
+
* with zero admin cross-module reach in either direction, and !1176 recorded
|
|
9
|
+
* that rung as exhausted. Re-measured, that reading enumerated the directories
|
|
10
|
+
* with zero reach in *both* directions: eighteen more have zero **incoming**
|
|
11
|
+
* reach and one or more outgoing, and `linkedin_ads` and `meta_ads` are the
|
|
12
|
+
* pair at the top of that set whose every host symbol
|
|
13
|
+
* `@endora-commerce/admin-kit` publishes. Their four outgoing reaches all land
|
|
14
|
+
* on one target — `sales_channels`' admin client — and are retired here by the
|
|
15
|
+
* exit `backend/scripts/ledgers/cross-module-imports/linkedin_ads.ts` names,
|
|
16
|
+
* which is the caller building the request from the published `apiClient` and
|
|
17
|
+
* the contract's own types. The shard is deleted with them.
|
|
18
|
+
*
|
|
19
|
+
* **This entry exports data and nothing else** (R2), like every `./admin`
|
|
20
|
+
* layer: `check:module-boundary`'s D-171 rule designates a subpath as contract
|
|
21
|
+
* surface when it emits no runtime binding, and `./admin` deliberately does not
|
|
22
|
+
* qualify, so a consumer reaching into another module's `./admin` stays a
|
|
23
|
+
* counted boundary reach.
|
|
24
|
+
*
|
|
25
|
+
* **Every component is a dynamic-import factory** (R6). The editor is named
|
|
26
|
+
* twice below — once for `/new` and once for `/:id` — and both are the same
|
|
27
|
+
* factory value, so Vite emits one chunk for the screen rather than one per
|
|
28
|
+
* route.
|
|
29
|
+
*/
|
|
30
|
+
import type { AdminContributions } from '@endora-commerce/admin-kit/contributions';
|
|
31
|
+
export declare const contributions: AdminContributions;
|
|
32
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/admin/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0CAA0C,CAAC;AAgBnF,eAAO,MAAM,aAAa,EAAE,kBAmD3B,CAAC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/** The module's landing route: the conversion-mapping list. */
|
|
2
|
+
const ROUTE_PATH = '/linkedin-ads';
|
|
3
|
+
/**
|
|
4
|
+
* The create and edit screens are one component behind one factory.
|
|
5
|
+
*
|
|
6
|
+
* `react-router` matches `/linkedin-ads/new` against the parametric route too,
|
|
7
|
+
* so the two declarations are deliberately separate — the editor reads
|
|
8
|
+
* `id === 'new'` as its create mode, which is the behaviour the host route
|
|
9
|
+
* table had when it declared both paths against one imported component.
|
|
10
|
+
*/
|
|
11
|
+
const editor = () => import('./pages/ConversionMappingEditPage.js');
|
|
12
|
+
export const contributions = {
|
|
13
|
+
routes: [
|
|
14
|
+
{
|
|
15
|
+
path: ROUTE_PATH,
|
|
16
|
+
component: () => import('./pages/ConversionMappingsListPage.js'),
|
|
17
|
+
// Read from the route this screen calls —
|
|
18
|
+
// `requireAdmin('linkedin_ads:read')` on
|
|
19
|
+
// `GET /admin/linkedin-ads/conversion-mappings` — and the same code the
|
|
20
|
+
// module's `open-linkedin-ads` palette action declares, which
|
|
21
|
+
// `check:action-route-permissions` holds to that route.
|
|
22
|
+
requiredPermission: 'linkedin_ads:read',
|
|
23
|
+
index: true,
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
path: `${ROUTE_PATH}/new`,
|
|
27
|
+
component: editor,
|
|
28
|
+
// The create form posts to `POST /admin/linkedin-ads/conversion-mappings`,
|
|
29
|
+
// which enforces the write code — the same code the
|
|
30
|
+
// `new-linkedin-conversion-mapping` palette action declares for this path.
|
|
31
|
+
requiredPermission: 'linkedin_ads:write',
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
path: `${ROUTE_PATH}/:id`,
|
|
35
|
+
component: editor,
|
|
36
|
+
requiredPermission: 'linkedin_ads:write',
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
nav: [
|
|
40
|
+
{
|
|
41
|
+
to: ROUTE_PATH,
|
|
42
|
+
// Module-relative (R8), resolved in this module's own namespace out of
|
|
43
|
+
// `packages/modules/linkedin_ads/i18n/`. It was `appShell.nav.linkedinAds`
|
|
44
|
+
// in the shared `_i18n` bundle, one of the four shared files a module
|
|
45
|
+
// author had to edit.
|
|
46
|
+
labelKey: 'nav.linkedInAds.label',
|
|
47
|
+
// The icon the hand-written NAV entry carried.
|
|
48
|
+
icon: 'Sparkles',
|
|
49
|
+
section: 'analyticsAds',
|
|
50
|
+
// Third of the four entries the hand-written NAV gave this section, after
|
|
51
|
+
// `analytics` (100) and `google_analytics` (200). With `meta_ads` landing
|
|
52
|
+
// in this same merge request the section holds no host-declared entry at
|
|
53
|
+
// all, so these weights are the whole of its order — and the order they
|
|
54
|
+
// produce is the one the hand-written table had, which is batch one's and
|
|
55
|
+
// batch two's recorded regression retired rather than merely noted.
|
|
56
|
+
weight: 300,
|
|
57
|
+
// The code that opens the screen. The sidebar advertises a destination,
|
|
58
|
+
// so it gates on the read code the landing route enforces and not on the
|
|
59
|
+
// write code its editor does.
|
|
60
|
+
requiredPermission: 'linkedin_ads:read',
|
|
61
|
+
},
|
|
62
|
+
],
|
|
63
|
+
};
|
|
64
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/admin/index.ts"],"names":[],"mappings":"AA+BA,+DAA+D;AAC/D,MAAM,UAAU,GAAG,eAAe,CAAC;AAEnC;;;;;;;GAOG;AACH,MAAM,MAAM,GAAG,GAA2C,EAAE,CAC1D,MAAM,CAAC,sCAAsC,CAAC,CAAC;AAEjD,MAAM,CAAC,MAAM,aAAa,GAAuB;IAC/C,MAAM,EAAE;QACN;YACE,IAAI,EAAE,UAAU;YAChB,SAAS,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,uCAAuC,CAAC;YAChE,0CAA0C;YAC1C,yCAAyC;YACzC,wEAAwE;YACxE,8DAA8D;YAC9D,wDAAwD;YACxD,kBAAkB,EAAE,mBAAmB;YACvC,KAAK,EAAE,IAAI;SACZ;QACD;YACE,IAAI,EAAE,GAAG,UAAU,MAAM;YACzB,SAAS,EAAE,MAAM;YACjB,2EAA2E;YAC3E,oDAAoD;YACpD,2EAA2E;YAC3E,kBAAkB,EAAE,oBAAoB;SACzC;QACD;YACE,IAAI,EAAE,GAAG,UAAU,MAAM;YACzB,SAAS,EAAE,MAAM;YACjB,kBAAkB,EAAE,oBAAoB;SACzC;KACF;IACD,GAAG,EAAE;QACH;YACE,EAAE,EAAE,UAAU;YACd,uEAAuE;YACvE,2EAA2E;YAC3E,sEAAsE;YACtE,sBAAsB;YACtB,QAAQ,EAAE,uBAAuB;YACjC,+CAA+C;YAC/C,IAAI,EAAE,UAAU;YAChB,OAAO,EAAE,cAAc;YACvB,0EAA0E;YAC1E,0EAA0E;YAC1E,yEAAyE;YACzE,wEAAwE;YACxE,0EAA0E;YAC1E,oEAAoE;YACpE,MAAM,EAAE,GAAG;YACX,wEAAwE;YACxE,yEAAyE;YACzE,8BAA8B;YAC9B,kBAAkB,EAAE,mBAAmB;SACxC;KACF;CACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConversionMappingEditPage.d.ts","sourceRoot":"","sources":["../../../src/admin/pages/ConversionMappingEditPage.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAoC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAyBzE,+DAA+D;AAC/D,MAAM,CAAC,OAAO,UAAU,yBAAyB,IAAI,SAAS,CAiK7D"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback, useEffect, useState } from 'react';
|
|
3
|
+
import { useNavigate, useParams } from 'react-router-dom';
|
|
4
|
+
import { LINKEDIN_TRIGGER_ACTIONS, } from '@endora-commerce/contracts';
|
|
5
|
+
import { Alert, AlertDescription, Button, Card, CardContent, Input, Label, PageHeader, Select, } from '@endora-commerce/admin-kit/ui';
|
|
6
|
+
import { ApiError } from '@endora-commerce/admin-kit/lib';
|
|
7
|
+
import { useTranslation } from '@endora-commerce/admin-kit/i18n';
|
|
8
|
+
import { linkedInAdsClient, listSalesChannels } from '../api/linkedin-ads-client.js';
|
|
9
|
+
const ALL_CHANNELS = '__all__';
|
|
10
|
+
/** Create / edit one conversion mapping (feature 063, US3). */
|
|
11
|
+
export default function ConversionMappingEditPage() {
|
|
12
|
+
const t = useTranslation('linkedin_ads');
|
|
13
|
+
const navigate = useNavigate();
|
|
14
|
+
const { id } = useParams();
|
|
15
|
+
const isNew = id === undefined;
|
|
16
|
+
const [channels, setChannels] = useState([]);
|
|
17
|
+
const [existing, setExisting] = useState(null);
|
|
18
|
+
const [triggerAction, setTriggerAction] = useState('purchase');
|
|
19
|
+
const [conversionId, setConversionId] = useState('');
|
|
20
|
+
const [conversionRuleUrn, setConversionRuleUrn] = useState('');
|
|
21
|
+
const [salesChannelId, setSalesChannelId] = useState(ALL_CHANNELS);
|
|
22
|
+
const [enabled, setEnabled] = useState(true);
|
|
23
|
+
const [busy, setBusy] = useState(false);
|
|
24
|
+
const [error, setError] = useState(null);
|
|
25
|
+
const messageFor = useCallback((err) => {
|
|
26
|
+
if (err instanceof ApiError) {
|
|
27
|
+
if (err.envelope.error.code === 'VERSION_CONFLICT')
|
|
28
|
+
return t('error.versionConflict');
|
|
29
|
+
return err.envelope.error.message;
|
|
30
|
+
}
|
|
31
|
+
return t('error.generic');
|
|
32
|
+
}, [t]);
|
|
33
|
+
useEffect(() => {
|
|
34
|
+
void (async () => {
|
|
35
|
+
const chans = await listSalesChannels().catch(() => ({ items: [] }));
|
|
36
|
+
setChannels(chans.items);
|
|
37
|
+
if (isNew)
|
|
38
|
+
return;
|
|
39
|
+
try {
|
|
40
|
+
const row = await linkedInAdsClient.get(id);
|
|
41
|
+
setExisting(row);
|
|
42
|
+
setTriggerAction(row.triggerAction);
|
|
43
|
+
setConversionId(row.conversionId);
|
|
44
|
+
setConversionRuleUrn(row.conversionRuleUrn ?? '');
|
|
45
|
+
setSalesChannelId(row.salesChannelId ?? ALL_CHANNELS);
|
|
46
|
+
setEnabled(row.enabled);
|
|
47
|
+
}
|
|
48
|
+
catch (err) {
|
|
49
|
+
setError(messageFor(err));
|
|
50
|
+
}
|
|
51
|
+
})();
|
|
52
|
+
}, [id, isNew, messageFor]);
|
|
53
|
+
const save = async () => {
|
|
54
|
+
setBusy(true);
|
|
55
|
+
setError(null);
|
|
56
|
+
const channel = salesChannelId === ALL_CHANNELS ? null : salesChannelId;
|
|
57
|
+
const urn = conversionRuleUrn.trim() || null;
|
|
58
|
+
try {
|
|
59
|
+
if (isNew) {
|
|
60
|
+
await linkedInAdsClient.create({
|
|
61
|
+
triggerAction,
|
|
62
|
+
conversionId: conversionId.trim(),
|
|
63
|
+
salesChannelId: channel,
|
|
64
|
+
conversionRuleUrn: urn,
|
|
65
|
+
enabled,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
else if (existing) {
|
|
69
|
+
await linkedInAdsClient.update(existing.id, {
|
|
70
|
+
triggerAction,
|
|
71
|
+
conversionId: conversionId.trim(),
|
|
72
|
+
salesChannelId: channel,
|
|
73
|
+
conversionRuleUrn: urn,
|
|
74
|
+
enabled,
|
|
75
|
+
version: existing.version,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
navigate('/linkedin-ads');
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
setError(messageFor(err));
|
|
82
|
+
}
|
|
83
|
+
finally {
|
|
84
|
+
setBusy(false);
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
return (_jsxs("div", { children: [_jsx(PageHeader, { title: isNew ? t('mappings.new') : t('mappings.edit') }), error ? (_jsx(Alert, { variant: "destructive", className: "mb-3", children: _jsx(AlertDescription, { children: error }) })) : null, _jsx(Card, { children: _jsxs(CardContent, { className: "space-y-4 pt-6", children: [_jsxs("div", { children: [_jsx(Label, { htmlFor: "triggerAction", children: t('mappings.triggerAction') }), _jsx(Select, { id: "triggerAction", value: triggerAction, onChange: (e) => setTriggerAction(e.target.value), children: LINKEDIN_TRIGGER_ACTIONS.map((a) => (_jsx("option", { value: a, children: t(`mappings.action.${a}`) }, a))) })] }), _jsxs("div", { children: [_jsx(Label, { htmlFor: "conversionId", children: t('mappings.conversionId') }), _jsx(Input, { id: "conversionId", value: conversionId, inputMode: "numeric", onChange: (e) => setConversionId(e.target.value) }), _jsx("p", { className: "mt-1 text-xs text-muted-foreground", children: t('mappings.conversionIdHint') })] }), _jsxs("div", { children: [_jsx(Label, { htmlFor: "conversionRuleUrn", children: t('mappings.conversionRuleUrn') }), _jsx(Input, { id: "conversionRuleUrn", value: conversionRuleUrn, placeholder: "urn:lla:llaPartnerConversion:\u2026", onChange: (e) => setConversionRuleUrn(e.target.value) }), _jsx("p", { className: "mt-1 text-xs text-muted-foreground", children: t('mappings.conversionRuleUrnHint') })] }), _jsxs("div", { children: [_jsx(Label, { htmlFor: "salesChannelId", children: t('mappings.salesChannel') }), _jsxs(Select, { id: "salesChannelId", value: salesChannelId, onChange: (e) => setSalesChannelId(e.target.value), children: [_jsx("option", { value: ALL_CHANNELS, children: t('mappings.allChannels') }), channels.map((c) => (_jsx("option", { value: c.id, children: c.code }, c.id)))] })] }), _jsxs("label", { className: "flex items-center gap-2 text-sm", children: [_jsx("input", { type: "checkbox", checked: enabled, onChange: (e) => setEnabled(e.target.checked) }), t('mappings.enabled')] }), _jsx(Button, { disabled: busy || conversionId.trim() === '', onClick: () => void save(), children: t('mappings.save') })] }) })] }));
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=ConversionMappingEditPage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConversionMappingEditPage.js","sourceRoot":"","sources":["../../../src/admin/pages/ConversionMappingEditPage.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Conversion mappings list (feature 063, US3). Per-channel Settings (Partner ID,
|
|
4
|
+
* consent, server-side, access token) live on the generic Settings page.
|
|
5
|
+
*/
|
|
6
|
+
export default function ConversionMappingsListPage(): ReactNode;
|
|
7
|
+
//# sourceMappingURL=ConversionMappingsListPage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConversionMappingsListPage.d.ts","sourceRoot":"","sources":["../../../src/admin/pages/ConversionMappingsListPage.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAoC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAezE;;;GAGG;AACH,MAAM,CAAC,OAAO,UAAU,0BAA0B,IAAI,SAAS,CAkH9D"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback, useEffect, useState } from 'react';
|
|
3
|
+
import { Link } from 'react-router-dom';
|
|
4
|
+
import { Alert, AlertDescription, Badge, Button, PageHeader, } from '@endora-commerce/admin-kit/ui';
|
|
5
|
+
import { ResponsiveTable } from '@endora-commerce/admin-kit/components';
|
|
6
|
+
import { ApiError } from '@endora-commerce/admin-kit/lib';
|
|
7
|
+
import { useTranslation } from '@endora-commerce/admin-kit/i18n';
|
|
8
|
+
import { linkedInAdsClient, listSalesChannels } from '../api/linkedin-ads-client.js';
|
|
9
|
+
/**
|
|
10
|
+
* Conversion mappings list (feature 063, US3). Per-channel Settings (Partner ID,
|
|
11
|
+
* consent, server-side, access token) live on the generic Settings page.
|
|
12
|
+
*/
|
|
13
|
+
export default function ConversionMappingsListPage() {
|
|
14
|
+
const t = useTranslation('linkedin_ads');
|
|
15
|
+
const [items, setItems] = useState([]);
|
|
16
|
+
const [channels, setChannels] = useState([]);
|
|
17
|
+
const [loading, setLoading] = useState(true);
|
|
18
|
+
const [error, setError] = useState(null);
|
|
19
|
+
const messageFor = useCallback((err) => err instanceof ApiError ? err.envelope.error.message : t('error.generic'), [t]);
|
|
20
|
+
const reload = useCallback(async () => {
|
|
21
|
+
setLoading(true);
|
|
22
|
+
setError(null);
|
|
23
|
+
try {
|
|
24
|
+
const [rows, chans] = await Promise.all([
|
|
25
|
+
linkedInAdsClient.list(),
|
|
26
|
+
// A channel read failure must not hide the mappings themselves — the
|
|
27
|
+
// channel column simply falls back to the raw id.
|
|
28
|
+
listSalesChannels().catch(() => ({ items: [] })),
|
|
29
|
+
]);
|
|
30
|
+
setItems(rows);
|
|
31
|
+
setChannels(chans.items);
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
setError(messageFor(err));
|
|
35
|
+
}
|
|
36
|
+
finally {
|
|
37
|
+
setLoading(false);
|
|
38
|
+
}
|
|
39
|
+
}, [messageFor]);
|
|
40
|
+
useEffect(() => {
|
|
41
|
+
void reload();
|
|
42
|
+
}, [reload]);
|
|
43
|
+
const channelLabel = (id) => {
|
|
44
|
+
if (id === null)
|
|
45
|
+
return t('mappings.allChannels');
|
|
46
|
+
return channels.find((c) => c.id === id)?.code ?? id;
|
|
47
|
+
};
|
|
48
|
+
const onDelete = async (row) => {
|
|
49
|
+
if (!window.confirm(t('mappings.deleteConfirm')))
|
|
50
|
+
return;
|
|
51
|
+
try {
|
|
52
|
+
await linkedInAdsClient.remove(row.id);
|
|
53
|
+
await reload();
|
|
54
|
+
}
|
|
55
|
+
catch (err) {
|
|
56
|
+
setError(messageFor(err));
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
const columns = [
|
|
60
|
+
{
|
|
61
|
+
id: 'triggerAction',
|
|
62
|
+
header: t('mappings.triggerAction'),
|
|
63
|
+
primary: true,
|
|
64
|
+
render: (r) => t(`mappings.action.${r.triggerAction}`),
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
id: 'conversionId',
|
|
68
|
+
header: t('mappings.conversionId'),
|
|
69
|
+
render: (r) => _jsx("code", { className: "text-xs", children: r.conversionId }),
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
id: 'salesChannel',
|
|
73
|
+
header: t('mappings.salesChannel'),
|
|
74
|
+
render: (r) => channelLabel(r.salesChannelId),
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
id: 'enabled',
|
|
78
|
+
header: t('mappings.enabled'),
|
|
79
|
+
render: (r) => r.enabled ? _jsx(Badge, { children: t('mappings.enabled') }) : _jsx(Badge, { variant: "secondary", children: "\u2014" }),
|
|
80
|
+
},
|
|
81
|
+
];
|
|
82
|
+
return (_jsxs("div", { children: [_jsx(PageHeader, { title: t('mappings.title'), description: t('mappings.subtitle'), actions: _jsx(Button, { asChild: true, children: _jsx(Link, { to: "/linkedin-ads/new", children: t('mappings.new') }) }) }), error ? (_jsx(Alert, { variant: "destructive", className: "mb-3", children: _jsx(AlertDescription, { children: error }) })) : null, loading ? null : (_jsx(ResponsiveTable, { columns: columns, data: items, keyExtractor: (r) => r.id, emptyState: _jsx("p", { className: "text-sm text-muted-foreground", children: t('mappings.empty') }), renderActions: (r) => (_jsxs("div", { className: "flex justify-end gap-2", children: [_jsx(Button, { asChild: true, variant: "outline", size: "sm", children: _jsx(Link, { to: `/linkedin-ads/${r.id}`, children: t('mappings.edit') }) }), _jsx(Button, { variant: "destructive", size: "sm", onClick: () => void onDelete(r), children: t('mappings.delete') })] })) }))] }));
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=ConversionMappingsListPage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConversionMappingsListPage.js","sourceRoot":"","sources":["../../../src/admin/pages/ConversionMappingsListPage.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { OptionalProps } from '@mikro-orm/core';
|
|
2
|
+
import type { LinkedInTriggerAction } from '@endora-commerce/contracts';
|
|
3
|
+
/**
|
|
4
|
+
* LinkedInConversionMapping (feature 063, US3). Binds a storefront action to a
|
|
5
|
+
* LinkedIn conversion rule defined in Campaign Manager.
|
|
6
|
+
*
|
|
7
|
+
* Platform configuration authored by operators and scoped by sales channel, not
|
|
8
|
+
* by organization, so it is a `@GlobalEntity()` — the same classification as
|
|
9
|
+
* `GaCustomEvent`. `sales_channel_id` null means the mapping applies to every
|
|
10
|
+
* channel.
|
|
11
|
+
*
|
|
12
|
+
* Intentionally NOT unique on (channel, action): one action may legitimately
|
|
13
|
+
* report to several conversion rules. The "at most one conversion" rule is per
|
|
14
|
+
* mapping, not per action.
|
|
15
|
+
*/
|
|
16
|
+
export declare class LinkedInConversionMapping {
|
|
17
|
+
[OptionalProps]?: 'salesChannelId' | 'conversionRuleUrn' | 'enabled' | 'version' | 'createdAt' | 'updatedAt';
|
|
18
|
+
id: string;
|
|
19
|
+
salesChannelId: string | null;
|
|
20
|
+
triggerAction: LinkedInTriggerAction;
|
|
21
|
+
/** Numeric id from Campaign Manager, kept as text — it is an identifier. */
|
|
22
|
+
conversionId: string;
|
|
23
|
+
/** Null ⇒ derived from `conversionId` at delivery time. */
|
|
24
|
+
conversionRuleUrn: string | null;
|
|
25
|
+
enabled: boolean;
|
|
26
|
+
version: number;
|
|
27
|
+
createdAt: Date;
|
|
28
|
+
updatedAt: Date;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=linkedin-conversion-mapping.entity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"linkedin-conversion-mapping.entity.d.ts","sourceRoot":"","sources":["../../../src/backend/entities/linkedin-conversion-mapping.entity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,aAAa,EAAwB,MAAM,iBAAiB,CAAC;AAGrF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAExE;;;;;;;;;;;;GAYG;AACH,qBAMa,yBAAyB;IACpC,CAAC,aAAa,CAAC,CAAC,EACZ,gBAAgB,GAChB,mBAAmB,GACnB,SAAS,GACT,SAAS,GACT,WAAW,GACX,WAAW,CAAC;IAGhB,EAAE,EAAE,MAAM,CAAgB;IAG1B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAQ;IAGrC,aAAa,EAAG,qBAAqB,CAAC;IAEtC,4EAA4E;IAE5E,YAAY,EAAG,MAAM,CAAC;IAEtB,2DAA2D;IAE3D,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAQ;IAGxC,OAAO,EAAE,OAAO,CAAQ;IAGxB,OAAO,EAAE,MAAM,CAAK;IAGpB,SAAS,EAAE,IAAI,CAAc;IAG7B,SAAS,EAAE,IAAI,CAAc;CAC9B"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
import { Entity, Index, OptionalProps, PrimaryKey, Property } from '@mikro-orm/core';
|
|
11
|
+
import { GlobalEntity } from '@endora-commerce/platform/tenancy';
|
|
12
|
+
import { randomUUID } from 'crypto';
|
|
13
|
+
/**
|
|
14
|
+
* LinkedInConversionMapping (feature 063, US3). Binds a storefront action to a
|
|
15
|
+
* LinkedIn conversion rule defined in Campaign Manager.
|
|
16
|
+
*
|
|
17
|
+
* Platform configuration authored by operators and scoped by sales channel, not
|
|
18
|
+
* by organization, so it is a `@GlobalEntity()` — the same classification as
|
|
19
|
+
* `GaCustomEvent`. `sales_channel_id` null means the mapping applies to every
|
|
20
|
+
* channel.
|
|
21
|
+
*
|
|
22
|
+
* Intentionally NOT unique on (channel, action): one action may legitimately
|
|
23
|
+
* report to several conversion rules. The "at most one conversion" rule is per
|
|
24
|
+
* mapping, not per action.
|
|
25
|
+
*/
|
|
26
|
+
let LinkedInConversionMapping = class LinkedInConversionMapping {
|
|
27
|
+
[OptionalProps];
|
|
28
|
+
id = randomUUID();
|
|
29
|
+
salesChannelId = null;
|
|
30
|
+
triggerAction;
|
|
31
|
+
/** Numeric id from Campaign Manager, kept as text — it is an identifier. */
|
|
32
|
+
conversionId;
|
|
33
|
+
/** Null ⇒ derived from `conversionId` at delivery time. */
|
|
34
|
+
conversionRuleUrn = null;
|
|
35
|
+
enabled = true;
|
|
36
|
+
version = 1;
|
|
37
|
+
createdAt = new Date();
|
|
38
|
+
updatedAt = new Date();
|
|
39
|
+
};
|
|
40
|
+
__decorate([
|
|
41
|
+
PrimaryKey({ type: 'uuid' }),
|
|
42
|
+
__metadata("design:type", String)
|
|
43
|
+
], LinkedInConversionMapping.prototype, "id", void 0);
|
|
44
|
+
__decorate([
|
|
45
|
+
Property({ type: 'uuid', fieldName: 'sales_channel_id', nullable: true }),
|
|
46
|
+
__metadata("design:type", Object)
|
|
47
|
+
], LinkedInConversionMapping.prototype, "salesChannelId", void 0);
|
|
48
|
+
__decorate([
|
|
49
|
+
Property({ type: 'string', length: 32, fieldName: 'trigger_action' }),
|
|
50
|
+
__metadata("design:type", String)
|
|
51
|
+
], LinkedInConversionMapping.prototype, "triggerAction", void 0);
|
|
52
|
+
__decorate([
|
|
53
|
+
Property({ type: 'string', length: 32, fieldName: 'conversion_id' }),
|
|
54
|
+
__metadata("design:type", String)
|
|
55
|
+
], LinkedInConversionMapping.prototype, "conversionId", void 0);
|
|
56
|
+
__decorate([
|
|
57
|
+
Property({ type: 'string', length: 128, fieldName: 'conversion_rule_urn', nullable: true }),
|
|
58
|
+
__metadata("design:type", Object)
|
|
59
|
+
], LinkedInConversionMapping.prototype, "conversionRuleUrn", void 0);
|
|
60
|
+
__decorate([
|
|
61
|
+
Property({ type: 'boolean' }),
|
|
62
|
+
__metadata("design:type", Boolean)
|
|
63
|
+
], LinkedInConversionMapping.prototype, "enabled", void 0);
|
|
64
|
+
__decorate([
|
|
65
|
+
Property({ type: 'integer' }),
|
|
66
|
+
__metadata("design:type", Number)
|
|
67
|
+
], LinkedInConversionMapping.prototype, "version", void 0);
|
|
68
|
+
__decorate([
|
|
69
|
+
Property({ type: 'datetime', fieldName: 'created_at', onCreate: () => new Date() }),
|
|
70
|
+
__metadata("design:type", Date)
|
|
71
|
+
], LinkedInConversionMapping.prototype, "createdAt", void 0);
|
|
72
|
+
__decorate([
|
|
73
|
+
Property({ type: 'datetime', fieldName: 'updated_at', onUpdate: () => new Date() }),
|
|
74
|
+
__metadata("design:type", Date)
|
|
75
|
+
], LinkedInConversionMapping.prototype, "updatedAt", void 0);
|
|
76
|
+
LinkedInConversionMapping = __decorate([
|
|
77
|
+
GlobalEntity(),
|
|
78
|
+
Entity({ tableName: 'linkedin_conversion_mappings' }),
|
|
79
|
+
Index({
|
|
80
|
+
name: 'linkedin_conversion_mappings_channel_action_idx',
|
|
81
|
+
properties: ['salesChannelId', 'triggerAction'],
|
|
82
|
+
})
|
|
83
|
+
], LinkedInConversionMapping);
|
|
84
|
+
export { LinkedInConversionMapping };
|
|
85
|
+
//# sourceMappingURL=linkedin-conversion-mapping.entity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"linkedin-conversion-mapping.entity.js","sourceRoot":"","sources":["../../../src/backend/entities/linkedin-conversion-mapping.entity.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AACrF,OAAO,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAGpC;;;;;;;;;;;;GAYG;AAOI,IAAM,yBAAyB,GAA/B,MAAM,yBAAyB;IACpC,CAAC,aAAa,CAAC,CAMC;IAGhB,EAAE,GAAW,UAAU,EAAE,CAAC;IAG1B,cAAc,GAAkB,IAAI,CAAC;IAGrC,aAAa,CAAyB;IAEtC,4EAA4E;IAE5E,YAAY,CAAU;IAEtB,2DAA2D;IAE3D,iBAAiB,GAAkB,IAAI,CAAC;IAGxC,OAAO,GAAY,IAAI,CAAC;IAGxB,OAAO,GAAW,CAAC,CAAC;IAGpB,SAAS,GAAS,IAAI,IAAI,EAAE,CAAC;IAG7B,SAAS,GAAS,IAAI,IAAI,EAAE,CAAC;CAC9B,CAAA;AA3BC;IADC,UAAU,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;qDACH;AAG1B;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,kBAAkB,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;iEACrC;AAGrC;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,gBAAgB,EAAE,CAAC;;gEAChC;AAItC;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,eAAe,EAAE,CAAC;;+DAC/C;AAItB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,qBAAqB,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;oEACpD;AAGxC;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;;0DACN;AAGxB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;;0DACV;AAGpB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC;8BACzE,IAAI;4DAAc;AAG7B;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC;8BACzE,IAAI;4DAAc;AApClB,yBAAyB;IANrC,YAAY,EAAE;IACd,MAAM,CAAC,EAAE,SAAS,EAAE,8BAA8B,EAAE,CAAC;IACrD,KAAK,CAAC;QACL,IAAI,EAAE,iDAAiD;QACvD,UAAU,EAAE,CAAC,gBAAgB,EAAE,eAAe,CAAC;KAChD,CAAC;GACW,yBAAyB,CAqCrC"}
|