Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions .agents/skills/dubbo-admin-console-api/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
---
name: dubbo-admin-console-api
description: Implements and reviews dubbo-admin Console API changes. Use when the user asks about HTTP endpoints, Gin routes, handlers, request or response models, console services, error handling, API pagination, or the handler to service to manager to store flow under pkg/console/. Do not use for frontend-only, discovery-only, or store-internals tasks unless they affect Console API behavior.
---

# dubbo-admin Console API

## Purpose

Use this skill to change or explain dubbo-admin Web MVC behavior consistently across router, handler, model, service, manager, and store layers.

## When to use

Use for Console API endpoint additions, request binding, response models, service logic, route registration, API error handling, and backend API review.

Do not use for Vue-only changes, registry discovery internals, or memory store implementation details unless an API contract depends on them.

## Inputs

Required:
- Target endpoint, handler, model, or package path.
- Intended API behavior or observed bug.

Optional:
- Example request or response payload.
- Related frontend API caller.
- Existing route or service function to mirror.

If missing, inspect `pkg/console/router/router.go` first and ask only for behavior that cannot be inferred from code.

## Workflow

1. Locate the route in `pkg/console/router/router.go`.
2. Read the matching handler in `pkg/console/handler/` for binding and response style.
3. Read or update request and response types in `pkg/console/model/`.
4. Put business logic in `pkg/console/service/`; keep handlers focused on HTTP concerns.
5. Use `ctx.ResourceManager()` and helpers in `pkg/core/manager/` for resource access.
6. Return responses with `model.NewSuccessResp`, `util.HandleArgumentError`, or `util.HandleServiceError`.
7. If endpoint behavior is unclear, read `references/web-mvc-flow.md`.

## Output format

Return changed files, endpoint behavior, request and response contract, validation performed, and any frontend impact.

## Validation

- Confirm the route is registered under `/api/v1`.
- Confirm handler binding matches method semantics: query for reads, JSON body for mutations.
- Confirm service code returns typed models and propagates business errors.
- Run focused Go tests for changed packages; use `make test` for shared API behavior.

## Edge cases

- Some handlers include lightweight auth, cookie, or parameter logic; do not force all logic into services.
- If changing response fields, check frontend callers under `ui-vue3/src/api/`.
- If a resource query becomes slow, switch to `dubbo-admin-store`.

## References

- Read `references/web-mvc-flow.md` for the current route, handler, service, and response pattern.
30 changes: 30 additions & 0 deletions .agents/skills/dubbo-admin-console-api/evals/evals.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"skill_name": "dubbo-admin-console-api",
"evals": [
{
"id": "obvious-trigger",
"prompt": "Add a new GET endpoint under /api/v1/service that returns a typed response from pkg/console/service.",
"expected_behavior": "Use the Console API router, handler, model, service, and manager workflow."
},
{
"id": "paraphrased-trigger",
"prompt": "The admin backend route binds query parameters incorrectly and returns the wrong CommonResp data.",
"expected_behavior": "Inspect pkg/console handlers, models, services, and response helpers."
},
{
"id": "file-based-trigger",
"prompt": "Review changes in pkg/console/router/router.go and pkg/console/handler/application.go.",
"expected_behavior": "Use this skill because Console API files are touched."
},
{
"id": "no-trigger",
"prompt": "Change the Vue sidebar icon for the service page.",
"expected_behavior": "Do not use this skill; use the frontend skill."
},
{
"id": "conflict-trigger",
"prompt": "A frontend API call fails because the backend response field changed.",
"expected_behavior": "Use this skill for backend contract review and coordinate with frontend skill for caller updates."
}
]
}
202 changes: 202 additions & 0 deletions .agents/skills/dubbo-admin-console-api/references/web-mvc-flow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
# Console API Web MVC Implementation

This reference explains how dubbo-admin exposes backend HTTP APIs through Gin handlers, typed models, console services, resource managers, and stores.

## End-to-end call chain

```text
runtime.RegisterComponent(&consoleWebServer{})
-> Bootstrap initializes consoleWebServer.Init
-> Init creates gin.Engine, middleware, static UI, health route
-> Runtime starts consoleWebServer.Start
-> Start creates consolectx.NewConsoleContext(coreRt)
-> router.InitRouter(c.Engine, c.cs)
-> HTTP request under /api/v1
-> handler binds query/path/body
-> handler calls service function
-> service uses consolectx.Context and ctx.ResourceManager()
-> manager/store reads or writes resources
-> service returns typed model response
-> handler wraps with model.NewSuccessResp or util.Handle*Error
```

