Files
docs/superpowers/plans/2026-08-11-yoresee-doc-sdk-migration.md

586 lines
16 KiB
Markdown

# Yoresee Doc SDK Migration Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Publish versioned Go and Node protobuf SDK repositories on Gitea and migrate backend, collab-go, frontend, and collab to consume them.
**Architecture:** `proto` remains the only source of the protobuf contract. The two SDK repositories commit generated artifacts: Go stubs in the Go module root, and both ESM/Connect and CommonJS/gRPC outputs in separate Node subdirectories. Services consume tagged Gitea dependencies; existing local generation scripts and Dockerfiles remain unchanged.
**Tech Stack:** Protobuf, Buf 1.72.0, `protoc-gen-go` 1.36.12, `protoc-gen-go-grpc` 1.6.2, `protoc-gen-es`, `protoc-gen-connect-es`, `grpc-tools` 1.13.1, `protoc-gen-js` 3.21.4-4, Go modules, npm Git dependencies, Gitea Git over SSH.
## Global Constraints
- The protobuf source remains `proto/yoresee_doc/v1/yoresee_doc.proto`.
- The Go module path is `git.yoresee.cc/YoreseeDoc/yoresee_doc_sdk_go`.
- The Node package name is `@yoresee-doc/sdk-node`.
- The initial SDK release is `v0.1.0`; consumers pin that tag.
- The protobuf `go_package` is `git.yoresee.cc/YoreseeDoc/yoresee_doc_sdk_go/yoresee_doc/v1;yoreseedocpb`.
- Do not modify `deploy/script/gen_proto.sh`, Dockerfiles, Docker Compose, `clone_all.sh`, or CI/CD configuration.
- Do not change protobuf messages, fields, services, or runtime behavior.
- Preserve unrelated pre-existing changes, including untracked files under `backend/`.
- Private Gitea module/package reads require working SSH access; Go consumers use `GOPRIVATE=git.yoresee.cc/YoreseeDoc`.
---
### Task 1: Point The Proto Contract At The Go SDK
**Files:**
- Modify: `proto/yoresee_doc/v1/yoresee_doc.proto:5`
- Test: proto diff and source-format checks
**Interfaces:**
- Produces the canonical Go import path used by generated SDK code and both Go services.
- [ ] **Step 1: Replace the Go package option**
Change the only `go_package` option to:
```protobuf
option go_package = "git.yoresee.cc/YoreseeDoc/yoresee_doc_sdk_go/yoresee_doc/v1;yoreseedocpb";
```
Do not alter any other proto line.
- [ ] **Step 2: Verify the focused proto diff**
Run from `proto/`:
```bash
git diff --check
git diff -- yoresee_doc/v1/yoresee_doc.proto
```
Expected: one changed `go_package` line and no whitespace errors.
- [ ] **Step 3: Commit and push the proto source change**
Run from `proto/`, staging only the proto file:
```bash
git add yoresee_doc/v1/yoresee_doc.proto
git diff --cached --check
git commit -m "feat: point Go protobuf package at SDK"
git push origin master
```
Record the resulting source commit with:
```bash
git rev-parse HEAD
```
The commit hash is recorded in both SDK READMEs.
### Task 2: Generate And Validate The Go SDK
**Files:**
- Create: `yoresee_doc_sdk_go/go.mod`
- Create: `yoresee_doc_sdk_go/go.sum`
- Create: `yoresee_doc_sdk_go/buf.gen.yaml`
- Create: `yoresee_doc_sdk_go/README.md`
- Create: `yoresee_doc_sdk_go/yoresee_doc/v1/yoresee_doc.pb.go`
- Create: `yoresee_doc_sdk_go/yoresee_doc/v1/yoresee_doc_grpc.pb.go`
**Interfaces:**
- Consumes the proto directory from `yoresee_doc/proto`.
- Produces Go package `yoreseedocpb` at import path `git.yoresee.cc/YoreseeDoc/yoresee_doc_sdk_go/yoresee_doc/v1`.
- [ ] **Step 1: Initialize the empty SDK repository on `master`**
Run from `my-repos/`:
```bash
cd yoresee_doc_sdk_go
git init -b master
git remote add origin git@git.yoresee.cc:YoreseeDoc/yoresee_doc_sdk_go.git
```
If the repository already has a local Git initialization, keep it and only add the missing remote.
- [ ] **Step 2: Create the Go module metadata**
Create `go.mod` with:
```go
module git.yoresee.cc/YoreseeDoc/yoresee_doc_sdk_go
go 1.24
require (
google.golang.org/grpc v1.79.2
google.golang.org/protobuf v1.36.10
)
```
Create `buf.gen.yaml` with:
```yaml
version: v2
plugins:
- local: protoc-gen-go
out: .
opt:
- paths=source_relative
- local: protoc-gen-go-grpc
out: .
opt:
- paths=source_relative
```
- [ ] **Step 3: Generate both Go protobuf outputs**
Run from `yoresee_doc_sdk_go/`:
```bash
export PATH="$HOME/go/bin:$PATH"
buf generate ../yoresee_doc/proto --template buf.gen.yaml
```
Expected files:
```text
yoresee_doc/v1/yoresee_doc.pb.go
yoresee_doc/v1/yoresee_doc_grpc.pb.go
```
- [ ] **Step 4: Resolve and test the Go module**
Run from `yoresee_doc_sdk_go/`:
```bash
go mod tidy
go test ./...
go vet ./...
```
Expected: the generated package compiles with no test or vet failures.
- [ ] **Step 5: Write the Go SDK README**
Document the module path, generated package import example, source proto path, recorded proto commit hash from Task 1, generator versions, and the fact that generated artifacts are committed.
- [ ] **Step 6: Commit the Go SDK artifact**
Run from `yoresee_doc_sdk_go/`, staging only SDK files:
```bash
git add README.md buf.gen.yaml go.mod go.sum yoresee_doc
git diff --cached --check
git commit -m "feat: add generated Go protobuf SDK"
```
### Task 3: Generate And Validate The Node SDK
**Files:**
- Create: `yoresee_doc_sdk_node/package.json`
- Create: `yoresee_doc_sdk_node/package-lock.json`
- Create: `yoresee_doc_sdk_node/buf.gen.yaml`
- Create: `yoresee_doc_sdk_node/README.md`
- Create: `yoresee_doc_sdk_node/esm/index.js`
- Create: `yoresee_doc_sdk_node/cjs/index.js`
- Create: `yoresee_doc_sdk_node/cjs/package.json`
- Create: `yoresee_doc_sdk_node/esm/yoresee_doc/v1/yoresee_doc_pb.js`
- Create: `yoresee_doc_sdk_node/esm/yoresee_doc/v1/yoresee_doc_connect.js`
- Create: `yoresee_doc_sdk_node/cjs/yoresee_doc/v1/yoresee_doc_pb.js`
- Create: `yoresee_doc_sdk_node/cjs/yoresee_doc/v1/yoresee_doc_grpc_pb.js`
**Interfaces:**
- ESM consumers import `@yoresee-doc/sdk-node/esm/yoresee_doc/v1/...`.
- CommonJS consumers require `@yoresee-doc/sdk-node/cjs/yoresee_doc/v1/...`.
- [ ] **Step 1: Initialize the empty Node SDK repository on `master`**
Run from `my-repos/`:
```bash
cd yoresee_doc_sdk_node
git init -b master
git remote add origin git@git.yoresee.cc:YoreseeDoc/yoresee_doc_sdk_node.git
```
If the repository already has a local Git initialization, keep it and only add the missing remote.
- [ ] **Step 2: Create the Node package contract**
Create `package.json` with this contract:
```json
{
"name": "@yoresee-doc/sdk-node",
"version": "0.1.0",
"type": "module",
"files": ["esm", "cjs", "README.md"],
"exports": {
".": {
"import": "./esm/index.js",
"require": "./cjs/index.js"
},
"./esm/*": "./esm/*",
"./cjs/*": "./cjs/*"
},
"dependencies": {
"@bufbuild/protobuf": "^1.10.0",
"@connectrpc/connect": "^1.7.0",
"@grpc/grpc-js": "^1.12.0",
"google-protobuf": "^4.0.2"
}
}
```
Create `cjs/package.json` with:
```json
{
"type": "commonjs"
}
```
Create `buf.gen.yaml` with:
```yaml
version: v2
plugins:
- local: protoc-gen-es
out: esm
opt:
- target=js
- import_extension=.js
- local: protoc-gen-connect-es
out: esm
opt:
- target=js
- import_extension=.js
```
- [ ] **Step 3: Generate the ESM/Connect outputs**
Run from `yoresee_doc_sdk_node/`:
```bash
buf generate ../yoresee_doc/proto --template buf.gen.yaml
```
Expected files:
```text
esm/yoresee_doc/v1/yoresee_doc_pb.js
esm/yoresee_doc/v1/yoresee_doc_connect.js
```
- [ ] **Step 4: Generate the CommonJS/gRPC outputs**
Run from `yoresee_doc_sdk_node/`:
```bash
npm install -g protoc-gen-js@3.21.4-4
mkdir -p cjs
grpc_tools_node_protoc -I ../yoresee_doc/proto \
--plugin=protoc-gen-grpc="$(command -v grpc_tools_node_protoc_plugin)" \
--plugin=protoc-gen-js="$(command -v protoc-gen-js)" \
--grpc_out=grpc_js:cjs \
--js_out=import_style=commonjs,binary:cjs \
../yoresee_doc/proto/yoresee_doc/v1/yoresee_doc.proto
```
Expected files:
```text
cjs/yoresee_doc/v1/yoresee_doc_pb.js
cjs/yoresee_doc/v1/yoresee_doc_grpc_pb.js
```
- [ ] **Step 5: Add package entry points and lock dependencies**
Create `esm/index.js`:
```js
export * from './yoresee_doc/v1/yoresee_doc_pb.js'
export * from './yoresee_doc/v1/yoresee_doc_connect.js'
```
Create `cjs/index.js`:
```js
module.exports = {
messages: require('./yoresee_doc/v1/yoresee_doc_pb.js'),
services: require('./yoresee_doc/v1/yoresee_doc_grpc_pb.js')
}
```
Run `npm install` in the SDK root to create `package-lock.json`.
- [ ] **Step 6: Validate both Node module formats**
Run from `yoresee_doc_sdk_node/`:
```bash
npm pack --dry-run
node --input-type=module -e "import('./esm/yoresee_doc/v1/yoresee_doc_pb.js').then(() => console.log('esm ok'))"
node -e "require('./cjs/yoresee_doc/v1/yoresee_doc_pb.js'); require('./cjs/yoresee_doc/v1/yoresee_doc_grpc_pb.js'); console.log('cjs ok')"
```
The ESM check must load the generated ESM file without a module-format error. The consumer package-path checks are performed after the service dependencies are installed in Tasks 5 and 6.
- [ ] **Step 7: Write and commit the Node SDK artifact**
Document the source proto commit, generator versions, ESM/Connect import path, CommonJS/gRPC import path, and Gitea tag in `README.md`. Then run:
```bash
git add README.md buf.gen.yaml package.json package-lock.json esm cjs
git diff --cached --check
git commit -m "feat: add generated Node protobuf SDK"
```
### Task 4: Publish Both SDK Releases
**Files:**
- Modify: Git history and refs of `yoresee_doc_sdk_go`
- Modify: Git history and refs of `yoresee_doc_sdk_node`
**Interfaces:**
- Produces `master` commits and immutable `v0.1.0` tags consumed by the services.
- [ ] **Step 1: Push each SDK commit to `master`**
Run separately in each SDK repository after checking the staged diff and clean working tree:
```bash
git push -u origin master
```
- [ ] **Step 2: Tag and push the initial release**
Run separately in each SDK repository:
```bash
git tag -a v0.1.0 -m "Release v0.1.0"
git push origin v0.1.0
```
- [ ] **Step 3: Verify remote refs**
Run from `my-repos/`:
```bash
git ls-remote --heads git@git.yoresee.cc:YoreseeDoc/yoresee_doc_sdk_go.git
git ls-remote --tags git@git.yoresee.cc:YoreseeDoc/yoresee_doc_sdk_go.git
git ls-remote --heads git@git.yoresee.cc:YoreseeDoc/yoresee_doc_sdk_node.git
git ls-remote --tags git@git.yoresee.cc:YoreseeDoc/yoresee_doc_sdk_node.git
```
Expected: `master` and `v0.1.0` exist in both repositories.
### Task 5: Migrate Go Service Consumers
**Files:**
- Modify: all backend Go files importing `github.com/XingfenD/yoresee_doc/pkg/gen/yoresee_doc/v1`
- Modify: `backend/go.mod`, `backend/go.sum`
- Modify: all collab-go Go files importing `github.com/XingfenD/yoresee_doc/collab-go/pkg/gen/yoresee_doc/v1`
- Modify: `collab-go/go.mod`, `collab-go/go.sum`
- Do not modify: `backend/AGENTS.md`, `backend/docs/`, Dockerfiles, or generation scripts
**Interfaces:**
- Both services import `yoreseedocpb` from `git.yoresee.cc/YoreseeDoc/yoresee_doc_sdk_go/yoresee_doc/v1`.
- [ ] **Step 1: Replace backend import paths**
In every backend source file returned by:
```bash
git grep -l 'github.com/XingfenD/yoresee_doc/pkg/gen/yoresee_doc/v1' -- '*.go'
```
replace only the import path with:
```go
git.yoresee.cc/YoreseeDoc/yoresee_doc_sdk_go/yoresee_doc/v1
```
Preserve existing aliases such as `pb`.
- [ ] **Step 2: Add the pinned Go SDK dependency to backend**
Add this direct requirement to `backend/go.mod`:
```go
git.yoresee.cc/YoreseeDoc/yoresee_doc_sdk_go v0.1.0
```
Run from `backend/`:
```bash
GOPRIVATE=git.yoresee.cc/YoreseeDoc go mod tidy
```
- [ ] **Step 3: Replace collab-go import paths**
In every collab-go source file returned by:
```bash
git grep -l 'github.com/XingfenD/yoresee_doc/collab-go/pkg/gen/yoresee_doc/v1' -- '*.go'
```
replace only the import path with:
```go
git.yoresee.cc/YoreseeDoc/yoresee_doc_sdk_go/yoresee_doc/v1
```
Preserve the existing `yoreseedocpb` alias.
- [ ] **Step 4: Add the pinned Go SDK dependency to collab-go**
Add the same direct requirement to `collab-go/go.mod`, then run from `collab-go/`:
```bash
GOPRIVATE=git.yoresee.cc/YoreseeDoc go mod tidy
```
- [ ] **Step 5: Verify old paths are gone and Go services compile**
Run:
```bash
(cd backend && git grep 'github.com/XingfenD/yoresee_doc/pkg/gen/yoresee_doc/v1' -- '*.go') || true
(cd collab-go && git grep 'github.com/XingfenD/yoresee_doc/collab-go/pkg/gen/yoresee_doc/v1' -- '*.go') || true
(cd backend && GOPRIVATE=git.yoresee.cc/YoreseeDoc go test ./...)
(cd collab-go && GOPRIVATE=git.yoresee.cc/YoreseeDoc go test ./...)
```
Expected: no old import matches and both modules compile against the remote SDK tag.
### Task 6: Migrate Node Service Consumers
**Files:**
- Modify: `frontend/package.json`, `frontend/package-lock.json`
- Modify: `frontend/src/services/grpc_client.js`
- Modify: `collab/package.json`, `collab/package-lock.json`
- Modify: `collab/src/grpc/client.js`
- Modify: `collab/src/grpc/document.js`
- Modify: `collab/src/grpc/system.js`
- Do not modify: Node Dockerfiles or generation scripts
**Interfaces:**
- Frontend uses the SDK ESM/Connect subpaths.
- Collab uses the SDK CommonJS/gRPC subpaths.
- [ ] **Step 1: Add the pinned Git dependency to frontend and collab**
Add this dependency to both `package.json` files:
```json
"@yoresee-doc/sdk-node": "git+ssh://git@git.yoresee.cc/YoreseeDoc/yoresee_doc_sdk_node.git#v0.1.0"
```
Run `npm install` separately in `frontend/` and `collab/` to update their lockfiles. The command requires SSH read access to Gitea.
- [ ] **Step 2: Replace frontend generated imports**
In `frontend/src/services/grpc_client.js`, replace:
```js
@/gen/yoresee_doc/v1/yoresee_doc_connect.js
@/gen/yoresee_doc/v1/yoresee_doc_pb.js
```
with:
```js
@yoresee-doc/sdk-node/esm/yoresee_doc/v1/yoresee_doc_connect.js
@yoresee-doc/sdk-node/esm/yoresee_doc/v1/yoresee_doc_pb.js
```
- [ ] **Step 3: Replace collab generated requires**
In the three `collab/src/grpc/*.js` files, replace the relative `../gen/yoresee_doc/v1/` prefix with:
```js
@yoresee-doc/sdk-node/cjs/yoresee_doc/v1/
```
Keep the existing generated filenames and CommonJS `require` calls.
- [ ] **Step 4: Verify Node imports and builds**
Run:
```bash
(cd frontend && npm run build)
(cd collab && node -e "require('@yoresee-doc/sdk-node/cjs/yoresee_doc/v1/yoresee_doc_pb'); require('@yoresee-doc/sdk-node/cjs/yoresee_doc/v1/yoresee_doc_grpc_pb'); console.log('collab SDK imports ok')")
```
Expected: no service imports point to local generated directories, the frontend build succeeds, and collab loads both CJS modules.
### Task 7: Commit And Push Service Migrations
**Files:**
- Modify: `proto` repository history already prepared in Task 1
- Modify: `backend` repository history
- Modify: `collab-go` repository history
- Modify: `frontend` repository history
- Modify: `collab` repository history
- [ ] **Step 1: Review each component diff and exclude unrelated changes**
Before every commit, run in that component:
```bash
git status --short
git diff --check
git diff
```
In `backend`, do not stage the pre-existing untracked `AGENTS.md` or `docs/` files.
- [ ] **Step 2: Commit each service migration separately**
Use these commit messages and stage only the listed migration files:
```text
backend: feat: consume generated Go SDK
collab-go: feat: consume generated Go SDK
frontend: feat: consume generated Node SDK
collab: feat: consume generated Node SDK
```
- [ ] **Step 3: Push each service `master` branch**
Run from each service repository after its focused commit:
```bash
git push origin master
```
Do not update unrelated root gitlinks or modify deployment scripts in this task.
### Task 8: Final Cross-Repository Verification
**Files:**
- Verify: both SDK repositories, `proto`, `backend`, `collab-go`, `frontend`, and `collab`
- [ ] **Step 1: Verify all remotes and release refs**
Run:
```bash
git ls-remote --heads git@git.yoresee.cc:YoreseeDoc/yoresee_doc_sdk_go.git
git ls-remote --tags git@git.yoresee.cc:YoreseeDoc/yoresee_doc_sdk_go.git
git ls-remote --heads git@git.yoresee.cc:YoreseeDoc/yoresee_doc_sdk_node.git
git ls-remote --tags git@git.yoresee.cc:YoreseeDoc/yoresee_doc_sdk_node.git
```
- [ ] **Step 2: Verify service dependency metadata**
Run:
```bash
(cd backend && git grep 'git.yoresee.cc/YoreseeDoc/yoresee_doc_sdk_go')
(cd collab-go && git grep 'git.yoresee.cc/YoreseeDoc/yoresee_doc_sdk_go')
(cd frontend && git grep '@yoresee-doc/sdk-node' -- package.json src)
(cd collab && git grep '@yoresee-doc/sdk-node' -- package.json src)
```
- [ ] **Step 3: Verify clean intended worktrees**
Run `git status --short` in each changed component and confirm only explicitly preserved unrelated files remain. Confirm no generated `node_modules`, secrets, or build output is staged.