feat(crm): dedupe duplicates, fix deal titles, and add cleanup CLI

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>
This commit is contained in:
2026-06-24 12:34:14 +01:00
co-authored by Cursor
parent e03fd62200
commit c77519fac5
21 changed files with 1832 additions and 46 deletions
+48
View File
@@ -0,0 +1,48 @@
package main
import (
onlyoffice "github.com/eslider/go-onlyoffice"
"github.com/spf13/cobra"
)
var crmCmd = &cobra.Command{
Use: "crm",
Short: "CRM maintenance (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)
}
}