/
merge-groups.ts
147 lines (120 loc) · 3.77 KB
/
merge-groups.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
import { SafeBulkWriter } from 'shared/safe-bulk-writer'
import { type SupabaseDirectClient } from 'shared/supabase/init'
import { bulkUpsert } from 'shared/supabase/utils'
import { runScript } from 'run-script'
import { upsertGroupEmbedding } from 'shared/helpers/embeddings'
// note: you should turn off the on-update-contract trigger (notifications, embedding recalculation) if it's a ton of contracts
export async function mergeGroups(
pg: SupabaseDirectClient,
firestore: any,
fromSlug: string,
toSlug: string
) {
if (fromSlug === toSlug) {
return
}
const from = await pg.one(
'select id from groups where slug = $1',
[fromSlug],
(row) => row.id
)
const to = await pg.one(
'select id from groups where slug = $1',
[toSlug],
(row) => row.id
)
console.log(`merging ${from} into ${to}`)
console.log('update posts')
await pg.none('update old_posts set group_id = $1 where group_id = $2', [
to,
from,
])
const contracts: string[] = await pg.map(
'select contract_id from group_contracts where group_id = $1',
[from],
(row) => row.contract_id
)
// if (contracts.length > 100) {
// throw new Error(
// `found ${contracts.length} contracts in group ${from}. are you sure?`
// )
// }
if (contracts.length > 0) {
console.log(`re-tagging ${contracts.length} contracts`)
console.log(contracts)
await bulkUpsert(
pg,
'group_contracts',
['group_id', 'contract_id'],
contracts.map((contract) => ({ group_id: to, contract_id: contract }))
)
console.log('removing old group contracts')
await pg.none('delete from group_contracts where group_id = $1', [from])
console.log('correcting contract group slugs')
await updateGroupLinksOnContracts(pg, firestore, contracts)
console.log('recalculating group embedding')
await upsertGroupEmbedding(pg, to)
} else {
console.log('no contracts to re-tag')
}
// move members
const members: string[] = await pg.map(
'select member_id from group_members where group_id = $1',
[from],
(row) => row.member_id
)
console.log(`moving ${members.length} members`)
await bulkUpsert(
pg,
'group_members',
['group_id', 'member_id'],
members.map((member) => ({ group_id: to, member_id: member }))
)
console.log('correcting group member count')
await pg.none(
'update groups set total_members = (select count(*) from group_members where group_id = $1) where id = $1',
[to]
)
console.log('removing old group members')
await pg.none('delete from group_members where group_id = $1', [from])
console.log('removing old group')
await pg.none('delete from groups where id = $1', [from])
}
export async function updateGroupLinksOnContracts(
pg: SupabaseDirectClient,
firestore: any,
contractIds: string[]
) {
const bulkWriter = new SafeBulkWriter()
for (const contractId of contractIds) {
const contractRef = firestore.collection('contracts').doc(contractId)
const groups = await pg.manyOrNone<{
group_id: string
slug: string
name: string
}>(
`select g.id as group_id, g.slug, g.name from groups g join group_contracts gc
on g.id = gc.group_id where gc.contract_id = $1
order by g.importance_score desc`,
[contractId]
)
bulkWriter.update(contractRef, {
groupSlugs: groups.map((g) => g.slug),
groupLinks: groups.map((g) => ({
groupId: g.group_id,
slug: g.slug,
name: g.name,
})),
})
}
await bulkWriter.flush()
}
if (require.main === module) {
if (process.argv.length < 4) {
console.error('usage: merge-groups.ts <from> <to>')
process.exit(1)
}
runScript(async ({ pg, firestore }) => {
await mergeGroups(pg, firestore, process.argv[2], process.argv[3])
})
}