## Console component

Key file: `pkg/console/component.go`

Console is registered as a runtime component and depends on `runtime.ResourceManager`:

```go
func init() {
runtime.RegisterComponent(&consoleWebServer{})
}

func (c *consoleWebServer) RequiredDependencies() []runtime.ComponentType {
return []runtime.ComponentType{runtime.ResourceManager}
}
```

`Init` sets up Gin:

- embedded admin UI mounted at `/admin`
- SPA fallback for `/admin/**`
- `/health` endpoint
- cookie session store
- auth middleware
- zap logging and recovery middleware
- Gin mode from config

`Start` creates console context and registers `/api/v1` routes:

```go
c.cs = consolectx.NewConsoleContext(coreRt)
router.InitRouter(c.Engine, c.cs)
httpServer := c.startHttpServer(errChan)
```

On stop, the HTTP server shuts down with `Shutdown(context.Background())`.

## Auth behavior

`authMiddleware` skips paths ending in `/login`. Other requests require a session value named `user`. Missing user returns HTTP 401 with `model.NewBizErrorResp`.

This means many API handlers assume authentication already passed.

## Console context

Key file: `pkg/console/context/context.go`

`consolectx.Context` wraps runtime access:

```go
type Context interface {
ResourceManager() manager.ResourceManager
CounterManager() counter.CounterManager
Config() app.AdminConfig
AppContext() context.Context
LockManager() lock.Lock
}
```

`ResourceManager()` retrieves the runtime ResourceManager component and returns its manager:

```go
rmc, _ := c.coreRt.GetComponent(runtime.ResourceManager)
return rmc.(manager.ResourceManagerComponent).ResourceManager()
```

CounterManager and LockManager are optional and may return nil.

## Route registration

Key file: `pkg/console/router/router.go`

All Console API routes are grouped under `/api/v1`:

```go
router := r.Group("/api/v1")
```

Common groups include:

- `/auth`
- `/instance`
- `/application`
- `/service`
- `/configurator`
- `/condition-rule`
- `/tag-rule`
- global `/search`, `/overview`, `/metadata`, `/meshes`

When adding an endpoint, register the route in the existing group that matches frontend URL structure.

## Handler pattern

Handlers usually close over `consolectx.Context` and return `gin.HandlerFunc`:

```go
func GetApplicationDetail(ctx consolectx.Context) gin.HandlerFunc {
return func(c *gin.Context) {
req := &model.ApplicationDetailReq{}
if err := c.ShouldBindQuery(req); err != nil {
util.HandleArgumentError(c, err)
return
}
resp, err := service.GetApplicationDetail(ctx, req)
if err != nil {
util.HandleServiceError(c, err)
return
}
c.JSON(http.StatusOK, model.NewSuccessResp(resp))
}
}
```

Read endpoints commonly use `ShouldBindQuery`. Mutation endpoints commonly use `ShouldBindJSON` or path parameters depending on existing handler style.

## Error and response model

Key files:

- `pkg/console/model/common.go`
- `pkg/console/util/error.go`

Success response:

```go
model.NewSuccessResp(data)
```

Service errors are normalized to `bizerror.Error` and returned with HTTP 200:

```go
func HandleServiceError(ctx *gin.Context, err error) {
var e bizerror.Error
if !errors.As(err, &e) {
e = bizerror.New(bizerror.UnknownError, err.Error())
}
ctx.JSON(http.StatusOK, model.NewBizErrorResp(e))
}
```

Argument errors use `bizerror.InvalidArgument`. Auth middleware is an exception and returns HTTP 401.

## Service layer

Key directory: `pkg/console/service/`

Services receive `consolectx.Context` and typed request models. They usually access resources through generic manager helpers or `ctx.ResourceManager()` directly.

Typical resource query:

```go
resources, err := manager.ListByIndexes[*meshresource.ServiceProviderMetadataResource](
ctx.ResourceManager(),
meshresource.ServiceProviderMetadataKind,
[]index.IndexCondition{...},
)
```

Do not put store/index details into handlers. Keep HTTP binding in handlers and resource logic in services.

## Frontend contract

Frontend API callers live under `ui-vue3/src/api/`. If a response field, request parameter, or endpoint path changes, check both Console model structs and frontend caller usage.

## Common failure modes

