@kaikybrofc/omnizap-system 2.2.4 → 2.2.5
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 +5 -0
- package/README.md +13 -13
- package/app/modules/stickerPackModule/catalogHandlers/catalogAdminHttp.js +68 -0
- package/app/modules/stickerPackModule/catalogHandlers/catalogAuthHttp.js +34 -0
- package/app/modules/stickerPackModule/catalogHandlers/catalogPublicHttp.js +179 -0
- package/app/modules/stickerPackModule/catalogHandlers/catalogUploadHttp.js +92 -0
- package/app/modules/stickerPackModule/catalogRouter.js +79 -0
- package/app/modules/stickerPackModule/domainEventOutboxRepository.js +243 -0
- package/app/modules/stickerPackModule/domainEvents.js +61 -0
- package/app/modules/stickerPackModule/stickerAssetClassificationRepository.js +21 -0
- package/app/modules/stickerPackModule/stickerAssetRepository.js +19 -0
- package/app/modules/stickerPackModule/stickerClassificationBackgroundRuntime.js +55 -15
- package/app/modules/stickerPackModule/stickerDedicatedTaskWorkerRuntime.js +238 -0
- package/app/modules/stickerPackModule/stickerDomainEventBus.js +71 -0
- package/app/modules/stickerPackModule/stickerDomainEventConsumerRuntime.js +198 -0
- package/app/modules/stickerPackModule/stickerObjectStorageService.js +285 -0
- package/app/modules/stickerPackModule/stickerPackCatalogHttp.js +537 -529
- package/app/modules/stickerPackModule/stickerPackEngagementRepository.js +44 -0
- package/app/modules/stickerPackModule/stickerPackItemRepository.js +18 -0
- package/app/modules/stickerPackModule/stickerPackRepository.js +51 -0
- package/app/modules/stickerPackModule/stickerPackScoreSnapshotRepository.js +191 -0
- package/app/modules/stickerPackModule/stickerPackScoreSnapshotRuntime.js +301 -0
- package/app/modules/stickerPackModule/stickerStorageService.js +111 -10
- package/app/modules/stickerPackModule/stickerWorkerPipelineRuntime.js +21 -0
- package/app/modules/stickerPackModule/stickerWorkerTaskQueueRepository.js +59 -7
- package/app/observability/metrics.js +169 -0
- package/app/services/featureFlagService.js +137 -0
- package/database/index.js +5 -0
- package/database/migrations/20260228_0022_sticker_scale_indexes.sql +16 -0
- package/database/migrations/20260228_0023_sticker_pack_score_snapshot.sql +25 -0
- package/database/migrations/20260228_0024_domain_event_outbox.sql +42 -0
- package/database/migrations/20260228_0025_sticker_worker_task_idempotency_dlq.sql +23 -0
- package/database/migrations/20260228_0026_feature_flags.sql +21 -0
- package/ecosystem.prod.config.cjs +70 -9
- package/index.js +26 -0
- package/package.json +5 -1
- package/public/index.html +30 -3
- package/scripts/sticker-catalog-loadtest.mjs +208 -0
- package/scripts/sticker-worker-task.mjs +122 -0
package/.env.example
CHANGED
|
@@ -434,6 +434,11 @@ WHATSAPP_LOGIN_PATH=/login/
|
|
|
434
434
|
WHATSAPP_LOGIN_LINK_SECRET=troque_por_um_segredo_forte
|
|
435
435
|
WHATSAPP_LOGIN_LINK_TTL_SECONDS=900
|
|
436
436
|
WHATSAPP_LOGIN_REQUIRE_SIGNATURE=true
|
|
437
|
+
# Canonical/cookies do catalogo web (necessario para compartilhar sessao entre www e dominio raiz)
|
|
438
|
+
SITE_CANONICAL_HOST=omnizap.shop
|
|
439
|
+
SITE_CANONICAL_SCHEME=https
|
|
440
|
+
SITE_CANONICAL_REDIRECT_ENABLED=true
|
|
441
|
+
SITE_COOKIE_DOMAIN=omnizap.shop
|
|
437
442
|
|
|
438
443
|
# Paths locais (legado/uso auxiliar)
|
|
439
444
|
STORE_PATH=./temp
|
package/README.md
CHANGED
|
@@ -53,27 +53,27 @@ Atualização em cache: **30 minutos** por padrão (`README_SUMMARY_CACHE_SECOND
|
|
|
53
53
|
<!-- README_SNAPSHOT:START -->
|
|
54
54
|
### Snapshot do Sistema
|
|
55
55
|
|
|
56
|
-
> Atualizado em `2026-02-
|
|
56
|
+
> Atualizado em `2026-02-28T04:28:50.529Z` | cache `1800s`
|
|
57
57
|
|
|
58
58
|
| Métrica | Valor |
|
|
59
59
|
| --- | ---: |
|
|
60
|
-
| Usuários (lid_map) | 5.
|
|
60
|
+
| Usuários (lid_map) | 5.504 |
|
|
61
61
|
| Grupos | 116 |
|
|
62
|
-
| Packs |
|
|
63
|
-
| Stickers | 6.
|
|
64
|
-
| Mensagens registradas |
|
|
62
|
+
| Packs | 294 |
|
|
63
|
+
| Stickers | 6.796 |
|
|
64
|
+
| Mensagens registradas | 440.582 |
|
|
65
65
|
|
|
66
66
|
#### Tipos de mensagem mais usados (amostra: 25.000)
|
|
67
67
|
| Tipo | Total |
|
|
68
68
|
| --- | ---: |
|
|
69
|
-
| `texto` | 16.
|
|
70
|
-
| `figurinha` | 4.
|
|
71
|
-
| `reacao` | 1.
|
|
72
|
-
| `imagem` | 1.
|
|
73
|
-
| `outros` |
|
|
74
|
-
| `video` |
|
|
75
|
-
| `audio` |
|
|
76
|
-
| `documento` |
|
|
69
|
+
| `texto` | 16.293 |
|
|
70
|
+
| `figurinha` | 4.718 |
|
|
71
|
+
| `reacao` | 1.506 |
|
|
72
|
+
| `imagem` | 1.286 |
|
|
73
|
+
| `outros` | 744 |
|
|
74
|
+
| `video` | 232 |
|
|
75
|
+
| `audio` | 216 |
|
|
76
|
+
| `documento` | 5 |
|
|
77
77
|
|
|
78
78
|
<details><summary>Comandos disponíveis (62)</summary>
|
|
79
79
|
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
export const handleCatalogAdminRoutes = async ({
|
|
2
|
+
req,
|
|
3
|
+
res,
|
|
4
|
+
url,
|
|
5
|
+
segments,
|
|
6
|
+
handlers,
|
|
7
|
+
sendJson,
|
|
8
|
+
}) => {
|
|
9
|
+
if (segments[0] !== 'admin') return false;
|
|
10
|
+
|
|
11
|
+
if (segments.length === 2 && segments[1] === 'overview') {
|
|
12
|
+
await handlers.handleAdminOverviewRequest(req, res);
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (segments.length === 2 && segments[1] === 'users') {
|
|
17
|
+
await handlers.handleAdminUsersRequest(req, res, url);
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (segments.length === 2 && segments[1] === 'moderators') {
|
|
22
|
+
await handlers.handleAdminModeratorsRequest(req, res);
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (segments.length === 3 && segments[1] === 'moderators') {
|
|
27
|
+
await handlers.handleAdminModeratorDeleteRequest(req, res, segments[2]);
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (segments.length === 2 && segments[1] === 'packs') {
|
|
32
|
+
await handlers.handleAdminPacksRequest(req, res, url);
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (segments.length === 3 && segments[1] === 'packs') {
|
|
37
|
+
await handlers.handleAdminPackDetailsRequest(req, res, segments[2]);
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (segments.length === 4 && segments[1] === 'packs' && segments[3] === 'delete') {
|
|
42
|
+
await handlers.handleAdminPackDeleteRequest(req, res, segments[2]);
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (segments.length === 6 && segments[1] === 'packs' && segments[3] === 'stickers' && segments[5] === 'delete') {
|
|
47
|
+
await handlers.handleAdminPackStickerDeleteRequest(req, res, segments[2], segments[4]);
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (segments.length === 4 && segments[1] === 'stickers' && segments[3] === 'delete') {
|
|
52
|
+
await handlers.handleAdminGlobalStickerDeleteRequest(req, res, segments[2]);
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (segments.length === 2 && segments[1] === 'bans') {
|
|
57
|
+
await handlers.handleAdminBansRequest(req, res);
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (segments.length === 4 && segments[1] === 'bans' && segments[3] === 'revoke') {
|
|
62
|
+
await handlers.handleAdminBanRevokeRequest(req, res, segments[2]);
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
sendJson(req, res, 404, { error: 'Rota admin nao encontrada.' });
|
|
67
|
+
return true;
|
|
68
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
const METHOD_NOT_ALLOWED_BODY = { error: 'Metodo nao permitido.' };
|
|
2
|
+
|
|
3
|
+
const isReadMethod = (method) => method === 'GET' || method === 'HEAD';
|
|
4
|
+
|
|
5
|
+
export const handleCatalogAuthRoutes = async ({
|
|
6
|
+
req,
|
|
7
|
+
res,
|
|
8
|
+
pathname,
|
|
9
|
+
url,
|
|
10
|
+
apiBasePath,
|
|
11
|
+
handlers,
|
|
12
|
+
sendJson,
|
|
13
|
+
}) => {
|
|
14
|
+
if (pathname === `${apiBasePath}/auth/google/session`) {
|
|
15
|
+
await handlers.handleGoogleAuthSessionRequest(req, res);
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (pathname === `${apiBasePath}/me`) {
|
|
20
|
+
if (!isReadMethod(req.method || '')) {
|
|
21
|
+
sendJson(req, res, 405, METHOD_NOT_ALLOWED_BODY);
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
await handlers.handleMyProfileRequest(req, res, url);
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (pathname === `${apiBasePath}/admin/session`) {
|
|
29
|
+
await handlers.handleAdminPanelSessionRequest(req, res);
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return false;
|
|
34
|
+
};
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
const METHOD_NOT_ALLOWED_BODY = { error: 'Metodo nao permitido.' };
|
|
2
|
+
|
|
3
|
+
const isReadMethod = (method) => method === 'GET' || method === 'HEAD';
|
|
4
|
+
|
|
5
|
+
export const handleCatalogPublicRoutes = async ({
|
|
6
|
+
req,
|
|
7
|
+
res,
|
|
8
|
+
pathname,
|
|
9
|
+
url,
|
|
10
|
+
segments,
|
|
11
|
+
apiBasePath,
|
|
12
|
+
orphanApiPath,
|
|
13
|
+
handlers,
|
|
14
|
+
sendJson,
|
|
15
|
+
}) => {
|
|
16
|
+
if (pathname === apiBasePath) {
|
|
17
|
+
if (!isReadMethod(req.method || '')) {
|
|
18
|
+
sendJson(req, res, 405, METHOD_NOT_ALLOWED_BODY);
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
await handlers.handleListRequest(req, res, url);
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (pathname === `${apiBasePath}/intents`) {
|
|
26
|
+
if (!isReadMethod(req.method || '')) {
|
|
27
|
+
sendJson(req, res, 405, METHOD_NOT_ALLOWED_BODY);
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
await handlers.handleIntentCollectionsRequest(req, res, url);
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (pathname === `${apiBasePath}/creators`) {
|
|
35
|
+
if (!isReadMethod(req.method || '')) {
|
|
36
|
+
sendJson(req, res, 405, METHOD_NOT_ALLOWED_BODY);
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
await handlers.handleCreatorRankingRequest(req, res, url);
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (pathname === `${apiBasePath}/recommendations`) {
|
|
44
|
+
if (!isReadMethod(req.method || '')) {
|
|
45
|
+
sendJson(req, res, 405, METHOD_NOT_ALLOWED_BODY);
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
await handlers.handleRecommendationsRequest(req, res, url);
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (pathname === `${apiBasePath}/stats`) {
|
|
53
|
+
if (!isReadMethod(req.method || '')) {
|
|
54
|
+
sendJson(req, res, 405, METHOD_NOT_ALLOWED_BODY);
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
await handlers.handleMarketplaceStatsRequest(req, res, url);
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (pathname === `${apiBasePath}/create-config`) {
|
|
62
|
+
if (!isReadMethod(req.method || '')) {
|
|
63
|
+
sendJson(req, res, 405, METHOD_NOT_ALLOWED_BODY);
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
await handlers.handleCreatePackConfigRequest(req, res);
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (pathname === orphanApiPath) {
|
|
71
|
+
if (!isReadMethod(req.method || '')) {
|
|
72
|
+
sendJson(req, res, 405, METHOD_NOT_ALLOWED_BODY);
|
|
73
|
+
return true;
|
|
74
|
+
}
|
|
75
|
+
await handlers.handleOrphanStickerListRequest(req, res, url);
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (segments.length === 1 && segments[0] === 'data-files') {
|
|
80
|
+
if (!isReadMethod(req.method || '')) {
|
|
81
|
+
sendJson(req, res, 405, METHOD_NOT_ALLOWED_BODY);
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
await handlers.handleDataFileListRequest(req, res, url);
|
|
85
|
+
return true;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (segments.length === 1 && segments[0] === 'system-summary') {
|
|
89
|
+
if (!isReadMethod(req.method || '')) {
|
|
90
|
+
sendJson(req, res, 405, METHOD_NOT_ALLOWED_BODY);
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
await handlers.handleSystemSummaryRequest(req, res);
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (segments.length === 1 && segments[0] === 'project-summary') {
|
|
98
|
+
if (!isReadMethod(req.method || '')) {
|
|
99
|
+
sendJson(req, res, 405, METHOD_NOT_ALLOWED_BODY);
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
await handlers.handleGitHubProjectSummaryRequest(req, res);
|
|
103
|
+
return true;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (segments.length === 1 && segments[0] === 'global-ranking-summary') {
|
|
107
|
+
if (!isReadMethod(req.method || '')) {
|
|
108
|
+
sendJson(req, res, 405, METHOD_NOT_ALLOWED_BODY);
|
|
109
|
+
return true;
|
|
110
|
+
}
|
|
111
|
+
await handlers.handleGlobalRankingSummaryRequest(req, res);
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (segments.length === 1 && segments[0] === 'readme-summary') {
|
|
116
|
+
if (!isReadMethod(req.method || '')) {
|
|
117
|
+
sendJson(req, res, 405, METHOD_NOT_ALLOWED_BODY);
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
120
|
+
await handlers.handleReadmeSummaryRequest(req, res);
|
|
121
|
+
return true;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (segments.length === 1 && segments[0] === 'readme-markdown') {
|
|
125
|
+
if (!isReadMethod(req.method || '')) {
|
|
126
|
+
sendJson(req, res, 405, METHOD_NOT_ALLOWED_BODY);
|
|
127
|
+
return true;
|
|
128
|
+
}
|
|
129
|
+
await handlers.handleReadmeMarkdownRequest(req, res);
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (segments.length === 1 && segments[0] === 'support') {
|
|
134
|
+
if (!isReadMethod(req.method || '')) {
|
|
135
|
+
sendJson(req, res, 405, METHOD_NOT_ALLOWED_BODY);
|
|
136
|
+
return true;
|
|
137
|
+
}
|
|
138
|
+
await handlers.handleSupportInfoRequest(req, res);
|
|
139
|
+
return true;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (segments.length === 1 && segments[0] === 'bot-contact') {
|
|
143
|
+
if (!isReadMethod(req.method || '')) {
|
|
144
|
+
sendJson(req, res, 405, METHOD_NOT_ALLOWED_BODY);
|
|
145
|
+
return true;
|
|
146
|
+
}
|
|
147
|
+
await handlers.handleBotContactInfoRequest(req, res);
|
|
148
|
+
return true;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (segments.length === 1) {
|
|
152
|
+
if (!isReadMethod(req.method || '')) {
|
|
153
|
+
sendJson(req, res, 405, METHOD_NOT_ALLOWED_BODY);
|
|
154
|
+
return true;
|
|
155
|
+
}
|
|
156
|
+
await handlers.handleDetailsRequest(req, res, segments[0], url);
|
|
157
|
+
return true;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (segments.length === 2 && ['open', 'like', 'dislike'].includes(segments[1])) {
|
|
161
|
+
if (req.method !== 'POST') {
|
|
162
|
+
sendJson(req, res, 405, METHOD_NOT_ALLOWED_BODY);
|
|
163
|
+
return true;
|
|
164
|
+
}
|
|
165
|
+
await handlers.handlePackInteractionRequest(req, res, segments[0], segments[1], url);
|
|
166
|
+
return true;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if (segments.length === 3 && segments[1] === 'stickers') {
|
|
170
|
+
if (!isReadMethod(req.method || '')) {
|
|
171
|
+
sendJson(req, res, 405, METHOD_NOT_ALLOWED_BODY);
|
|
172
|
+
return true;
|
|
173
|
+
}
|
|
174
|
+
await handlers.handleAssetRequest(req, res, segments[0], segments[2]);
|
|
175
|
+
return true;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
return false;
|
|
179
|
+
};
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
const METHOD_NOT_ALLOWED_BODY = { error: 'Metodo nao permitido.' };
|
|
2
|
+
|
|
3
|
+
const isPublishStateMethod = (method) => method === 'GET' || method === 'HEAD' || method === 'POST';
|
|
4
|
+
|
|
5
|
+
export const handleCatalogUploadRoutes = async ({
|
|
6
|
+
req,
|
|
7
|
+
res,
|
|
8
|
+
pathname,
|
|
9
|
+
url,
|
|
10
|
+
segments,
|
|
11
|
+
apiBasePath,
|
|
12
|
+
handlers,
|
|
13
|
+
sendJson,
|
|
14
|
+
}) => {
|
|
15
|
+
if (pathname === `${apiBasePath}/create`) {
|
|
16
|
+
if (req.method !== 'POST') {
|
|
17
|
+
sendJson(req, res, 405, METHOD_NOT_ALLOWED_BODY);
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
await handlers.handleCreatePackRequest(req, res);
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (segments.length === 2 && segments[1] === 'manage') {
|
|
25
|
+
await handlers.handleManagedPackRequest(req, res, segments[0]);
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (segments.length === 3 && segments[1] === 'manage' && segments[2] === 'clone') {
|
|
30
|
+
await handlers.handleManagedPackCloneRequest(req, res, segments[0]);
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (segments.length === 3 && segments[1] === 'manage' && segments[2] === 'cover') {
|
|
35
|
+
await handlers.handleManagedPackCoverRequest(req, res, segments[0]);
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (segments.length === 3 && segments[1] === 'manage' && segments[2] === 'reorder') {
|
|
40
|
+
await handlers.handleManagedPackReorderRequest(req, res, segments[0]);
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (segments.length === 3 && segments[1] === 'manage' && segments[2] === 'analytics') {
|
|
45
|
+
await handlers.handleManagedPackAnalyticsRequest(req, res, segments[0]);
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (segments.length === 3 && segments[1] === 'manage' && segments[2] === 'stickers') {
|
|
50
|
+
await handlers.handleManagedPackStickerCreateRequest(req, res, segments[0]);
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (segments.length === 4 && segments[1] === 'manage' && segments[2] === 'stickers') {
|
|
55
|
+
await handlers.handleManagedPackStickerDeleteRequest(req, res, segments[0], segments[3]);
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (segments.length === 5 && segments[1] === 'manage' && segments[2] === 'stickers' && segments[4] === 'replace') {
|
|
60
|
+
await handlers.handleManagedPackStickerReplaceRequest(req, res, segments[0], segments[3]);
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (segments.length === 2 && segments[1] === 'publish-state') {
|
|
65
|
+
if (!isPublishStateMethod(req.method || '')) {
|
|
66
|
+
sendJson(req, res, 405, METHOD_NOT_ALLOWED_BODY);
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
await handlers.handlePackPublishStateRequest(req, res, segments[0], url);
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (segments.length === 2 && segments[1] === 'finalize') {
|
|
74
|
+
if (req.method !== 'POST') {
|
|
75
|
+
sendJson(req, res, 405, METHOD_NOT_ALLOWED_BODY);
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
await handlers.handleFinalizePackRequest(req, res, segments[0]);
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (segments.length === 2 && segments[1] === 'stickers-upload') {
|
|
83
|
+
if (req.method !== 'POST') {
|
|
84
|
+
sendJson(req, res, 405, METHOD_NOT_ALLOWED_BODY);
|
|
85
|
+
return true;
|
|
86
|
+
}
|
|
87
|
+
await handlers.handleUploadStickerToPackRequest(req, res, segments[0]);
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return false;
|
|
92
|
+
};
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { handleCatalogAuthRoutes } from './catalogHandlers/catalogAuthHttp.js';
|
|
2
|
+
import { handleCatalogAdminRoutes } from './catalogHandlers/catalogAdminHttp.js';
|
|
3
|
+
import { handleCatalogUploadRoutes } from './catalogHandlers/catalogUploadHttp.js';
|
|
4
|
+
import { handleCatalogPublicRoutes } from './catalogHandlers/catalogPublicHttp.js';
|
|
5
|
+
|
|
6
|
+
const decodePathSegments = (suffix) =>
|
|
7
|
+
suffix.split('/').filter(Boolean).map((segment) => {
|
|
8
|
+
try {
|
|
9
|
+
return decodeURIComponent(segment);
|
|
10
|
+
} catch {
|
|
11
|
+
return segment;
|
|
12
|
+
}
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
export const createCatalogApiRouter = ({
|
|
16
|
+
apiBasePath,
|
|
17
|
+
orphanApiPath,
|
|
18
|
+
handlers,
|
|
19
|
+
sendJson,
|
|
20
|
+
}) => {
|
|
21
|
+
if (!apiBasePath || typeof handlers !== 'object' || typeof sendJson !== 'function') {
|
|
22
|
+
throw new Error('catalog_api_router_config_invalid');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return async ({ req, res, pathname, url }) => {
|
|
26
|
+
const handledAuth = await handleCatalogAuthRoutes({
|
|
27
|
+
req,
|
|
28
|
+
res,
|
|
29
|
+
pathname,
|
|
30
|
+
url,
|
|
31
|
+
apiBasePath,
|
|
32
|
+
handlers,
|
|
33
|
+
sendJson,
|
|
34
|
+
});
|
|
35
|
+
if (handledAuth) return true;
|
|
36
|
+
if (!pathname.startsWith(apiBasePath)) return false;
|
|
37
|
+
|
|
38
|
+
const suffix = pathname.slice(apiBasePath.length).replace(/^\/+/, '');
|
|
39
|
+
const segments = decodePathSegments(suffix);
|
|
40
|
+
|
|
41
|
+
const handledAdmin = await handleCatalogAdminRoutes({
|
|
42
|
+
req,
|
|
43
|
+
res,
|
|
44
|
+
url,
|
|
45
|
+
segments,
|
|
46
|
+
handlers,
|
|
47
|
+
sendJson,
|
|
48
|
+
});
|
|
49
|
+
if (handledAdmin) return true;
|
|
50
|
+
|
|
51
|
+
const handledUpload = await handleCatalogUploadRoutes({
|
|
52
|
+
req,
|
|
53
|
+
res,
|
|
54
|
+
pathname,
|
|
55
|
+
url,
|
|
56
|
+
segments,
|
|
57
|
+
apiBasePath,
|
|
58
|
+
handlers,
|
|
59
|
+
sendJson,
|
|
60
|
+
});
|
|
61
|
+
if (handledUpload) return true;
|
|
62
|
+
|
|
63
|
+
const handledPublic = await handleCatalogPublicRoutes({
|
|
64
|
+
req,
|
|
65
|
+
res,
|
|
66
|
+
pathname,
|
|
67
|
+
url,
|
|
68
|
+
segments,
|
|
69
|
+
apiBasePath,
|
|
70
|
+
orphanApiPath,
|
|
71
|
+
handlers,
|
|
72
|
+
sendJson,
|
|
73
|
+
});
|
|
74
|
+
if (handledPublic) return true;
|
|
75
|
+
|
|
76
|
+
sendJson(req, res, 404, { error: 'Rota de sticker pack nao encontrada.' });
|
|
77
|
+
return true;
|
|
78
|
+
};
|
|
79
|
+
};
|