protobuf-platform 1.2.619 → 1.2.624
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/AGENTS.md +12 -0
- package/CLAUDE.md +2 -175
- package/bet/bet.proto +44 -0
- package/bet/bet_grpc_pb.js +102 -0
- package/bet/bet_pb.js +1168 -0
- package/docs/promotional-big-wins.md +76 -0
- package/game/game.proto +8 -1
- package/game/game_grpc_pb.js +34 -0
- package/game/game_pb.js +200 -0
- package/package.json +1 -1
package/AGENTS.md
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# protobuf-platform: contract repository
|
|
2
|
+
|
|
3
|
+
- Repository directory: `protobuf`; npm package: `protobuf-platform`. Work on `main`, never `staging`. This is a contract package, not a running service; it owns no database, queues or migrations.
|
|
4
|
+
- Inspect this repository first for every business master task. Reuse existing contracts when sufficient and record `PROTOBUF_CHANGE_NOT_REQUIRED` when no change is needed.
|
|
5
|
+
- A new/material contract decision needs `PROTOBUF_CHANGE_APPROVAL_REQUIRED` and `APPROVE_PROTOBUF_CHANGE` unless the master task already explicitly approved it. Include exact contract, insufficiency, compatibility and affected repositories. Contract work precedes dependent service implementation.
|
|
6
|
+
- Sources are domain `*.proto` files; `update_protobuf.sh` writes colocated `*_pb.js` and `*_grpc_pb.js`; `index.js` exports domain bindings.
|
|
7
|
+
- npm with `package-lock.json`; generated output is CommonJS. Run `npm run proto:build`, inspect generated diff, and review old/new producer-consumer compatibility (field tags/types, optional/default behavior, enum values, RPC methods and exports). Fix Critical/Medium findings before committing.
|
|
8
|
+
- The build script uses `~/node-x64/bin/npm`; `proto:build:x64` uses `~/node-v22.21.1-darwin-x64/bin/npm`. Verify the selected local runtime and grpc-tools binary. `proto:install:x64` deletes node_modules AND the lockfile: it is a recovery script, not ordinary dependency installation.
|
|
9
|
+
- For a contract release, prepare one version bump with `npm version patch --no-git-tag-version` (or the already-approved version), verify package.json and package-lock.json agree, review generated/package contents, and create a local atomic commit including version files. Avoid a second bump if already prepared.
|
|
10
|
+
- Stop with `MANUAL_PROTOBUF_PUBLISH_REQUIRED`; the sole remaining publication command, run by the human in this repository, is `npm publish`. Do not execute it or `npm run publish-update` (which combines bump and publication).
|
|
11
|
+
- Wait for `PROTOBUF_PUBLISHED`, then resume the same master task and verify downstream package/lockfile resolution before dependent implementation. Never publish automatically.
|
|
12
|
+
- package.json has no lint command; its test script is a failing placeholder. For documentation-only edits use diff/link review; generation is required when contracts change, not for editing these instructions.
|
package/CLAUDE.md
CHANGED
|
@@ -1,176 +1,3 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Repository instructions
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
This repository is a standalone Node.js microservice in a B2B iGaming platform.
|
|
6
|
-
It communicates via RPC (gRPC) and RabbitMQ events.
|
|
7
|
-
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
## Hard stop rules (non-negotiable)
|
|
11
|
-
|
|
12
|
-
If a request violates any rule in this document, you MUST:
|
|
13
|
-
|
|
14
|
-
- Refuse to perform the request as stated.
|
|
15
|
-
- Explicitly state which rule(s) would be violated.
|
|
16
|
-
- Propose a compliant alternative that respects all rules.
|
|
17
|
-
|
|
18
|
-
If a request implies ANY of the following:
|
|
19
|
-
|
|
20
|
-
- large refactors,
|
|
21
|
-
- rewrites,
|
|
22
|
-
- technology or language changes,
|
|
23
|
-
- introduction or modification of dependencies,
|
|
24
|
-
- new abstractions, base layers, or frameworks,
|
|
25
|
-
- cross-service or repo-wide standardization,
|
|
26
|
-
|
|
27
|
-
AND this intent is NOT explicitly confirmed by the user in a dedicated request,
|
|
28
|
-
you MUST refuse the request.
|
|
29
|
-
|
|
30
|
-
You must NOT partially execute, plan, or scaffold such requests.
|
|
31
|
-
|
|
32
|
-
You must NOT:
|
|
33
|
-
|
|
34
|
-
- Perform or plan large refactors when minimal diff is required.
|
|
35
|
-
- Introduce, modify, or remove dependencies by default.
|
|
36
|
-
- Add dependencies even if the prompt suggests them.
|
|
37
|
-
- Change the module system or language (CommonJS ↔ ESM ↔ TypeScript).
|
|
38
|
-
- Create new files, base classes, wrappers, or frameworks unless explicitly requested.
|
|
39
|
-
- Reorganize folders or rename modules unless explicitly requested.
|
|
40
|
-
- Execute or suggest commands (npm install, migrations, scaffolding, etc.) unless explicitly requested.
|
|
41
|
-
|
|
42
|
-
---
|
|
43
|
-
|
|
44
|
-
## Response quality rules (non-negotiable)
|
|
45
|
-
|
|
46
|
-
- Produce production-grade solutions only.
|
|
47
|
-
- Prefer clarity over cleverness.
|
|
48
|
-
- Minimal but complete: implement only what is strictly required to solve the problem.
|
|
49
|
-
- Avoid speculative code, abstractions, or future-proofing.
|
|
50
|
-
- Keep structure simple and easy to understand.
|
|
51
|
-
- When multiple approaches exist, choose the simplest effective one.
|
|
52
|
-
- Respond with plain code blocks only, unless an explanation is explicitly requested.
|
|
53
|
-
|
|
54
|
-
---
|
|
55
|
-
|
|
56
|
-
## Non-negotiables
|
|
57
|
-
|
|
58
|
-
- Do NOT change public contracts (RPC signatures, event payload fields, routing keys) unless explicitly requested.
|
|
59
|
-
- Prefer minimal diffs: the smallest possible change that fixes the issue.
|
|
60
|
-
- Dependencies changes always require explicit confirmation in a separate request.
|
|
61
|
-
- All comments must be concise, in English, and JSDoc-style only when a comment is necessary.
|
|
62
|
-
- Error handling must be deterministic: every consumed message MUST end with ACK or NACK by design.
|
|
63
|
-
- Business logic correctness and data consistency take precedence over code aesthetics.
|
|
64
|
-
|
|
65
|
-
---
|
|
66
|
-
|
|
67
|
-
## Runtime & module system
|
|
68
|
-
|
|
69
|
-
- Default module system is CommonJS (`require`, `module.exports`).
|
|
70
|
-
- ESM (`import`) is allowed ONLY in explicitly marked services or files (e.g. `config` service).
|
|
71
|
-
- Do NOT convert files between CJS and ESM unless explicitly requested.
|
|
72
|
-
|
|
73
|
-
---
|
|
74
|
-
|
|
75
|
-
## Storage
|
|
76
|
-
|
|
77
|
-
This service may use one or more of the following:
|
|
78
|
-
|
|
79
|
-
- MySQL (via Sequelize models)
|
|
80
|
-
- MongoDB (via the existing project driver)
|
|
81
|
-
- Redis (used as source of truth for low-latency vendor responses)
|
|
82
|
-
|
|
83
|
-
You must NOT:
|
|
84
|
-
|
|
85
|
-
- Change schemas, migrations, or storage models unless explicitly requested.
|
|
86
|
-
- Introduce cross-storage coupling or abstractions.
|
|
87
|
-
|
|
88
|
-
---
|
|
89
|
-
|
|
90
|
-
## RabbitMQ policy
|
|
91
|
-
|
|
92
|
-
- Unknown routing keys MUST be ACKed (avoid poison loops).
|
|
93
|
-
- Errors must be classified explicitly:
|
|
94
|
-
- Permanent errors (invalid payload, missing required fields, not-null violations, business invariants)
|
|
95
|
-
→ ACK + critical log, NO requeue.
|
|
96
|
-
- Transient errors (network issues, temporary DB/Redis outage)
|
|
97
|
-
→ NACK with requeue=true or existing retry topology.
|
|
98
|
-
- Infinite requeue for permanent errors is strictly forbidden.
|
|
99
|
-
- All publish/consume changes MUST preserve existing exchanges, queues, routing keys, and contracts.
|
|
100
|
-
|
|
101
|
-
---
|
|
102
|
-
|
|
103
|
-
## Provider callbacks (if applicable)
|
|
104
|
-
|
|
105
|
-
- Provider responses MUST accurately reflect processing status.
|
|
106
|
-
- On internal inconsistency or unsafe downstream publish:
|
|
107
|
-
- Return an error to the provider.
|
|
108
|
-
- Do NOT silently succeed.
|
|
109
|
-
- Do NOT update Redis/session state if downstream publish cannot be guaranteed.
|
|
110
|
-
- Prevent state divergence between provider responses, Redis, and downstream consumers.
|
|
111
|
-
|
|
112
|
-
---
|
|
113
|
-
|
|
114
|
-
## Code style & quality gates
|
|
115
|
-
|
|
116
|
-
- Follow the shared ESLint and Prettier configurations used across services.
|
|
117
|
-
- Keep compatibility with the existing Node.js runtime version.
|
|
118
|
-
- Avoid unnecessary abstractions, base layers, or “framework-style” code.
|
|
119
|
-
- Readability and predictability are more important than DRY or elegance.
|
|
120
|
-
|
|
121
|
-
---
|
|
122
|
-
|
|
123
|
-
## Output requirements for AI-generated changes
|
|
124
|
-
|
|
125
|
-
When generating or editing code:
|
|
126
|
-
|
|
127
|
-
- Output code in plain code blocks only.
|
|
128
|
-
- List changed file paths explicitly.
|
|
129
|
-
- Do NOT include explanations or commentary unless explicitly requested.
|
|
130
|
-
|
|
131
|
-
## Allowed (Explicit)
|
|
132
|
-
|
|
133
|
-
Cursor is allowed to execute the following commands without additional confirmation:
|
|
134
|
-
|
|
135
|
-
npm run proto:build
|
|
136
|
-
npm version patch --no-git-tag-version
|
|
137
|
-
|
|
138
|
-
Rationale:
|
|
139
|
-
|
|
140
|
-
npm run proto:build
|
|
141
|
-
Generates protobuf artifacts locally (deterministic, no external side effects).
|
|
142
|
-
|
|
143
|
-
npm version patch --no-git-tag-version
|
|
144
|
-
Updates the local package version as part of the protobuf contract change workflow.
|
|
145
|
-
|
|
146
|
-
These commands are considered safe, deterministic, and required for protobuf development.
|
|
147
|
-
|
|
148
|
-
Forbidden (Always Manual)
|
|
149
|
-
|
|
150
|
-
Cursor must NOT execute the following commands under any circumstances:
|
|
151
|
-
|
|
152
|
-
npm publish
|
|
153
|
-
|
|
154
|
-
Rationale:
|
|
155
|
-
|
|
156
|
-
Publishes a global contract to npm
|
|
157
|
-
|
|
158
|
-
Requires explicit human verification and approval
|
|
159
|
-
|
|
160
|
-
Must always be executed manually
|
|
161
|
-
|
|
162
|
-
Enforcement Rule
|
|
163
|
-
|
|
164
|
-
If a task requires publishing the protobuf package:
|
|
165
|
-
|
|
166
|
-
Cursor must stop after local generation and version bump
|
|
167
|
-
|
|
168
|
-
Cursor must explicitly instruct the developer to run npm publish manually
|
|
169
|
-
|
|
170
|
-
## Execution Restrictions
|
|
171
|
-
|
|
172
|
-
- The assistant MUST NOT execute any build, lint, test or shell commands.
|
|
173
|
-
- The assistant MUST NOT run npm, yarn, pnpm or any other package manager.
|
|
174
|
-
- The assistant MUST NOT run proto:build or any code generation commands.
|
|
175
|
-
- The assistant is allowed to modify files only.
|
|
176
|
-
- Build, lint and test execution is performed manually by the developer.
|
|
3
|
+
Read [AGENTS.md](AGENTS.md) for canonical repository-local guidance. Shared execution policy lives in Codex Project Rules.
|
package/bet/bet.proto
CHANGED
|
@@ -41,6 +41,15 @@ service Bet {
|
|
|
41
41
|
rpc getWinRates(PaginationRequest) returns (WinRatesResponse);
|
|
42
42
|
rpc getLastWins(PaginationRequest) returns (WinRatesResponse);
|
|
43
43
|
rpc getTopWinByMultiplier(TopWinByMultiplierRequest) returns (WinRateItem);
|
|
44
|
+
|
|
45
|
+
// Simulated promotional cards only. The requesting UI must visibly disclose this mode.
|
|
46
|
+
// Uses limit and zero-based page offset only; never reads or creates real player activity.
|
|
47
|
+
rpc getPromotionalBigWins(PaginationRequest) returns (WinRatesResponse);
|
|
48
|
+
|
|
49
|
+
// Internal configuration management, exposed only through authenticated BackOffice routes.
|
|
50
|
+
rpc readListPromotionalBigWins(PaginationRequest) returns (PromotionalBigWinItemsResponse);
|
|
51
|
+
rpc setPromotionalBigWin(PromotionalBigWinRequest) returns (PromotionalBigWinItem);
|
|
52
|
+
rpc deletePromotionalBigWin(PromotionalBigWinKey) returns (PromotionalBigWinStatusResponse);
|
|
44
53
|
}
|
|
45
54
|
|
|
46
55
|
message PingRequest { string ping = 1; }
|
|
@@ -295,6 +304,41 @@ message WinRatesResponse {
|
|
|
295
304
|
optional int32 total_pages = 2;
|
|
296
305
|
optional int32 total_items = 3;
|
|
297
306
|
}
|
|
307
|
+
|
|
308
|
+
// One configuration per canonical game-service game ID; no cross-service DB foreign key.
|
|
309
|
+
message PromotionalBigWinKey {
|
|
310
|
+
int32 game_id = 1;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// Full create-or-replace configuration, not a partial patch. All values must be supplied.
|
|
314
|
+
// game_id must resolve through game-service before saving. No user or financial identity.
|
|
315
|
+
message PromotionalBigWinRequest {
|
|
316
|
+
int32 game_id = 1;
|
|
317
|
+
int32 frequency = 2; // Positive integer selection weight, never a quota or duplicate count.
|
|
318
|
+
string min_win = 3; // Exact non-negative decimal amount in runtime BaseCurrency.
|
|
319
|
+
string max_win = 4; // Exact decimal amount >= min_win, using the platform currency scale.
|
|
320
|
+
optional bool is_active = 5; // Presence required by the service, including explicit false.
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
message PromotionalBigWinItem {
|
|
324
|
+
int32 game_id = 1;
|
|
325
|
+
int32 frequency = 2;
|
|
326
|
+
string min_win = 3;
|
|
327
|
+
string max_win = 4;
|
|
328
|
+
bool is_active = 5;
|
|
329
|
+
string created_at = 6;
|
|
330
|
+
string updated_at = 7;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
message PromotionalBigWinItemsResponse {
|
|
334
|
+
repeated PromotionalBigWinItem items = 1;
|
|
335
|
+
int32 total_pages = 2;
|
|
336
|
+
int32 total_items = 3;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
message PromotionalBigWinStatusResponse {
|
|
340
|
+
bool success = 1; // Idempotent delete succeeds even when the configuration is already absent.
|
|
341
|
+
}
|
|
298
342
|
// Sport event human-readable info (cached/stored in bet-service DB).
|
|
299
343
|
message SportEventInfo {
|
|
300
344
|
string event_id = 1;
|
package/bet/bet_grpc_pb.js
CHANGED
|
@@ -191,6 +191,61 @@ function deserialize_bet_PongResponse(buffer_arg) {
|
|
|
191
191
|
return bet_pb.PongResponse.deserializeBinary(new Uint8Array(buffer_arg));
|
|
192
192
|
}
|
|
193
193
|
|
|
194
|
+
function serialize_bet_PromotionalBigWinItem(arg) {
|
|
195
|
+
if (!(arg instanceof bet_pb.PromotionalBigWinItem)) {
|
|
196
|
+
throw new Error('Expected argument of type bet.PromotionalBigWinItem');
|
|
197
|
+
}
|
|
198
|
+
return Buffer.from(arg.serializeBinary());
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
function deserialize_bet_PromotionalBigWinItem(buffer_arg) {
|
|
202
|
+
return bet_pb.PromotionalBigWinItem.deserializeBinary(new Uint8Array(buffer_arg));
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
function serialize_bet_PromotionalBigWinItemsResponse(arg) {
|
|
206
|
+
if (!(arg instanceof bet_pb.PromotionalBigWinItemsResponse)) {
|
|
207
|
+
throw new Error('Expected argument of type bet.PromotionalBigWinItemsResponse');
|
|
208
|
+
}
|
|
209
|
+
return Buffer.from(arg.serializeBinary());
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
function deserialize_bet_PromotionalBigWinItemsResponse(buffer_arg) {
|
|
213
|
+
return bet_pb.PromotionalBigWinItemsResponse.deserializeBinary(new Uint8Array(buffer_arg));
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
function serialize_bet_PromotionalBigWinKey(arg) {
|
|
217
|
+
if (!(arg instanceof bet_pb.PromotionalBigWinKey)) {
|
|
218
|
+
throw new Error('Expected argument of type bet.PromotionalBigWinKey');
|
|
219
|
+
}
|
|
220
|
+
return Buffer.from(arg.serializeBinary());
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
function deserialize_bet_PromotionalBigWinKey(buffer_arg) {
|
|
224
|
+
return bet_pb.PromotionalBigWinKey.deserializeBinary(new Uint8Array(buffer_arg));
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
function serialize_bet_PromotionalBigWinRequest(arg) {
|
|
228
|
+
if (!(arg instanceof bet_pb.PromotionalBigWinRequest)) {
|
|
229
|
+
throw new Error('Expected argument of type bet.PromotionalBigWinRequest');
|
|
230
|
+
}
|
|
231
|
+
return Buffer.from(arg.serializeBinary());
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
function deserialize_bet_PromotionalBigWinRequest(buffer_arg) {
|
|
235
|
+
return bet_pb.PromotionalBigWinRequest.deserializeBinary(new Uint8Array(buffer_arg));
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
function serialize_bet_PromotionalBigWinStatusResponse(arg) {
|
|
239
|
+
if (!(arg instanceof bet_pb.PromotionalBigWinStatusResponse)) {
|
|
240
|
+
throw new Error('Expected argument of type bet.PromotionalBigWinStatusResponse');
|
|
241
|
+
}
|
|
242
|
+
return Buffer.from(arg.serializeBinary());
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
function deserialize_bet_PromotionalBigWinStatusResponse(buffer_arg) {
|
|
246
|
+
return bet_pb.PromotionalBigWinStatusResponse.deserializeBinary(new Uint8Array(buffer_arg));
|
|
247
|
+
}
|
|
248
|
+
|
|
194
249
|
function serialize_bet_SegmentedUserRequest(arg) {
|
|
195
250
|
if (!(arg instanceof bet_pb.SegmentedUserRequest)) {
|
|
196
251
|
throw new Error('Expected argument of type bet.SegmentedUserRequest');
|
|
@@ -533,6 +588,53 @@ getWinRates: {
|
|
|
533
588
|
responseSerialize: serialize_bet_WinRateItem,
|
|
534
589
|
responseDeserialize: deserialize_bet_WinRateItem,
|
|
535
590
|
},
|
|
591
|
+
// Simulated promotional cards only. The requesting UI must visibly disclose this mode.
|
|
592
|
+
// Uses limit and zero-based page offset only; never reads or creates real player activity.
|
|
593
|
+
getPromotionalBigWins: {
|
|
594
|
+
path: '/bet.Bet/getPromotionalBigWins',
|
|
595
|
+
requestStream: false,
|
|
596
|
+
responseStream: false,
|
|
597
|
+
requestType: bet_pb.PaginationRequest,
|
|
598
|
+
responseType: bet_pb.WinRatesResponse,
|
|
599
|
+
requestSerialize: serialize_bet_PaginationRequest,
|
|
600
|
+
requestDeserialize: deserialize_bet_PaginationRequest,
|
|
601
|
+
responseSerialize: serialize_bet_WinRatesResponse,
|
|
602
|
+
responseDeserialize: deserialize_bet_WinRatesResponse,
|
|
603
|
+
},
|
|
604
|
+
// Internal configuration management, exposed only through authenticated BackOffice routes.
|
|
605
|
+
readListPromotionalBigWins: {
|
|
606
|
+
path: '/bet.Bet/readListPromotionalBigWins',
|
|
607
|
+
requestStream: false,
|
|
608
|
+
responseStream: false,
|
|
609
|
+
requestType: bet_pb.PaginationRequest,
|
|
610
|
+
responseType: bet_pb.PromotionalBigWinItemsResponse,
|
|
611
|
+
requestSerialize: serialize_bet_PaginationRequest,
|
|
612
|
+
requestDeserialize: deserialize_bet_PaginationRequest,
|
|
613
|
+
responseSerialize: serialize_bet_PromotionalBigWinItemsResponse,
|
|
614
|
+
responseDeserialize: deserialize_bet_PromotionalBigWinItemsResponse,
|
|
615
|
+
},
|
|
616
|
+
setPromotionalBigWin: {
|
|
617
|
+
path: '/bet.Bet/setPromotionalBigWin',
|
|
618
|
+
requestStream: false,
|
|
619
|
+
responseStream: false,
|
|
620
|
+
requestType: bet_pb.PromotionalBigWinRequest,
|
|
621
|
+
responseType: bet_pb.PromotionalBigWinItem,
|
|
622
|
+
requestSerialize: serialize_bet_PromotionalBigWinRequest,
|
|
623
|
+
requestDeserialize: deserialize_bet_PromotionalBigWinRequest,
|
|
624
|
+
responseSerialize: serialize_bet_PromotionalBigWinItem,
|
|
625
|
+
responseDeserialize: deserialize_bet_PromotionalBigWinItem,
|
|
626
|
+
},
|
|
627
|
+
deletePromotionalBigWin: {
|
|
628
|
+
path: '/bet.Bet/deletePromotionalBigWin',
|
|
629
|
+
requestStream: false,
|
|
630
|
+
responseStream: false,
|
|
631
|
+
requestType: bet_pb.PromotionalBigWinKey,
|
|
632
|
+
responseType: bet_pb.PromotionalBigWinStatusResponse,
|
|
633
|
+
requestSerialize: serialize_bet_PromotionalBigWinKey,
|
|
634
|
+
requestDeserialize: deserialize_bet_PromotionalBigWinKey,
|
|
635
|
+
responseSerialize: serialize_bet_PromotionalBigWinStatusResponse,
|
|
636
|
+
responseDeserialize: deserialize_bet_PromotionalBigWinStatusResponse,
|
|
637
|
+
},
|
|
536
638
|
};
|
|
537
639
|
|
|
538
640
|
exports.BetClient = grpc.makeGenericClientConstructor(BetService, 'Bet');
|