- Route registered under wrong group or duplicate service group block.
- Handler binds query when frontend sends JSON, or vice versa.
- Model tags do not match frontend parameter names.
- Service returns raw resource shape not expected by frontend view.
- Error returned directly instead of through `util.HandleServiceError`.
- Optional managers such as CounterManager or LockManager are nil.

## Review checklist

- Route path and HTTP method match frontend usage.
- Handler binding matches request source.
- Request/response models have correct tags and JSON field names.
- Service owns business logic and uses ResourceManager/store helpers.
- Response uses `CommonResp` consistently.
- Frontend API client is updated when contract changes.
59 changes: 59 additions & 0 deletions .agents/skills/dubbo-admin-discovery/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
---
name: dubbo-admin-discovery
description: Implements and reviews dubbo-admin registry discovery changes. Use when the user asks about Zookeeper or Nacos discovery, ListAndWatch, informers, discovery factories, discovery subscribers, ServiceProviderMetadata or ServiceConsumerMetadata processing, or Application, Service, RPCInstance, and Instance derivation under pkg/core/discovery/ and pkg/core/controller/. Do not use for engine-sourced RuntimeInstance behavior.
---

# dubbo-admin Discovery

## Purpose

Use this skill to trace registry-sourced resources from ListWatcher input through informer events, EventBus dispatch, subscribers, store writes, and derived mesh resources.

## When to use

Use for Zookeeper or Nacos registry flow, discovery ListWatchers, discovery subscribers, metadata-derived services, application instance counts, and registry event bugs.

Do not use for Kubernetes runtime infrastructure engine flow; use `dubbo-admin-engine` for RuntimeInstance behavior.

## Inputs

Required:
- Registry type, resource kind, subscriber, or discovery package path.
- The event or resource transition being changed or debugged.

Optional:
- Example registry metadata.
- Store query or index involved.
- Console API result affected by discovery data.

If missing, start at `pkg/core/discovery/component.go` and identify the subscriber for the resource kind.

## Workflow

1. Read `pkg/core/discovery/component.go` for dependencies, informer creation, subscriber registration, and start behavior.
2. Inspect `pkg/core/controller/listwatcher.go` and `pkg/core/controller/informer.go`.
3. Follow registry-specific ListWatcher creation through `pkg/core/discovery/factory.go`.
4. Read the relevant subscriber under `pkg/core/discovery/subscriber/`.
5. Verify resource writes against store and index behavior.
6. Read `references/discovery-flow.md` for subscriber registration and event flow details.

## Output format

Return the resource flow, affected subscriber, store/index interactions, changed files, and validation commands or residual test gaps.

## Validation

- Confirm informer events emit the expected `cache.DeltaType`.
- Confirm subscriber `ResourceKind()` matches the event resource kind.
- Confirm derived resources use stable resource keys.
- Run targeted subscriber or controller tests; use `make test` for broad discovery changes.

## Edge cases

- Nacos and Zookeeper register extra subscribers conditionally.
- Delete events may need old objects and must not assume `NewObj()` exists.
- If dispatch semantics are the problem, switch to `dubbo-admin-events`.

## References

- Read `references/discovery-flow.md` for ListWatcher, informer, and subscriber details.
30 changes: 30 additions & 0 deletions .agents/skills/dubbo-admin-discovery/evals/evals.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"skill_name": "dubbo-admin-discovery",
"evals": [
{
"id": "obvious-trigger",
"prompt": "Fix ServiceProviderMetadataEventSubscriber so Service resources update after provider metadata deletion.",
"expected_behavior": "Use discovery subscriber and informer event flow."
},
{
"id": "paraphrased-trigger",
"prompt": "Nacos registry changes are not reflected in applications shown by dubbo-admin.",
"expected_behavior": "Trace registry ListWatcher, informer events, subscribers, and store writes."
},
{
"id": "file-based-trigger",
"prompt": "Review pkg/core/discovery/component.go and pkg/core/discovery/subscriber/service_consumer_metadata.go.",
"expected_behavior": "Use this skill because discovery orchestration and subscribers are touched."
},
{
"id": "no-trigger",
"prompt": "Change how EventBus handles subscriber errors for all domains.",
"expected_behavior": "Do not use this skill as primary; use dubbo-admin-events."
},
{
"id": "conflict-trigger",
"prompt": "A RuntimeInstance from Kubernetes is not merged into an Instance resource.",
"expected_behavior": "Use dubbo-admin-engine, not discovery, because RuntimeInstance is engine-sourced."
}
]
}
Loading
Loading