Add gateway implementation planning docs
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
# C# Style Guide
|
||||
|
||||
This guide defines C# conventions for the gateway, worker, .NET client, test
|
||||
CLIs, and C# tests.
|
||||
|
||||
## Baseline
|
||||
|
||||
- Use the latest stable C# version supported by the target runtime.
|
||||
- Enable nullable reference types in new projects.
|
||||
- Treat compiler warnings as actionable. Suppress only with a narrow reason.
|
||||
- Prefer file-scoped namespaces.
|
||||
- Prefer `sealed` classes unless inheritance is required.
|
||||
- Keep public APIs explicit and small. Do not expose generated or transport
|
||||
internals through handwritten abstractions unless raw access is intentional.
|
||||
|
||||
## Source Documentation
|
||||
|
||||
- Maintain the existing documentation style in the file, project, and
|
||||
surrounding component.
|
||||
- Write comments that include business-specific or domain-specific context when
|
||||
that context is available from the code, surrounding docs, or naming.
|
||||
- Prefer XML documentation on public APIs when the behavior is not obvious from
|
||||
the signature.
|
||||
- Avoid comments that restate syntax or control flow.
|
||||
|
||||
## Naming
|
||||
|
||||
- Use PascalCase for public types, methods, properties, events, and enum
|
||||
members.
|
||||
- Use camelCase for local variables, parameters, and private fields.
|
||||
- Prefix private fields with `_` only when that pattern is already established
|
||||
in the project.
|
||||
- Use `Async` suffixes for methods that return `Task`, `Task<T>`,
|
||||
`ValueTask`, or `ValueTask<T>`.
|
||||
- Keep names aligned with MXAccess terms: `MxStatusProxy`, `ServerHandle`,
|
||||
`ItemHandle`, `HResult`, and event family names should match the contract.
|
||||
|
||||
## Async And Cancellation
|
||||
|
||||
- Accept `CancellationToken` on public async methods that perform I/O or wait.
|
||||
- Pass cancellation tokens through to called APIs.
|
||||
- Do not use `Task.Run` to hide blocking COM calls. MXAccess calls belong on
|
||||
the worker STA.
|
||||
- Use `ConfigureAwait(false)` in reusable libraries. It is optional in ASP.NET
|
||||
Core request handling where no synchronization context exists.
|
||||
- Dispose async resources with `await using` when the type implements
|
||||
`IAsyncDisposable`.
|
||||
|
||||
## Errors
|
||||
|
||||
- Preserve protocol, gateway, worker, COM HRESULT, and MXAccess status details.
|
||||
- Use typed exceptions at API boundaries, but prefer result DTOs when callers
|
||||
need method-specific MXAccess output.
|
||||
- Do not log API keys, passwords, secured write values, or full tag values by
|
||||
default.
|
||||
- Include correlation id and session id in diagnostics when available.
|
||||
|
||||
## Protobuf And Generated Code
|
||||
|
||||
- Do not hand-edit generated protobuf or gRPC files.
|
||||
- Keep generated code in a clearly named `Generated` namespace or directory.
|
||||
- Keep mapping code outside gRPC handlers so it can be unit tested.
|
||||
|
||||
## Formatting
|
||||
|
||||
- Run `dotnet format` when a solution or project is available.
|
||||
- Use four spaces for indentation.
|
||||
- Keep one public type per file unless a small nested type is clearer.
|
||||
- Avoid region-heavy files. Split large responsibilities into focused types.
|
||||
|
||||
## Tests
|
||||
|
||||
- Use test names that describe behavior, condition, and result.
|
||||
- Prefer fake workers, fake transports, or fake gRPC services over live
|
||||
MXAccess in unit tests.
|
||||
- Mark live MXAccess tests as opt-in integration tests.
|
||||
@@ -0,0 +1,68 @@
|
||||
# Go Style Guide
|
||||
|
||||
This guide defines Go conventions for the MXAccess Gateway Go client module,
|
||||
test CLI, and tests.
|
||||
|
||||
## Baseline
|
||||
|
||||
- Use idiomatic Go and keep package APIs small.
|
||||
- Run `gofmt` on every changed Go file.
|
||||
- Run `go vet` for non-trivial changes when the module is available.
|
||||
- Keep generated protobuf code under `internal/generated` unless the public API
|
||||
intentionally exposes it.
|
||||
|
||||
## Source Documentation
|
||||
|
||||
- Maintain the existing documentation style in the file, package, and
|
||||
surrounding component.
|
||||
- Write comments that include business-specific or domain-specific context when
|
||||
that context is available from the code, surrounding docs, or naming.
|
||||
- Document exported names when they are part of the public client API.
|
||||
- Avoid comments that restate syntax or control flow.
|
||||
|
||||
## Packages
|
||||
|
||||
- Use short, lowercase package names without underscores.
|
||||
- Keep the reusable library separate from CLI code.
|
||||
- Keep generated code separate from handwritten wrappers.
|
||||
- Prefer internal packages for implementation details that callers should not
|
||||
import.
|
||||
|
||||
## Naming
|
||||
|
||||
- Use exported names only for public API.
|
||||
- Use initialisms consistently: `APIKey`, `TLS`, `HTTP`, `ID`.
|
||||
- Keep MXAccess terms explicit: `ServerHandle`, `ItemHandle`, `MxStatusProxy`,
|
||||
and `HResult`.
|
||||
- Avoid generic helper names such as `Do` or `Process` for command-specific
|
||||
MXAccess behavior.
|
||||
|
||||
## Context And Cancellation
|
||||
|
||||
- Accept `context.Context` as the first parameter for operations that can block.
|
||||
- Do not store contexts in structs.
|
||||
- Respect context cancellation, but document that canceling a client call does
|
||||
not abort an in-flight worker COM call.
|
||||
- Close streams and connections deterministically.
|
||||
|
||||
## Errors
|
||||
|
||||
- Return errors instead of panicking.
|
||||
- Wrap errors with useful context using `%w`.
|
||||
- Support `errors.Is` and `errors.As` for typed gateway, command, and MXAccess
|
||||
errors.
|
||||
- Preserve raw command replies on command errors when available.
|
||||
- Redact API keys and credential-bearing values in error messages.
|
||||
|
||||
## Concurrency
|
||||
|
||||
- Avoid unbounded goroutines and unbounded channels.
|
||||
- Close channels exactly once from the sending side.
|
||||
- Propagate stream errors through explicit result types such as `EventResult`.
|
||||
- Use the race detector for concurrency-heavy changes when practical.
|
||||
|
||||
## Tests
|
||||
|
||||
- Use table-driven tests for conversion and error mapping.
|
||||
- Use `bufconn` or fake generated clients for unit tests.
|
||||
- Keep integration tests behind `MXGATEWAY_INTEGRATION=1` or build tags.
|
||||
@@ -0,0 +1,65 @@
|
||||
# Java Style Guide
|
||||
|
||||
This guide defines Java conventions for the MXAccess Gateway Java client
|
||||
library, CLI, and tests.
|
||||
|
||||
## Baseline
|
||||
|
||||
- Target the Java version defined by the client build, with Java 21 preferred.
|
||||
- Use Gradle unless the repository standardizes on Maven.
|
||||
- Apply a formatter such as Spotless or Google Java Format when configured.
|
||||
- Keep generated protobuf code separate from handwritten wrappers.
|
||||
|
||||
## Source Documentation
|
||||
|
||||
- Maintain the existing documentation style in the file, package, and
|
||||
surrounding component.
|
||||
- Write comments that include business-specific or domain-specific context when
|
||||
that context is available from the code, surrounding docs, or naming.
|
||||
- Use Javadoc for public APIs when behavior, parity constraints, or security
|
||||
requirements are not obvious from the signature.
|
||||
- Avoid comments that restate syntax or control flow.
|
||||
|
||||
## Packages
|
||||
|
||||
- Use lowercase package names under `com.dohertylan.mxgateway`.
|
||||
- Keep client library code separate from CLI code.
|
||||
- Keep generated protobuf classes in a generated package.
|
||||
- Do not expose implementation-only transport helpers as public API.
|
||||
|
||||
## Naming
|
||||
|
||||
- Use `PascalCase` for classes, records, interfaces, and enums.
|
||||
- Use `camelCase` for methods, fields, parameters, and local variables.
|
||||
- Use `UPPER_SNAKE_CASE` for constants.
|
||||
- Use MXAccess terms consistently: `serverHandle`, `itemHandle`,
|
||||
`mxStatusProxy`, and `hResult`.
|
||||
|
||||
## API Design
|
||||
|
||||
- Prefer immutable options objects with builders for public configuration.
|
||||
- Implement `AutoCloseable` for clients and sessions that own resources.
|
||||
- Provide async methods with `CompletableFuture` where useful, but keep a
|
||||
blocking API for simple CLI workflows.
|
||||
- Expose raw generated protobuf messages where parity tests need them.
|
||||
|
||||
## Errors
|
||||
|
||||
- Use typed exceptions for gateway, authentication, authorization, session,
|
||||
worker, command, and MXAccess failures.
|
||||
- Preserve raw command replies in command exceptions when available.
|
||||
- Redact API keys, passwords, and secured write values in `toString`, logs, and
|
||||
CLI output.
|
||||
|
||||
## Streaming
|
||||
|
||||
- Cancel gRPC calls explicitly when callers stop consuming streams.
|
||||
- Do not reorder, coalesce, or drop events in client code.
|
||||
- Avoid unbounded queues in async stream helpers.
|
||||
|
||||
## Tests
|
||||
|
||||
- Use JUnit 5.
|
||||
- Use in-process gRPC servers for unit tests.
|
||||
- Keep live gateway tests behind `MXGATEWAY_INTEGRATION=1` and JUnit
|
||||
assumptions.
|
||||
@@ -0,0 +1,64 @@
|
||||
# Protobuf Style Guide
|
||||
|
||||
This guide defines protobuf conventions for MXAccess Gateway public gRPC and
|
||||
gateway-to-worker IPC contracts.
|
||||
|
||||
## Baseline
|
||||
|
||||
- Use `proto3`.
|
||||
- Keep public gateway contracts and worker IPC contracts in separate `.proto`
|
||||
files.
|
||||
- Treat field numbers as permanent once released.
|
||||
- Do not reuse removed field numbers or enum values. Reserve them.
|
||||
- Keep generated code reproducible from checked-in `.proto` files.
|
||||
|
||||
## Source Documentation
|
||||
|
||||
- Maintain the existing documentation style in the `.proto` file and
|
||||
surrounding contract docs.
|
||||
- Write comments that include business-specific or domain-specific context when
|
||||
that context is available from the contract, surrounding docs, or naming.
|
||||
- Comment fields that carry MXAccess parity details, credential-sensitive data,
|
||||
raw HRESULT/status information, or compatibility constraints.
|
||||
- Avoid comments that restate field types or message nesting.
|
||||
|
||||
## Naming
|
||||
|
||||
- Use `snake_case` for package names, file names, field names, and enum values.
|
||||
- Use `PascalCase` for message, enum, and service names.
|
||||
- Prefix enum values with the enum name or a clear abbreviation to avoid name
|
||||
collisions in generated languages.
|
||||
- Keep MXAccess event family and command names recognizable in enum values.
|
||||
|
||||
## Compatibility
|
||||
|
||||
- Add fields instead of changing field meaning.
|
||||
- Use `oneof` for command payloads, reply payloads, value unions, and event
|
||||
bodies.
|
||||
- Add explicit `UNKNOWN` or `UNSPECIFIED` enum zero values.
|
||||
- Preserve raw HRESULT, MXAccess status, and diagnostic metadata in replies and
|
||||
events.
|
||||
- Use protocol version fields in worker IPC envelopes.
|
||||
|
||||
## Field Rules
|
||||
|
||||
- Do not use required semantics in application code for newly added optional
|
||||
fields unless compatibility behavior is documented.
|
||||
- Prefer explicit wrapper messages for repeated structured values.
|
||||
- Use signed or unsigned integer types based on the actual semantic range.
|
||||
- Represent timestamps with `google.protobuf.Timestamp` unless the source value
|
||||
is not a real timestamp.
|
||||
- Represent durations with `google.protobuf.Duration`.
|
||||
|
||||
## Security
|
||||
|
||||
- Do not define fields that require clients or workers to log secrets.
|
||||
- Mark credential-bearing request fields clearly in comments.
|
||||
- Keep raw values out of diagnostics unless an explicit redacted or opt-in path
|
||||
exists.
|
||||
|
||||
## Generated Code
|
||||
|
||||
- Do not hand-edit generated code.
|
||||
- Keep generation commands documented near the contracts project.
|
||||
- Regenerate all affected language outputs when a contract changes.
|
||||
@@ -0,0 +1,68 @@
|
||||
# Python Style Guide
|
||||
|
||||
This guide defines Python conventions for the MXAccess Gateway Python package,
|
||||
CLI, and tests.
|
||||
|
||||
## Baseline
|
||||
|
||||
- Target modern supported Python versions defined by `pyproject.toml`.
|
||||
- Use `pyproject.toml` for package metadata and tool configuration.
|
||||
- Use type hints for public APIs and non-trivial internal functions.
|
||||
- Run the configured formatter and linter when the package is available.
|
||||
- Keep generated protobuf code separate from handwritten modules.
|
||||
|
||||
## Source Documentation
|
||||
|
||||
- Maintain the existing documentation style in the file, package, and
|
||||
surrounding component.
|
||||
- Write comments that include business-specific or domain-specific context when
|
||||
that context is available from the code, surrounding docs, or naming.
|
||||
- Use docstrings for public classes, functions, and modules when behavior,
|
||||
parity constraints, or security requirements are not obvious from the name and
|
||||
type hints.
|
||||
- Avoid comments that restate syntax or control flow.
|
||||
|
||||
## Package Structure
|
||||
|
||||
- Put library code under `src/mxgateway/`.
|
||||
- Put CLI entry points under `src/mxgateway_cli/`.
|
||||
- Keep generated protobuf modules under a clearly named `generated` package.
|
||||
- Avoid import side effects that open channels, read environment variables, or
|
||||
start background tasks.
|
||||
|
||||
## Naming
|
||||
|
||||
- Use `snake_case` for functions, variables, modules, and methods.
|
||||
- Use `PascalCase` for classes and exceptions.
|
||||
- Use `UPPER_SNAKE_CASE` for constants.
|
||||
- Keep MXAccess names recognizable in public APIs, even when Python wrappers
|
||||
use idiomatic method names.
|
||||
|
||||
## Async
|
||||
|
||||
- Make the client async-first.
|
||||
- Use async context managers for clients and sessions when practical.
|
||||
- Cancel gRPC streams when async iteration is canceled.
|
||||
- Document that canceling a Python task does not abort an in-flight MXAccess
|
||||
COM call inside the worker.
|
||||
|
||||
## Errors
|
||||
|
||||
- Use typed exceptions for transport, authentication, authorization, session,
|
||||
worker, command, and MXAccess failures.
|
||||
- Attach raw protobuf replies to command exceptions when available.
|
||||
- Redact API keys, passwords, and secured write values in exception messages and
|
||||
CLI output.
|
||||
|
||||
## CLI
|
||||
|
||||
- Keep CLI output deterministic for tests.
|
||||
- Support JSON output for automation.
|
||||
- Load API keys from explicit flags or named environment variables. Do not read
|
||||
secrets implicitly during module import.
|
||||
|
||||
## Tests
|
||||
|
||||
- Use `pytest` and `pytest-asyncio`.
|
||||
- Use fake generated stubs or an in-process test gRPC server for unit tests.
|
||||
- Keep live integration tests behind `MXGATEWAY_INTEGRATION=1`.
|
||||
@@ -0,0 +1,65 @@
|
||||
# Rust Style Guide
|
||||
|
||||
This guide defines Rust conventions for the MXAccess Gateway Rust client crate,
|
||||
CLI, and tests.
|
||||
|
||||
## Baseline
|
||||
|
||||
- Run `cargo fmt` on every changed Rust file.
|
||||
- Run `cargo clippy` for non-trivial changes when the crate is available.
|
||||
- Use the current stable Rust toolchain unless the project pins a version.
|
||||
- Keep generated protobuf modules isolated from handwritten API wrappers.
|
||||
|
||||
## Source Documentation
|
||||
|
||||
- Maintain the existing documentation style in the file, crate, and surrounding
|
||||
component.
|
||||
- Write comments that include business-specific or domain-specific context when
|
||||
that context is available from the code, surrounding docs, or naming.
|
||||
- Use `///` documentation for public APIs when behavior, parity constraints, or
|
||||
security requirements are not obvious from the type signature.
|
||||
- Avoid comments that restate syntax or control flow.
|
||||
|
||||
## Crate Structure
|
||||
|
||||
- Keep the reusable client library separate from the CLI binary.
|
||||
- Use small modules for `client`, `session`, `options`, `auth`, `value`, and
|
||||
`error`.
|
||||
- Re-export public types intentionally from `lib.rs`.
|
||||
- Keep generated modules private unless raw protobuf access is part of the API.
|
||||
|
||||
## Naming
|
||||
|
||||
- Use `snake_case` for functions, variables, modules, and fields.
|
||||
- Use `UpperCamelCase` for types, traits, and enum variants.
|
||||
- Use `SCREAMING_SNAKE_CASE` for constants.
|
||||
- Keep protocol names aligned with the protobuf contract where exactness
|
||||
matters.
|
||||
|
||||
## Async And Ownership
|
||||
|
||||
- Use `async` APIs with `tokio` for network operations.
|
||||
- Prefer explicit `close` methods for sessions. Do not rely on `Drop` for async
|
||||
cleanup.
|
||||
- Avoid unbounded channels and background tasks without a shutdown path.
|
||||
- Use borrowed parameters such as `&str` where ownership is not needed.
|
||||
|
||||
## Errors
|
||||
|
||||
- Use `thiserror` for library error enums.
|
||||
- Preserve `tonic::Status`, transport errors, command replies, HRESULTs, and
|
||||
MXAccess status details.
|
||||
- Redact API keys and secured values in `Debug`, `Display`, and tracing output.
|
||||
- Avoid string-only errors for public API failures.
|
||||
|
||||
## Security
|
||||
|
||||
- Use a secret wrapper for API keys when adding a dependency is acceptable.
|
||||
- Do not derive `Debug` on types that contain unredacted secrets.
|
||||
- Prefer explicit redacted display implementations for options and errors.
|
||||
|
||||
## Tests
|
||||
|
||||
- Use `#[tokio::test]` for async tests.
|
||||
- Use fake `tonic` services or trait-backed clients for unit tests.
|
||||
- Keep live gateway tests behind `MXGATEWAY_INTEGRATION=1`.
|
||||
Reference in New Issue
Block a user