@kaikybrofc/omnizap-system 2.1.8
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/.env.example +534 -0
- package/LICENSE +21 -0
- package/README.md +431 -0
- package/RELEASE-v2.1.2.md +83 -0
- package/app/config/adminIdentity.js +87 -0
- package/app/config/baileysConfig.js +693 -0
- package/app/config/groupUtils.js +388 -0
- package/app/connection/socketController.js +992 -0
- package/app/controllers/messageController.js +354 -0
- package/app/modules/adminModule/groupCommandHandlers.js +1294 -0
- package/app/modules/adminModule/groupEventHandlers.js +355 -0
- package/app/modules/aiModule/catCommand.js +1006 -0
- package/app/modules/broadcastModule/noticeCommand.js +416 -0
- package/app/modules/gameModule/diceCommand.js +67 -0
- package/app/modules/menuModule/common.js +311 -0
- package/app/modules/menuModule/menus.js +59 -0
- package/app/modules/playModule/playCommand.js +1615 -0
- package/app/modules/quoteModule/quoteCommand.js +851 -0
- package/app/modules/rpgPokemonModule/rpgBattleCanvasRenderer.js +786 -0
- package/app/modules/rpgPokemonModule/rpgBattleService.js +2082 -0
- package/app/modules/rpgPokemonModule/rpgBattleService.test.js +760 -0
- package/app/modules/rpgPokemonModule/rpgEvolutionUtils.js +22 -0
- package/app/modules/rpgPokemonModule/rpgPokemonCommand.js +172 -0
- package/app/modules/rpgPokemonModule/rpgPokemonDomain.js +192 -0
- package/app/modules/rpgPokemonModule/rpgPokemonDomain.test.js +93 -0
- package/app/modules/rpgPokemonModule/rpgPokemonEvolution.test.js +46 -0
- package/app/modules/rpgPokemonModule/rpgPokemonMessages.js +746 -0
- package/app/modules/rpgPokemonModule/rpgPokemonRepository.js +1859 -0
- package/app/modules/rpgPokemonModule/rpgPokemonService.js +6738 -0
- package/app/modules/rpgPokemonModule/rpgProfileCanvasRenderer.js +354 -0
- package/app/modules/statsModule/globalRankingCommand.js +65 -0
- package/app/modules/statsModule/noMessageCommand.js +288 -0
- package/app/modules/statsModule/rankingCommand.js +60 -0
- package/app/modules/statsModule/rankingCommon.js +889 -0
- package/app/modules/stickerModule/addStickerMetadata.js +239 -0
- package/app/modules/stickerModule/convertToWebp.js +390 -0
- package/app/modules/stickerModule/stickerCommand.js +454 -0
- package/app/modules/stickerModule/stickerConvertCommand.js +156 -0
- package/app/modules/stickerModule/stickerTextCommand.js +657 -0
- package/app/modules/stickerPackModule/autoPackCollectorRuntime.js +20 -0
- package/app/modules/stickerPackModule/autoPackCollectorService.js +284 -0
- package/app/modules/stickerPackModule/semanticReclassificationEngine.js +466 -0
- package/app/modules/stickerPackModule/semanticReclassificationEngine.test.js +88 -0
- package/app/modules/stickerPackModule/semanticThemeClusterService.js +571 -0
- package/app/modules/stickerPackModule/stickerAssetClassificationRepository.js +449 -0
- package/app/modules/stickerPackModule/stickerAssetRepository.js +400 -0
- package/app/modules/stickerPackModule/stickerAssetReprocessQueueRepository.js +180 -0
- package/app/modules/stickerPackModule/stickerAutoPackByTagsRuntime.js +4078 -0
- package/app/modules/stickerPackModule/stickerClassificationBackgroundRuntime.js +598 -0
- package/app/modules/stickerPackModule/stickerClassificationService.js +588 -0
- package/app/modules/stickerPackModule/stickerMarketplaceDriftService.js +102 -0
- package/app/modules/stickerPackModule/stickerPackCatalogHttp.js +7506 -0
- package/app/modules/stickerPackModule/stickerPackCommandHandlers.js +1095 -0
- package/app/modules/stickerPackModule/stickerPackEngagementRepository.js +108 -0
- package/app/modules/stickerPackModule/stickerPackErrors.js +30 -0
- package/app/modules/stickerPackModule/stickerPackInteractionEventRepository.js +110 -0
- package/app/modules/stickerPackModule/stickerPackItemRepository.js +440 -0
- package/app/modules/stickerPackModule/stickerPackMarketplaceService.js +337 -0
- package/app/modules/stickerPackModule/stickerPackMessageService.js +296 -0
- package/app/modules/stickerPackModule/stickerPackRepository.js +442 -0
- package/app/modules/stickerPackModule/stickerPackService.js +788 -0
- package/app/modules/stickerPackModule/stickerPackServiceRuntime.js +51 -0
- package/app/modules/stickerPackModule/stickerPackUtils.js +97 -0
- package/app/modules/stickerPackModule/stickerStorageService.js +507 -0
- package/app/modules/stickerPackModule/stickerWorkerPipelineRuntime.js +233 -0
- package/app/modules/stickerPackModule/stickerWorkerTaskQueueRepository.js +205 -0
- package/app/modules/systemMetricsModule/pingCommand.js +421 -0
- package/app/modules/tiktokModule/tiktokCommand.js +798 -0
- package/app/modules/userModule/userCommand.js +1217 -0
- package/app/modules/waifuPicsModule/waifuPicsCommand.js +177 -0
- package/app/observability/metrics.js +734 -0
- package/app/services/captchaService.js +492 -0
- package/app/services/dbWriteQueue.js +572 -0
- package/app/services/groupMetadataService.js +279 -0
- package/app/services/lidMapService.js +663 -0
- package/app/services/messagePersistenceService.js +56 -0
- package/app/services/newsBroadcastService.js +351 -0
- package/app/services/pokeApiService.js +398 -0
- package/app/services/queueUtils.js +57 -0
- package/app/services/socketState.js +7 -0
- package/app/store/aiPromptStore.js +38 -0
- package/app/store/groupConfigStore.js +58 -0
- package/app/store/premiumUserStore.js +36 -0
- package/app/utils/antiLink/antiLinkModule.js +804 -0
- package/app/utils/http/getImageBufferModule.js +18 -0
- package/app/utils/json/jsonSanitizer.js +113 -0
- package/app/utils/json/jsonSanitizer.test.js +40 -0
- package/app/utils/logger/loggerModule.js +262 -0
- package/app/utils/systemMetrics/systemMetricsModule.js +91 -0
- package/database/index.js +2052 -0
- package/database/init.js +516 -0
- package/database/migrations/20260203_0001_sticker_packs.sql +54 -0
- package/database/migrations/20260210_0003_rpg_pokemon.sql +58 -0
- package/database/migrations/20260210_0004_rpg_shiny_biome.sql +9 -0
- package/database/migrations/20260210_0005_rpg_missions.sql +14 -0
- package/database/migrations/20260210_0006_rpg_world_pokedex_traits.sql +27 -0
- package/database/migrations/20260210_0007_rpg_raid_pvp.sql +56 -0
- package/database/migrations/20260210_0008_rpg_social_system.sql +195 -0
- package/database/migrations/20260211_0009_rpg_social_xp.sql +36 -0
- package/database/migrations/20260222_0010_remove_message_xp.sql +2 -0
- package/database/migrations/20260226_0011_sticker_asset_classification.sql +17 -0
- package/database/migrations/20260226_0012_sticker_pack_engagement.sql +16 -0
- package/database/migrations/20260226_0013_sticker_marketplace_intelligence.sql +19 -0
- package/database/migrations/20260226_0014_sticker_pack_publish_flow.sql +30 -0
- package/database/migrations/20260226_0014_sticker_worker_queues.sql +42 -0
- package/database/migrations/20260226_0015_sticker_auto_pack_curation_integrity.sql +18 -0
- package/database/migrations/20260226_0016_sticker_web_google_auth_persistence.sql +34 -0
- package/database/migrations/20260226_0017_sticker_web_admin_ban.sql +22 -0
- package/database/migrations/20260226_0018_sticker_web_admin_moderator.sql +18 -0
- package/database/migrations/20260227_0019_sticker_classification_v2_signals.sql +12 -0
- package/database/migrations/20260227_0020_semantic_theme_clusters.sql +35 -0
- package/docker-compose.yml +103 -0
- package/ecosystem.prod.config.cjs +35 -0
- package/eslint.config.js +61 -0
- package/index.js +437 -0
- package/ml/clip_classifier/Dockerfile +16 -0
- package/ml/clip_classifier/README.md +120 -0
- package/ml/clip_classifier/adaptive_scoring.py +40 -0
- package/ml/clip_classifier/classifier.py +654 -0
- package/ml/clip_classifier/embedding_store.py +481 -0
- package/ml/clip_classifier/env_loader.py +15 -0
- package/ml/clip_classifier/llm_label_expander.py +144 -0
- package/ml/clip_classifier/main.py +213 -0
- package/ml/clip_classifier/requirements.txt +10 -0
- package/ml/clip_classifier/similarity_engine.py +74 -0
- package/observability/alert-rules.yml +60 -0
- package/observability/grafana/dashboards/omnizap-mysql.json +136 -0
- package/observability/grafana/dashboards/omnizap-overview.json +170 -0
- package/observability/grafana/provisioning/dashboards/dashboards.yml +11 -0
- package/observability/grafana/provisioning/datasources/datasources.yml +15 -0
- package/observability/loki-config.yml +38 -0
- package/observability/mysql-exporter.cnf +5 -0
- package/observability/mysql-setup.sql +46 -0
- package/observability/prometheus.yml +32 -0
- package/observability/promtail-config.yml +84 -0
- package/package.json +109 -0
- package/public/api-docs/index.html +144 -0
- package/public/css/github-project-panel.css +297 -0
- package/public/css/stickers-admin.css +1272 -0
- package/public/css/styles.css +671 -0
- package/public/index.html +1311 -0
- package/public/js/apps/apiDocsApp.js +310 -0
- package/public/js/apps/createPackApp.js +2069 -0
- package/public/js/apps/homeApp.js +396 -0
- package/public/js/apps/stickersAdminApp.js +1744 -0
- package/public/js/apps/stickersApp.js +4830 -0
- package/public/js/catalog.js +1019 -0
- package/public/js/github-panel/components/CommitList.js +34 -0
- package/public/js/github-panel/components/ErrorState.js +16 -0
- package/public/js/github-panel/components/GithubProjectPanel.js +106 -0
- package/public/js/github-panel/components/ReleaseList.js +38 -0
- package/public/js/github-panel/components/SkeletonPanel.js +22 -0
- package/public/js/github-panel/components/StatCard.js +15 -0
- package/public/js/github-panel/index.js +15 -0
- package/public/js/github-panel/useGithubRepoData.js +154 -0
- package/public/js/github-panel/vendor/react.js +11 -0
- package/public/js/runtime/react-runtime.js +19 -0
- package/public/licenca/index.html +106 -0
- package/public/stickers/admin/index.html +23 -0
- package/public/stickers/create/index.html +47 -0
- package/public/stickers/index.html +48 -0
- package/public/termos-de-uso/index.html +125 -0
- package/scripts/cache-bust.mjs +107 -0
- package/scripts/deploy.sh +458 -0
- package/scripts/github-deploy-notify.mjs +174 -0
- package/scripts/release.sh +129 -0
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
import { React, createRoot, useEffect, useState } from '../runtime/react-runtime.js';
|
|
2
|
+
|
|
3
|
+
const h = React.createElement;
|
|
4
|
+
|
|
5
|
+
function Icon({ cls }) {
|
|
6
|
+
return h('i', { className: `icon ${cls}`, 'aria-hidden': 'true' });
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function Card({ title, code, iconClass }) {
|
|
10
|
+
return h(
|
|
11
|
+
'section',
|
|
12
|
+
{ className: 'card' },
|
|
13
|
+
h('h2', null, h(Icon, { cls: iconClass || 'fa-solid fa-file-code' }), title),
|
|
14
|
+
h('pre', null, h('code', null, code)),
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function SectionTitle({ iconClass, children }) {
|
|
19
|
+
return h('h2', { className: 'section-title' }, h(Icon, { cls: iconClass }), children);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function StatusPanel() {
|
|
23
|
+
const [state, setState] = useState({
|
|
24
|
+
loading: true,
|
|
25
|
+
ok: false,
|
|
26
|
+
latencyMs: null,
|
|
27
|
+
cpu: null,
|
|
28
|
+
ram: null,
|
|
29
|
+
uptime: null,
|
|
30
|
+
error: '',
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
useEffect(() => {
|
|
34
|
+
let active = true;
|
|
35
|
+
|
|
36
|
+
const load = async () => {
|
|
37
|
+
const start = Date.now();
|
|
38
|
+
try {
|
|
39
|
+
const response = await fetch('/api/sticker-packs/system-summary');
|
|
40
|
+
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
|
41
|
+
const payload = await response.json();
|
|
42
|
+
const data = payload?.data || {};
|
|
43
|
+
const host = data.host || {};
|
|
44
|
+
const process = data.process || {};
|
|
45
|
+
|
|
46
|
+
if (!active) return;
|
|
47
|
+
setState({
|
|
48
|
+
loading: false,
|
|
49
|
+
ok: true,
|
|
50
|
+
latencyMs: Date.now() - start,
|
|
51
|
+
cpu: Number.isFinite(Number(host.cpu_percent)) ? `${Number(host.cpu_percent).toFixed(2)}%` : 'n/d',
|
|
52
|
+
ram:
|
|
53
|
+
host.memory_used && host.memory_total
|
|
54
|
+
? `${host.memory_used} / ${host.memory_total} (${Number(host.memory_percent || 0).toFixed(2)}%)`
|
|
55
|
+
: 'n/d',
|
|
56
|
+
uptime: process.uptime || 'n/d',
|
|
57
|
+
error: '',
|
|
58
|
+
});
|
|
59
|
+
} catch (error) {
|
|
60
|
+
if (!active) return;
|
|
61
|
+
setState({
|
|
62
|
+
loading: false,
|
|
63
|
+
ok: false,
|
|
64
|
+
latencyMs: null,
|
|
65
|
+
cpu: null,
|
|
66
|
+
ram: null,
|
|
67
|
+
uptime: null,
|
|
68
|
+
error: error?.message || 'Falha ao consultar status da API',
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
load();
|
|
74
|
+
const timer = setInterval(load, 60 * 1000);
|
|
75
|
+
return () => {
|
|
76
|
+
active = false;
|
|
77
|
+
clearInterval(timer);
|
|
78
|
+
};
|
|
79
|
+
}, []);
|
|
80
|
+
|
|
81
|
+
const statusLabel = state.loading ? 'Consultando...' : state.ok ? 'Online' : 'Instável';
|
|
82
|
+
const statusClass = state.loading ? 'badge badge-warn' : state.ok ? 'badge badge-ok' : 'badge badge-bad';
|
|
83
|
+
|
|
84
|
+
return h(
|
|
85
|
+
'section',
|
|
86
|
+
{ className: 'card' },
|
|
87
|
+
h('h3', { className: 'sub-title' }, h(Icon, { cls: 'fa-solid fa-heart-pulse' }), 'Status em tempo real'),
|
|
88
|
+
h('div', { className: 'status-row' }, h('span', { className: statusClass }, statusLabel), state.latencyMs ? h('span', { className: 'status-meta' }, `Latência: ${state.latencyMs}ms`) : null),
|
|
89
|
+
h(
|
|
90
|
+
'div',
|
|
91
|
+
{ className: 'status-grid' },
|
|
92
|
+
h('div', { className: 'status-item' }, h('strong', null, 'CPU host'), h('span', null, state.cpu || 'n/d')),
|
|
93
|
+
h('div', { className: 'status-item' }, h('strong', null, 'RAM host'), h('span', null, state.ram || 'n/d')),
|
|
94
|
+
h('div', { className: 'status-item' }, h('strong', null, 'Uptime processo'), h('span', null, state.uptime || 'n/d')),
|
|
95
|
+
),
|
|
96
|
+
state.error ? h('p', { className: 'status-error' }, `Falha: ${state.error}`) : null,
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function ApiDocsApp() {
|
|
101
|
+
return h(
|
|
102
|
+
'main',
|
|
103
|
+
{ className: 'wrap' },
|
|
104
|
+
h(
|
|
105
|
+
'div',
|
|
106
|
+
{ className: 'top' },
|
|
107
|
+
h('a', { href: '/' }, h(Icon, { cls: 'fa-solid fa-house' }), 'Home'),
|
|
108
|
+
h('a', { href: '/stickers/' }, h(Icon, { cls: 'fa-solid fa-icons' }), 'Stickers'),
|
|
109
|
+
h('a', { href: '/termos-de-uso/' }, h(Icon, { cls: 'fa-solid fa-file-contract' }), 'Termos'),
|
|
110
|
+
h('a', { href: '/licenca/' }, h(Icon, { cls: 'fa-solid fa-scale-balanced' }), 'Licença'),
|
|
111
|
+
h('a', { href: 'https://github.com/Kaikygr/omnizap-system', target: '_blank', rel: 'noreferrer noopener' }, h(Icon, { cls: 'fa-brands fa-github' }), 'GitHub'),
|
|
112
|
+
),
|
|
113
|
+
h('h1', null, h(Icon, { cls: 'fa-solid fa-code' }), 'OmniZap API Docs'),
|
|
114
|
+
h('p', null, 'API pública para catálogo de packs, stickers, métricas e interações em tempo real.'),
|
|
115
|
+
h(SectionTitle, { iconClass: 'fa-solid fa-route' }, 'Maneiras de uso'),
|
|
116
|
+
h(
|
|
117
|
+
'section',
|
|
118
|
+
{ className: 'card' },
|
|
119
|
+
h('ul', { className: 'list' },
|
|
120
|
+
h('li', null, 'Uso direto no front-end web para catálogo e busca de packs.'),
|
|
121
|
+
h('li', null, 'Integração server-to-server para sincronização com sistemas próprios.'),
|
|
122
|
+
h('li', null, 'Consumo em bots/automação para abrir pack, baixar sticker e montar fluxos.')
|
|
123
|
+
),
|
|
124
|
+
),
|
|
125
|
+
h(StatusPanel),
|
|
126
|
+
h(SectionTitle, { iconClass: 'fa-solid fa-plug-circle-check' }, 'Endpoints'),
|
|
127
|
+
h(Card, { title: 'Base URL', code: 'https://omnizap.shop/api/sticker-packs', iconClass: 'fa-solid fa-link' }),
|
|
128
|
+
h(Card, {
|
|
129
|
+
title: 'Listar packs',
|
|
130
|
+
code: 'GET /api/sticker-packs?q=&visibility=public|unlisted|all&limit=&offset=',
|
|
131
|
+
iconClass: 'fa-solid fa-layer-group',
|
|
132
|
+
}),
|
|
133
|
+
h(Card, {
|
|
134
|
+
title: 'Listar stickers sem pack',
|
|
135
|
+
code: 'GET /api/sticker-packs/orphan-stickers?q=&categories=&limit=&offset=',
|
|
136
|
+
iconClass: 'fa-solid fa-box-open',
|
|
137
|
+
}),
|
|
138
|
+
h(Card, { title: 'Detalhes de pack', code: 'GET /api/sticker-packs/:packKey', iconClass: 'fa-solid fa-circle-info' }),
|
|
139
|
+
h(Card, {
|
|
140
|
+
title: 'Interações do pack (dados reais)',
|
|
141
|
+
code:
|
|
142
|
+
'POST /api/sticker-packs/:packKey/open\n' +
|
|
143
|
+
'POST /api/sticker-packs/:packKey/like\n' +
|
|
144
|
+
'POST /api/sticker-packs/:packKey/dislike',
|
|
145
|
+
iconClass: 'fa-solid fa-thumbs-up',
|
|
146
|
+
}),
|
|
147
|
+
h(Card, { title: 'Contato de suporte', code: 'GET /api/sticker-packs/support', iconClass: 'fa-brands fa-whatsapp' }),
|
|
148
|
+
h(Card, {
|
|
149
|
+
title: 'Imagem de sticker',
|
|
150
|
+
code: 'GET /api/sticker-packs/:packKey/stickers/:stickerId.webp\nGET /data/stickers/:owner/:file.webp',
|
|
151
|
+
iconClass: 'fa-solid fa-image',
|
|
152
|
+
}),
|
|
153
|
+
h(Card, { title: 'Resumo de métricas do sistema', code: 'GET /api/sticker-packs/system-summary', iconClass: 'fa-solid fa-gauge-high' }),
|
|
154
|
+
h(Card, { title: 'Resumo do projeto no GitHub', code: 'GET /api/sticker-packs/project-summary', iconClass: 'fa-brands fa-github' }),
|
|
155
|
+
h(Card, { title: 'Ranking global (cacheado)', code: 'GET /api/sticker-packs/global-ranking-summary', iconClass: 'fa-solid fa-ranking-star' }),
|
|
156
|
+
h(SectionTitle, { iconClass: 'fa-solid fa-brackets-curly' }, 'Como a API responde'),
|
|
157
|
+
h(Card, {
|
|
158
|
+
title: 'Padrão de resposta (sucesso)',
|
|
159
|
+
code:
|
|
160
|
+
'{\n' +
|
|
161
|
+
' "data": [ ... ],\n' +
|
|
162
|
+
' "pagination": { "limit": 24, "offset": 0, "has_more": true, "next_offset": 24 },\n' +
|
|
163
|
+
' "filters": { "q": "", "visibility": "public", "categories": [] }\n' +
|
|
164
|
+
'}',
|
|
165
|
+
iconClass: 'fa-solid fa-circle-check',
|
|
166
|
+
}),
|
|
167
|
+
h(Card, {
|
|
168
|
+
title: 'Padrão de resposta (erro)',
|
|
169
|
+
code:
|
|
170
|
+
'{\n' +
|
|
171
|
+
' "ok": false,\n' +
|
|
172
|
+
' "error": "mensagem descritiva do erro"\n' +
|
|
173
|
+
'}',
|
|
174
|
+
iconClass: 'fa-solid fa-triangle-exclamation',
|
|
175
|
+
}),
|
|
176
|
+
h(Card, {
|
|
177
|
+
title: 'Exemplo real de retorno (pack + engagement)',
|
|
178
|
+
code:
|
|
179
|
+
'{\n' +
|
|
180
|
+
' "data": {\n' +
|
|
181
|
+
' "pack_key": "auto-manga-panel-2-iu4n2",\n' +
|
|
182
|
+
' "name": "[AUTO] Manga Panel #2",\n' +
|
|
183
|
+
' "sticker_count": 30,\n' +
|
|
184
|
+
' "tags": ["manga-panel", "anime"],\n' +
|
|
185
|
+
' "engagement": {\n' +
|
|
186
|
+
' "open_count": 120,\n' +
|
|
187
|
+
' "like_count": 34,\n' +
|
|
188
|
+
' "dislike_count": 2,\n' +
|
|
189
|
+
' "score": 32\n' +
|
|
190
|
+
' }\n' +
|
|
191
|
+
' }\n' +
|
|
192
|
+
'}',
|
|
193
|
+
iconClass: 'fa-solid fa-database',
|
|
194
|
+
}),
|
|
195
|
+
h(SectionTitle, { iconClass: 'fa-solid fa-filter' }, 'Filtros e paginação'),
|
|
196
|
+
h(Card, {
|
|
197
|
+
title: 'Parâmetros principais',
|
|
198
|
+
code:
|
|
199
|
+
'q: texto de busca (nome, publisher, descrição, pack_key)\n' +
|
|
200
|
+
'visibility: public | unlisted | all\n' +
|
|
201
|
+
'categories: lista separada por vírgula (ex: anime,meme)\n' +
|
|
202
|
+
'limit: tamanho da página\n' +
|
|
203
|
+
'offset: deslocamento para próxima página',
|
|
204
|
+
iconClass: 'fa-solid fa-sliders',
|
|
205
|
+
}),
|
|
206
|
+
h(Card, {
|
|
207
|
+
title: 'Exemplo de paginação incremental',
|
|
208
|
+
code:
|
|
209
|
+
'GET /api/sticker-packs?visibility=public&limit=24&offset=0\n' +
|
|
210
|
+
'GET /api/sticker-packs?visibility=public&limit=24&offset=24\n' +
|
|
211
|
+
'GET /api/sticker-packs?visibility=public&limit=24&offset=48',
|
|
212
|
+
iconClass: 'fa-solid fa-forward-step',
|
|
213
|
+
}),
|
|
214
|
+
h(SectionTitle, { iconClass: 'fa-solid fa-diagram-project' }, 'Como integrar no seu sistema'),
|
|
215
|
+
h(Card, {
|
|
216
|
+
title: 'Passo a passo de integração',
|
|
217
|
+
code:
|
|
218
|
+
'1) Defina a base URL: https://omnizap.shop/api/sticker-packs\n' +
|
|
219
|
+
'2) Faça um health-check inicial em /system-summary\n' +
|
|
220
|
+
'3) Liste packs com /?visibility=public&limit=24\n' +
|
|
221
|
+
'4) Abra detalhes com /:packKey\n' +
|
|
222
|
+
'5) Baixe stickers com /:packKey/stickers/:stickerId.webp\n' +
|
|
223
|
+
'6) Trate paginação usando limit/offset e has_more',
|
|
224
|
+
iconClass: 'fa-solid fa-list-check',
|
|
225
|
+
}),
|
|
226
|
+
h(Card, {
|
|
227
|
+
title: 'Exemplo cURL',
|
|
228
|
+
code:
|
|
229
|
+
'curl -sS "https://omnizap.shop/api/sticker-packs?visibility=public&limit=5"\n' +
|
|
230
|
+
'curl -sS "https://omnizap.shop/api/sticker-packs?categories=anime,meme&limit=12"\n' +
|
|
231
|
+
'curl -sS "https://omnizap.shop/api/sticker-packs/orphan-stickers?limit=20&offset=0"\n' +
|
|
232
|
+
'curl -sS -X POST "https://omnizap.shop/api/sticker-packs/<packKey>/open"\n' +
|
|
233
|
+
'curl -sS -X POST "https://omnizap.shop/api/sticker-packs/<packKey>/like"\n' +
|
|
234
|
+
'curl -sS "https://omnizap.shop/api/sticker-packs/support"\n' +
|
|
235
|
+
'curl -sS "https://omnizap.shop/api/sticker-packs/system-summary"\n' +
|
|
236
|
+
'curl -sS "https://omnizap.shop/api/sticker-packs/project-summary"',
|
|
237
|
+
iconClass: 'fa-solid fa-terminal',
|
|
238
|
+
}),
|
|
239
|
+
h(Card, {
|
|
240
|
+
title: 'Exemplo JavaScript (fetch)',
|
|
241
|
+
code:
|
|
242
|
+
"const API_BASE = 'https://omnizap.shop/api/sticker-packs';\n\n" +
|
|
243
|
+
'async function getPublicPacks() {\n' +
|
|
244
|
+
" const url = `${API_BASE}?visibility=public&limit=24&offset=0`;\n" +
|
|
245
|
+
' const response = await fetch(url);\n' +
|
|
246
|
+
" if (!response.ok) throw new Error(`HTTP ${response.status}`);\n" +
|
|
247
|
+
' const payload = await response.json();\n' +
|
|
248
|
+
' return payload?.data || [];\n' +
|
|
249
|
+
'}\n\n' +
|
|
250
|
+
'async function getPackDetails(packKey) {\n' +
|
|
251
|
+
' const response = await fetch(`${API_BASE}/${encodeURIComponent(packKey)}`);\n' +
|
|
252
|
+
" if (!response.ok) throw new Error(`HTTP ${response.status}`);\n" +
|
|
253
|
+
' const payload = await response.json();\n' +
|
|
254
|
+
' return payload?.data || null;\n' +
|
|
255
|
+
'}\n\n' +
|
|
256
|
+
'(async () => {\n' +
|
|
257
|
+
' try {\n' +
|
|
258
|
+
' const packs = await getPublicPacks();\n' +
|
|
259
|
+
" console.log('Packs encontrados:', packs.length);\n" +
|
|
260
|
+
' if (packs[0]?.pack_key) {\n' +
|
|
261
|
+
' const details = await getPackDetails(packs[0].pack_key);\n' +
|
|
262
|
+
" console.log('Primeiro pack:', details?.name, details?.pack_key);\n" +
|
|
263
|
+
" await fetch(`${API_BASE}/${encodeURIComponent(packs[0].pack_key)}/open`, { method: 'POST' });\n" +
|
|
264
|
+
' }\n' +
|
|
265
|
+
' } catch (error) {\n' +
|
|
266
|
+
" console.error('Falha ao consumir API:', error.message);\n" +
|
|
267
|
+
' }\n' +
|
|
268
|
+
'})();',
|
|
269
|
+
iconClass: 'fa-brands fa-js',
|
|
270
|
+
}),
|
|
271
|
+
h(Card, {
|
|
272
|
+
title: 'Exemplo Node.js (backend / integração server-to-server)',
|
|
273
|
+
code:
|
|
274
|
+
"const API_BASE = 'https://omnizap.shop/api/sticker-packs';\n" +
|
|
275
|
+
'\n' +
|
|
276
|
+
'export async function syncCatalogPage(offset = 0) {\n' +
|
|
277
|
+
' const url = `${API_BASE}?visibility=public&limit=50&offset=${offset}`;\n' +
|
|
278
|
+
' const response = await fetch(url, { headers: { Accept: "application/json" } });\n' +
|
|
279
|
+
' if (!response.ok) throw new Error(`Catalog HTTP ${response.status}`);\n' +
|
|
280
|
+
' const payload = await response.json();\n' +
|
|
281
|
+
' const packs = payload?.data || [];\n' +
|
|
282
|
+
' const nextOffset = payload?.pagination?.next_offset;\n' +
|
|
283
|
+
' return { packs, nextOffset, hasMore: Boolean(payload?.pagination?.has_more) };\n' +
|
|
284
|
+
'}\n' +
|
|
285
|
+
'\n' +
|
|
286
|
+
'export async function markPackLike(packKey) {\n' +
|
|
287
|
+
' const response = await fetch(`${API_BASE}/${encodeURIComponent(packKey)}/like`, { method: "POST" });\n' +
|
|
288
|
+
' if (!response.ok) throw new Error(`Like HTTP ${response.status}`);\n' +
|
|
289
|
+
' return response.json();\n' +
|
|
290
|
+
'}',
|
|
291
|
+
iconClass: 'fa-solid fa-server',
|
|
292
|
+
}),
|
|
293
|
+
h(Card, {
|
|
294
|
+
title: 'Checklist de produção',
|
|
295
|
+
code:
|
|
296
|
+
'- Implementar retry com backoff (429/5xx)\n' +
|
|
297
|
+
'- Cachear listagens por 30-120s no seu sistema\n' +
|
|
298
|
+
'- Validar next_offset para paginação contínua\n' +
|
|
299
|
+
'- Tratar 404 de pack removido/inválido\n' +
|
|
300
|
+
'- Registrar métricas de latência e taxa de erro do consumo',
|
|
301
|
+
iconClass: 'fa-solid fa-shield-heart',
|
|
302
|
+
}),
|
|
303
|
+
);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
const rootEl = document.getElementById('api-docs-react-root');
|
|
307
|
+
if (rootEl) {
|
|
308
|
+
const root = createRoot(rootEl);
|
|
309
|
+
root.render(h(ApiDocsApp));
|
|
310
|
+
}
|