func ProcessCITMetadataUpdate(exec boil.Executor, metadata CITMetadata, original, proxy *models.File) ([]events.Event, error) {
	unit, err := models.ContentUnits(qm.Where("uid = ?", metadata.UnitToFixUID.String)).One(exec)
	if err != nil {
		return nil, errors.Wrapf(err, "lookup unit UID %s", metadata.UnitToFixUID.String)
	}

	evnts, err := doProcess(exec, metadata, original, proxy, unit)
	if err != nil {
		return nil, errors.Wrap(err, "doProcess")
	}

	// We remove only files generated in convert (carbon)
	// and previous trimmed not in our path.
	// Other, manually inserted, files are not touched and are left to admin
	// to figure out what to do with them.

	// Figure out merged set of file IDs
	// which are either ancestor of original or proxy
	// These should be excluded from removal.
	mutualAncestors := hashset.New()

	oPath, err := FindFileAncestors(exec, original.ID)
	if err != nil {
		return nil, errors.Wrapf(err, "lookup original ancestors %d", original.ID)
	}
	for i := range oPath {
		mutualAncestors.Add(oPath[i].ID)
	}

	if proxy != nil {
		pPath, err := FindFileAncestors(exec, proxy.ID)
		if err != nil {
			return nil, errors.Wrapf(err, "lookup proxy ancestors %d", original.ID)
		}
		for i := range pPath {
			mutualAncestors.Add(pPath[i].ID)
		}
	}

	ancestorsIDs := mutualAncestors.Values()
	// These are the fix. Not the problem. Don't remove them
	ancestorsIDs = append(ancestorsIDs, original.ID)
	if proxy != nil {
		ancestorsIDs = append(ancestorsIDs, original.ID, proxy.ID)
	}

	log.Infof("ancestorsIDs: %v", ancestorsIDs)

	// fetch file IDs to remove
	var fIDs pq.Int64Array
	q := `SELECT array_agg(distinct f.id)
FROM files f
  INNER JOIN files_operations fo ON f.id = fo.file_id
  INNER JOIN operations o ON fo.operation_id = o.id AND o.type_id = ANY($1)
WHERE f.content_unit_id = $2 AND NOT f.id = ANY($3) 
`
	err = queries.Raw(q, pq.Array([]int64{
		common.OPERATION_TYPE_REGISTRY.ByName[common.OP_TRIM].ID,
		common.OPERATION_TYPE_REGISTRY.ByName[common.OP_CONVERT].ID,
	}), unit.ID, pq.Array(ancestorsIDs)).QueryRow(exec).Scan(&fIDs)
	if err != nil {
		return nil, errors.Wrap(err, "fetch file IDs to remove")
	}

	log.Infof("%d files to remove: %v", len(fIDs), fIDs)
	wasPublished := false
	if len(fIDs) > 0 {
		// actual removal
		_, err = models.Files(
			qm.WhereIn("id in ?", utils.ConvertArgsInt64(fIDs)...)).
			UpdateAll(exec, models.M{
				"removed_at": null.TimeFrom(time.Now().UTC()),
			})
		if err != nil {
			return nil, errors.Wrap(err, "Update files to remove")
		}

		// file removed events
		removedFiles, err := models.Files(
			qm.Select("id", "uid", "published"),
			qm.WhereIn("id in ?", utils.ConvertArgsInt64(fIDs)...)).
			All(exec)
		if err != nil {
			return nil, errors.Wrap(err, "Refresh files to remove")
		}

		for i := range removedFiles {
			evnts = append(evnts, events.FileRemoveEvent(removedFiles[i]))
			wasPublished = wasPublished || removedFiles[i].Published
		}

	}

	// unit published status change
	impact, err := FileLeftUnitImpact(exec, wasPublished, unit.ID)
	if err != nil {
		return nil, errors.Wrap(err, "File left impact")
	}
	evnts = append(evnts, impact.Events()...)

	return evnts, nil
}
/* send-fix

Sometimes, after a unit was created in a send operation,
we need to fix it.

Either the metadata that was given is wrong or we might need a different trim.
For such cases a new button in the trim admin "fix" is made.

The workflow simply shows the same CIT screen and unit selection.
We should:

1. re-process the metadata in "update" mode
2. figure out files for removal
3. mark those as removed
4. update the unit's published status

*/
send-fix

