feat: app catalog v3 list, get by type and install app#4658
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds app catalog capability metadata, catalog listing and lookup endpoints, installation request variants, Go v3 handlers, JavaScript and Go client methods, generated API models, internal invoice/governance SDK operations, generator visibility changes, and end-to-end tests. ChangesApp Catalog and API Implementation
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant Client
participant Server
participant AppsHandler
participant AppService
Client->>Server: Request catalog or installation operation
Server->>AppsHandler: Forward request
AppsHandler->>AppService: Query marketplace or install app
AppService-->>AppsHandler: Return listing or installed app
AppsHandler-->>Server: Encode API response
Server-->>Client: Return result
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
df6bf17 to
4430441
Compare
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (2)
api/v3/handlers/apps/get_app_catalog.go (1)
15-20: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueConsider the request type naming.
GetAppCatalogRequest = app.GetOauth2InstallURLInputreuses an OAuth2-specific input type for a general catalog item lookup. While functionally correct (the type only carries aTypefield), the name is misleading at the call site. If this is the only shared input shape, consider introducing a more generic domain type likeapp.GetMarketplaceListingInputor aliasing it clearly.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@api/v3/handlers/apps/get_app_catalog.go` around lines 15 - 20, The request type alias in GetAppCatalogHandler is misleading because GetAppCatalogRequest currently reuses the OAuth2-specific app.GetOauth2InstallURLInput for a general catalog lookup. Update the request type in this handler to use a more generic domain input name, such as a marketplace/listing input, or add a clearly named alias in the app package so the call site reflects the actual purpose of GetAppCatalogHandler and GetAppCatalogRequest.e2e/apps_v3_test.go (1)
22-72: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd e2e coverage for the single-item app catalog endpoints
The list endpoint is covered here, butGetAppCatalogandGetAppCatalogOauth2InstallUrlstill need a couple of focused e2e cases to catch routing and response-shape regressions.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@e2e/apps_v3_test.go` around lines 22 - 72, The app catalog e2e coverage currently exercises only ListAppCatalog, so add focused tests for the single-item endpoints as requested. Extend TestV3AppCatalogList or add a nearby test to call GetAppCatalog and GetAppCatalogOauth2InstallUrl through the existing newV3Client helper, using known catalog items such as BillingAppCatalogItemTypeSandbox or BillingAppCatalogItemTypeStripe. Assert the responses are OK and the returned payloads have the expected shape and key fields so routing and serialization regressions are caught.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@api/spec/packages/aip/src/apps/catalog.tsp`:
- Line 38: The `@example` description in the catalog app has a typo in the
Stripe text; update the string in the example metadata so it says “integration”
instead of “interation” in the `catalog.tsp` example block. Locate the affected
`description` field near the Stripe example and correct the spelling without
changing the rest of the sentence.
In `@api/spec/packages/aip/src/apps/operations.tsp`:
- Around line 65-67: The doc comment above getOAuth2InstallURL is using a plain
block comment instead of a recognized TypeSpec doc comment, so update it to the
proper doc comment syntax used by the other operations in operations.tsp. Keep
the existing description but ensure it is attached to getOAuth2InstallURL with
the correct comment form so it shows up in the generated OpenAPI spec.
In `@api/v3/handlers/apps/get_app_catalog_oauth2.go`:
- Line 52: The OAuth2 install URL endpoint is reusing the same operation name as
GetAppCatalog, which makes the two handlers indistinguishable in telemetry.
Update the httptransport.WithOperationName value in get_app_catalog_oauth2.go to
a unique name for this endpoint, and keep GetAppCatalog’s operation name
unchanged so metrics, traces, and logs can tell them apart.
In `@api/v3/handlers/apps/get_app_catalog.go`:
- Around line 48-53: The operation name used in get_app_catalog_oauth2.go is
still shared with the catalog-item handler, which causes log, metric, and trace
collisions. Update the httptransport.WithOperationName value in the
getAppCatalogOAuth2InstallURL-related setup to use the distinct name
get-app-catalog-item-oauth2-install-url, keeping the rest of the
httptransport.AppendOptions configuration unchanged.
---
Nitpick comments:
In `@api/v3/handlers/apps/get_app_catalog.go`:
- Around line 15-20: The request type alias in GetAppCatalogHandler is
misleading because GetAppCatalogRequest currently reuses the OAuth2-specific
app.GetOauth2InstallURLInput for a general catalog lookup. Update the request
type in this handler to use a more generic domain input name, such as a
marketplace/listing input, or add a clearly named alias in the app package so
the call site reflects the actual purpose of GetAppCatalogHandler and
GetAppCatalogRequest.
In `@e2e/apps_v3_test.go`:
- Around line 22-72: The app catalog e2e coverage currently exercises only
ListAppCatalog, so add focused tests for the single-item endpoints as requested.
Extend TestV3AppCatalogList or add a nearby test to call GetAppCatalog and
GetAppCatalogOauth2InstallUrl through the existing newV3Client helper, using
known catalog items such as BillingAppCatalogItemTypeSandbox or
BillingAppCatalogItemTypeStripe. Assert the responses are OK and the returned
payloads have the expected shape and key fields so routing and serialization
regressions are caught.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 74e37b96-7639-46c4-9d0e-0b7f7bb1aab3
⛔ Files ignored due to path filters (1)
api/v3/openapi.yamlis excluded by!**/openapi.yaml
📒 Files selected for processing (23)
api/spec/packages/aip-client-javascript/README.mdapi/spec/packages/aip-client-javascript/src/funcs/apps.tsapi/spec/packages/aip-client-javascript/src/index.tsapi/spec/packages/aip-client-javascript/src/models/operations/apps.tsapi/spec/packages/aip-client-javascript/src/models/schemas.tsapi/spec/packages/aip-client-javascript/src/models/types.tsapi/spec/packages/aip-client-javascript/src/sdk/apps.tsapi/spec/packages/aip/src/apps/capability.tspapi/spec/packages/aip/src/apps/catalog.tspapi/spec/packages/aip/src/apps/oauth.tspapi/spec/packages/aip/src/apps/operations.tspapi/spec/packages/aip/src/konnect.tspapi/spec/packages/aip/src/openmeter.tspapi/v3/api.gen.goapi/v3/handlers/apps/convert.gen.goapi/v3/handlers/apps/convert.goapi/v3/handlers/apps/get_app_catalog.goapi/v3/handlers/apps/get_app_catalog_oauth2.goapi/v3/handlers/apps/handler.goapi/v3/handlers/apps/list_app_catalog.goapi/v3/server/routes.goe2e/apps_v3_test.goe2e/v3helpers_test.go
0a24c1c to
4e4372d
Compare
There was a problem hiding this comment.
Actionable comments posted: 7
🧹 Nitpick comments (2)
e2e/apps_v3_test.go (2)
26-28: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd concise given/when/then intent comments to these subtests.
As per coding guidelines, non-trivial service and lifecycle subtests must begin with concise given, when, and then intent comments.
Also applies to: 60-67, 87-94
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@e2e/apps_v3_test.go` around lines 26 - 28, The affected catalog subtests should begin with concise Given/When/Then intent comments. Add these comments to the subtests around Apps.ListCatalog and the additional ranges at 60-67 and 87-94, describing the setup, service action, and expected outcome without changing test behavior.Source: Coding guidelines
87-98: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winCover the billing-profile installation path.
The new orchestration’s meaningful failure and default-assignment behavior only runs with
CreateBillingProfile: true; this test would still pass if that entire branch regressed. Add an install case that verifies the profile and returned default capability types.As per path instructions, tests should meaningfully cover behavior introduced by the PR.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@e2e/apps_v3_test.go` around lines 87 - 98, Add coverage to the “Should install external invoicing app” test for the CreateBillingProfile: true path, verifying the installed billing profile and the returned default capability types. Keep the existing external-invoicing assertions, and ensure the test fails if billing-profile orchestration or default capability assignment regresses.Source: Path instructions
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@api/v3/client/models_apps.go`:
- Around line 340-342: Update the TypeSpec source documentation for
CreateBillingProfile and the corresponding related fields at the other generated
locations so each comment accurately describes billing-profile creation behavior
and consequences. Regenerate api/v3/client/models_apps.go from the TypeSpec
source; do not edit the generated Go file directly.
In `@api/v3/client/README.md`:
- Line 206: Populate the missing description for om.Apps.Install in the API
operation documentation, preferably by adding the appropriate source `@doc` text
if this README is generated, then regenerate or update the table so the Install
row contains a clear description.
In `@api/v3/handlers/apps/handler.go`:
- Around line 36-47: The New constructor currently does not explicitly receive a
logger. Add a required *slog.Logger parameter, store it on the handler struct,
and update server initialization to pass the production logger through New;
ensure all constructor call sites are updated accordingly.
In `@api/v3/handlers/apps/install_app.go`:
- Around line 43-57: The InstallAppRequest conversion flow around
body.Discriminator and ToDomainAppTypeFromAPIBillingAppType must return the
repository’s structured bad-request error, including the relevant payload field
context, rather than plain fmt.Errorf values. Apply the same treatment to all
corresponding discriminator and variant-conversion failures in the covered
conversion paths, while preserving the existing error messages and successful
conversion behavior.
- Around line 114-133: The InstallApp flow must not leave an installed app
behind when createBillingProfile fails. Update the installation and
createBillingProfile operations to use a shared transaction where supported;
otherwise add compensating cleanup or idempotency keyed to the request so failed
provisioning is retriable without duplicate state. Preserve the existing error
responses while ensuring the installedApp state is rolled back or safely marked
when provisioning fails.
- Around line 194-227: Update the capability assignment after CreateProfile in
the install flow: only populate defaultForCapabilityTypes with the three Stripe
capabilities when setDefaultBillingProfile is true; otherwise return an empty
list. Also explicitly define the intended behavior for a nil
defaultBillingProfile and ensure setDefaultBillingProfile reflects that decision
consistently.
In `@e2e/apps_v3_test.go`:
- Around line 53-57: The app catalog handler must convert the domain billing
type custom_invoicing to the public API enum external_invoicing. Update
ToAPIBillingAppTypeFromDomain and its use in the catalog handler, then remove
the test waiver and assert the custom invoicing entry through the generated
external-invoicing enum.
---
Nitpick comments:
In `@e2e/apps_v3_test.go`:
- Around line 26-28: The affected catalog subtests should begin with concise
Given/When/Then intent comments. Add these comments to the subtests around
Apps.ListCatalog and the additional ranges at 60-67 and 87-94, describing the
setup, service action, and expected outcome without changing test behavior.
- Around line 87-98: Add coverage to the “Should install external invoicing app”
test for the CreateBillingProfile: true path, verifying the installed billing
profile and the returned default capability types. Keep the existing
external-invoicing assertions, and ensure the test fails if billing-profile
orchestration or default capability assignment regresses.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 09540580-1a5c-4b13-a549-c0ee42bf780f
⛔ Files ignored due to path filters (1)
api/v3/openapi.yamlis excluded by!**/openapi.yaml
📒 Files selected for processing (25)
api/spec/packages/aip-client-javascript/README.mdapi/spec/packages/aip-client-javascript/src/funcs/apps.tsapi/spec/packages/aip-client-javascript/src/index.tsapi/spec/packages/aip-client-javascript/src/models/operations/apps.tsapi/spec/packages/aip-client-javascript/src/models/schemas.tsapi/spec/packages/aip-client-javascript/src/models/types.tsapi/spec/packages/aip-client-javascript/src/sdk/apps.tsapi/spec/packages/aip/src/apps/capability.tspapi/spec/packages/aip/src/apps/catalog.tspapi/spec/packages/aip/src/apps/operations.tspapi/spec/packages/aip/src/konnect.tspapi/spec/packages/aip/src/openmeter.tspapi/v3/api.gen.goapi/v3/client/README.mdapi/v3/client/apps.goapi/v3/client/models_apps.goapi/v3/handlers/apps/convert.gen.goapi/v3/handlers/apps/convert.goapi/v3/handlers/apps/get_app_catalog.goapi/v3/handlers/apps/handler.goapi/v3/handlers/apps/install_app.goapi/v3/handlers/apps/list_app_catalog.goapi/v3/server/routes.goapi/v3/server/server.goe2e/apps_v3_test.go
🚧 Files skipped from review as they are similar to previous changes (8)
- api/spec/packages/aip/src/konnect.tsp
- api/spec/packages/aip/src/openmeter.tsp
- api/v3/handlers/apps/get_app_catalog.go
- api/spec/packages/aip/src/apps/capability.tsp
- api/v3/handlers/apps/convert.gen.go
- api/v3/handlers/apps/convert.go
- api/v3/handlers/apps/list_app_catalog.go
- api/spec/packages/aip-client-javascript/src/models/schemas.ts
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
openmeter/app/service/service.go (1)
38-47: 🩺 Stability & Availability | 🔴 Critical | ⚡ Quick winInitialize new dependencies in the constructor.
Hey! It looks like we missed initializing the new
billingServiceandstripeAppServicedependencies in theNewconstructor. Since they're now part of theServicestruct, leaving them out here means they'll benil, which will trigger a panic whenInstallApptries to use them.Could you also double-check that they are added to the
Configstruct and validated inConfig.Validate()if they are strictly required?Here's a quick fix for the constructor (assuming the
Configfields follow the usual naming conventions):🛠️ Proposed fix for the constructor
func New(config Config) (*Service, error) { if err := config.Validate(); err != nil { return nil, err } return &Service{ adapter: config.Adapter, + billingService: config.BillingService, + stripeAppService: config.StripeAppService, publisher: config.Publisher, }, nil }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@openmeter/app/service/service.go` around lines 38 - 47, Update New to initialize the Service struct’s billingService and stripeAppService fields from the corresponding Config dependencies, alongside adapter and publisher. Ensure those dependencies are present in Config and are checked by Config.Validate() when required, so InstallApp never receives nil services.openmeter/app/httpdriver/marketplace.go (1)
95-123: 🎯 Functional Correctness | 🔴 Critical | ⚡ Quick winPass
CreateDefaultBillingProfiledirectly toInstallAppV3Input.Hey! Great job pulling the common fields into
InstallAppV3Input! However, it looks like we're still assigning the fallback billing profile boolean to the wrapper'sCreateBillingProfilefield instead of passing it intoInstallAppV3Input.CreateDefaultBillingProfile. Because of this, the underlying service will receivefalse(the default struct value) and will inadvertently skip creating the default billing profile during installation.
openmeter/app/httpdriver/marketplace.go#L95-L123: For the API key install, drop theCreateBillingProfilefield fromMarketplaceAppAPIKeyInstallRequestand assignCreateDefaultBillingProfile: lo.FromPtrOr(body.CreateBillingProfile, true)directly inside the innerInstallAppV3Input.openmeter/app/httpdriver/marketplace.go#L164-L191: For the standard install, similarly drop the field fromMarketplaceAppInstallRequestand move the assignment directly toInstallAppV3Input.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@openmeter/app/httpdriver/marketplace.go` around lines 95 - 123, The install request wrappers currently retain the billing-profile flag instead of passing it to the underlying input. In openmeter/app/httpdriver/marketplace.go lines 95-123, remove CreateBillingProfile from MarketplaceAppAPIKeyInstallRequest and set CreateDefaultBillingProfile directly in its InstallAppV3Input using the existing default-true fallback; apply the same change to MarketplaceAppInstallRequest at lines 164-191.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@openmeter/app/marketplace.go`:
- Around line 150-165: Update InstallAppV3Input.Validate to accumulate
validation failures for MarketplaceListingID, Namespace, and APIKey instead of
returning on the first error. Preserve field-specific context for each failure,
then return models.NewNillableGenericValidationError(errors.Join(errs...));
return the nillable validation result even when no errors are collected.
In `@openmeter/app/service/marketplace.go`:
- Around line 77-78: Update the service constructor and configuration to require
and validate billingService and stripeAppService alongside adapter and
publisher. Initialize both corresponding Service fields, then update every
constructor call site to supply the new dependencies so createBillingProfile and
Stripe provisioning no longer access nil services.
- Around line 94-103: The Sandbox branch in the app capability provisioning flow
must only report capabilities when this app becomes the default billing profile.
Update the logic around ProvisionDefaultBillingProfile to detect its no-op
case—preferably by returning or retrieving the resulting profile and verifying
its app reference—and return no capabilities when another default already
exists; preserve the existing capability list only when the installed Sandbox
app is actually defaulted.
In `@test/app/custominvoicing/invocing_test.go`:
- Around line 49-56: Make the installation assertion fatal before the custom
invoicing configuration upsert and any dereference of customInvoicingApp.App.
Replace the non-fatal NoError handling for the install result with the test
suite’s fatal requirement mechanism, while preserving the existing error message
and subsequent provisioning flow.
---
Outside diff comments:
In `@openmeter/app/httpdriver/marketplace.go`:
- Around line 95-123: The install request wrappers currently retain the
billing-profile flag instead of passing it to the underlying input. In
openmeter/app/httpdriver/marketplace.go lines 95-123, remove
CreateBillingProfile from MarketplaceAppAPIKeyInstallRequest and set
CreateDefaultBillingProfile directly in its InstallAppV3Input using the existing
default-true fallback; apply the same change to MarketplaceAppInstallRequest at
lines 164-191.
In `@openmeter/app/service/service.go`:
- Around line 38-47: Update New to initialize the Service struct’s
billingService and stripeAppService fields from the corresponding Config
dependencies, alongside adapter and publisher. Ensure those dependencies are
present in Config and are checked by Config.Validate() when required, so
InstallApp never receives nil services.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 4313bf0b-efd0-4f74-b345-f18648846c44
⛔ Files ignored due to path filters (1)
api/v3/openapi.yamlis excluded by!**/openapi.yaml
📒 Files selected for processing (22)
api/spec/packages/aip-client-javascript/README.mdapi/spec/packages/aip-client-javascript/src/funcs/apps.tsapi/spec/packages/aip-client-javascript/src/models/schemas.tsapi/spec/packages/aip-client-javascript/src/models/types.tsapi/spec/packages/aip-client-javascript/src/sdk/apps.tsapi/spec/packages/aip/src/apps/catalog.tspapi/spec/packages/aip/src/apps/operations.tspapi/v3/api.gen.goapi/v3/client/README.mdapi/v3/client/apps.goapi/v3/client/models_apps.goapi/v3/handlers/apps/install_app.goopenmeter/app/httpdriver/marketplace.goopenmeter/app/marketplace.goopenmeter/app/service.goopenmeter/app/service/marketplace.goopenmeter/app/service/service.goopenmeter/server/server_test.gotest/app/custominvoicing/invocing_test.gotest/app/stripe/appstripe.gotest/app/stripe/fixture.gotest/billing/suite.go
🚧 Files skipped from review as they are similar to previous changes (10)
- api/v3/client/README.md
- api/spec/packages/aip-client-javascript/README.md
- api/spec/packages/aip/src/apps/operations.tsp
- api/spec/packages/aip/src/apps/catalog.tsp
- api/spec/packages/aip-client-javascript/src/funcs/apps.ts
- api/spec/packages/aip-client-javascript/src/sdk/apps.ts
- api/v3/client/models_apps.go
- api/v3/client/apps.go
- api/spec/packages/aip-client-javascript/src/models/types.ts
- api/spec/packages/aip-client-javascript/src/models/schemas.ts
7a86c69 to
16a6c46
Compare
16a6c46 to
ac1c672
Compare
… and get oauth install url, add install app endpoint, improve test, unify app install on service level, collect validation errors, import cycle error
dfe9ae7 to
c5938b2
Compare
App Catalog List/GetByType/Install Endpoints — What / Why / How
What
Added v3 API endpoints for app catalog discovery and installation:
GET /api/v3/openmeter/apps/catalog— List available apps with paginationGET /api/v3/openmeter/apps/catalog/{type}— Get app catalog details by typePOST /api/v3/openmeter/apps/install— Install an app with optional automatic billing profile creationUnified app installation logic at the service layer, consolidating
InstallMarketplaceListingWithAPIKeyandInstallMarketplaceListinginto a single transactionalInstallApp()method.Generated TypeScript and Go client SDKs with corresponding models and operation types.
Why
Discoverability: Users need a stable way to discover available app types (Sandbox, Stripe, External Invoicing) and their capabilities (tax calculation, invoicing, payments) without coupling to internal service details.
Installation UX: Combining app installation with optional billing profile auto-provisioning reduces multi-step workflows. Transactional execution prevents partial installations on errors (e.g., app created but billing profile fails).
Service clarity: Unifying two separate install methods eliminates duplicated validation logic and error handling, simplifying future maintenance.
How
catalog.tspandcapability.tspdefining app catalog models, install request/response discriminated unions, and install method enumsInstallApp()wraps installation intransaction.Run(), calls either API-key or OAuth path based on input, then invokes billing profile callback if requestedInstallAppV3Input.Validate()collects all errors (errors.Join()) instead of returning on first failureGenerated artifacts: TypeSpec emits OpenAPI spec and SDKs;
make gen-apiupdatesapi/v3/api.gen.goand TypeScript client.Summary by CodeRabbit
Greptile Summary
This PR adds v3 app catalog discovery and installation APIs. The main changes are:
Confidence Score: 5/5
This looks safe to merge.
Important Files Changed
Reviews (15): Last reviewed commit: "fix: generator issue" | Re-trigger Greptile
Context used (3)