# mk-sdk

SDK de tracking de e-commerce + try-on da MetaKosmos. Um único `<script>` que
roda em todas as páginas da loja: mede a jornada de compra (visita → produto →
carrinho → compra) e injeta o botão de provador virtual de forma zero-touch.

Publicado no npm como [`mk-sdk-git`](https://www.npmjs.com/package/mk-sdk-git)
e distribuído via CDN — **unpkg** por padrão (jsDelivr como alternativa).

## Instalação

Cole **uma linha** antes de `</head>`, em **todas as páginas** da loja:

```html
<script src="https://unpkg.com/mk-sdk-git@1/dist/mk-sdk.js"
        data-mk-project="SEU_PROJECT_ID"
        data-mk-product="mk-fashion"
        async></script>
```

- `data-mk-project` — ID do projeto (obrigatório).
- `data-mk-product` — produto MetaKosmos da página (`mk-fashion`, `mk-beauty`,
  `mk-3d`…). Opcional; default `mk-fashion`.
- `async` — não bloqueia o carregamento da página.

### Versão do CDN

O CDN padrão é o **unpkg** (`https://unpkg.com/…`). Motivo: lojas com CSP
restritiva (ex.: Wake/Fbits) costumam liberar o unpkg mas **não** o jsDelivr —
usar unpkg por padrão evita a tag ser bloqueada pela política da loja.

| Forma | URL | Quando usar |
|---|---|---|
| **Major fixo** (recomendado) | `https://unpkg.com/mk-sdk-git@1/dist/mk-sdk.js` | Pega o último `1.x.y` automaticamente — recebe correções sem quebrar |
| **Versão exata** | `https://unpkg.com/mk-sdk-git@1.2.3/dist/mk-sdk.js` | Trava numa versão específica (imutável) |
| **jsDelivr** (alternativa) | `https://cdn.jsdelivr.net/npm/mk-sdk-git@1/dist/mk-sdk.js` | Só se a CSP da loja liberar jsDelivr e não unpkg |

> Evite `@latest` em produção: cache fraco e risco de um release novo quebrar a
> loja sem aviso. Prefira o major fixo (`@1`).
>
> O bootstrap deriva o CDN do core da própria tag: seja qual for o CDN da tag
> (unpkg/jsDelivr), o `mk-core.js` vem do **mesmo** CDN — sem hardcode.

### Via bundler (opcional)

```bash
npm install mk-sdk-git
```
O SDK é um IIFE auto-executável feito pra `<script>`. Num bundler, importe e
garanta que `window.__MK = { projectId, product }` esteja definido antes do
import (não há tag `<script>` pra ler os `data-*`).

## React Native

Para apps React Native use o pacote
[`mk-sdk-react-native`](packages/react-native/README.md) (provador em WebView +
tracking com API explícita). O protocolo compartilhado (eventos, bridge do
visualizer, sanitize) vive em [`mk-sdk-shared`](packages/shared/README.md) —
**mudanças de protocolo precisam ser aplicadas lá e em `src/` até a web migrar
pro pacote shared.**

## Configuração

Lida do `<script>` (`data-mk-*`) ou de `window.__MK` antes do boot:

| Campo | Origem | Default |
|---|---|---|
| `projectId` | `data-mk-project` / `__MK.projectId` | — (obrigatório) |
| `product` | `data-mk-product` / `__MK.product` | `mk-fashion` |
| `collectorUrl` | `data-mk-collector` / `__MK.collectorUrl` | `api-collector.mk3dlabs.com` |
| `apiUrl` | `__MK.apiUrl` | `mkfashion-new-api.mk3dlabs.com` |
| `debug` | `data-mk-debug` / `?mkdebug` | `false` |
| `anchor` | `__MK.anchor` | `null` (cai no CMS/heurística) |

## API pública (`window.mk`)

```js
mk.open({ projectId, identifier });   // abre o provador
mk.close();
mk.isAvailable(projectId, identifier);
mk.onReady(cb); mk.onAddToCart(cb); mk.onProductLoaded(cb); /* … */
```

## Coleta

Eventos vão em batch para `POST {collectorUrl}/v1/track` com header
`X-MK-Project-Id`. Dados pessoais (e-mail, CPF, telefone, etc.) são descartados
antes do envio.

Cada POST vira **um objeto no S3**, e a agregação abre um por um — por isso o
lote é fechado o mais tarde possível. Gatilhos (o primeiro que acontecer):

| Gatilho | Default | Override (`window.__MK`) |
|---|---|---|
| Contagem | 50 eventos (teto do collector) | `batchMaxSize` |
| Timer **com piso** | a cada 15s, só se já houver ≥ 25 eventos | `batchIntervalMs`, `batchMinSize` |
| Retenção máxima | 120s desde o evento mais antigo | `batchMaxHoldMs` |
| **Saída da página** | `visibilitychange`→hidden, `pagehide`, `beforeunload` | — |

O piso é o que evita o pior caso (uma página parada emite 1 evento a cada 15s,
e cada um virava um objeto sozinho no S3). O flush de saída ignora o piso e
manda tudo, com `fetch({ keepalive: true })` — mesma garantia de sobrevida ao
unload que o `sendBeacon`, mas com CORS funcionando (ver comentário em
`src/core/transport.js`).

## Build

```bash
npm install
npm run build         # gera dist/mk-sdk.js
npm run build:ext     # gera dist + copia pra extension/mk-sdk.js
npm run build:watch   # rebuild em watch
```

## Release

Push na `main` publica no npm (`.github/workflows/publish.yml`). Se a versão do
`package.json` já estiver publicada, o job bumpa o patch a partir do *latest* do
registry, dentro do runner, e publica.

O bump não é commitado: a `main` é protegida por ruleset da organização
(PR aprovado obrigatório, sem bypass), então o bot não consegue pushar. Por isso
o `package.json` do repo fica atrás do npm de propósito — a versão real é a do
registry, e cada release ganha uma tag `vX.Y.Z` no commit que a gerou.

Para um minor/major, bumpe o `package.json` à mão no PR: se a versão ainda não
existir no npm, o job a usa como está.

## Extensão de QA

`extension/` é uma extensão Chrome que injeta o `mk-sdk` em qualquer loja para
validar a integração (tracking, detecção de plataforma/SKU, picker de posição
do botão) sem a marca precisar instalar o script. Veja `extension/README.md`.

## Diagnóstico

`scripts/` tem sondas (`probe-*.js`, `recon-loja.js`) para inspecionar detecção
de plataforma/SKU e fluxo de carrinho ao vivo numa loja.
