Files
eSlider 82da45dc4d
Release Please / Release Please (push) Skipped
Release / GoReleaser (push) Skipped
Tests / Secret scan (gitleaks) (push) Skipped
Tests / Test (Go 1.25) (push) Skipped
Tests / Test (Go stable) (push) Skipped
Tests / Secret scan (gitleaks) (pull_request) Successful in 5s
Tests / Test (Go 1.25) (pull_request) Successful in 1m16s
Tests / Test (Go stable) (pull_request) Successful in 1m36s
feat: upstream generic workspace tooling (board-sync, crm audit, catalog names)
Promote the generic, reusable parts of the private oo-workspace into the
public library/CLI, so oo-workspace can shrink to business glue.

- board.go: Board types + (c *Client) SyncBoard — upsert project
  milestones/tasks by exact title from a YAML board (dry-run when
  apply=false). CLI: oo projects board-sync.
- crm_audit.go: OpportunityAudit + (c *Client) AuditOpportunities —
  file/task/member counts with a generic class (ok|dup|empty|junk-title).
  CLI: oo crm audit [--out].
- catalog/names.go: CleanPersonNames / GuessNameFromEmail /
  FormatProjectTitle (ported from oo-workspace).
- catalog: adopt the newer apply/match logic — name repair (never encode
  company in lastName), company grouping key, contact-info type
  normalization, preserve an already-applied oo_id. Keeps the local
  Address/OOProjects fields and the config-driven classifier.

Business-only oo-workspace commands (crm clean/migrate, folders, search)
deliberately stay private.
2026-09-22 23:13:40 +01:00

49 lines
1.1 KiB
Go

package main
import (
onlyoffice "github.com/eslider/go-onlyoffice"
"github.com/spf13/cobra"
)
var crmCmd = &cobra.Command{
Use: "crm",
Short: "CRM maintenance (audit, dedupe, cleanup)",
}
func init() {
rootCmd.AddCommand(crmCmd)
crmCmd.AddCommand(crmCleanupCmd())
}
func crmCleanupCmd() *cobra.Command {
var ignoreCompanySuffix bool
cmd := &cobra.Command{
Use: "cleanup",
Short: "Run all CRM dedupe passes (companies, persons, associations, titles)",
RunE: func(cmd *cobra.Command, args []string) error {
c, err := newOO(cmd)
if err != nil {
return err
}
out, err := onlyoffice.CleanupCRM(cmd.Context(), c, ignoreCompanySuffix)
if err != nil {
return err
}
printObject(out)
return nil
},
}
cmd.Flags().BoolVar(&ignoreCompanySuffix, "ignore-company-suffix", false, "group deals by position only (strip ' @ Company')")
return cmd
}
func dedupeRunE(fn func(cmd *cobra.Command, c *onlyoffice.Client) error) func(*cobra.Command, []string) error {
return func(cmd *cobra.Command, args []string) error {
c, err := newOO(cmd)
if err != nil {
return err
}
return fn(cmd, c)
}
}