Repository navigation
Expand file tree
/
Copy pathaddFieldDistributorUserType.js
More file actions
161 lines (149 loc) · 5.28 KB
/
Copy pathaddFieldDistributorUserType.js
File metadata and controls
161 lines (149 loc) · 5.28 KB
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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
const admin = require("firebase-admin");
const prod = require("./prodAccKey.json");
const dev = require("./testAccKey.json");
const assert = require("assert");
key = dev;
// key = prod;
const dryRun = true;
// const dryRun = false;
admin.initializeApp({ credential: admin.credential.cert(key) });
const db = admin.firestore();
let distributorUsersSnapshot = null;
let productKeysSnapshot = null;
async function assertNoDuplicateKeys() {
const pKeysSet = new Set();
for (const productKeyDoc of productKeysSnapshot.docs) {
const pKey = productKeyDoc.get("Key");
assert(!pKeysSet.has(pKey), `Duplicate product key found: ${pKey}`);
pKeysSet.add(pKey);
}
const dKeysSet = new Set();
for (const distributorUserDoc of distributorUsersSnapshot.docs) {
const dKey = distributorUserDoc.id;
assert(
!dKeysSet.has(dKey),
`Duplicate distributor user doc found for product key: ${dKey}`,
);
dKeysSet.add(dKey);
}
}
async function main() {
distributorUsersSnapshot = await db
.collectionGroup("Users")
.select("userType", "UserType", "Used", "keyUsed", "UsedBy", "userId")
.get();
productKeysSnapshot = await db
.collection("ProductKeys")
.select("Key", "UserType")
.get();
userSnapshot = await db
.collection("User")
.select("ProductKey", "UserType")
.get();
await assertNoDuplicateKeys();
// get distributor key docs with missing userType field
const missingUserTypeKeysDocs = distributorUsersSnapshot.docs.filter(
(doc) =>
doc.get("userType") === undefined && doc.get("UserType") === undefined,
);
if (missingUserTypeKeysDocs.length == 0) {
console.log(`No distributor user docs with missing userType field found.`);
return;
}
console.log(
`Distributor user docs with missing userType field: ${missingUserTypeKeysDocs.length}`,
);
// assert that all other keys have a valid userType field
for (const dKeyDoc of distributorUsersSnapshot.docs) {
if (missingUserTypeKeysDocs.includes(dKeyDoc)) {
continue;
}
const dKey = dKeyDoc.id;
const dUserType = dKeyDoc.get("userType") || dKeyDoc.get("UserType");
assert(
dUserType === "Therapist" || dUserType === "Patient",
`Distributor user doc has invalid userType field: [Key: ${dKey}, UserType: ${dUserType}]`,
);
}
// match documents from 'ProductKeys' and 'User'
matches = [];
for (const dKeyDoc of missingUserTypeKeysDocs) {
const dKey = dKeyDoc.id;
const dDoc = await dKeyDoc.ref.parent.parent.get();
const dName = dDoc.get("Name");
assert(
dName !== undefined,
`Distributor user doc for product key ${dKey} does not have a name field.`,
);
const pDoc = productKeysSnapshot.docs.find(
(doc) => doc.get("Key") === dKey,
);
assert(
pDoc !== undefined,
`No matching product key doc found for distributor user doc: ${dKey}`,
);
const pUserType = pDoc.get("UserType");
const uDoc = userSnapshot.docs.find(
(doc) => doc.get("ProductKey") === dKey,
);
const uUserType = uDoc?.get("UserType");
assert(
uDoc === undefined || uUserType !== undefined,
`User document for product key ${dKey} does not have a userType field.`,
);
matches.push({
dKeyDoc,
dKey,
dName,
pDoc,
pId: pDoc.id,
pUserType,
uDoc,
uUserType,
});
}
// migrate database
for (const match of matches) {
const { dKeyDoc, dKey, dName, pDoc, pId, pUserType, uDoc, uUserType } =
match;
if (uUserType === undefined) {
// no user document was created with this product key yet, assume Therapist
console.log(
`Case 1: No user doc, set distributor doc ${dKey} (${dName}) to Therapist`,
);
if (!dryRun) {
await dKeyDoc.ref.update({ userType: "Therapist" });
}
} else if (pUserType === "Patient" && uUserType === "Therapist") {
// prefer type of already registered user over type defined in ProductKeys, especially for Therapist
console.log(
`Case 2: Product key says Patient, but user doc says Therapist. Update distributor doc ${dKey} (${dName}) from user document: ${uUserType}`,
);
if (!dryRun) {
await dKeyDoc.ref.update({ userType: "Therapist" });
}
} else if (pUserType === "Therapist" && uUserType === "Patient") {
// prefer type of already registered user over type defined in ProductKeys, even for Patient; this is different when distributor user type is defined, though
console.warn(
`Case 3: Product key says Therapist, but user doc says Patient. Update distributor doc ${dKey} (${dName}) from user document: ${uUserType}`,
);
if (!dryRun) {
await dKeyDoc.ref.update({ userType: "Patient" });
await pDoc.ref.update({ UserType: "Patient" });
}
} else if (pUserType === uUserType) {
console.log(
`Case 4: Product key and user doc have the same userType. Update distributor doc ${dKey} (${dName}) from user document: ${uUserType}`,
);
if (!dryRun) {
await dKeyDoc.ref.update({ userType: uUserType });
}
} else {
assert(
false,
`Unexpected case for product key ${dKey} (${dName}): [ProductKey UserType: ${pUserType}, User Document UserType: ${uUserType}]`,
);
}
}
}
main().catch(console.error);