Sometimes, after a unit was created in a send operation,
we need to fix it.

Either the metadata that was given is wrong or we might need a different trim.
For such cases a new button in the trim admin "fix" is made.

The workflow simply shows the same CIT screen and unit selection.
We should.

1. re-process the metadata in "update" mode
2. figure out files for removal
3. mark those as removed
4. update the unit's published status
/ * send - fix Sometimes after a unit was created in a send operation we need to fix it . Either the metadata that was given is wrong or we might need a different trim . For such cases a new button in the trim admin " fix " is made . The workflow simply shows the same CIT screen and unit selection . We should : 1 . re - process the metadata in " update " mode 2 . figure out files for removal 3 . mark those as removed 4 . update the unit ' s published status * /
func ProcessCITMetadataUpdate(exec boil.Executor, metadata CITMetadata, original, proxy *models.File) ([]events.Event, error) {
	unit, err := models.ContentUnits(qm.Where("uid = ?", metadata.UnitToFixUID.String)).One(exec)
	if err != nil {
		return nil, errors.Wrapf(err, "lookup unit UID %s", metadata.UnitToFixUID.String)
	}
	evnts, err := doProcess(exec, metadata, original, proxy, unit)
	if err != nil {
		return nil, errors.Wrap(err, "doProcess")
	}
	mutualAncestors := hashset.New()
	oPath, err := FindFileAncestors(exec, original.ID)
	if err != nil {
		return nil, errors.Wrapf(err, "lookup original ancestors %d", original.ID)
	}
	for i := range oPath {
		mutualAncestors.Add(oPath[i].ID)
	}
	if proxy != nil {
		pPath, err := FindFileAncestors(exec, proxy.ID)
		if err != nil {
			return nil, errors.Wrapf(err, "lookup proxy ancestors %d", original.ID)
		}
		for i := range pPath {
			mutualAncestors.Add(pPath[i].ID)
		}
	}
	ancestorsIDs := mutualAncestors.Values()
	ancestorsIDs = append(ancestorsIDs, original.ID)
	if proxy != nil {
		ancestorsIDs = append(ancestorsIDs, original.ID, proxy.ID)
	}
	log.Infof("ancestorsIDs: %v", ancestorsIDs)
	var fIDs pq.Int64Array
	q := `SELECT array_agg(distinct f.id)
FROM files f
  INNER JOIN files_operations fo ON f.id = fo.file_id
  INNER JOIN operations o ON fo.operation_id = o.id AND o.type_id = ANY($1)
WHERE f.content_unit_id = $2 AND NOT f.id = ANY($3) 
`
	err = queries.Raw(q, pq.Array([]int64{
		common.OPERATION_TYPE_REGISTRY.ByName[common.OP_TRIM].ID,
		common.OPERATION_TYPE_REGISTRY.ByName[common.OP_CONVERT].ID,
	}), unit.ID, pq.Array(ancestorsIDs)).QueryRow(exec).Scan(&fIDs)
	if err != nil {
		return nil, errors.Wrap(err, "fetch file IDs to remove")
	}
	log.Infof("%d files to remove: %v", len(fIDs), fIDs)
	wasPublished := false
	if len(fIDs) > 0 {
		_, err = models.Files(
			qm.WhereIn("id in ?", utils.ConvertArgsInt64(fIDs)...)).
			UpdateAll(exec, models.M{
				"removed_at": null.TimeFrom(time.Now().UTC()),
			})
		if err != nil {
			return nil, errors.Wrap(err, "Update files to remove")
		}
		removedFiles, err := models.Files(
			qm.Select("id", "uid", "published"),
			qm.WhereIn("id in ?", utils.ConvertArgsInt64(fIDs)...)).
			All(exec)
		if err != nil {
			return nil, errors.Wrap(err, "Refresh files to remove")
		}
		for i := range removedFiles {
			evnts = append(evnts, events.FileRemoveEvent(removedFiles[i]))
			wasPublished = wasPublished || removedFiles[i].Published
		}
	}
	impact, err := FileLeftUnitImpact(exec, wasPublished, unit.ID)
	if err != nil {
		return nil, errors.Wrap(err, "File left impact")
	}
	evnts = append(evnts, impact.Events()...)
	return evnts, nil
}
func ProcessCITMetadataUpdate ( exec boil . Executor , metadata CITMetadata , original , proxy * models . File ) ( [ ] events . Event , error ) { unit , err := models . ContentUnits ( qm . Where ( " " , metadata . UnitToFixUID . String ) ) . One ( exec ) if err != nil { return nil , errors . Wrapf ( err , " " , metadata . UnitToFixUID . String ) } evnts , err := doProcess ( exec , metadata , original , proxy , unit ) if err != nil { return nil , errors . Wrap ( err , " " ) } mutualAncestors := hashset . New ( ) oPath , err := FindFileAncestors ( exec , original . ID ) if err != nil { return nil , errors . Wrapf ( err , " " , original . ID ) } for i := range oPath { mutualAncestors . Add ( oPath [ i ] . ID ) } if proxy != nil { pPath , err := FindFileAncestors ( exec , proxy . ID ) if err != nil { return nil , errors . Wrapf ( err , " " , original . ID ) } for i := range pPath { mutualAncestors . Add ( pPath [ i ] . ID ) } } ancestorsIDs := mutualAncestors . Values ( ) ancestorsIDs = append ( ancestorsIDs , original . ID ) if proxy != nil { ancestorsIDs = append ( ancestorsIDs , original . ID , proxy . ID ) } log . Infof ( " " , ancestorsIDs ) var fIDs pq . Int64Array q := `SELECT array_agg(distinct f.id)
FROM files f
  INNER JOIN files_operations fo ON f.id = fo.file_id
  INNER JOIN operations o ON fo.operation_id = o.id AND o.type_id = ANY($1)
WHERE f.content_unit_id = $2 AND NOT f.id = ANY($3) 
` err = queries . Raw ( q , pq . Array ( [ ] int64 { common . OPERATION_TYPE_REGISTRY . ByName [ common . OP_TRIM ] . ID , common . OPERATION_TYPE_REGISTRY . ByName [ common . OP_CONVERT ] . ID , } ) , unit . ID , pq . Array ( ancestorsIDs ) ) . QueryRow ( exec ) . Scan ( & fIDs ) if err != nil { return nil , errors . Wrap ( err , " " ) } log . Infof ( " " , len ( fIDs ) , fIDs ) wasPublished := false if len ( fIDs ) > 0 { _ , err = models . Files ( qm . WhereIn ( " " , utils . ConvertArgsInt64 ( fIDs ) ... ) ) . UpdateAll ( exec , models . M { " " : null . TimeFrom ( time . Now ( ) . UTC ( ) ) , } ) if err != nil { return nil , errors . Wrap ( err , " " ) } removedFiles , err := models . Files ( qm . Select ( " " , " " , " " ) , qm . WhereIn ( " " , utils . ConvertArgsInt64 ( fIDs ) ... ) ) . All ( exec ) if err != nil { return nil , errors . Wrap ( err , " " ) } for i := range removedFiles { evnts = append ( evnts , events . FileRemoveEvent ( removedFiles [ i ] ) ) wasPublished = wasPublished || removedFiles [ i ] . Published } } impact , err := FileLeftUnitImpact ( exec , wasPublished , unit . ID ) if err != nil { return nil , errors . Wrap ( err , " " ) } evnts = append ( evnts , impact . Events ( ) ... ) return evnts , nil }
send-fix
send - fix
// We remove only files generated in convert (carbon) // and previous trimmed not in our path. // Other, manually inserted, files are not touched and are left to admin // to figure out what to do with them. // Figure out merged set of file IDs // which are either ancestor of original or proxy // These should be excluded from removal. // These are the fix. Not the problem. Don't remove them // fetch file IDs to remove // actual removal // file removed events // unit published status change