BREAKING:
- Flat oo verb-noun layout replaced with subject → verb, mirroring the
gitea `tea` CLI. Every subject is one file in cmd/oo/:
oo calendar list | events | add | delete
oo projects list | get | milestones | create | update | delete
oo tasks list | get | create | update | delete | subtask add
oo users list | self (alias: oo whoami)
oo contacts list | get | delete | info-add
oo persons list | create | delete
oo companies list | create | delete
oo opportunities list | get | create | delete | stages | member-add
oo cases list | create | delete | member-add
oo crm-tasks list | create | delete | categories
oo applications sync
- Global `--output/-o table|json` flag on the root command; every list uses
a single printTable helper that flattens nested bidCurrency → abbreviation
for readability, truncates long cells, and dumps verbatim in JSON mode.
Library additions surfaced in the CLI:
- oo users / oo whoami via SelfUserID + GetUsers.
- oo projects full CRUD via Create/Update/Delete/GetProjectByID/Milestones.
- oo crm-tasks and oo cases via ListCRMTasks/CreateCRMTask/DeleteCRMTask/
ListTaskCategories/ListCases/CreateCase/DeleteCase/AddCaseMember.
- oo contacts info-add via AddContactInfo.
- oo opportunities stages/member-add via ListDealStages/AddOpportunityMember.
Internal:
- cmd/oo/common.go — rootCmd, newOO (uses AuthenticateContext), printTable,
printObject, fmtCell, deref* helpers.
- cmd/oo/crm.go deleted; content split into contacts.go, opportunities.go,
cases.go, crm_tasks.go for locality.
Docs:
- README: new subject→verb table + migration note.
- AGENTS.md: CLI section rewritten; new rule enforcing subject→verb and
printTable/printObject routing.
- CHANGELOG: 0.5.0 entry with full old→new mapping.
Made-with: Cursor
4.3 KiB
4.3 KiB
AGENTS — go-onlyoffice
Canonical Go client for OnlyOffice Workspace (Projects + Calendar + CRM) and the oo command.
Topology
- Library — flat package
onlyofficeat repo root. Split by domain file, not by subpackage, so every call site readsc.XxxYyy()against a single*Client. Files:client.go—Client,Credentials,Defaults, env helpers,NewClient.request.go—Request,Query,Time,Token,MetaResponse,Permissions.auth.go—Authenticate,AuthenticateContext,InvalidateToken,Auth, token lifecycle.http.go— transport + DRY response decoders (ResponseArray/ResponseObject/postFormObject/putFormObject/deleteObject).projects.go,tasks.go,users.go,calendar.go,crm.go,files.go— typed / untyped domain methods.- Pure stdlib +
google/go-querystring; no UI, no dotenv.
- CLI —
cmd/oo/aspackage main. Cobra wrapper that loads.envviagodotenvat startup. Subject-based command tree mirroringtea:main.go— entry point (docstring lists the command tree).common.go—rootCmd,newOO,printTable/printObject,--output table|jsonflag.calendar.go,projects.go,tasks.go,users.go,contacts.go,opportunities.go,cases.go,crm_tasks.go,apps.go— one file per subject, each registers its subjectcobra.Commandininit()and attaches verb subcommands (list/get/create/update/delete/…).- CLI-only deps (
spf13/cobra,joho/godotenv) stay out of the library.
- Applications sync —
cmd/oo/applications/. README→CRM bridge, CV-specific; kept undercmd/oo/so it's clear it's internal to the binary, not a library feature.
Rules
- Library must never call
godotenv.Load()— the CLI does that. - New endpoints go into the library first; CLI commands are thin wrappers.
- Prefer
ResponseObject/postFormObject/putFormObject/deleteObjectover hand-rolledjson.Unmarshal(responseField(...))blocks — they exist for DRY, use them. - Domain split is by file, not by subpackage. Don't introduce
internal/orpkg/*subpackages inside the library — it flattens the*Clientcall surface for a reason. - CLI commands follow subject → verb structure (
oo <subject> <verb>), neveroo <verb>-<subject>. Add new commands to the existing subject file if one fits; create a newcmd/oo/<subject>.gofor a genuinely new domain. - Every table output goes through
printTable(headers, rows); every single-object throughprintObject(v). Do notfmt.Printlnrows ad-hoc or the--output jsonflag breaks for that command. - No secrets in the repo; use
.env(gitignored). Commit.env.exampleonly. - Follow SemVer on tags; this repo is tagged at GitHub under
git@github.com:eSlider/go-onlyoffice.git.
Testing policy (2026-04-24)
No synthetic OnlyOffice mockups. Protocol-level behaviour must be
verified against a real OnlyOffice instance. httptest.NewServer is only
acceptable for testing the caller's logic that the library can't reach
(for example, the user's own HTTP handler). Anywhere we would otherwise
write mux.HandleFunc("/api/2.0/...") to emulate OnlyOffice, we write an
integration test instead.
- Unit tests (
*_test.go, no build tag) — pure Go: parsers, encoders, struct conversions. No network. No fake servers that emulate the vendor. - Integration tests (
//go:build integrationtag in*_integration_test.go) — hit a live OnlyOffice instance. Credentials come fromONLYOFFICE_URL,ONLYOFFICE_USER,ONLYOFFICE_PASS(aliases_HOST/_NAME/_PASSWORDalso accepted). Tests skip cleanly when credentials are missing sogo test ./...remains green in CI. - Run integration with:
go test -tags=integration ./.... - New endpoints must ship with an integration test before merge.
Related
eSlider/inventar— ASR/ADR (see ASR-0008 Go library module conventions).eSlider/inventar-sync— OnlyOffice → Gitea issue sync, consumes this library.produktor.io/vidarr— legacy consumer being migrated frompkg/onlyofficeto this module.