Merge duplicate companies/persons/deals by name, remove duplicate contact info and opportunity members, and rename malformed " @ Company" titles. Applications sync now avoids empty-position titles and duplicate members. Co-authored-by: Cursor <cursoragent@cursor.com>
12 KiB
Changelog
All notable changes to this project are documented here. The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[Unreleased]
Added — library
- CRM dedupe & cleanup —
crm_normalize.go,crm_dedupe_plan.go,crm_dedupe.go: merge duplicate companies/persons/deals by normalized name; remove duplicate contact-info rows and opportunity members (including samedisplayNamewith different ids); fix malformed deal titles (@ Company→Company).MergeContacts,UpdateOpportunityTitle,ListAllContacts,ListAllOpportunities,DeleteContactInfo,RemoveOpportunityMember,IsOpportunityMember,HasContactInfo,CleanupCRM. crm_integration_test.go— live merge, rename, dedupe smoke tests.
Added — CLI
oo companies dedupe|dedupe-persons,oo persons dedupe,oo contacts dedupe-info,oo opportunities dedupe|dedupe-members|fix-titles,oo crm cleanup.
Changed — CLI
oo applications sync— empty position uses company-only deal title; skips duplicate opportunity members; paginated find-or-create lookups.oonow loads OnlyOffice credentials only from.envin the current working directory.- Produktor.io shorthand env names are accepted by the CLI dotenv loader:
OO_URL→ONLYOFFICE_URL,OO_USER→ONLYOFFICE_USER, andOO_PASS→ONLYOFFICE_PASS. CanonicalONLYOFFICE_*values still win when already set in the process environment.
[0.6.0] - 2026-04-24
Added — library
- Project & task Documents API in
files.go:FileEntry,FolderEntry,ProjectFilesResponsetypes.GetProjectFiles,GetTaskFiles,GetFile.UploadProjectFile—POST /api/2.0/files/{folderId}/uploadinto the project'sprojectFolder(resolved viaGetProjectByIDor first folder fromGetProjectFiles).AttachFilesToTask—POST .../project/task/{id}/fileswith formfiles=<id>(OnlyOffice expects existing file ids, not multipart).UploadTaskFile— uploads viaUploadProjectFileusing the task'sprojectOwner.id, then attaches.DetachTaskFile—DELETE .../files?fileid=.RenameFile—PUT /api/2.0/files/file/{id}.jsonwith JSON body.DeleteFiles—PUT /api/2.0/files/fileops/delete.jsonwithfileIds.DownloadFile—GetFilethenGETonviewUrlwithAuthorization.- Helpers:
FileEntryNumericID,FileEntryTitle,SafeLocalFileName.
putJSONon*Clientinhttp.gofor JSON PUT bodies.
Added — CLI
oo projects files list|upload|download|rename|delete— seecmd/oo/projects_files.go;listsupports--folders.oo tasks files list|upload|detach— seecmd/oo/tasks_files.go.
Added — tests
files_integration_test.go— live roundtrip against OnlyOffice (same credential rules asclient_test.go).files_test.go+testdata/*.json— envelope decode unit tests (no network).
[0.5.0] - 2026-04-24
Changed — CLI BREAKING
-
Subject-based command tree (
tea-style). The flatoo verb-nounlayout is replaced withoo <subject> <verb>:Old New oo cal-listoo calendar listoo cal-eventsoo calendar eventsoo cal-add/cal-deleteoo calendar add/calendar deleteoo task-listoo tasks listoo task-addoo tasks createoo task-updateoo tasks update(deletion moved tooo tasks delete)oo subtask-addoo tasks subtask addoo crm-contactsoo contacts list(plus filteredoo persons list/oo companies list)oo crm-add-contact --company …oo companies create --name …oo crm-add-contact --person-first …oo persons create --first …oo crm-dealsoo opportunities listoo crm-deals --stagesoo opportunities stagesoo crm-add-dealoo opportunities createoo crm-casesoo cases listoo applications-syncoo applications sync -
New subjects:
oo projects {list,get,milestones,create,update,delete},oo users {list,self}(plus top-leveloo whoami),oo crm-tasks {list,create,delete,categories},oo cases {create,delete,member-add},oo contacts {get,info-add}. -
Global
--output/-oflag: all list-like commands now support--output table(default; tabwriter-aligned, truncated to 80 chars per cell) and--output json. NestedbidCurrencyflattened to itsabbreviationin the table view. -
Module aliases:
oo calendar|cal,oo projects|prj,oo tasks|task,oo persons|person,oo companies|company,oo opportunities|deals|deal,oo cases|case,oo applications|apps.delete|rmon every leaf that removes things.
Added
cmd/oo/common.go— sharedprintTable(headers, rows)andprintObject(v)helpers that dispatch on the--outputflag.cmd/oo/users.go— exposesoo users list,oo users self,oo whoamivia the library'sGetUsers+SelfUserID.cmd/oo/projects.go— full CRUD for projects backed byCreateProject,UpdateProject,DeleteProject,GetProjectByID,GetProjectMilestones.cmd/oo/crm_tasks.go— dedicatedoo crm-taskssubject (distinct from projectoo tasks).cmd/oo/contacts.go— unified contacts/persons/companies with shared list/filter implementation.
Changed — library (minor)
newOOincmd/oo/common.gonow callsAuthenticateContext(cmd.Context())so CLI aborts propagate to the auth request.
[0.4.0] - 2026-04-24
Changed — project structure
- Library files reorganised by domain (mechanical split; zero API surface
change). The former monolithic
onlyoffice.go(687 LOC) is now split into:client.go—Client,Credentials,Defaults, env helpers,NewClient.request.go—Request,Query,Time,Token,MetaResponse,Permissions,requestBodyReader.auth.go—Authenticate,AuthenticateContext,InvalidateToken,Auth,ensureToken,authHeader,tokenValid.http.go— transport helpers and DRY response decoders (ResponseArray,ResponseObject,postFormObject,putFormObject,deleteObject,unmarshalResponseObject).projects.go—Project,Projects,Milestone,ProjectOwner+GetProjects/CreateProject/UpdateProject/DeleteProject/GetProjectByID/GetProjectMilestones.tasks.go—Task,ProjectTaskStatus,TaskPriority,ProjectGetTasksRequestet al. plus the form-encoded helpers formerly intasks_extra.go(ListTasks,AddTask,AddSubtask,UpdateTaskStatus,DeleteTask,GetTaskByID).users.go—User,Contact,Group,GetUsers,SelfUserID.calendar.go,crm.go,files.go— unchanged in scope, refactored through the new DRY helpers.httpx.go→ renamedhttp.go.onlyoffice.goandtasks_extra.go— deleted (content redistributed).
Changed — CLI BREAKING
- Binary renamed
oo-cli→oo. Install withgo install github.com/eslider/go-onlyoffice/cmd/oo@latest. - Package path
cmd/oo-cli→cmd/oo. The old path is removed. internal/cliis gone. Cobra commands now live directly undercmd/oo/aspackage main, split by domain:calendar.go,crm.go,tasks.go,apps.go,common.go. Rationale: cobra wiring is a CLI-only concern and does not belong inside apkg-level internal/.internal/applications→cmd/oo/applications/. This is a CV-specific CRM workflow — not a general OnlyOffice feature — and is only consumed by theooCLI. Keeping it undercmd/oo/prevents accidental external adoption and makes the coupling explicit.examples/applications/removed. It imported an internal package, which was a policy smell. Remaining examples (basic,calendar,crm,subtasks) use only the exported library surface.
Added
(*Client).ResponseObject— GET-and-decode-object counterpart to the existingResponseArray.(*Client).postFormObject/putFormObject/deleteObject— eliminate the ~15 identical "form request →responseField→json.Unmarshal" blocks previously duplicated acrosscrm.go/tasks_extra.go/calendar.go/files.go.
Migration
External library consumers: no changes required. The module path
(github.com/eslider/go-onlyoffice), the onlyoffice package name, and
every exported symbol are unchanged.
CLI users: replace oo-cli with oo in scripts and CI. The command set
and flags are identical.
[0.3.2] - 2026-04-24
Fixed
Project.String()no longer interprets the title as a format string (fmt.Sprintf(*p.Title)) and is now nil-safe on a zero-valueProject.internal/applications.buildSummaryno longer panics at regex compile time on Go 1.23+ — the previous(?= ...)lookahead is replaced with an RE2-safe non-capturing trailing delimiter.
Changed
Client.Querynow routes token acquisition through the sharedensureTokenpath instead of duplicating the auth-expiry check inline.- Request body marshalling is consolidated into an unexported
requestBodyReaderhelper (DRY; no change to the public surface). - The
Request.Debugfield is preserved for backwards compatibility but no longer changes behaviour — both branches used to unmarshal into the same target value. We'll remove the field in a future major release.
Tests
- Deleted
httptest.NewServerfixtures that emulated OnlyOffice protocol endpoints. Replaced them with:- pure-Go unit tests in
unit_test.go(no network); - real integration tests in
client_test.goguarded by//go:build integration. Run withgo test -tags=integration ./.... Tests skip cleanly whenONLYOFFICE_URL/USER/PASS(or aliases) are absent.
- pure-Go unit tests in
- New policy documented in
AGENTS.mdand.cursor/rules/no-synthetic-mocks.mdc.
[0.3.1] - 2026-04-24
Added
AuthenticateContext(ctx)— context-aware auth that honours cancellation and deadlines. Preferred entry point for long-running syncs (cron, watchers).InvalidateToken()— clears the cached token to force re-auth on the next request. Use this to recover from a mid-sync 401 when the server has revoked the session while the localExpirestimestamp still looks fresh.
Notes
- Plain
Authenticate()is unchanged and remains a convenience wrapper aroundAuthenticateContext(context.Background()). - No breaking changes; a patch release.
[0.3.0] - 2026-04-24
Added
- Calendar helpers:
ListCalendars,ListEvents,AddEvent,DeleteEvent. - CRM helpers: contacts (
ListContacts,GetContact,FindCompany,FindPerson,CreateCompany,CreatePerson,AddContactInfo,DeleteContact), deals (ListOpportunities,GetOpportunity,CreateOpportunity,AddOpportunityMember,ListDealStages,DeleteOpportunity), cases (ListCases,CreateCase,AddCaseMember,DeleteCase), CRM tasks (ListCRMTasks,CreateCRMTask,DeleteCRMTask,ListTaskCategories), and history notes (AddHistoryNote). - Project task extras:
GetProjectByID,ListTasks,ListAllTasks,GetTaskByID,AddTask,AddSubtask,UpdateTaskStatus,DeleteTask. - File upload:
UploadOpportunityFile(multipart). SelfUserIDcached lookup ofpeople/@self.Defaultsstruct +SetDefaults+GetEnvironmentDefaultsfor optional calendar/project fallbacks.- Alias env vars accepted by
GetEnvironmentCredentials:ONLYOFFICE_HOST/ONLYOFFICE_NAME/ONLYOFFICE_PASSWORD. - Public
Authenticate()that primes the token eagerly. - Bundled CLI:
cmd/oo-cli(Cobra) with commandscal-list,cal-events,cal-add,cal-delete,task-list,task-add,subtask-add,task-update,crm-contacts,crm-add-contact,crm-deals,crm-add-deal,crm-cases,applications-sync. - httptest-based unit tests for form / multipart / CRM helpers.
Changed
- The
onlyoffice.Clientstruct gained unexported fields (defaults,selfID,noteCatID); the public API is unchanged and remains backwards compatible.
[0.2.0] - earlier
- Badges, docs expansion (Gitea sync use case, Gantt/PM workflows).
[0.1.0] - earlier
- Initial release: OnlyOffice Project Management API client.