Skip to content

Update to asyncapi v3#31

Open
JarnoRFB wants to merge 6 commits intomainfrom
chore-AFC-6665
Open

Update to asyncapi v3#31
JarnoRFB wants to merge 6 commits intomainfrom
chore-AFC-6665

Conversation

@JarnoRFB
Copy link
Contributor

@JarnoRFB JarnoRFB commented Mar 5, 2026

Summary by CodeRabbit

  • Documentation

    • Upgraded AsyncAPI specification to v3.1.0 with improved structure and messaging organization.
  • Updates

    • Enhanced TypeScript type definitions with richer article properties and improved payload structures.
    • Deprecated totalGross field in payment responses.
  • Chores

    • Updated dependencies and tooling versions.
    • Upgraded GitHub Actions workflows to latest versions.

@vercel
Copy link

vercel bot commented Mar 5, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
cash-register-api-example-client Ready Ready Preview, Comment Mar 5, 2026 10:43pm

Request Review

@coderabbitai
Copy link

coderabbitai bot commented Mar 5, 2026

Walkthrough

This 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 @asyncapi/cli and @asyncapi/parser, refactors the TypeScript code generation to use the new parser instance API, and regenerates type definitions with restructured interface shapes for articles and payment data.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Update to asyncapi v3' accurately reflects the main change in the changeset, which upgrades the AsyncAPI specification and related tooling from v2 to v3.
Linked Issues check ✅ Passed The pull request comprehensively addresses the linked issue AFC-6665 by migrating the cash register client to AsyncAPI v3, including spec updates, dependency upgrades, and type generation changes.
Out of Scope Changes check ✅ Passed All changes are directly related to the AsyncAPI v3 migration objective: workflow updates, spec restructuring, dependency updates, and generated type updates remain in scope.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between bf5ddc4 and 72eeb5e.

⛔ Files ignored due to path filters (1)
  • example-client/pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (5)
  • .github/workflows/pages.yml
  • api.yml
  • example-client/package.json
  • example-client/src/generateTypes.ts
  • example-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.ts
  • example-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 totalGross as deprecated improves migration guidance for consumers.

Also applies to: 614-615


477-517: Added singular article interfaces are useful.

SyncedArticle and BasketArticle improve reusability for consumers that need item-level typing.

Also applies to: 555-589

Comment on lines +45 to +47
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.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

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).

Comment on lines 650 to 684
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:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

find . -name "api.yml" -type f | head -20

Repository: VisioLab/cash-register-api

Length of output: 79


🏁 Script executed:

wc -l ./api.yml

Repository: VisioLab/cash-register-api

Length of output: 83


🏁 Script executed:

sed -n '640,700p' ./api.yml

Repository: VisioLab/cash-register-api

Length of output: 1797


🏁 Script executed:

# Check other messages to verify consistency pattern
rg -n "payload:\s*$" ./api.yml | head -20

Repository: 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.yml

Repository: VisioLab/cash-register-api

Length of output: 448


🏁 Script executed:

# Check another message payload
sed -n '516,535p' ./api.yml

Repository: VisioLab/cash-register-api

Length of output: 547


🏁 Script executed:

# Search for the typo "warining" mentioned in original scratchpad
rg -n "warining" ./api.yml

Repository: 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 -10

Repository: 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 -50

Repository: 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.

Suggested change
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).

Comment on lines +20 to +33
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"))
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# Check if the files exist and examine the code
find . -name "generateTypes.ts" -o -name "types.ts" | head -20

Repository: 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"
fi

Repository: 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.

Suggested change
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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant