Skip to content

Commit cda4fd8

Browse files
BRBussyclaude
andauthored
feat: mocks target ClientInterface exclusively + SearchUsers + docs cleanup (#196)
* feat: generated mocks implement ClientInterface for non-streaming services Generated Mock*Service types now satisfy both *Service and *ServiceClientInterface for services without streaming methods. This eliminates the need to hand-write verbose mock structs with panic stubs for Close/Group/WithGroup when tests depend on the client interface. For streaming services the mock remains unchanged because Service and ClientInterface have incompatible streaming method signatures. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: streaming service mocks target ClientInterface with client-side signatures Streaming mocks (LimitOrderService, TransactionService) now use client-side method signatures returning (StreamClient, error) instead of server-side signatures accepting a stream parameter. All mocks uniformly implement *ServiceClientInterface with Close(), Group(), and WithGroup() methods. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * update deps * correct version specification * chore: update release command and remove outdated hand-written TS docs Add Step 6 to release command to merge the 5 auto-generated version-bump PRs after deployment workflows complete. Remove obsolete CLAUDE.md guidance about hand-written TypeScript client wrappers (all now auto-generated by protoc-gen-meshts). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: prettier formatting in ts-old groupHeaderInterceptor Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix versions --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 9b77ef4 commit cda4fd8

File tree

34 files changed

+2340
-16046
lines changed

34 files changed

+2340
-16046
lines changed

.claude/commands/release.md

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,12 +93,34 @@ Expected completion times:
9393

9494
If any workflow fails, check logs with `gh run view <run-id> --log-failed` and fix.
9595

96-
### Step 6: Report Results
96+
### Step 6: Merge Auto-Generated Version PRs
97+
98+
After all workflows complete successfully, 5 auto-generated PRs will exist that bump version files back into master. Merge all of them:
99+
100+
**Expected PRs (by branch name):**
101+
- `chore/pypi-version-update-$1` — updates `pyproject.toml`
102+
- `chore/maven-version-update-$1` — updates `java/pom.xml`
103+
- `chore/npm-ts-node-version-update-$1` — updates `ts-node/package.json`
104+
- `chore/npm-ts-web-version-update-$1` — updates `ts-web/package.json`
105+
- `chore/npm-ts-old-version-update-$1` — updates `ts-old/package.json`
106+
107+
1. List PRs to confirm they all exist: `gh pr list --limit 10`
108+
2. Merge each PR and delete its branch:
109+
```bash
110+
gh pr merge chore/pypi-version-update-$1 --merge --delete-branch
111+
gh pr merge chore/maven-version-update-$1 --merge --delete-branch
112+
gh pr merge chore/npm-ts-node-version-update-$1 --merge --delete-branch
113+
gh pr merge chore/npm-ts-web-version-update-$1 --merge --delete-branch
114+
gh pr merge chore/npm-ts-old-version-update-$1 --merge --delete-branch
115+
```
116+
3. If any PR is missing, the corresponding workflow may still be running or may have failed — check `gh run list --limit 15`
117+
118+
### Step 7: Report Results
97119

98120
Show the user:
99121
1. All 8 releases created with links
100122
2. All workflow statuses (success/failure) - verify all triggered via `push` event
101-
3. List of auto-generated PRs to merge: `gh pr list --limit 10`
123+
3. All 5 version-bump PRs merged successfully
102124

103125
---
104126

CLAUDE.md

Lines changed: 2 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -380,31 +380,6 @@ Before testing, validate your development environment:
380380
- **Extension Tag Management**: Be careful with protobuf extension tag conflicts across option files
381381
- **Response Message Cleanup**: Remove unused response messages when methods return resources directly
382382

383-
### TypeScript Hand-Written Code Maintenance
384-
- **Post-Generation Updates**: After running `./dev/tool.sh generate` or `./dev/tool.sh all`, hand-written TypeScript client wrappers may need updates:
385-
- Method name changes: `get()``getResource()`, `create()``createResource()`
386-
- Return type changes: Get/Create methods return resources directly, not response wrappers
387-
- Import statement updates: Remove imports for deleted response message types
388-
- Add imports for resource types (e.g., `import { Client } from "./client_pb"`)
389-
- **Missing Method Detection**: Compare wrapper methods to generated service interface to ensure all RPC methods are exposed
390-
- **Breaking Change Detection**: TypeScript compilation errors after generation indicate needed updates:
391-
- Missing exported members = removed response types that need import cleanup
392-
- Missing properties on service clients = method name changes
393-
- Use `yarn build` and `yarn lint` in `/ts` to validate all changes
394-
- **Hand-Written Client Pattern**: Client wrapper classes in `*_grpc_web.ts` files should:
395-
- Mirror the generated gRPC service interface exactly
396-
- Use consistent method naming with resource names included
397-
- Return the same types as the generated service (resources directly for Get/Create)
398-
- Maintain proper JSDoc documentation with updated parameter and return types
399-
- Include ALL methods from the corresponding protobuf service definition
400-
- **Client Wrapper Validation Process**:
401-
1. After protobuf changes, run `./dev/tool.sh all` to regenerate code
402-
2. Check each `*_grpc_web.ts` file to ensure all service methods are wrapped
403-
3. Update imports to include all required request/response types
404-
4. Run `yarn build` and `yarn lint` in `/ts` to verify compilation
405-
5. Look for methods in `service_grpc_web_pb.d.ts` that aren't in the wrapper client
406-
- **Orphaned File Cleanup**: Remove hand-written files when their corresponding proto services are deleted
407-
408383
## Protobuf Refactoring Best Practices
409384

410385
### Role and Method Type Management
@@ -419,14 +394,12 @@ Before testing, validate your development environment:
419394
1. Modify protobuf files in `/proto/` directory
420395
2. Run `buf lint` to validate changes
421396
3. Run `./dev/tool.sh all` to regenerate all client libraries
422-
4. Check TypeScript client wrappers for missing methods or imports
423-
5. Run language-specific tests and linting to verify correctness
397+
4. Run language-specific tests and linting to verify correctness
424398

425399
### Protobuf Syntax for Options
426400

427401
When adding options to protobuf files, keep the following in mind:
428402

429403
- **Option Syntax:** Custom options for services or methods should be declared directly. The correct syntax is `option (custom.option) = VALUE;` and not `option (custom.option) = { key: VALUE };`.
430404
- **Enum Scopes:** When referencing enums from an imported `.proto` file (like `method_type.proto` or `role.proto`), you should use the enum value directly (e.g., `METHOD_TYPE_READ`) without the fully qualified package path, as long as the necessary import statement is present.
431-
- **Option Scopes (`FileOptions` vs. `ServiceOptions`):** It's critical to apply options at the correct level. For example, `standard_roles` is a `FileOption` and must be declared at the top level of the file, not within a `service` definition, which uses `ServiceOptions`.
432-
- **TypeScript Wrapper Dependencies:** When adding new RPC methods, you must manually update any hand-written client wrappers. This includes not only adding the new client method but also importing the newly generated request/response message types (e.g., `GetApiUserByKeyHashRequest` from `service_pb.ts`).
405+
- **Option Scopes (`FileOptions` vs. `ServiceOptions`):** It's critical to apply options at the correct level. For example, `standard_roles` is a `FileOption` and must be declared at the top level of the file, not within a `service` definition, which uses `ServiceOptions`.
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"log"
6+
7+
userv1 "github.com/meshtrade/api/go/iam/user/v1"
8+
)
9+
10+
func main() {
11+
ctx := context.Background()
12+
13+
// Default configuration is used and credentials come from MESH_API_CREDENTIALS
14+
// environment variable or default discovery methods. Zero config required
15+
// unless you want custom configuration.
16+
service, err := userv1.NewUserService()
17+
if err != nil {
18+
log.Fatalf("Failed to create service: %v", err)
19+
}
20+
defer service.Close()
21+
22+
// Create request with service-specific parameters
23+
request := &userv1.SearchUsersRequest{
24+
// FIXME: Populate service-specific request fields
25+
}
26+
27+
// Call the SearchUsers method
28+
response, err := service.SearchUsers(ctx, request)
29+
if err != nil {
30+
log.Fatalf("SearchUsers failed: %v", err)
31+
}
32+
33+
// FIXME: Add relevant response object usage
34+
log.Printf("SearchUsers successful: %+v", response)
35+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import co.meshtrade.api.iam.user.v1.UserService;
2+
import co.meshtrade.api.iam.user.v1.Service.SearchUsersRequest;
3+
import co.meshtrade.api.iam.user.v1.Service.SearchUsersResponse;
4+
5+
import java.util.Optional;
6+
7+
public class SearchUsersExample {
8+
public static void main(String[] args) {
9+
// Default configuration is used and credentials come from MESH_API_CREDENTIALS
10+
// environment variable or default discovery methods. Zero config required
11+
// unless you want custom configuration.
12+
try (UserService service = new UserService()) {
13+
// Create request with service-specific parameters
14+
SearchUsersRequest request = SearchUsersRequest.newBuilder()
15+
// FIXME: Populate service-specific request fields
16+
.build();
17+
18+
// Call the SearchUsers method
19+
SearchUsersResponse response = service.searchUsers(request, Optional.empty());
20+
21+
// FIXME: Add relevant response object usage
22+
System.out.println("SearchUsers successful: " + response);
23+
} catch (Exception e) {
24+
System.err.println("SearchUsers failed: " + e.getMessage());
25+
e.printStackTrace();
26+
}
27+
}
28+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from meshtrade.iam.user.v1 import (
2+
SearchUsersRequest,
3+
UserService,
4+
)
5+
6+
7+
def main():
8+
# Default configuration is used and credentials come from MESH_API_CREDENTIALS
9+
# environment variable or default discovery methods. Zero config required
10+
# unless you want custom configuration.
11+
service = UserService()
12+
13+
with service:
14+
# Create request with service-specific parameters
15+
request = SearchUsersRequest(
16+
# FIXME: Populate service-specific request fields
17+
)
18+
19+
# Call the SearchUsers method
20+
response = service.search_users(request)
21+
22+
# FIXME: Add relevant response object usage
23+
print("SearchUsers successful:", response)
24+
25+
26+
if __name__ == "__main__":
27+
main()

go/compliance/client/v1/serviceMock.meshgo.go

Lines changed: 27 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

go/iam/api_user/v1/serviceMock.meshgo.go

Lines changed: 32 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

go/iam/group/v1/serviceMock.meshgo.go

Lines changed: 28 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

go/iam/user/v1/service.meshgo.go

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)