Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
WalkthroughThis pull request updates the project's GitHub Actions workflows, API specification, and tooling to newer versions. It upgrades GitHub Actions steps from v3/v2 to v4, migrates the AsyncAPI specification from version 2.6.0 to 3.1.0 with restructured channels and operations, updates dependencies including Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@api.yml`:
- Around line 45-47: Fix the documentation typo: replace the misspelled event
name "warining" with the correct "warning" in the sentence that currently reads
"both sides can send a `warining` event" so it instead reads "both sides can
send a `warning` event" (reference: the line mentioning the `error` event and
the deprecated events).
- Around line 650-684: The apiError and apiWarning message schemas currently
define payload.properties (with event and data) but do not enforce that those
fields are present or block extra fields; update both payload schemas
(referencing apiError.payload and apiWarning.payload) to add required:
["event","data"] and additionalProperties: false so event and data become
mandatory and no unknown properties are allowed; modify the payload objects
under the apiError and apiWarning definitions accordingly (keep the existing
properties and examples intact).
In `@example-client/src/generateTypes.ts`:
- Around line 20-33: The generated types collide because messages and schemas
use the same type names; when building messageTypes from
document.allMessages().all() call compile() with a prefixed name (e.g.,
"Message" + message.id()) so compiled message types become Message{OriginalName}
and cannot collide with schema types; update the map over messages that calls
compile(message.payload()?.json() ?? {}, message.id(), ...) to instead use
compile(message.payload()?.json() ?? {}, `Message${message.id()}`, {
bannerComment: "", additionalProperties: false }) and keep schemaTypes
unchanged, then write the concatenated results as before.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: c22c700a-1af7-4fc2-bd42-a4953e54edbc
⛔ Files ignored due to path filters (1)
example-client/pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (5)
.github/workflows/pages.ymlapi.ymlexample-client/package.jsonexample-client/src/generateTypes.tsexample-client/src/types.ts
📜 Review details
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2026-03-05T22:13:37.420Z
Learnt from: CR
Repo: VisioLab/cash-register-api PR: 0
File: README.md:0-0
Timestamp: 2026-03-05T22:13:37.420Z
Learning: Use the AsyncAPI standard to describe WebSocket APIs where VisioLab acts as a server
Applied to files:
api.yml
📚 Learning: 2026-03-05T22:13:41.250Z
Learnt from: CR
Repo: VisioLab/cash-register-api PR: 0
File: example-client/README.md:0-0
Timestamp: 2026-03-05T22:13:41.250Z
Learning: Generate TypeScript types for messages from the AsyncAPI spec using the 'npm run generateTypes' command
Applied to files:
example-client/src/generateTypes.tsexample-client/package.json
🔇 Additional comments (5)
.github/workflows/pages.yml (1)
27-50: Action version bumps look good.The v4 upgrades are consistent and don’t introduce behavioral changes in this workflow.
example-client/package.json (1)
8-46: Tooling update set is coherent.CLI/parser upgrades and script adjustments are aligned with the AsyncAPI v3 migration direction.
example-client/src/generateTypes.ts (1)
7-18: Parser v3 migration and diagnostics gate look good.This is a clean switch to the Parser instance API with explicit parse-failure handling.
example-client/src/types.ts (2)
196-197: Deprecation annotation is clear and useful.Marking
totalGrossas deprecated improves migration guidance for consumers.Also applies to: 614-615
477-517: Added singular article interfaces are useful.
SyncedArticleandBasketArticleimprove reusability for consumers that need item-level typing.Also applies to: 555-589
| In case of malformed messages or other errors, the register or the scanner | ||
| can send an `error` event. If deprecated events are being received, both | ||
| sides can send a `warining` event. |
There was a problem hiding this comment.
Fix typo in warning event name in docs.
warining should be warning.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@api.yml` around lines 45 - 47, Fix the documentation typo: replace the
misspelled event name "warining" with the correct "warning" in the sentence that
currently reads "both sides can send a `warining` event" so it instead reads
"both sides can send a `warning` event" (reference: the line mentioning the
`error` event and the deprecated events).
| apiError: | ||
| title: API Error | ||
| summary: Report an error. | ||
| description: > | ||
| Report an error that occurred either in response to a received event or due to some | ||
| external factor. | ||
| Report an error that occurred either in response to a received event or | ||
| due to some external factor. | ||
| payload: | ||
| type: object | ||
| properties: | ||
| event: | ||
| type: string | ||
| const: error | ||
| data: | ||
| $ref: "#/components/schemas/ApiError" | ||
| $ref: '#/components/schemas/ApiError' | ||
| examples: | ||
| - payload: | ||
| event: error | ||
| data: | ||
| reason: malformed | ||
| message: "Event data could not be decoded." | ||
|
|
||
| message: Event data could not be decoded. | ||
| apiWarning: | ||
| title: API Warning | ||
| summary: Report a warning. | ||
| description: > | ||
| Report a warning that occurred either in response to a received event or due to some | ||
| external factor. | ||
| Report a warning that occurred either in response to a received event or | ||
| due to some external factor. | ||
| payload: | ||
| type: object | ||
| properties: | ||
| event: | ||
| type: string | ||
| const: warning | ||
| data: | ||
| $ref: "#/components/schemas/ApiWarning" | ||
| $ref: '#/components/schemas/ApiWarning' | ||
| examples: |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
find . -name "api.yml" -type f | head -20Repository: VisioLab/cash-register-api
Length of output: 79
🏁 Script executed:
wc -l ./api.ymlRepository: VisioLab/cash-register-api
Length of output: 83
🏁 Script executed:
sed -n '640,700p' ./api.ymlRepository: VisioLab/cash-register-api
Length of output: 1797
🏁 Script executed:
# Check other messages to verify consistency pattern
rg -n "payload:\s*$" ./api.yml | head -20Repository: VisioLab/cash-register-api
Length of output: 489
🏁 Script executed:
# Check multiple message payloads to verify the required/additionalProperties pattern
sed -n '400,415p' ./api.ymlRepository: VisioLab/cash-register-api
Length of output: 448
🏁 Script executed:
# Check another message payload
sed -n '516,535p' ./api.ymlRepository: VisioLab/cash-register-api
Length of output: 547
🏁 Script executed:
# Search for the typo "warining" mentioned in original scratchpad
rg -n "warining" ./api.ymlRepository: VisioLab/cash-register-api
Length of output: 111
🏁 Script executed:
# Check if there are generated types files
find . -name "*types.ts" -o -name "*types.d.ts" | head -10Repository: VisioLab/cash-register-api
Length of output: 99
🏁 Script executed:
# Check for optional event/data fields in generated types for apiError/apiWarning
rg -n -A5 "interface.*Error|interface.*Warning" ./example-client/src/types.ts | head -50Repository: VisioLab/cash-register-api
Length of output: 658
Add required and additionalProperties: false to apiError and apiWarning payloads.
These payloads lack constraints present in other messages, causing event and data to be generated as optional fields downstream.
🔧 Proposed fix
apiError:
title: API Error
summary: Report an error.
description: >
Report an error that occurred either in response to a received event or
due to some external factor.
payload:
type: object
properties:
event:
type: string
const: error
data:
$ref: '#/components/schemas/ApiError'
+ required:
+ - event
+ - data
+ additionalProperties: false
examples:
- payload:
event: error
data:
reason: malformed
message: Event data could not be decoded.
apiWarning:
title: API Warning
summary: Report a warning.
description: >
Report a warning that occurred either in response to a received event or
due to some external factor.
payload:
type: object
properties:
event:
type: string
const: warning
data:
$ref: '#/components/schemas/ApiWarning'
+ required:
+ - event
+ - data
+ additionalProperties: false
examples:📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| apiError: | |
| title: API Error | |
| summary: Report an error. | |
| description: > | |
| Report an error that occurred either in response to a received event or due to some | |
| external factor. | |
| Report an error that occurred either in response to a received event or | |
| due to some external factor. | |
| payload: | |
| type: object | |
| properties: | |
| event: | |
| type: string | |
| const: error | |
| data: | |
| $ref: "#/components/schemas/ApiError" | |
| $ref: '#/components/schemas/ApiError' | |
| examples: | |
| - payload: | |
| event: error | |
| data: | |
| reason: malformed | |
| message: "Event data could not be decoded." | |
| message: Event data could not be decoded. | |
| apiWarning: | |
| title: API Warning | |
| summary: Report a warning. | |
| description: > | |
| Report a warning that occurred either in response to a received event or due to some | |
| external factor. | |
| Report a warning that occurred either in response to a received event or | |
| due to some external factor. | |
| payload: | |
| type: object | |
| properties: | |
| event: | |
| type: string | |
| const: warning | |
| data: | |
| $ref: "#/components/schemas/ApiWarning" | |
| $ref: '#/components/schemas/ApiWarning' | |
| examples: | |
| apiError: | |
| title: API Error | |
| summary: Report an error. | |
| description: > | |
| Report an error that occurred either in response to a received event or | |
| due to some external factor. | |
| payload: | |
| type: object | |
| properties: | |
| event: | |
| type: string | |
| const: error | |
| data: | |
| $ref: '#/components/schemas/ApiError' | |
| required: | |
| - event | |
| - data | |
| additionalProperties: false | |
| examples: | |
| - payload: | |
| event: error | |
| data: | |
| reason: malformed | |
| message: Event data could not be decoded. | |
| apiWarning: | |
| title: API Warning | |
| summary: Report a warning. | |
| description: > | |
| Report a warning that occurred either in response to a received event or | |
| due to some external factor. | |
| payload: | |
| type: object | |
| properties: | |
| event: | |
| type: string | |
| const: warning | |
| data: | |
| $ref: '#/components/schemas/ApiWarning' | |
| required: | |
| - event | |
| - data | |
| additionalProperties: false | |
| examples: |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@api.yml` around lines 650 - 684, The apiError and apiWarning message schemas
currently define payload.properties (with event and data) but do not enforce
that those fields are present or block extra fields; update both payload schemas
(referencing apiError.payload and apiWarning.payload) to add required:
["event","data"] and additionalProperties: false so event and data become
mandatory and no unknown properties are allowed; modify the payload objects
under the apiError and apiWarning definitions accordingly (keep the existing
properties and examples intact).
| const messageTypes = await Promise.all( | ||
| document.allMessages().all() | ||
| .map((message) => | ||
| compile(message.payload()?.json() ?? {}, message.id(), { bannerComment: "", additionalProperties: false })) | ||
| ) | ||
| await fs.writeFile("./src/types.ts", types.join("\n")) | ||
|
|
||
| const schemaTypes = await Promise.all( | ||
| document.allSchemas().all() | ||
| .filter((schema) => !schema.id().startsWith("<anonymous")) | ||
| .map((schema) => | ||
| compile(schema.json(), schema.id(), { bannerComment: "", additionalProperties: false })) | ||
| ) | ||
|
|
||
| await fs.writeFile("./src/types.ts", messageTypes.concat(schemaTypes).join("\n")) |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# Check if the files exist and examine the code
find . -name "generateTypes.ts" -o -name "types.ts" | head -20Repository: VisioLab/cash-register-api
Length of output: 137
🏁 Script executed:
# List files in the example-client directory
ls -la example-client/src/ 2>/dev/null || echo "Directory not found"Repository: VisioLab/cash-register-api
Length of output: 1060
🏁 Script executed:
# Read the generateTypes.ts file to see the actual code
cat -n example-client/src/generateTypes.ts 2>/dev/null | sed -n '1,50p'Repository: VisioLab/cash-register-api
Length of output: 1614
🏁 Script executed:
# Run the verification script to check for duplicate type names
if [ -f "example-client/src/types.ts" ]; then
python - <<'PY'
import re
from collections import Counter
from pathlib import Path
text = Path("example-client/src/types.ts").read_text()
names = re.findall(r'^export (?:interface|type) (\w+)', text, flags=re.M)
dups = {name: count for name, count in Counter(names).items() if count > 1}
if dups:
print("DUPLICATES FOUND:")
print(dups)
else:
print("NO DUPLICATES FOUND")
print(f"Total exported types: {len(names)}")
print(f"Unique types: {len(set(names))}")
PY
else
echo "File example-client/src/types.ts does not exist"
fiRepository: VisioLab/cash-register-api
Length of output: 162
Prevent message/schema type-name collisions during generation.
The generated types file contains duplicate interface/type declarations (ApiError and ApiWarning each appear twice). This occurs because messages and schemas can share the same IDs in the AsyncAPI document, both being passed to the compile() function with identical type names.
Apply the proposed fix to prefix message-derived types with Message:
Suggested fix
+ const toMessageTypeName = (id: string): string =>
+ `Message${id.charAt(0).toUpperCase()}${id.slice(1)}`
+
const messageTypes = await Promise.all(
document.allMessages().all()
.map((message) =>
- compile(message.payload()?.json() ?? {}, message.id(), { bannerComment: "", additionalProperties: false }))
+ compile(message.payload()?.json() ?? {}, toMessageTypeName(message.id()), { bannerComment: "", additionalProperties: false }))
)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const messageTypes = await Promise.all( | |
| document.allMessages().all() | |
| .map((message) => | |
| compile(message.payload()?.json() ?? {}, message.id(), { bannerComment: "", additionalProperties: false })) | |
| ) | |
| await fs.writeFile("./src/types.ts", types.join("\n")) | |
| const schemaTypes = await Promise.all( | |
| document.allSchemas().all() | |
| .filter((schema) => !schema.id().startsWith("<anonymous")) | |
| .map((schema) => | |
| compile(schema.json(), schema.id(), { bannerComment: "", additionalProperties: false })) | |
| ) | |
| await fs.writeFile("./src/types.ts", messageTypes.concat(schemaTypes).join("\n")) | |
| const toMessageTypeName = (id: string): string => | |
| `Message${id.charAt(0).toUpperCase()}${id.slice(1)}` | |
| const messageTypes = await Promise.all( | |
| document.allMessages().all() | |
| .map((message) => | |
| compile(message.payload()?.json() ?? {}, toMessageTypeName(message.id()), { bannerComment: "", additionalProperties: false })) | |
| ) | |
| const schemaTypes = await Promise.all( | |
| document.allSchemas().all() | |
| .filter((schema) => !schema.id().startsWith("<anonymous")) | |
| .map((schema) => | |
| compile(schema.json(), schema.id(), { bannerComment: "", additionalProperties: false })) | |
| ) | |
| await fs.writeFile("./src/types.ts", messageTypes.concat(schemaTypes).join("\n")) |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@example-client/src/generateTypes.ts` around lines 20 - 33, The generated
types collide because messages and schemas use the same type names; when
building messageTypes from document.allMessages().all() call compile() with a
prefixed name (e.g., "Message" + message.id()) so compiled message types become
Message{OriginalName} and cannot collide with schema types; update the map over
messages that calls compile(message.payload()?.json() ?? {}, message.id(), ...)
to instead use compile(message.payload()?.json() ?? {},
`Message${message.id()}`, { bannerComment: "", additionalProperties: false })
and keep schemaTypes unchanged, then write the concatenated results as before.
Summary by CodeRabbit
Documentation
Updates
totalGrossfield in payment responses.Chores