done with upgrades..... I believe
This commit is contained in:
@@ -32,7 +32,7 @@
|
|||||||
"ioredis": "^5.3.2",
|
"ioredis": "^5.3.2",
|
||||||
"lucide-svelte": "^0.424.0",
|
"lucide-svelte": "^0.424.0",
|
||||||
"node-fetch": "^3.3.2",
|
"node-fetch": "^3.3.2",
|
||||||
"surrealdb.js": "^0.8.2",
|
"surrealdb": "^1.1.0",
|
||||||
"svelte-french-toast": "^1.1.0",
|
"svelte-french-toast": "^1.1.0",
|
||||||
"svelte-headlessui": "^0.0.20",
|
"svelte-headlessui": "^0.0.20",
|
||||||
"tailwind-merge": "^2.4.0",
|
"tailwind-merge": "^2.4.0",
|
||||||
|
|||||||
50
pnpm-lock.yaml
generated
50
pnpm-lock.yaml
generated
@@ -65,9 +65,9 @@ importers:
|
|||||||
node-fetch:
|
node-fetch:
|
||||||
specifier: ^3.3.2
|
specifier: ^3.3.2
|
||||||
version: 3.3.2
|
version: 3.3.2
|
||||||
surrealdb.js:
|
surrealdb:
|
||||||
specifier: ^0.8.2
|
specifier: ^1.1.0
|
||||||
version: 0.8.4
|
version: 1.1.0(tslib@2.6.2)(typescript@5.2.2)(ws@8.14.2)
|
||||||
svelte-french-toast:
|
svelte-french-toast:
|
||||||
specifier: ^1.1.0
|
specifier: ^1.1.0
|
||||||
version: 1.2.0(svelte@4.2.1)
|
version: 1.2.0(svelte@4.2.1)
|
||||||
@@ -1141,6 +1141,11 @@ packages:
|
|||||||
isexe@2.0.0:
|
isexe@2.0.0:
|
||||||
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
|
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
|
||||||
|
|
||||||
|
isows@1.0.6:
|
||||||
|
resolution: {integrity: sha512-lPHCayd40oW98/I0uvgaHKWCSvkzY27LjWLbtzOm64yQ+G3Q5npjjbdppU65iZXkK1Zt+kH9pfegli0AYfwYYw==}
|
||||||
|
peerDependencies:
|
||||||
|
ws: '*'
|
||||||
|
|
||||||
jiti@1.21.6:
|
jiti@1.21.6:
|
||||||
resolution: {integrity: sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==}
|
resolution: {integrity: sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
@@ -1561,8 +1566,12 @@ packages:
|
|||||||
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
|
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
surrealdb.js@0.8.4:
|
surrealdb@1.1.0:
|
||||||
resolution: {integrity: sha512-ToCyBHxpVPGXth31ZktQvv+s7fvZG6+sR3mXHNAlhq0/43yYiYx3+3cYvCDGZQNBNUI42KENv8/aBQ5mGQZEEA==}
|
resolution: {integrity: sha512-EAopFKeIo1lVCR+XEE/oMuh8LCPAIa2xC9MyVs5nw+BJyHc0Fr6F/UWVF9399LRtTBCoqe5G1W0hgxqLqkWaYA==}
|
||||||
|
engines: {node: '>=18.0.0'}
|
||||||
|
peerDependencies:
|
||||||
|
tslib: ^2.6.3
|
||||||
|
typescript: ^5.0.0
|
||||||
|
|
||||||
svelte-check@3.5.2:
|
svelte-check@3.5.2:
|
||||||
resolution: {integrity: sha512-5a/YWbiH4c+AqAUP+0VneiV5bP8YOk9JL3jwvN+k2PEPLgpu85bjQc5eE67+eIZBBwUEJzmO3I92OqKcqbp3fw==}
|
resolution: {integrity: sha512-5a/YWbiH4c+AqAUP+0VneiV5bP8YOk9JL3jwvN+k2PEPLgpu85bjQc5eE67+eIZBBwUEJzmO3I92OqKcqbp3fw==}
|
||||||
@@ -1760,12 +1769,6 @@ packages:
|
|||||||
unplugin@1.5.0:
|
unplugin@1.5.0:
|
||||||
resolution: {integrity: sha512-9ZdRwbh/4gcm1JTOkp9lAkIDrtOyOxgHmY7cjuwI8L/2RTikMcVG25GsZwNAgRuap3iDw2jeq7eoqtAsz5rW3A==}
|
resolution: {integrity: sha512-9ZdRwbh/4gcm1JTOkp9lAkIDrtOyOxgHmY7cjuwI8L/2RTikMcVG25GsZwNAgRuap3iDw2jeq7eoqtAsz5rW3A==}
|
||||||
|
|
||||||
unws@0.2.4:
|
|
||||||
resolution: {integrity: sha512-/N1ajiqrSp0A/26/LBg7r10fOcPtGXCqJRJ61sijUFoGZMr6ESWGYn7i0cwr7fR7eEECY5HsitqtjGHDZLAu2w==}
|
|
||||||
engines: {node: '>=16.14.0'}
|
|
||||||
peerDependencies:
|
|
||||||
ws: '*'
|
|
||||||
|
|
||||||
update-browserslist-db@1.1.0:
|
update-browserslist-db@1.1.0:
|
||||||
resolution: {integrity: sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==}
|
resolution: {integrity: sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
@@ -1779,6 +1782,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==}
|
resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
uuidv7@1.0.2:
|
||||||
|
resolution: {integrity: sha512-8JQkH4ooXnm1JCIhqTMbtmdnYEn6oKukBxHn1Ic9878jMkL7daTI7anTExfY18VRCX7tcdn5quzvCb6EWrR8PA==}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
vite-node@0.33.0:
|
vite-node@0.33.0:
|
||||||
resolution: {integrity: sha512-19FpHYbwWWxDr73ruNahC+vtEdza52kA90Qb3La98yZ0xULqV8A5JLNPUff0f5zID4984tW7l3DH2przTJUZSw==}
|
resolution: {integrity: sha512-19FpHYbwWWxDr73ruNahC+vtEdza52kA90Qb3La98yZ0xULqV8A5JLNPUff0f5zID4984tW7l3DH2przTJUZSw==}
|
||||||
engines: {node: '>=v14.18.0'}
|
engines: {node: '>=v14.18.0'}
|
||||||
@@ -2830,6 +2837,10 @@ snapshots:
|
|||||||
|
|
||||||
isexe@2.0.0: {}
|
isexe@2.0.0: {}
|
||||||
|
|
||||||
|
isows@1.0.6(ws@8.14.2):
|
||||||
|
dependencies:
|
||||||
|
ws: 8.14.2
|
||||||
|
|
||||||
jiti@1.21.6: {}
|
jiti@1.21.6: {}
|
||||||
|
|
||||||
jsonc-parser@3.2.0: {}
|
jsonc-parser@3.2.0: {}
|
||||||
@@ -3202,13 +3213,14 @@ snapshots:
|
|||||||
|
|
||||||
supports-preserve-symlinks-flag@1.0.0: {}
|
supports-preserve-symlinks-flag@1.0.0: {}
|
||||||
|
|
||||||
surrealdb.js@0.8.4:
|
surrealdb@1.1.0(tslib@2.6.2)(typescript@5.2.2)(ws@8.14.2):
|
||||||
dependencies:
|
dependencies:
|
||||||
unws: 0.2.4(ws@8.14.2)
|
isows: 1.0.6(ws@8.14.2)
|
||||||
ws: 8.14.2
|
tslib: 2.6.2
|
||||||
|
typescript: 5.2.2
|
||||||
|
uuidv7: 1.0.2
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- bufferutil
|
- ws
|
||||||
- utf-8-validate
|
|
||||||
|
|
||||||
svelte-check@3.5.2(postcss-load-config@4.0.1(postcss@8.4.40))(postcss@8.4.40)(svelte@4.2.1):
|
svelte-check@3.5.2(postcss-load-config@4.0.1(postcss@8.4.40))(postcss@8.4.40)(svelte@4.2.1):
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -3426,10 +3438,6 @@ snapshots:
|
|||||||
webpack-sources: 3.2.3
|
webpack-sources: 3.2.3
|
||||||
webpack-virtual-modules: 0.5.0
|
webpack-virtual-modules: 0.5.0
|
||||||
|
|
||||||
unws@0.2.4(ws@8.14.2):
|
|
||||||
dependencies:
|
|
||||||
ws: 8.14.2
|
|
||||||
|
|
||||||
update-browserslist-db@1.1.0(browserslist@4.23.3):
|
update-browserslist-db@1.1.0(browserslist@4.23.3):
|
||||||
dependencies:
|
dependencies:
|
||||||
browserslist: 4.23.3
|
browserslist: 4.23.3
|
||||||
@@ -3440,6 +3448,8 @@ snapshots:
|
|||||||
|
|
||||||
uuid@9.0.1: {}
|
uuid@9.0.1: {}
|
||||||
|
|
||||||
|
uuidv7@1.0.2: {}
|
||||||
|
|
||||||
vite-node@0.33.0(@types/node@20.6.4):
|
vite-node@0.33.0(@types/node@20.6.4):
|
||||||
dependencies:
|
dependencies:
|
||||||
cac: 6.7.14
|
cac: 6.7.14
|
||||||
|
|||||||
@@ -1,36 +1,32 @@
|
|||||||
import Surreal from "surrealdb.js";
|
import Surreal, { RecordId, StringRecordId } from "surrealdb";
|
||||||
export type { QueryResult } from "surrealdb.js/script/types";
|
export type { QueryResult } from "surrealdb";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (document || window) {
|
if (document || window) {
|
||||||
throw new Error("SurrealDB needs a NodeJS environment to run.");
|
throw new Error("SurrealDB needs a NodeJS environment to run.");
|
||||||
}
|
}
|
||||||
} catch (err) {}
|
} catch (err) {}
|
||||||
|
|
||||||
const CONFIG = {
|
const CONFIG = {
|
||||||
url: process.env.SURREAL_URL ?? "",
|
url: process.env.SURREAL_URL ?? "",
|
||||||
user: process.env.SURREAL_USER ?? "",
|
user: process.env.SURREAL_USER ?? "",
|
||||||
pass: process.env.SURREAL_PASS ?? "",
|
pass: process.env.SURREAL_PASS ?? "",
|
||||||
ns: process.env.SURREAL_NS ?? "",
|
ns: process.env.SURREAL_NS ?? "",
|
||||||
db: process.env.SURREAL_DB ?? "",
|
db: process.env.SURREAL_DB ?? "",
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
// for (let key in CONFIG) {
|
const db = new Surreal();
|
||||||
// if (
|
|
||||||
// !CONFIG[key as keyof typeof CONFIG] ||
|
|
||||||
// CONFIG[key as keyof typeof CONFIG] === ""
|
|
||||||
// ) {
|
|
||||||
// throw new Error(`Missing configuration for ${key}`);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
let _surreal =
|
export function parseToRID(idStr: string) {
|
||||||
CONFIG.url.length > 0
|
return new StringRecordId(idStr);
|
||||||
? new Surreal(`http://${CONFIG.url}/rpc`, {
|
// const [a, b] = idStr.split(":");
|
||||||
auth: { user: CONFIG.user, pass: CONFIG.pass },
|
// return new RecordId(a, b);
|
||||||
ns: CONFIG.ns,
|
}
|
||||||
db: CONFIG.db,
|
|
||||||
})
|
|
||||||
: undefined;
|
|
||||||
|
|
||||||
export const surreal = _surreal as Surreal;
|
if (CONFIG.url.length > 0) {
|
||||||
|
await db.connect(`http://${CONFIG.url}/rpc`);
|
||||||
|
await db.use({ namespace: CONFIG.ns, database: CONFIG.db });
|
||||||
|
await db.signin({ username: CONFIG.user, password: CONFIG.pass });
|
||||||
|
}
|
||||||
|
|
||||||
|
export const surreal = db as Surreal;
|
||||||
|
|||||||
@@ -3,210 +3,279 @@ import { chunkArray } from "../array.chunk";
|
|||||||
import { surreal } from "../connectors/surreal.db";
|
import { surreal } from "../connectors/surreal.db";
|
||||||
|
|
||||||
const getTableName = (date: string) => {
|
const getTableName = (date: string) => {
|
||||||
return `apidata${date.replaceAll("-", "")}`;
|
return `apidata${date.replaceAll("-", "")}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
const upsertData = async (
|
const upsertData = async (
|
||||||
data: BookingEntry[],
|
data: BookingEntry[],
|
||||||
date: string,
|
date: string,
|
||||||
tries: number = 0,
|
tries: number = 0,
|
||||||
): Promise<void> => {
|
): Promise<void> => {
|
||||||
const tableName = getTableName(date);
|
|
||||||
console.log(`[...] Upserting ${data.length} entries into ${tableName}`);
|
|
||||||
const alreadyPresentIds = new Set<string>();
|
|
||||||
try {
|
|
||||||
const [alreadyPresent] = await surreal.query<[string[]]>(
|
|
||||||
`select value id from type::table($tableName) where bookDate = $bookDate`,
|
|
||||||
{ tableName, bookDate: date },
|
|
||||||
);
|
|
||||||
for (let eId of alreadyPresent.result ?? []) {
|
|
||||||
alreadyPresentIds.add(eId);
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
console.log("Failed to fetch, seeing if can try again");
|
|
||||||
if (tries >= 3) {
|
if (tries >= 3) {
|
||||||
console.log("Max tries exceeded for initial fetch for upserting data");
|
console.log("Max tries exceeded for processing data");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
return await upsertData(data, date, tries++);
|
|
||||||
}
|
|
||||||
const oldEntries = [] as any[];
|
|
||||||
const newEntries = [] as BookingEntry[];
|
|
||||||
for (let entry of data) {
|
|
||||||
if (alreadyPresentIds.has(`${tableName}:${entry.id}`)) {
|
|
||||||
oldEntries.push({
|
|
||||||
distributorId: entry.distributorId,
|
|
||||||
dealerId: entry.dealerId,
|
|
||||||
drawId: entry.drawId,
|
|
||||||
bookDate: entry.bookDate.split(" ")[0],
|
|
||||||
number: entry.number,
|
|
||||||
first: entry.first,
|
|
||||||
second: entry.second,
|
|
||||||
changedBalance: entry.changedBalance,
|
|
||||||
sheetName: entry.sheetName,
|
|
||||||
sheetId: entry.sheetId,
|
|
||||||
requestId: entry.requestId,
|
|
||||||
updatedAt: new Date().toISOString(),
|
|
||||||
});
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
newEntries.push({
|
|
||||||
...entry,
|
|
||||||
id: `${tableName}:${entry.id}`,
|
|
||||||
createdAt: new Date().toISOString(),
|
|
||||||
updatedAt: new Date().toISOString(),
|
|
||||||
bookDate: entry.bookDate.split(" ")[0],
|
|
||||||
requestId: entry.requestId ?? "",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
console.log(
|
|
||||||
`[+] Inserting ${newEntries.length} new entries into ${tableName}`,
|
|
||||||
);
|
|
||||||
|
|
||||||
// 5 to 25% of the total data length
|
const tableName = getTableName(date);
|
||||||
let chunkSize = Math.floor(
|
const drawId = data[0].drawId;
|
||||||
Math.random() * (data.length * 0.2 - data.length * 0.05) +
|
|
||||||
data.length * 0.05,
|
|
||||||
);
|
|
||||||
if (chunkSize > 10_000) {
|
|
||||||
chunkSize = 10_000;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(`Chunk Size : ${chunkSize}`);
|
console.log(`[...] Processing ${data.length} entries for ${tableName}`);
|
||||||
|
|
||||||
console.log(`[+] Inserting new entries`);
|
try {
|
||||||
console.time("insertion time");
|
// Delete existing entries for this date
|
||||||
const chunks = chunkArray(newEntries, chunkSize).map(async (chunk) => {
|
console.log(
|
||||||
await surreal.insert<BookingEntry>(tableName, chunk);
|
`[...] Deleting existing entries for ${date} in ${tableName}`,
|
||||||
});
|
);
|
||||||
for (let i = 0; i < chunks.length; i += 2) {
|
console.time("deletion time");
|
||||||
await Promise.all(chunks.slice(i, i + 2));
|
await surreal.query(
|
||||||
}
|
`DELETE type::table($tableName) WHERE bookDate = $bookDate AND drawId = $drawId`,
|
||||||
console.timeEnd("insertion time");
|
{ tableName, bookDate: date, drawId },
|
||||||
|
);
|
||||||
|
console.timeEnd("deletion time");
|
||||||
|
|
||||||
console.log(
|
// Prepare new entries
|
||||||
`[+] Updating ${oldEntries.length} old entries into ${tableName}`,
|
const entries = data.map((entry) => ({
|
||||||
);
|
...entry,
|
||||||
|
id: `${tableName}:${entry.id}`,
|
||||||
|
createdAt: new Date().toISOString(),
|
||||||
|
updatedAt: new Date().toISOString(),
|
||||||
|
bookDate: entry.bookDate.split(" ")[0],
|
||||||
|
requestId: entry.requestId ?? "",
|
||||||
|
}));
|
||||||
|
|
||||||
const chunks2 = chunkArray(oldEntries, chunkSize).map(async (chunk) => {
|
// Calculate chunk size (5 to 25% of total data length, max 10,000)
|
||||||
await Promise.all(
|
let chunkSize = Math.floor(
|
||||||
chunk.map(async (entry) => {
|
Math.random() * (data.length * 0.2 - data.length * 0.05) +
|
||||||
// @ts-ignore
|
data.length * 0.05,
|
||||||
await surreal.update<BookingEntry>(`${tableName}:${entry.id}`, {
|
);
|
||||||
distributorId: entry.distributorId,
|
if (chunkSize > 1_000) {
|
||||||
dealerId: entry.dealerId,
|
chunkSize = 1_000;
|
||||||
drawId: entry.drawId,
|
}
|
||||||
bookDate: entry.bookDate.split(" ")[0],
|
|
||||||
number: entry.number,
|
console.log(`Chunk Size: ${chunkSize}`);
|
||||||
first: entry.first,
|
console.log(
|
||||||
second: entry.second,
|
`[+] Inserting ${entries.length} entries into ${tableName}`,
|
||||||
changedBalance: entry.changedBalance,
|
);
|
||||||
sheetName: entry.sheetName,
|
|
||||||
sheetId: entry.sheetId,
|
// Insert new entries in chunks
|
||||||
requestId: entry.requestId,
|
console.time("insertion time");
|
||||||
updatedAt: new Date().toISOString(),
|
const chunks = chunkArray(entries, chunkSize).map(async (chunk) => {
|
||||||
|
await surreal.insert<BookingEntry>(tableName, chunk);
|
||||||
});
|
});
|
||||||
}),
|
|
||||||
|
for (let i = 0; i < chunks.length; i += 2) {
|
||||||
|
await Promise.all(chunks.slice(i, i + 2));
|
||||||
|
}
|
||||||
|
console.timeEnd("insertion time");
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
`[+] Successfully processed ${data.length} entries into ${tableName}`,
|
||||||
|
);
|
||||||
|
} catch (err) {
|
||||||
|
console.log("Failed to process data, attempting retry");
|
||||||
|
return await upsertData(data, date, tries + 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const upsertDataDED = async (
|
||||||
|
data: BookingEntry[],
|
||||||
|
date: string,
|
||||||
|
tries: number = 0,
|
||||||
|
): Promise<void> => {
|
||||||
|
const tableName = getTableName(date);
|
||||||
|
console.log(`[...] Upserting ${data.length} entries into ${tableName}`);
|
||||||
|
const alreadyPresentIds = new Set<string>();
|
||||||
|
try {
|
||||||
|
const [alreadyPresent] = await surreal.query<[string[]]>(
|
||||||
|
`select value id from type::table($tableName) where bookDate = $bookDate`,
|
||||||
|
{ tableName, bookDate: date },
|
||||||
|
);
|
||||||
|
for (let eId of alreadyPresent ?? []) {
|
||||||
|
alreadyPresentIds.add(eId);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log("Failed to fetch, seeing if can try again");
|
||||||
|
if (tries >= 3) {
|
||||||
|
console.log(
|
||||||
|
"Max tries exceeded for initial fetch for upserting data",
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return await upsertData(data, date, tries++);
|
||||||
|
}
|
||||||
|
const oldEntries = [] as any[];
|
||||||
|
const newEntries = [] as BookingEntry[];
|
||||||
|
for (let entry of data) {
|
||||||
|
if (alreadyPresentIds.has(`${tableName}:${entry.id}`)) {
|
||||||
|
oldEntries.push({
|
||||||
|
distributorId: entry.distributorId,
|
||||||
|
dealerId: entry.dealerId,
|
||||||
|
drawId: entry.drawId,
|
||||||
|
bookDate: entry.bookDate.split(" ")[0],
|
||||||
|
number: entry.number,
|
||||||
|
first: entry.first,
|
||||||
|
second: entry.second,
|
||||||
|
changedBalance: entry.changedBalance,
|
||||||
|
sheetName: entry.sheetName,
|
||||||
|
sheetId: entry.sheetId,
|
||||||
|
requestId: entry.requestId,
|
||||||
|
updatedAt: new Date().toISOString(),
|
||||||
|
});
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
newEntries.push({
|
||||||
|
...entry,
|
||||||
|
id: `${tableName}:${entry.id}`,
|
||||||
|
createdAt: new Date().toISOString(),
|
||||||
|
updatedAt: new Date().toISOString(),
|
||||||
|
bookDate: entry.bookDate.split(" ")[0],
|
||||||
|
requestId: entry.requestId ?? "",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
console.log(
|
||||||
|
`[+] Inserting ${newEntries.length} new entries into ${tableName}`,
|
||||||
);
|
);
|
||||||
});
|
|
||||||
|
|
||||||
console.time("update time");
|
// 5 to 25% of the total data length
|
||||||
for (let i = 0; i < chunks2.length; i += 10) {
|
let chunkSize = Math.floor(
|
||||||
await Promise.all(chunks2.slice(i, i + 10));
|
Math.random() * (data.length * 0.2 - data.length * 0.05) +
|
||||||
}
|
data.length * 0.05,
|
||||||
console.timeEnd("update time");
|
);
|
||||||
|
if (chunkSize > 10_000) {
|
||||||
|
chunkSize = 10_000;
|
||||||
|
}
|
||||||
|
|
||||||
console.log(
|
console.log(`Chunk Size : ${chunkSize}`);
|
||||||
`[+] Successfully upserted ${data.length} entries into ${tableName}`,
|
|
||||||
);
|
console.log(`[+] Inserting new entries`);
|
||||||
|
console.time("insertion time");
|
||||||
|
const chunks = chunkArray(newEntries, chunkSize).map(async (chunk) => {
|
||||||
|
await surreal.insert<BookingEntry>(tableName, chunk);
|
||||||
|
});
|
||||||
|
for (let i = 0; i < chunks.length; i += 2) {
|
||||||
|
await Promise.all(chunks.slice(i, i + 2));
|
||||||
|
}
|
||||||
|
console.timeEnd("insertion time");
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
`[+] Updating ${oldEntries.length} old entries into ${tableName}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
const chunks2 = chunkArray(oldEntries, chunkSize).map(async (chunk) => {
|
||||||
|
await Promise.all(
|
||||||
|
chunk.map(async (entry) => {
|
||||||
|
// @ts-ignore
|
||||||
|
await surreal.update<BookingEntry>(`${tableName}:${entry.id}`, {
|
||||||
|
distributorId: entry.distributorId,
|
||||||
|
dealerId: entry.dealerId,
|
||||||
|
drawId: entry.drawId,
|
||||||
|
bookDate: entry.bookDate.split(" ")[0],
|
||||||
|
number: entry.number,
|
||||||
|
first: entry.first,
|
||||||
|
second: entry.second,
|
||||||
|
changedBalance: entry.changedBalance,
|
||||||
|
sheetName: entry.sheetName,
|
||||||
|
sheetId: entry.sheetId,
|
||||||
|
requestId: entry.requestId,
|
||||||
|
updatedAt: new Date().toISOString(),
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
console.time("update time");
|
||||||
|
for (let i = 0; i < chunks2.length; i += 10) {
|
||||||
|
await Promise.all(chunks2.slice(i, i + 10));
|
||||||
|
}
|
||||||
|
console.timeEnd("update time");
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
`[+] Successfully upserted ${data.length} entries into ${tableName}`,
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const getBookingEntriesForDealer = async (
|
const getBookingEntriesForDealer = async (
|
||||||
date: string,
|
date: string,
|
||||||
drawId: string,
|
drawId: string,
|
||||||
userId: string,
|
userId: string,
|
||||||
sorted?: boolean,
|
sorted?: boolean,
|
||||||
) => {
|
) => {
|
||||||
const tableName = getTableName(date);
|
const tableName = getTableName(date);
|
||||||
let query = `select * from type::table($tableName) where bookDate = $date and dealerId = $userId and drawId = $drawId`;
|
let query = `select * from type::table($tableName) where bookDate = $date and dealerId = $userId and drawId = $drawId`;
|
||||||
if (sorted) {
|
if (sorted) {
|
||||||
query += " order by requestId desc";
|
query += " order by requestId desc";
|
||||||
}
|
}
|
||||||
const [data] = await surreal.query<[BookingEntry[]]>(query, {
|
const [data] = await surreal.query<[BookingEntry[]]>(query, {
|
||||||
tableName,
|
tableName,
|
||||||
date: `${date}`,
|
date: `${date}`,
|
||||||
userId: parseInt(userId),
|
userId: parseInt(userId),
|
||||||
drawId: parseInt(drawId),
|
drawId: parseInt(drawId),
|
||||||
});
|
});
|
||||||
console.log(
|
console.log(
|
||||||
`Found ${JSON.stringify(
|
`Found ${JSON.stringify(
|
||||||
data,
|
data,
|
||||||
)} entries for ${userId}, filters are ${date}, ${drawId} for ${tableName}`,
|
)} entries for ${userId}, filters are ${date}, ${drawId} for ${tableName}`,
|
||||||
);
|
);
|
||||||
if (data.status === "OK") {
|
return data ?? [];
|
||||||
return data.result ?? [];
|
|
||||||
}
|
|
||||||
return [];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const getBookingEntriesByDraw = async (date: string, drawId: string) => {
|
const getBookingEntriesByDraw = async (date: string, drawId: string) => {
|
||||||
const tableName = getTableName(date);
|
const tableName = getTableName(date);
|
||||||
const [data] = await surreal.query<[BookingEntry[]]>(
|
const [data] = await surreal.query<[BookingEntry[]]>(
|
||||||
`select * from type::table($tableName) where bookDate = $date and drawId = $drawId`,
|
`select * from type::table($tableName) where bookDate = $date and drawId = $drawId`,
|
||||||
{
|
{
|
||||||
tableName,
|
tableName,
|
||||||
date: date,
|
date: date,
|
||||||
drawId: parseInt(drawId.includes(":") ? drawId.split(":")[1] : drawId),
|
drawId: parseInt(
|
||||||
},
|
drawId.includes(":") ? drawId.split(":")[1] : drawId,
|
||||||
);
|
),
|
||||||
if (data.status === "OK") {
|
},
|
||||||
return data.result ?? [];
|
);
|
||||||
}
|
return data ?? [];
|
||||||
return [];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const deleteDataOlderThan2Weeks = async () => {
|
const deleteDataOlderThan2Weeks = async () => {
|
||||||
const [out] = await surreal.query("info for db");
|
const [out] = await surreal.query("info for db");
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const tableNames = Object.keys(out.result.tables);
|
const tableNames = Object.keys(out.result.tables);
|
||||||
|
|
||||||
const twoWeeksAgo = new Date();
|
const twoWeeksAgo = new Date();
|
||||||
twoWeeksAgo.setDate(twoWeeksAgo.getDate() - 14);
|
twoWeeksAgo.setDate(twoWeeksAgo.getDate() - 14);
|
||||||
|
|
||||||
for (const tableName of tableNames) {
|
for (const tableName of tableNames) {
|
||||||
if (tableName.startsWith("apidata")) {
|
if (tableName.startsWith("apidata")) {
|
||||||
const datePart = tableName.slice(7);
|
const datePart = tableName.slice(7);
|
||||||
const d = new Date(
|
const d = new Date(
|
||||||
parseInt(datePart.slice(0, 4), 10),
|
parseInt(datePart.slice(0, 4), 10),
|
||||||
parseInt(datePart.slice(4, 6), 10) - 1, // Month is 0-based in JavaScript Date
|
parseInt(datePart.slice(4, 6), 10) - 1, // Month is 0-based in JavaScript Date
|
||||||
parseInt(datePart.slice(6, 8), 10),
|
parseInt(datePart.slice(6, 8), 10),
|
||||||
);
|
);
|
||||||
if (d < twoWeeksAgo) {
|
if (d < twoWeeksAgo) {
|
||||||
console.log(`[...] Deleting ${tableName}`);
|
console.log(`[...] Deleting ${tableName}`);
|
||||||
await surreal.query("remove table if exists " + tableName);
|
await surreal.query("remove table if exists " + tableName);
|
||||||
console.log(`[+] Deleted ${tableName}`);
|
console.log(`[+] Deleted ${tableName}`);
|
||||||
}
|
}
|
||||||
} else if (tableName.startsWith("apipostdata_")) {
|
} else if (tableName.startsWith("apipostdata_")) {
|
||||||
const datePart = tableName.slice(12);
|
const datePart = tableName.slice(12);
|
||||||
const d = new Date(
|
const d = new Date(
|
||||||
parseInt(datePart.slice(0, 4), 10),
|
parseInt(datePart.slice(0, 4), 10),
|
||||||
parseInt(datePart.slice(4, 6), 10) - 1, // Month is 0-based in JavaScript Date
|
parseInt(datePart.slice(4, 6), 10) - 1, // Month is 0-based in JavaScript Date
|
||||||
parseInt(datePart.slice(6, 8), 10),
|
parseInt(datePart.slice(6, 8), 10),
|
||||||
);
|
);
|
||||||
if (d < twoWeeksAgo) {
|
if (d < twoWeeksAgo) {
|
||||||
console.log(`[...] Deleting ${tableName}`);
|
console.log(`[...] Deleting ${tableName}`);
|
||||||
await surreal.query("remove table if exists " + tableName);
|
await surreal.query("remove table if exists " + tableName);
|
||||||
console.log(`[+] Deleted ${tableName}`);
|
console.log(`[+] Deleted ${tableName}`);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.log(`Skipping ${tableName}`);
|
console.log(`Skipping ${tableName}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const dbApiData = {
|
export const dbApiData = {
|
||||||
upsertData,
|
upsertData,
|
||||||
getBookingEntriesForDealer,
|
getBookingEntriesForDealer,
|
||||||
getBookingEntriesByDraw,
|
getBookingEntriesByDraw,
|
||||||
deleteDataOlderThan2Weeks,
|
deleteDataOlderThan2Weeks,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,100 +1,101 @@
|
|||||||
import { constants } from "$lib/utils/constants";
|
import { constants } from "$lib/utils/constants";
|
||||||
import type { Draw } from "$lib/utils/data.types";
|
import type { Draw } from "$lib/utils/data.types";
|
||||||
import { getDraws } from "../external/api.scraping.helpers";
|
import { getDraws } from "../external/api.scraping.helpers";
|
||||||
import { surreal } from "../connectors/surreal.db";
|
import { parseToRID, surreal } from "../connectors/surreal.db";
|
||||||
import { getSessionFromStore } from "../utils/session.service";
|
import { getSessionFromStore } from "../utils/session.service";
|
||||||
|
|
||||||
const tableName = "apidraw";
|
const tableName = "apidraw";
|
||||||
|
|
||||||
const _populateDrawsTable = async () => {
|
const _populateDrawsTable = async () => {
|
||||||
const session = await getSessionFromStore(constants.SCRAP_API_SESSION_KEY);
|
const session = await getSessionFromStore(constants.SCRAP_API_SESSION_KEY);
|
||||||
if (!session) {
|
if (!session) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const draws = await getDraws(session?.sessionToken);
|
const draws = await getDraws(session?.sessionToken);
|
||||||
if (draws.data.length === 0 || !draws.ok) {
|
if (draws.data.length === 0 || !draws.ok) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await surreal.insert<Draw>(
|
await surreal.insert<Draw>(
|
||||||
tableName,
|
tableName,
|
||||||
draws.data.map((e) => {
|
draws.data.map((e) => {
|
||||||
return {
|
return {
|
||||||
id: e.id,
|
id: e.id,
|
||||||
drawType: e.drawType,
|
drawType: e.drawType,
|
||||||
adminId: e.adminId,
|
adminId: e.adminId,
|
||||||
title: e.title,
|
title: e.title,
|
||||||
closeTime: e.closeTime,
|
closeTime: e.closeTime,
|
||||||
filterDuplicatesWhilePosting: false,
|
filterDuplicatesWhilePosting: false,
|
||||||
abRateF: 0,
|
abRateF: 0,
|
||||||
abcRateF: 0,
|
abcRateF: 0,
|
||||||
abRateS: 0,
|
abRateS: 0,
|
||||||
abcRateS: 0,
|
abcRateS: 0,
|
||||||
createdAt: new Date().toISOString(),
|
createdAt: new Date().toISOString(),
|
||||||
updatedAt: new Date().toISOString(),
|
updatedAt: new Date().toISOString(),
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const getAllDraws = async (
|
const getAllDraws = async (
|
||||||
skipOptional?: boolean,
|
skipOptional?: boolean,
|
||||||
retry: number = 0,
|
retry: number = 0,
|
||||||
): Promise<Draw[]> => {
|
): Promise<Draw[]> => {
|
||||||
let query = `select * from apidraw order by closeTime`;
|
const [out] = await surreal.query<[Draw[]]>(
|
||||||
const [out] = await surreal.query<[Draw[]]>(query);
|
`select * from apidraw order by closeTime`,
|
||||||
if (out.status === "OK") {
|
);
|
||||||
const draws = out.result ?? [];
|
if (out.length > 0) {
|
||||||
if (draws.length > 0) {
|
return out;
|
||||||
return draws;
|
|
||||||
}
|
}
|
||||||
await _populateDrawsTable();
|
await _populateDrawsTable();
|
||||||
if (retry < 3) {
|
if (retry < 3) {
|
||||||
return getAllDraws(skipOptional, retry + 1);
|
return getAllDraws(skipOptional, retry + 1);
|
||||||
}
|
}
|
||||||
}
|
return [];
|
||||||
return [];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
async function setFilterDuplicatesFlag(drawId: string, flag: boolean) {
|
async function setFilterDuplicatesFlag(drawId: string, flag: boolean) {
|
||||||
const [d] = await surreal.select<Draw>(drawId);
|
const rid = parseToRID(drawId);
|
||||||
if (!d || !d.id) {
|
const d = await surreal.select<Draw>(rid);
|
||||||
return;
|
if (!d || !d.id) {
|
||||||
}
|
return;
|
||||||
console.log("setFilterDuplicatesFlag :: ", drawId, flag);
|
}
|
||||||
await surreal.update(drawId, {
|
console.log("setFilterDuplicatesFlag :: ", rid, flag);
|
||||||
...d,
|
await surreal.update(rid, {
|
||||||
filterDuplicatesWhilePosting: flag,
|
...d,
|
||||||
updatedAt: new Date().toISOString(),
|
filterDuplicatesWhilePosting: flag,
|
||||||
} as Draw);
|
updatedAt: new Date().toISOString(),
|
||||||
|
} as Draw);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function updateDrawPresetInfo(draw: Draw) {
|
async function updateDrawPresetInfo(draw: Draw) {
|
||||||
const drawId = draw.id;
|
const drawId = parseToRID(draw.id);
|
||||||
const [d] = await surreal.select<Draw>(drawId);
|
const d = await surreal.select<Draw>(drawId);
|
||||||
if (!d || !d.id) {
|
if (!d || !d.id) {
|
||||||
return;
|
console.log(`Draw not present for ${drawId}`);
|
||||||
}
|
return;
|
||||||
await surreal.update(drawId, {
|
}
|
||||||
...d,
|
console.log(`Updating draw info ${drawId}`);
|
||||||
filterDuplicatesWhilePosting: draw.filterDuplicatesWhilePosting,
|
const out = await surreal.update(drawId, {
|
||||||
abRateF: draw.abRateF,
|
...d,
|
||||||
abcRateF: draw.abcRateF,
|
filterDuplicatesWhilePosting: draw.filterDuplicatesWhilePosting,
|
||||||
abRateS: draw.abRateS,
|
abRateF: draw.abRateF,
|
||||||
abcRateS: draw.abcRateS,
|
abcRateF: draw.abcRateF,
|
||||||
updatedAt: new Date().toISOString(),
|
abRateS: draw.abRateS,
|
||||||
} as Draw);
|
abcRateS: draw.abcRateS,
|
||||||
|
updatedAt: new Date().toISOString(),
|
||||||
|
} as Draw);
|
||||||
}
|
}
|
||||||
|
|
||||||
const getDraw = async (drawId: string): Promise<Draw | undefined> => {
|
const getDraw = async (drawId: string): Promise<Draw | undefined> => {
|
||||||
const draws = await surreal.select<Draw>(
|
const draws = await surreal.select<Draw>(
|
||||||
drawId.includes("apidraw") ? drawId : `apidraw:${drawId}`,
|
parseToRID(drawId.includes("apidraw") ? drawId : `apidraw:${drawId}`),
|
||||||
);
|
);
|
||||||
return draws[0];
|
return draws;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const dbDraw = {
|
export const dbDraw = {
|
||||||
getAllDraws,
|
getAllDraws,
|
||||||
getDraw,
|
getDraw,
|
||||||
setFilterDuplicatesFlag,
|
setFilterDuplicatesFlag,
|
||||||
updateDrawPresetInfo,
|
updateDrawPresetInfo,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,95 +2,98 @@ import type { PostDataEntry, PostDataHistory } from "$lib/utils/data.types";
|
|||||||
import { surreal } from "../connectors/surreal.db";
|
import { surreal } from "../connectors/surreal.db";
|
||||||
|
|
||||||
const getTableName = (date: string) => {
|
const getTableName = (date: string) => {
|
||||||
return `apipostdata_${date.replaceAll("-", "")}`;
|
return `apipostdata_${date.replaceAll("-", "")}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
const upsertData = async (data: PostDataHistory) => {
|
const upsertData = async (data: PostDataHistory) => {
|
||||||
const tableName = getTableName(data.bookDate);
|
const tableName = getTableName(data.bookDate);
|
||||||
const [check] = await surreal.query<[PostDataHistory[]]>(
|
const [check] = await surreal.query<[PostDataHistory[]]>(
|
||||||
`select * from type::table($tableName) where bookDate = $bookDate and drawId = $drawId`,
|
`select * from type::table($tableName) where bookDate = $bookDate and drawId = $drawId`,
|
||||||
{ tableName, bookDate: data.bookDate, drawId: data.drawId },
|
{ tableName, bookDate: data.bookDate, drawId: data.drawId },
|
||||||
);
|
|
||||||
console.log(check);
|
|
||||||
const firstOut = check.result ? check.result[0] : undefined;
|
|
||||||
if (check.status === "OK" && !!firstOut && !!firstOut.id) {
|
|
||||||
console.log(
|
|
||||||
`Adding ${data.data.length} entries to ${firstOut.data.length} existing array`,
|
|
||||||
);
|
);
|
||||||
firstOut.data.push(...data.data);
|
console.log(check);
|
||||||
console.log(`Now have ${firstOut.data.length} entries in data list`);
|
const firstOut = check && check.length > 0 ? check[0] : undefined;
|
||||||
console.log(`[...] Updating data row in db now`);
|
if (check.length > 0 && !!firstOut && !!firstOut.id) {
|
||||||
await surreal.update<PostDataHistory>(firstOut.id, {
|
console.log(
|
||||||
id: firstOut.id,
|
`Adding ${data.data.length} entries to ${firstOut.data.length} existing array`,
|
||||||
data: firstOut.data,
|
);
|
||||||
drawId: firstOut.drawId,
|
firstOut.data.push(...data.data);
|
||||||
bookDate: firstOut.bookDate,
|
console.log(`Now have ${firstOut.data.length} entries in data list`);
|
||||||
updatedAt: new Date().toISOString(),
|
console.log(`[...] Updating data row in db now`);
|
||||||
});
|
await surreal.update<PostDataHistory>(firstOut.id, {
|
||||||
|
id: firstOut.id,
|
||||||
|
data: firstOut.data,
|
||||||
|
drawId: firstOut.drawId,
|
||||||
|
bookDate: firstOut.bookDate,
|
||||||
|
updatedAt: new Date().toISOString(),
|
||||||
|
});
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await surreal.insert<PostDataHistory>(tableName, data);
|
await surreal.insert<PostDataHistory>(tableName, data);
|
||||||
console.log(
|
console.log(
|
||||||
`[+] Inserted post data in ${tableName} for ${data.bookDate} - ${data.drawId}`,
|
`[+] Inserted post data in ${tableName} for ${data.bookDate} - ${data.drawId}`,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const getPostDataByDraw = async (date: string, drawId: string) => {
|
const getPostDataByDraw = async (date: string, drawId: string) => {
|
||||||
const tableName = getTableName(date);
|
const tableName = getTableName(date);
|
||||||
const [data] = await surreal.query<[PostDataHistory[]]>(
|
const [data] = await surreal.query<[PostDataHistory[]]>(
|
||||||
`select * from type::table($tableName) where bookDate = $date and drawId = $drawId`,
|
`select * from type::table($tableName) where bookDate = $date and drawId = $drawId`,
|
||||||
{
|
{
|
||||||
tableName,
|
tableName,
|
||||||
date: date,
|
date,
|
||||||
drawId: parseInt(drawId.includes(":") ? drawId.split(":")[1] : drawId),
|
drawId: parseInt(
|
||||||
},
|
drawId.includes(":") ? drawId.split(":")[1] : drawId,
|
||||||
);
|
),
|
||||||
let out = [] as PostDataEntry[];
|
},
|
||||||
if (data.status === "OK" && data.result.length > 0) {
|
);
|
||||||
out = data.result[0].data;
|
let out = [] as PostDataEntry[];
|
||||||
}
|
if (data.length > 0) {
|
||||||
return out;
|
out = data[0].data;
|
||||||
|
}
|
||||||
|
return out;
|
||||||
};
|
};
|
||||||
|
|
||||||
async function doesPostHistoryDataExist(date: string, drawId: string) {
|
async function doesPostHistoryDataExist(date: string, drawId: string) {
|
||||||
const tableName = getTableName(date);
|
const tableName = getTableName(date);
|
||||||
const [data] = await surreal.query<[PostDataHistory[]]>(
|
const [data] = await surreal.query<[PostDataHistory[]]>(
|
||||||
`select id from type::table($tableName) where bookDate = $date and drawId = $drawId`,
|
`select id from type::table($tableName) where bookDate = $date and drawId = $drawId`,
|
||||||
{
|
{
|
||||||
tableName,
|
tableName,
|
||||||
date: date,
|
date: date,
|
||||||
drawId: parseInt(drawId.includes(":") ? drawId.split(":")[1] : drawId),
|
drawId: parseInt(
|
||||||
},
|
drawId.includes(":") ? drawId.split(":")[1] : drawId,
|
||||||
);
|
),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
if (data.status === "OK") {
|
return data[0]?.id.length > 0;
|
||||||
return data.result[0]?.id.length > 0;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function deletePostDataByDraw(date: string, drawId: string) {
|
async function deletePostDataByDraw(date: string, drawId: string) {
|
||||||
const tableName = getTableName(date);
|
const tableName = getTableName(date);
|
||||||
const [data] = await surreal.query<[PostDataHistory[]]>(
|
const [data] = await surreal.query<[PostDataHistory[]]>(
|
||||||
`select id from type::table($tableName) where bookDate = $date and drawId = $drawId`,
|
`select id from type::table($tableName) where bookDate = $date and drawId = $drawId`,
|
||||||
{
|
{
|
||||||
tableName,
|
tableName,
|
||||||
date: date,
|
date: date,
|
||||||
drawId: parseInt(drawId.includes(":") ? drawId.split(":")[1] : drawId),
|
drawId: parseInt(
|
||||||
},
|
drawId.includes(":") ? drawId.split(":")[1] : drawId,
|
||||||
);
|
),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
if (data.status === "OK") {
|
if (data.length > 0) {
|
||||||
await surreal.delete(tableName);
|
await surreal.delete(tableName);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const dbApiPostData = {
|
export const dbApiPostData = {
|
||||||
upsertData,
|
upsertData,
|
||||||
getPostDataByDraw,
|
getPostDataByDraw,
|
||||||
deletePostDataByDraw,
|
deletePostDataByDraw,
|
||||||
doesPostHistoryDataExist,
|
doesPostHistoryDataExist,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,281 +1,262 @@
|
|||||||
import {
|
import {
|
||||||
type ApiUser,
|
type ApiUser,
|
||||||
type LooseApiUser,
|
type LooseApiUser,
|
||||||
type ApiPostUser,
|
type ApiPostUser,
|
||||||
type ApiPostUserWithParent,
|
type ApiPostUserWithParent,
|
||||||
ApiUserTypes,
|
ApiUserTypes,
|
||||||
DEFAULT_RANDOM_DISTRIBUTOR,
|
DEFAULT_RANDOM_DISTRIBUTOR,
|
||||||
|
zApiPostUser,
|
||||||
} from "$lib/utils/data.types";
|
} from "$lib/utils/data.types";
|
||||||
import { surreal } from "../connectors/surreal.db";
|
import { parseToRID, surreal } from "../connectors/surreal.db";
|
||||||
|
|
||||||
const getUserById = async (userId: string) => {
|
const getUserById = async (userId: string) => {
|
||||||
const query = `select * from apiuser where id = $id`;
|
return await surreal.select<ApiUser>(parseToRID(userId));
|
||||||
const [rizzult] = await surreal.query<[ApiUser[]]>(query, { id: userId });
|
// const [rizzult] = await surreal.query<[ApiUser[]]>(query, { id: userId });
|
||||||
return rizzult.result?.[0];
|
// return rizzult[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
const getAllIdsByUserType = async (userType: number) => {
|
const getAllIdsByUserType = async (userType: number) => {
|
||||||
const query = `select value id from apiuser where userType = $userType`;
|
const query = `select value id from apiuser where userType = $userType`;
|
||||||
const rizzult = (await surreal.query<[string[]]>(query, { userType }))[0];
|
const [rizzult] = await surreal.query<[any[]]>(query, { userType });
|
||||||
return (rizzult.result ?? []).map((e) => {
|
return (rizzult ?? []).map((e) => {
|
||||||
return e.split(":")[1];
|
return e.id;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
async function allUsersOfTypeLimitedInfo(userType: number) {
|
async function allUsersOfTypeLimitedInfo(userType: number) {
|
||||||
const rizzult = (
|
const [rizzult] = await surreal.query<[ApiPostUser[]]>(
|
||||||
await surreal.query<[ApiPostUser[]]>(
|
`select id,userName,userId,postData from apiuser where userType = $userType`,
|
||||||
`select id,userName,userId,postData from apiuser where userType = $userType`,
|
{ userType: userType },
|
||||||
{ userType: userType },
|
);
|
||||||
)
|
return rizzult ?? [];
|
||||||
)[0];
|
|
||||||
if (rizzult.status == "OK") {
|
|
||||||
return rizzult.result ?? [];
|
|
||||||
}
|
|
||||||
return [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function setPostDataFlagForUsers(users: ApiPostUser[]) {
|
async function setPostDataFlagForUsers(users: ApiPostUser[]) {
|
||||||
for (const user of users) {
|
for (const user of users) {
|
||||||
const [u] = await surreal.select<ApiUser>(user.id);
|
const uid = parseToRID(user.id);
|
||||||
if (!u || !u.id) {
|
const u = await surreal.select<ApiUser>(uid);
|
||||||
continue;
|
if (!u || !u.id) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
console.log("Updating user :: ", uid);
|
||||||
|
await surreal.update<LooseApiUser>(uid, {
|
||||||
|
...u,
|
||||||
|
postData: user.postData ?? false,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
await surreal.update<LooseApiUser>(user.id, {
|
|
||||||
...u,
|
|
||||||
postData: user.postData ?? false,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const getUserTypeCount = async (userType: number) => {
|
const getUserTypeCount = async (userType: number) => {
|
||||||
const queryBase = `select count() from apiuser where userType = $userType`;
|
const queryBase = `select count() from apiuser where userType = $userType`;
|
||||||
let query = `${queryBase} and disable = 0 group all`;
|
let query = `${queryBase} and disable = 0 group all`;
|
||||||
let disabledQuery = `${queryBase} and disable = 1 group all`;
|
let disabledQuery = `${queryBase} and disable = 1 group all`;
|
||||||
const enabledRizzult = (
|
const enabledRizzult = (
|
||||||
await surreal.query<[{ count: number }[]]>(query, { userType: userType })
|
await surreal.query<[{ count: number }[]]>(query, {
|
||||||
)[0];
|
userType: userType,
|
||||||
const count = { enabled: 0, disabled: 0 };
|
})
|
||||||
if (enabledRizzult.status == "OK") {
|
)[0];
|
||||||
count.enabled = enabledRizzult.result[0]?.count ?? 0;
|
const count = { enabled: 0, disabled: 0 };
|
||||||
}
|
if (enabledRizzult.length > 0) {
|
||||||
const disabledRizzult = (
|
count.enabled = enabledRizzult[0]?.count ?? 0;
|
||||||
await surreal.query<[{ count: number }[]]>(disabledQuery, {
|
}
|
||||||
userType: userType,
|
const disabledRizzult = (
|
||||||
})
|
await surreal.query<[{ count: number }[]]>(disabledQuery, {
|
||||||
)[0];
|
userType: userType,
|
||||||
if (disabledRizzult.status == "OK") {
|
})
|
||||||
count.disabled = disabledRizzult.result[0]?.count ?? 0;
|
)[0];
|
||||||
}
|
if (disabledRizzult.length > 0) {
|
||||||
return count;
|
count.disabled = disabledRizzult[0]?.count ?? 0;
|
||||||
|
}
|
||||||
|
return count;
|
||||||
};
|
};
|
||||||
|
|
||||||
const allUsersOfType = async (userType: number) => {
|
const allUsersOfType = async (userType: number) => {
|
||||||
const rizzult = (
|
const rizzult = (
|
||||||
await surreal.query<[ApiUser[]]>(
|
await surreal.query<[ApiUser[]]>(
|
||||||
`select * from apiuser where userType = $userType`,
|
`select * from apiuser where userType = $userType`,
|
||||||
{ userType: userType },
|
{ userType: userType },
|
||||||
)
|
)
|
||||||
)[0];
|
)[0];
|
||||||
if (rizzult.status == "OK") {
|
return rizzult ?? [];
|
||||||
return rizzult.result ?? [];
|
|
||||||
}
|
|
||||||
return [];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
async function updatePostUsersBalances(
|
async function updatePostUsersBalances(
|
||||||
payload: { balance: number; id: string }[],
|
payload: { balance: number; id: string }[],
|
||||||
) {
|
) {
|
||||||
console.log("Updating users balances");
|
console.log("Updating users balances");
|
||||||
console.log(payload);
|
console.log(payload);
|
||||||
for (const each of payload) {
|
for (const each of payload) {
|
||||||
const [rizzult] = await surreal.query<[ApiUser[]]>(
|
const [rizzult] = await surreal.query<[ApiUser[]]>(
|
||||||
`update $userId set balance = $balance`,
|
`update type::table($tableName) set balance = $balance`,
|
||||||
{ userId: each.id, balance: each.balance },
|
{ tableName: each.id, balance: each.balance },
|
||||||
);
|
);
|
||||||
if (rizzult.status !== "OK") {
|
if (rizzult.length < 1) {
|
||||||
console.error("updatePostUsersBalance :: ", rizzult);
|
console.error("updatePostUsersBalance :: ", rizzult);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
console.log("Users balances updated");
|
||||||
console.log("Users balances updated");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getAllPostUsers() {
|
async function getAllPostUsers() {
|
||||||
const [rizzult] = await surreal.query<[ApiPostUser[]]>(
|
const [rizzult] = await surreal.query<[ApiPostUser[]]>(
|
||||||
`select id,userName,userId,postData from apiuser where postData = true`,
|
`select id,userName,userId,postData from apiuser where postData = true`,
|
||||||
);
|
);
|
||||||
if (rizzult.status === "OK") {
|
return rizzult ?? [];
|
||||||
return rizzult.result ?? [];
|
|
||||||
}
|
|
||||||
return [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getAllPostUsersWithParentUsers() {
|
async function getAllPostUsersWithParentUsers() {
|
||||||
const [rizzult] = await surreal.query<[ApiPostUserWithParent[]]>(
|
const [rizzult] = await surreal.query<[ApiPostUserWithParent[]]>(
|
||||||
`select id,userName,userId,postData,parentDistributor,parentAdmin from apiuser where postData = true`,
|
`select id,userName,userId,postData,parentDistributor,parentAdmin from apiuser where postData = true`,
|
||||||
);
|
);
|
||||||
if (rizzult.status === "OK") {
|
const out = [];
|
||||||
return rizzult.result ?? [];
|
for (const each of rizzult) {
|
||||||
}
|
out.push({ ...each, id: each.id.toString() });
|
||||||
return [];
|
}
|
||||||
|
return out;
|
||||||
|
// return rizzult ?? [];
|
||||||
}
|
}
|
||||||
|
|
||||||
const getAllDistributorsWithTheirChildren = async () => {
|
|
||||||
const distributorIds = await getAllIdsByUserType(ApiUserTypes.DISTRIBUTOR);
|
|
||||||
const out = distributorIds.map(async (id) => {
|
|
||||||
const [rizzult] = await surreal.query<[ApiUser[]]>(
|
|
||||||
`select *, (select * from apiuser where parentDistributor = $id) as children from apiuser where id = $prefixedId`,
|
|
||||||
{ id, prefixedId: `apiuser:${id}` },
|
|
||||||
);
|
|
||||||
if (rizzult.status == "OK") {
|
|
||||||
return rizzult.result[0];
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
});
|
|
||||||
const responses = await Promise.all(out);
|
|
||||||
return responses;
|
|
||||||
};
|
|
||||||
|
|
||||||
const getRandomDistributor = async (): Promise<ApiUser> => {
|
const getRandomDistributor = async (): Promise<ApiUser> => {
|
||||||
const ignoreList = ["001OP9"];
|
const ignoreList = ["001OP9"];
|
||||||
const randomUser = await _getRandomUser(ApiUserTypes.DISTRIBUTOR, ignoreList);
|
const randomUser = await _getRandomUser(
|
||||||
if (!randomUser) {
|
ApiUserTypes.DISTRIBUTOR,
|
||||||
console.log("getting random distributor....");
|
ignoreList,
|
||||||
return DEFAULT_RANDOM_DISTRIBUTOR;
|
);
|
||||||
}
|
if (!randomUser) {
|
||||||
return randomUser as any as ApiUser;
|
console.log("getting random distributor....");
|
||||||
|
return DEFAULT_RANDOM_DISTRIBUTOR;
|
||||||
|
}
|
||||||
|
return randomUser as any as ApiUser;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getRandomDealer = async (): Promise<ApiUser | undefined> => {
|
const getRandomDealer = async (): Promise<ApiUser | undefined> => {
|
||||||
const ignoreList = ["rizgnore"];
|
const ignoreList = ["rizgnore"];
|
||||||
return _getRandomUser(ApiUserTypes.DEALER, ignoreList);
|
return _getRandomUser(ApiUserTypes.DEALER, ignoreList);
|
||||||
};
|
};
|
||||||
|
|
||||||
const _getRandomUser = async (
|
const _getRandomUser = async (
|
||||||
userType: number,
|
userType: number,
|
||||||
ignoreList: string[],
|
ignoreList: string[],
|
||||||
): Promise<ApiUser | undefined> => {
|
): Promise<ApiUser | undefined> => {
|
||||||
console.log("_getRandomUser :: ", userType);
|
console.log("_getRandomUser :: ", userType);
|
||||||
const rizzult = (
|
const [rizzult] = await surreal.query<[ApiUser[]]>(
|
||||||
await surreal.query<[ApiUser[]]>(
|
`select * from apiuser where disable = 0 and userType = $userType and userId notinside $ignoreList order by rand() limit 1`,
|
||||||
`select * from apiuser where disable = 0 and userType = $userType and userId notinside $ignoreList order by rand() limit 1`,
|
{ userType: userType, ignoreList: ignoreList },
|
||||||
{ userType: userType, ignoreList: ignoreList },
|
);
|
||||||
)
|
|
||||||
)[0];
|
|
||||||
if (rizzult.status == "OK") {
|
|
||||||
console.log("found random user");
|
console.log("found random user");
|
||||||
return rizzult.result[0];
|
return rizzult[0];
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const doesExist = async (userId?: string) => {
|
const doesExist = async (userId?: string) => {
|
||||||
console.log("doesExist :: ", userId);
|
console.log("doesExist :: ", userId);
|
||||||
if (userId) {
|
if (userId) {
|
||||||
const [rizzult] = await surreal.query<{ count: number }[]>(
|
const [rizzult] = await surreal.query<{ count: number }[]>(
|
||||||
"select count() from apiuser where userId = $userId group all",
|
"select count() from apiuser where userId = $userId group all",
|
||||||
{ userId: userId },
|
{ userId: userId },
|
||||||
);
|
);
|
||||||
if (rizzult.status == "OK") {
|
return rizzult?.count > 0;
|
||||||
return rizzult.result?.count > 0;
|
|
||||||
}
|
}
|
||||||
}
|
return false;
|
||||||
return false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const insertMany = async (data: LooseApiUser[], postUsers: ApiPostUser[]) => {
|
const insertMany = async (data: LooseApiUser[], postUsers: ApiPostUser[]) => {
|
||||||
console.log("insertMany :: ", data.length);
|
console.log("insertMany :: ", data.length);
|
||||||
await surreal.insert<LooseApiUser>(
|
await surreal.insert<LooseApiUser>(
|
||||||
"apiuser",
|
"apiuser",
|
||||||
data.map((e) => {
|
data.map((e) => {
|
||||||
return {
|
return {
|
||||||
...e,
|
...e,
|
||||||
postData: !!postUsers.find((u) => u.userId === e.userId),
|
postData: !!postUsers.find((u) => u.userId === e.userId),
|
||||||
createdAt: new Date().toISOString(),
|
createdAt: new Date().toISOString(),
|
||||||
updatedAt: new Date().toISOString(),
|
updatedAt: new Date().toISOString(),
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
async function upsertMany(
|
async function upsertMany(
|
||||||
data: LooseApiUser[],
|
data: LooseApiUser[],
|
||||||
wipeTable: boolean,
|
wipeTable: boolean,
|
||||||
deleteUserType: typeof ApiUserTypes.DISTRIBUTOR | typeof ApiUserTypes.DEALER,
|
deleteUserType:
|
||||||
|
| typeof ApiUserTypes.DISTRIBUTOR
|
||||||
|
| typeof ApiUserTypes.DEALER,
|
||||||
) {
|
) {
|
||||||
const postUsers = await getAllPostUsers();
|
const postUsers = await getAllPostUsers();
|
||||||
console.log(postUsers);
|
console.log(postUsers);
|
||||||
if (wipeTable) {
|
if (wipeTable) {
|
||||||
console.log("[wipeTable] :: deleting all previous users");
|
console.log("[wipeTable] :: deleting all previous users");
|
||||||
await surreal.query("delete from apiuser where userType = $userType", {
|
await surreal.query("delete from apiuser where userType = $userType", {
|
||||||
userType: deleteUserType,
|
userType: deleteUserType,
|
||||||
});
|
});
|
||||||
}
|
|
||||||
console.log("upsertMany :: ", data.length);
|
|
||||||
const toCreate = [] as LooseApiUser[];
|
|
||||||
const out = data.map(async (apiUser) => {
|
|
||||||
// INFO: if you do want to keep disabled users, remove this check
|
|
||||||
if (apiUser.disable === 1) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
const [u] = await surreal.select<ApiUser>(`apiuser:${apiUser.id}`);
|
console.log("upsertMany :: ", data.length);
|
||||||
if (!u || !u.id) {
|
const toCreate = [] as LooseApiUser[];
|
||||||
toCreate.push(apiUser);
|
const out = data.map(async (apiUser) => {
|
||||||
return;
|
// INFO: if you do want to keep disabled users, remove this check
|
||||||
}
|
if (apiUser.disable === 1) {
|
||||||
let postData =
|
return;
|
||||||
u.postData ?? !!postUsers.find((pu) => pu.userId === u.userId) ?? false;
|
}
|
||||||
const qId = u.id;
|
const uid = parseToRID(`apiuser:${apiUser.id}`);
|
||||||
await surreal.update<LooseApiUser>(qId, {
|
const u = await surreal.select<ApiUser>(uid);
|
||||||
id: u.id,
|
if (!u || !u.id) {
|
||||||
userId: apiUser.userId,
|
toCreate.push(apiUser);
|
||||||
userType: apiUser.userType,
|
return;
|
||||||
disableBooking: apiUser.disableBooking,
|
}
|
||||||
sendVoucher: apiUser.sendVoucher,
|
let postData =
|
||||||
voucherGenerated: apiUser.voucherGenerated,
|
u.postData ??
|
||||||
parentAdmin: apiUser.parentAdmin,
|
!!postUsers.find((pu) => pu.userId === u.userId) ??
|
||||||
parentDistributor: apiUser.parentDistributor,
|
false;
|
||||||
userName: apiUser.userName,
|
const qId = parseToRID(u.id);
|
||||||
userCity: apiUser.userCity,
|
await surreal.update<LooseApiUser>(qId, {
|
||||||
password: apiUser.password,
|
id: u.id,
|
||||||
accessDenied: apiUser.accessDenied,
|
userId: apiUser.userId,
|
||||||
phoneNumber: apiUser.phoneNumber,
|
userType: apiUser.userType,
|
||||||
emailAddress: apiUser.emailAddress,
|
disableBooking: apiUser.disableBooking,
|
||||||
disable: apiUser.disable,
|
sendVoucher: apiUser.sendVoucher,
|
||||||
commission: apiUser.commission,
|
voucherGenerated: apiUser.voucherGenerated,
|
||||||
commissionPangora: apiUser.commissionPangora,
|
parentAdmin: apiUser.parentAdmin,
|
||||||
allowTitles: apiUser.allowTitles,
|
parentDistributor: apiUser.parentDistributor,
|
||||||
specialDealer: apiUser.specialDealer,
|
userName: apiUser.userName,
|
||||||
allowBalance: apiUser.allowBalance,
|
userCity: apiUser.userCity,
|
||||||
balance: apiUser.balance,
|
password: apiUser.password,
|
||||||
profitlossShare: apiUser.profitlossShare,
|
accessDenied: apiUser.accessDenied,
|
||||||
shareProfitonly: apiUser.shareProfitonly,
|
phoneNumber: apiUser.phoneNumber,
|
||||||
allowRemoveold: apiUser.allowRemoveold,
|
emailAddress: apiUser.emailAddress,
|
||||||
removeDays: apiUser.removeDays,
|
disable: apiUser.disable,
|
||||||
language: apiUser.language,
|
commission: apiUser.commission,
|
||||||
postData,
|
commissionPangora: apiUser.commissionPangora,
|
||||||
createdAt: u.createdAt,
|
allowTitles: apiUser.allowTitles,
|
||||||
updatedAt: new Date().toISOString(),
|
specialDealer: apiUser.specialDealer,
|
||||||
|
allowBalance: apiUser.allowBalance,
|
||||||
|
balance: apiUser.balance,
|
||||||
|
profitlossShare: apiUser.profitlossShare,
|
||||||
|
shareProfitonly: apiUser.shareProfitonly,
|
||||||
|
allowRemoveold: apiUser.allowRemoveold,
|
||||||
|
removeDays: apiUser.removeDays,
|
||||||
|
language: apiUser.language,
|
||||||
|
postData,
|
||||||
|
createdAt: u.createdAt,
|
||||||
|
updatedAt: new Date().toISOString(),
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
await Promise.allSettled(out);
|
||||||
await Promise.allSettled(out);
|
if (toCreate.length > 0) {
|
||||||
if (toCreate.length > 0) {
|
await insertMany(toCreate, postUsers);
|
||||||
await insertMany(toCreate, postUsers);
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const dbApiUser = {
|
export const dbApiUser = {
|
||||||
allUsersOfType,
|
allUsersOfType,
|
||||||
allUsersOfTypeLimitedInfo,
|
allUsersOfTypeLimitedInfo,
|
||||||
getUserById,
|
getUserById,
|
||||||
getAllDistributorsWithTheirChildren,
|
getUserTypeCount,
|
||||||
getUserTypeCount,
|
getAllIdsByUserType,
|
||||||
getAllIdsByUserType,
|
getAllPostUsers,
|
||||||
getAllPostUsers,
|
getAllPostUsersWithParentUsers,
|
||||||
getAllPostUsersWithParentUsers,
|
getRandomDistributor,
|
||||||
getRandomDistributor,
|
getRandomDealer,
|
||||||
getRandomDealer,
|
doesExist,
|
||||||
doesExist,
|
upsertMany,
|
||||||
upsertMany,
|
setPostDataFlagForUsers,
|
||||||
setPostDataFlagForUsers,
|
updatePostUsersBalances,
|
||||||
updatePostUsersBalances,
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
export const dbBooking = {
|
|
||||||
};
|
|
||||||
@@ -1,40 +1,39 @@
|
|||||||
import type { FinalSheetData } from "$lib/utils/data.types";
|
import type { FinalSheetData } from "$lib/utils/data.types";
|
||||||
import { surreal } from "../connectors/surreal.db";
|
import { parseToRID, surreal } from "../connectors/surreal.db";
|
||||||
|
|
||||||
const getTableName = (date: string) => {
|
const getTableName = (date: string) => {
|
||||||
return `finalsheet${date.replaceAll("-", "")}`;
|
return `finalsheet${date.replaceAll("-", "")}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
const upsertData = async (data: FinalSheetData, date: string) => {
|
const upsertData = async (data: FinalSheetData, date: string) => {
|
||||||
const tableName = getTableName(date);
|
const tableName = getTableName(date);
|
||||||
const [present] = await surreal.query<[FinalSheetData[]]>(
|
const [present] = await surreal.query<[FinalSheetData[]]>(
|
||||||
`select id from type::table($tableName) where date = $date and drawId = $drawId`,
|
`select id from type::table($tableName) where date = $date and drawId = $drawId`,
|
||||||
{ tableName, date: `${date}`, drawId: data.drawId }
|
{ tableName, date: `${date}`, drawId: data.drawId },
|
||||||
);
|
);
|
||||||
if (present) {
|
const id = parseToRID(`${tableName}:${data.id}`);
|
||||||
// @ts-ignore
|
if (present) {
|
||||||
await surreal.update<FinalSheetData>(`${tableName}:${data.id}`, {
|
// @ts-ignore
|
||||||
date: data.date,
|
await surreal.update<FinalSheetData>(id, {
|
||||||
drawId: data.drawId,
|
date: data.date,
|
||||||
data: data.data,
|
drawId: data.drawId,
|
||||||
totals: data.totals,
|
data: data.data,
|
||||||
// @ts-ignore
|
totals: data.totals,
|
||||||
createdAt: present?.result[0]?.createdAt ?? new Date().toISOString(),
|
// @ts-ignore
|
||||||
updatedAt: new Date().toISOString(),
|
createdAt: present[0]?.createdAt ?? new Date().toISOString(),
|
||||||
});
|
updatedAt: new Date().toISOString(),
|
||||||
} else {
|
});
|
||||||
// @ts-ignore
|
} else {
|
||||||
await surreal.create<FinalSheetData>(`${tableName}:${data.id}`, {
|
// @ts-ignore
|
||||||
date: data.date,
|
await surreal.create<FinalSheetData>(id, {
|
||||||
drawId: data.drawId,
|
date: data.date,
|
||||||
data: data.data,
|
drawId: data.drawId,
|
||||||
totals: data.totals,
|
data: data.data,
|
||||||
createdAt: new Date().toISOString(),
|
totals: data.totals,
|
||||||
updatedAt: new Date().toISOString(),
|
createdAt: new Date().toISOString(),
|
||||||
});
|
updatedAt: new Date().toISOString(),
|
||||||
}
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const dbFinalSheet = {
|
export const dbFinalSheet = { upsertData };
|
||||||
upsertData,
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -1,65 +1,62 @@
|
|||||||
import type {
|
import type { PresetDataEntry } from "$lib/utils/data.types";
|
||||||
ApiPostUser,
|
|
||||||
PostDataEntry,
|
|
||||||
PresetDataEntry,
|
|
||||||
} from "$lib/utils/data.types";
|
|
||||||
import { surreal } from "../connectors/surreal.db";
|
import { surreal } from "../connectors/surreal.db";
|
||||||
|
|
||||||
const getTableName = (date: string) => {
|
const getTableName = (date: string) => {
|
||||||
return `presetdata_${date.replaceAll("-", "")}`;
|
return `presetdata_${date.replaceAll("-", "")}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
const insertData = async (data: PresetDataEntry[]) => {
|
const insertData = async (data: PresetDataEntry[]) => {
|
||||||
if (data.length < 1) return;
|
if (data.length < 1) return;
|
||||||
const tableName = getTableName(data[0].bookDate);
|
const tableName = getTableName(data[0].bookDate);
|
||||||
const out = await surreal.insert<PresetDataEntry>(tableName, data);
|
console.log(`Inserting ${data.length} rows in ${tableName}`);
|
||||||
console.log(
|
const out = await surreal.insert<PresetDataEntry>(tableName, data);
|
||||||
`[+] Inserted post data in ${tableName} for ${data[0].bookDate} - ${data[0].drawId}`,
|
console.log(
|
||||||
);
|
`[+] Inserted post data in ${tableName} for ${data[0].bookDate} - ${data[0].drawId}`,
|
||||||
return out;
|
);
|
||||||
|
return out;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getDataByDraw = async (date: string, drawId: number) => {
|
const getDataByDraw = async (date: string, drawId: number) => {
|
||||||
const tableName = getTableName(date);
|
const tableName = getTableName(date);
|
||||||
const [data] = await surreal.query<[PresetDataEntry[]]>(
|
const [data] = await surreal.query<[PresetDataEntry[]]>(
|
||||||
`select * from type::table($tableName) where bookDate = $date and drawId = $drawId`,
|
`select * from type::table($tableName) where bookDate = $date and drawId = $drawId`,
|
||||||
{ tableName, date, drawId },
|
{ tableName, date, drawId },
|
||||||
);
|
);
|
||||||
return data.result || ([] as PresetDataEntry[]);
|
return data || ([] as PresetDataEntry[]);
|
||||||
};
|
};
|
||||||
|
|
||||||
const getDataGroupedBySheetByDraw = async (date: string, drawId: number) => {
|
const getDataGroupedBySheetByDraw = async (date: string, drawId: number) => {
|
||||||
const tableName = getTableName(date);
|
const tableName = getTableName(date);
|
||||||
const [data] = await surreal.query<[PresetDataEntry[]]>(
|
const [data] = await surreal.query<[PresetDataEntry[]]>(
|
||||||
`select * from type::table($tableName) where bookDate = $date and drawId = $drawId`,
|
`select * from type::table($tableName) where bookDate = $date and drawId = $drawId`,
|
||||||
{ tableName, date, drawId },
|
{ tableName, date, drawId },
|
||||||
);
|
);
|
||||||
const out = {
|
const out = {
|
||||||
abData: [] as PresetDataEntry[],
|
abData: [] as PresetDataEntry[],
|
||||||
abcData: [] as PresetDataEntry[],
|
abcData: [] as PresetDataEntry[],
|
||||||
all: data.result || ([] as PresetDataEntry[]),
|
all: data || ([] as PresetDataEntry[]),
|
||||||
};
|
};
|
||||||
for (const row of data.result ?? []) {
|
for (const row of data ?? []) {
|
||||||
if (row.number.length === 2) {
|
if (row.number.length === 2) {
|
||||||
out.abData.push(row);
|
out.abData.push(row);
|
||||||
} else if (row.number.length === 3) {
|
} else if (row.number.length === 3) {
|
||||||
out.abcData.push(row);
|
out.abcData.push(row);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
return out;
|
||||||
return out;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
async function deleteDataByIds(date: string, ids: string[]) {
|
async function deleteDataByIds(date: string, ids: string[]) {
|
||||||
const tableName = getTableName(date);
|
const tableName = getTableName(date);
|
||||||
await surreal.query<[PresetDataEntry[]]>(
|
await surreal.query<[PresetDataEntry[]]>(
|
||||||
`delete from type::table($tableName) where id in $ids`,
|
`delete from type::table($tableName) where id in $ids`,
|
||||||
{ tableName, ids },
|
{ tableName, ids },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export const dbPresetData = {
|
export const dbPresetData = {
|
||||||
insertData,
|
insertData,
|
||||||
getDataGroupedBySheetByDraw,
|
getDataGroupedBySheetByDraw,
|
||||||
getDataByDraw,
|
getDataByDraw,
|
||||||
deleteDataByIds,
|
deleteDataByIds,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,90 +1,76 @@
|
|||||||
import type { User } from "$lib/utils/data.types";
|
import type { User } from "$lib/utils/data.types";
|
||||||
import { surreal, type QueryResult } from "../connectors/surreal.db";
|
import { surreal } from "../connectors/surreal.db";
|
||||||
|
|
||||||
export const dbUser = {
|
export const dbUser = {
|
||||||
doesExist: async (username?: string) => {
|
doesExist: async (username?: string) => {
|
||||||
if (username) {
|
if (username) {
|
||||||
const [rizzult] = await surreal.query<{ count: number }[]>(
|
const [rizzult] = await surreal.query<{ count: number }[]>(
|
||||||
"select count() from user where username = $username group all",
|
"select count() from user where username = $username group all",
|
||||||
{ username: username }
|
{ username },
|
||||||
);
|
);
|
||||||
if (rizzult.status == "OK") {
|
return rizzult?.count > 0;
|
||||||
return rizzult.result?.count > 0;
|
}
|
||||||
}
|
return false;
|
||||||
}
|
},
|
||||||
return false;
|
create: async (data: {
|
||||||
},
|
username: string;
|
||||||
create: async (data: {
|
password: string;
|
||||||
username: string;
|
userType: string;
|
||||||
password: string;
|
association: string;
|
||||||
userType: string;
|
}) => {
|
||||||
association: string;
|
const doesUserAlreadyExist = await dbUser.doesExist(data.username);
|
||||||
}) => {
|
console.log("doesUserAlreadyExist :: ", doesUserAlreadyExist);
|
||||||
const doesUserAlreadyExist = await dbUser.doesExist(data.username);
|
if (doesUserAlreadyExist) {
|
||||||
console.log("doesUserAlreadyExist :: ", doesUserAlreadyExist);
|
return [{ message: "User already exists." }];
|
||||||
if (doesUserAlreadyExist) {
|
}
|
||||||
return [{ message: "User already exists." }];
|
const { username, password, association, userType } = data;
|
||||||
}
|
const out = await surreal.create<any>(`user`, {
|
||||||
const { username, password, association, userType } = data;
|
createdAt: Date.now().toString(),
|
||||||
const out = await surreal.create<any>(`user:ulid()`, {
|
updatedAt: Date.now().toString(),
|
||||||
createdAt: Date.now().toString(),
|
username,
|
||||||
updatedAt: Date.now().toString(),
|
password,
|
||||||
username,
|
userType,
|
||||||
password,
|
association,
|
||||||
userType,
|
});
|
||||||
association,
|
return out as User[];
|
||||||
});
|
},
|
||||||
return out as User[];
|
all: async () => {
|
||||||
},
|
return await surreal.select<User>("user");
|
||||||
all: async () => {
|
},
|
||||||
return await surreal.select<User>("user");
|
get: async (d: {
|
||||||
},
|
username?: string;
|
||||||
get: async (d: {
|
id?: string;
|
||||||
username?: string;
|
}): Promise<User | undefined> => {
|
||||||
id?: string;
|
if (d.id) {
|
||||||
}): Promise<User | undefined> => {
|
return (await surreal.select<User>(`user:${d.id}`))[0];
|
||||||
if (d.id) {
|
}
|
||||||
return (await surreal.select<User>(`user:${d.id}`))[0];
|
if (d.username) {
|
||||||
}
|
const rizzult = (
|
||||||
if (d.username) {
|
await surreal.query<[User[]]>(
|
||||||
const rizzult = (
|
`select * from user where username = $username`,
|
||||||
await surreal.query<[User[]]>(
|
{ username: d.username },
|
||||||
`select * from user where username = $username`,
|
)
|
||||||
{ username: d.username }
|
)[0];
|
||||||
)
|
return rizzult[0];
|
||||||
)[0];
|
}
|
||||||
if (rizzult.status == "OK") {
|
return undefined;
|
||||||
return rizzult.result[0];
|
},
|
||||||
}
|
getChildren: async (username?: string) => {
|
||||||
}
|
const [rizzult] = await surreal.query<User[]>(
|
||||||
return undefined;
|
`select * from user where association = $username`,
|
||||||
},
|
{ username: username },
|
||||||
getChildren: async (username?: string) => {
|
);
|
||||||
const rizzult = await surreal.query<User[]>(
|
return rizzult;
|
||||||
`select * from user where association = $username`,
|
},
|
||||||
{ username: username }
|
update: async (id: string, data: { association: string }) => {
|
||||||
);
|
const [rizzult] = await surreal.update<User>(`user:${id}`, {
|
||||||
return getParsedUsers(rizzult);
|
updatedAt: Date.now().toString(),
|
||||||
},
|
association: data.association,
|
||||||
update: async (id: string, data: { association: string }) => {
|
} as User);
|
||||||
const [rizzult] = await surreal.update<User>(`user:${id}`, {
|
return rizzult;
|
||||||
updatedAt: Date.now().toString(),
|
},
|
||||||
association: data.association,
|
delete: async (id: string) => {
|
||||||
} as User);
|
const out = await surreal.delete(`user:${id}`);
|
||||||
return rizzult;
|
return out[0].id;
|
||||||
},
|
},
|
||||||
delete: async (id: string) => {
|
|
||||||
const out = await surreal.delete(`user:${id}`);
|
|
||||||
return out[0].id;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const getParsedUsers = (data: QueryResult<User>[]) => {
|
|
||||||
const users = [] as User[];
|
|
||||||
for (const each of data) {
|
|
||||||
if (each.status == "OK") {
|
|
||||||
users.push(each.result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return users;
|
|
||||||
};
|
};
|
||||||
|
|||||||
550
src/lib/server/external/api.scraping.helpers.ts
vendored
550
src/lib/server/external/api.scraping.helpers.ts
vendored
@@ -13,317 +13,317 @@ import { rng } from "$lib/utils/rng";
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
export const testIfSessionIsValid = async (jwt: string) => {
|
export const testIfSessionIsValid = async (jwt: string) => {
|
||||||
try {
|
try {
|
||||||
const res = await fetch(
|
const res = await fetch(
|
||||||
`${constants.SCRAP_API_URL}/v1/user/get-balance?userId=6339`,
|
`${constants.SCRAP_API_URL}/v1/user/get-balance?userId=6339`,
|
||||||
{
|
{
|
||||||
headers: {
|
headers: {
|
||||||
...constants.SCRAP_API_BASE_HEADERS,
|
...constants.SCRAP_API_BASE_HEADERS,
|
||||||
Authorization: jwt,
|
Authorization: jwt,
|
||||||
"User-Agent": getRandomUserAgent(),
|
"User-Agent": getRandomUserAgent(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
if (res.status !== 200) {
|
if (res.status !== 200) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
const rj = (await res.json()) as {
|
||||||
|
code: number;
|
||||||
|
success: boolean;
|
||||||
|
message: string;
|
||||||
|
data: any;
|
||||||
|
time: string;
|
||||||
|
};
|
||||||
|
return rj.code == 200 && rj.success;
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
const rj = (await res.json()) as {
|
|
||||||
code: number;
|
|
||||||
success: boolean;
|
|
||||||
message: string;
|
|
||||||
data: any;
|
|
||||||
time: string;
|
|
||||||
};
|
|
||||||
return rj.code == 200 && rj.success;
|
|
||||||
} catch (err) {
|
|
||||||
console.log(err);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getSessionToken = async (payload: {
|
export const getSessionToken = async (payload: {
|
||||||
userId: string;
|
userId: string;
|
||||||
password: string;
|
password: string;
|
||||||
verifyToken: string;
|
verifyToken: string;
|
||||||
code: string;
|
code: string;
|
||||||
userType: number;
|
userType: number;
|
||||||
}): Promise<{ ok: boolean; message: string }> => {
|
}): Promise<{ ok: boolean; message: string }> => {
|
||||||
console.log("Requesting...");
|
console.log("Requesting...");
|
||||||
const res = await fetch(`${constants.SCRAP_API_URL}/v1/auth/login`, {
|
const res = await fetch(`${constants.SCRAP_API_URL}/v1/auth/login`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
...constants.SCRAP_API_BASE_HEADERS,
|
...constants.SCRAP_API_BASE_HEADERS,
|
||||||
"User-Agent": getRandomUserAgent(),
|
"User-Agent": getRandomUserAgent(),
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
},
|
},
|
||||||
body: JSON.stringify(payload),
|
body: JSON.stringify(payload),
|
||||||
});
|
});
|
||||||
const out = await res.json();
|
const out = await res.json();
|
||||||
if (out.code !== 200) {
|
if (out.code !== 200) {
|
||||||
return { ok: false, message: out.message };
|
return { ok: false, message: out.message };
|
||||||
}
|
}
|
||||||
return { ok: true, message: out.data.token };
|
return { ok: true, message: out.data.token };
|
||||||
};
|
};
|
||||||
|
|
||||||
export async function getUsersBalance(userId: number, jwt: string) {
|
export async function getUsersBalance(userId: number, jwt: string) {
|
||||||
try {
|
try {
|
||||||
const res = await fetch(
|
const res = await fetch(
|
||||||
`${constants.SCRAP_API_URL}/v1/user/get-balance?userId=${userId}`,
|
`${constants.SCRAP_API_URL}/v1/user/get-balance?userId=${userId}`,
|
||||||
{
|
{
|
||||||
headers: {
|
headers: {
|
||||||
...constants.SCRAP_API_BASE_HEADERS,
|
...constants.SCRAP_API_BASE_HEADERS,
|
||||||
Authorization: jwt,
|
Authorization: jwt,
|
||||||
"User-Agent": getRandomUserAgent(),
|
"User-Agent": getRandomUserAgent(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
const rj = (await res.json()) as {
|
const rj = (await res.json()) as {
|
||||||
code: number;
|
code: number;
|
||||||
success: boolean;
|
success: boolean;
|
||||||
message: string;
|
message: string;
|
||||||
data: { allowedBalance: number; balance: number };
|
data: { allowedBalance: number; balance: number };
|
||||||
time: string;
|
time: string;
|
||||||
};
|
};
|
||||||
if (res.status !== 200 || rj.code !== 200 || !rj.success) {
|
if (res.status !== 200 || rj.code !== 200 || !rj.success) {
|
||||||
console.log(
|
console.log(
|
||||||
`[!] Error getting balance for ${userId} :: ${JSON.stringify(rj)}`,
|
`[!] Error getting balance for ${userId} :: ${JSON.stringify(rj)}`,
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
return rj.data.balance;
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return rj.data.balance;
|
|
||||||
} catch (err) {
|
|
||||||
console.log(err);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getDealers = async (jwt: string, distributor_ids: string[]) => {
|
export const getDealers = async (jwt: string, distributor_ids: string[]) => {
|
||||||
try {
|
try {
|
||||||
// // Create an array of promises for each fetch request
|
// // Create an array of promises for each fetch request
|
||||||
const requests = distributor_ids.map(async (did) => {
|
const requests = distributor_ids.map(async (did) => {
|
||||||
await sleep(rng(100, 10000));
|
await sleep(rng(100, 10000));
|
||||||
const res = await fetch(
|
const res = await fetch(
|
||||||
`${constants.SCRAP_API_URL}/v1/user/dealer-list`,
|
`${constants.SCRAP_API_URL}/v1/user/dealer-list`,
|
||||||
{
|
{
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
...constants.SCRAP_API_BASE_HEADERS,
|
...constants.SCRAP_API_BASE_HEADERS,
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
"User-Agent": getRandomUserAgent(),
|
"User-Agent": getRandomUserAgent(),
|
||||||
Authorization: jwt,
|
Authorization: jwt,
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
page: 1,
|
page: 1,
|
||||||
pageSize: 999999,
|
pageSize: 999999,
|
||||||
parentDistributor: parseInt(did),
|
parentDistributor: parseInt(did),
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
const data = (await res.json()) as {
|
const data = (await res.json()) as {
|
||||||
code: number;
|
code: number;
|
||||||
success: boolean;
|
success: boolean;
|
||||||
message: string;
|
message: string;
|
||||||
data: {
|
data: {
|
||||||
items: any[];
|
items: any[];
|
||||||
total: number;
|
total: number;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
if (data.code !== 200 || !data.success) {
|
if (data.code !== 200 || !data.success) {
|
||||||
|
return {
|
||||||
|
dealers: [],
|
||||||
|
ok: false,
|
||||||
|
code: data.code,
|
||||||
|
message: data.message,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
const dealers = data.data.items.map((item) => item.dealer);
|
||||||
|
|
||||||
|
// dumpDealers(dealers);
|
||||||
|
|
||||||
|
return {
|
||||||
|
dealers,
|
||||||
|
ok: res.status === 200 && data.success,
|
||||||
|
code: data.code,
|
||||||
|
message: data.message,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
// // Wait for all promises to resolve
|
||||||
|
const responses = await Promise.all(requests);
|
||||||
|
const dealers: LooseApiUser[] = [];
|
||||||
|
const errors: { message: string }[] = [];
|
||||||
|
for (const res of responses) {
|
||||||
|
if (res.code !== 200 || !res.ok) {
|
||||||
|
errors.push({ message: res.message });
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (const dealer of res.dealers) {
|
||||||
|
dealers.push(dealer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// fs.writeFileSync("dealers.json", JSON.stringify(dealers, null, 2));
|
||||||
|
|
||||||
|
return { dealers, errors };
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
return {
|
return {
|
||||||
dealers: [],
|
dealers: [],
|
||||||
ok: false,
|
errors: [{ message: "An error occured during fetching dealers" }],
|
||||||
code: data.code,
|
|
||||||
message: data.message,
|
|
||||||
};
|
};
|
||||||
}
|
|
||||||
const dealers = data.data.items.map((item) => item.dealer);
|
|
||||||
|
|
||||||
// dumpDealers(dealers);
|
|
||||||
|
|
||||||
return {
|
|
||||||
dealers,
|
|
||||||
ok: res.status === 200 && data.success,
|
|
||||||
code: data.code,
|
|
||||||
message: data.message,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
// // Wait for all promises to resolve
|
|
||||||
const responses = await Promise.all(requests);
|
|
||||||
const dealers: LooseApiUser[] = [];
|
|
||||||
const errors: { message: string }[] = [];
|
|
||||||
for (const res of responses) {
|
|
||||||
if (res.code !== 200 || !res.ok) {
|
|
||||||
errors.push({ message: res.message });
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
for (const dealer of res.dealers) {
|
|
||||||
dealers.push(dealer);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// fs.writeFileSync("dealers.json", JSON.stringify(dealers, null, 2));
|
|
||||||
|
|
||||||
return { dealers, errors };
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
return {
|
|
||||||
dealers: [],
|
|
||||||
errors: [{ message: "An error occured during fetching dealers" }],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getDistributors = async (jwt: string) => {
|
export const getDistributors = async (jwt: string) => {
|
||||||
const res = await fetch(
|
const res = await fetch(
|
||||||
`${constants.SCRAP_API_URL}/v1/user/distributor-list`,
|
`${constants.SCRAP_API_URL}/v1/user/distributor-list`,
|
||||||
{
|
{
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
...constants.SCRAP_API_BASE_HEADERS,
|
...constants.SCRAP_API_BASE_HEADERS,
|
||||||
Authorization: jwt,
|
Authorization: jwt,
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
"User-Agent": getRandomUserAgent(),
|
"User-Agent": getRandomUserAgent(),
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
page: 1,
|
page: 1,
|
||||||
pageSize: 999999,
|
pageSize: 999999,
|
||||||
parentDistributor: 15,
|
parentDistributor: 15,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
const json = (await res.json()) as {
|
const json = (await res.json()) as {
|
||||||
code: number;
|
code: number;
|
||||||
success: boolean;
|
success: boolean;
|
||||||
message: string;
|
message: string;
|
||||||
data: { total: number; items: any[] };
|
data: { total: number; items: any[] };
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!json.data.items || json.code !== 200 || !json.success) {
|
if (!json.data.items || json.code !== 200 || !json.success) {
|
||||||
return { ok: false, message: json.message, data: [] };
|
return { ok: false, message: json.message, data: [] };
|
||||||
}
|
}
|
||||||
|
|
||||||
// fs.writeFileSync(
|
// fs.writeFileSync(
|
||||||
// "distributors.json",
|
// "distributors.json",
|
||||||
// JSON.stringify(json.data.items, null, 2),
|
// JSON.stringify(json.data.items, null, 2),
|
||||||
// );
|
// );
|
||||||
|
|
||||||
// dumpDistributors(json.data.items.map((item) => item.distributor));
|
// dumpDistributors(json.data.items.map((item) => item.distributor));
|
||||||
|
|
||||||
return {
|
return {
|
||||||
ok: true,
|
ok: true,
|
||||||
message: "",
|
message: "",
|
||||||
data: json.data.items.map((item) => item.distributor),
|
data: json.data.items.map((item) => item.distributor),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getDraws = async (jwt: string) => {
|
export const getDraws = async (jwt: string) => {
|
||||||
const res = await fetch(
|
const res = await fetch(
|
||||||
`${constants.SCRAP_API_URL}/v1/draw/list-my?userId=15`,
|
`${constants.SCRAP_API_URL}/v1/draw/list-my?userId=15`,
|
||||||
{
|
{
|
||||||
method: "GET",
|
method: "GET",
|
||||||
headers: {
|
headers: {
|
||||||
...constants.SCRAP_API_BASE_HEADERS,
|
...constants.SCRAP_API_BASE_HEADERS,
|
||||||
Authorization: jwt,
|
Authorization: jwt,
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
"User-Agent": getRandomUserAgent(),
|
"User-Agent": getRandomUserAgent(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
type J = {
|
type J = {
|
||||||
code: number;
|
code: number;
|
||||||
success: boolean;
|
success: boolean;
|
||||||
message: string;
|
message: string;
|
||||||
data: { draw: Draw }[];
|
data: { draw: Draw }[];
|
||||||
};
|
};
|
||||||
let decoded = (await res.json()) as { data: J };
|
let decoded = (await res.json()) as { data: J };
|
||||||
const json = (decoded.data.success ? decoded.data : decoded) as any as J;
|
const json = (decoded.data.success ? decoded.data : decoded) as any as J;
|
||||||
if (json.code !== 200 || !json.success || !json.data) {
|
if (json.code !== 200 || !json.success || !json.data) {
|
||||||
return { ok: false, message: json.message, data: [] };
|
return { ok: false, message: json.message, data: [] };
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
ok: true,
|
ok: true,
|
||||||
message: "",
|
message: "",
|
||||||
data: json.data.map((item) => item.draw),
|
data: json.data.map((item) => item.draw),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getData = async (
|
export const getData = async (
|
||||||
jwt: string,
|
jwt: string,
|
||||||
userIds: number[],
|
userIds: number[],
|
||||||
drawId: number,
|
drawId: number,
|
||||||
chosenDate: string,
|
chosenDate: string,
|
||||||
) => {
|
) => {
|
||||||
const res = await fetch(`${constants.SCRAP_API_URL}/v1/book/list2`, {
|
const res = await fetch(`${constants.SCRAP_API_URL}/v1/book/list2`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
...constants.SCRAP_API_BASE_HEADERS,
|
...constants.SCRAP_API_BASE_HEADERS,
|
||||||
Authorization: jwt,
|
Authorization: jwt,
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
"User-Agent": getRandomUserAgent(),
|
"User-Agent": getRandomUserAgent(),
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
userType: 3,
|
userType: 3,
|
||||||
userIds,
|
userIds,
|
||||||
drawId: drawId,
|
drawId: drawId,
|
||||||
startDate: chosenDate,
|
startDate: chosenDate,
|
||||||
endDate: chosenDate,
|
endDate: chosenDate,
|
||||||
beAdmin: false,
|
beAdmin: false,
|
||||||
containImported: false,
|
containImported: false,
|
||||||
keyword: "",
|
keyword: "",
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
type J = {
|
type J = {
|
||||||
code: number;
|
code: number;
|
||||||
success: boolean;
|
success: boolean;
|
||||||
message: string;
|
message: string;
|
||||||
data: { book: BookingEntry; user: any }[];
|
data: { book: BookingEntry; user: any }[];
|
||||||
};
|
};
|
||||||
let decoded = (await res.json()) as { data: J };
|
let decoded = (await res.json()) as { data: J };
|
||||||
const json = (decoded.data.success ? decoded.data : decoded) as any as J;
|
const json = (decoded.data.success ? decoded.data : decoded) as any as J;
|
||||||
if (json.code !== 200 || !json.success || !json.data) {
|
if (json.code !== 200 || !json.success || !json.data) {
|
||||||
return { ok: false, message: json.message, data: [] };
|
return { ok: false, message: json.message, data: [] };
|
||||||
}
|
}
|
||||||
return { ok: true, message: "", data: json.data.map((e) => e.book) };
|
return { ok: true, message: "", data: json.data.map((e) => e.book) };
|
||||||
};
|
};
|
||||||
|
|
||||||
export const mockGetUserData = async (
|
export const mockGetUserData = async (
|
||||||
jwt: string,
|
jwt: string,
|
||||||
userIds: number[],
|
userIds: number[],
|
||||||
drawId: number,
|
drawId: number,
|
||||||
chosenDate: string,
|
chosenDate: string,
|
||||||
) => {
|
) => {
|
||||||
const entries = [] as BookingEntry[];
|
const entries = [] as BookingEntry[];
|
||||||
|
|
||||||
const rng = (min: number, max: number) => {
|
const rng = (min: number, max: number) => {
|
||||||
return Math.floor(Math.random() * (max - min + 1)) + min;
|
return Math.floor(Math.random() * (max - min + 1)) + min;
|
||||||
};
|
};
|
||||||
const randomCeil = rng(10_000, 200_000);
|
const randomCeil = rng(10_000, 200_000);
|
||||||
|
|
||||||
await sleep(rng(100, 1000));
|
await sleep(rng(100, 1000));
|
||||||
|
|
||||||
for (let i = 0; i < randomCeil; i++) {
|
for (let i = 0; i < randomCeil; i++) {
|
||||||
const _f = rng(5, 50);
|
const _f = rng(5, 50);
|
||||||
const _s = rng(5, 50);
|
const _s = rng(5, 50);
|
||||||
const f = _f - (_f % 5);
|
const f = _f - (_f % 5);
|
||||||
const s = _s - (_s % 5);
|
const s = _s - (_s % 5);
|
||||||
|
|
||||||
entries.push({
|
entries.push({
|
||||||
id: getULID(),
|
id: getULID(),
|
||||||
bookDate: chosenDate,
|
bookDate: chosenDate,
|
||||||
changedBalance: f + s,
|
changedBalance: f + s,
|
||||||
first: f,
|
first: f,
|
||||||
second: s,
|
second: s,
|
||||||
dealerId: userIds[rng(0, userIds.length - 1)],
|
dealerId: userIds[rng(0, userIds.length - 1)],
|
||||||
distributorId: 6339,
|
distributorId: 6339,
|
||||||
drawId: drawId,
|
drawId: drawId,
|
||||||
number: rng(0, 9999).toString(),
|
number: rng(0, 9999).toString(),
|
||||||
requestId: new Date().getTime().toString(),
|
requestId: new Date().getTime().toString(),
|
||||||
createdAt: new Date().toISOString(),
|
createdAt: new Date().toISOString(),
|
||||||
updatedAt: new Date().toISOString(),
|
updatedAt: new Date().toISOString(),
|
||||||
sheetId: "0",
|
sheetId: "0",
|
||||||
sheetName: "",
|
sheetName: "",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return { ok: true, message: "", data: entries };
|
return { ok: true, message: "", data: entries };
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,320 +1,334 @@
|
|||||||
import { getRandomUserAgent, getULID, sleep } from "$lib/utils";
|
import { getRandomUserAgent, getULID, sleep } from "$lib/utils";
|
||||||
import { constants } from "$lib/utils/constants";
|
import { constants } from "$lib/utils/constants";
|
||||||
import type {
|
import type {
|
||||||
ApiPostUserWithParent,
|
ApiPostUserWithParent,
|
||||||
APISession,
|
APISession,
|
||||||
Draw,
|
Draw,
|
||||||
PostDataEntry,
|
PostDataEntry,
|
||||||
ServerError,
|
ServerError,
|
||||||
} from "$lib/utils/data.types";
|
} from "$lib/utils/data.types";
|
||||||
import Fetch from "node-fetch";
|
import Fetch from "node-fetch";
|
||||||
import { HttpsProxyAgent } from "https-proxy-agent";
|
import { HttpsProxyAgent } from "https-proxy-agent";
|
||||||
|
|
||||||
export type APIRespnose<T> = {
|
export type APIRespnose<T> = {
|
||||||
code: number;
|
code: number;
|
||||||
success: boolean;
|
success: boolean;
|
||||||
message: string;
|
message: string;
|
||||||
data: T;
|
data: T;
|
||||||
time: string;
|
time: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function buildMessageString(
|
export function buildMessageString(
|
||||||
ptr: number,
|
ptr: number,
|
||||||
rows: PostDataEntry[],
|
rows: PostDataEntry[],
|
||||||
distributorId: number,
|
distributorId: number,
|
||||||
dealerId: number,
|
dealerId: number,
|
||||||
drawId: number,
|
drawId: number,
|
||||||
date: string,
|
date: string,
|
||||||
) {
|
) {
|
||||||
let message = "";
|
let message = "";
|
||||||
let jumpSize = Math.floor(Math.random() * 490) + 10;
|
let jumpSize = Math.floor(Math.random() * 490) + 10;
|
||||||
let total = 0;
|
let total = 0;
|
||||||
let startReqId = new Date().getTime();
|
let startReqId = new Date().getTime();
|
||||||
let x = 0;
|
let x = 0;
|
||||||
for (let j = ptr; j < ptr + jumpSize; j++) {
|
for (let j = ptr; j < ptr + jumpSize; j++) {
|
||||||
if (j >= rows.length) {
|
if (j >= rows.length) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
const row = rows[j];
|
||||||
|
const reqId = startReqId + x++;
|
||||||
|
const no = row.number.trim();
|
||||||
|
const f = row.first;
|
||||||
|
const s = row.second;
|
||||||
|
const mTotal = f + s;
|
||||||
|
if (mTotal <= 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
total += mTotal;
|
||||||
|
message += `${reqId},${distributorId},${dealerId},${drawId},${date},${no},${f},${s},${mTotal};`;
|
||||||
}
|
}
|
||||||
const row = rows[j];
|
message = message.slice(0, -1);
|
||||||
const reqId = startReqId + x++;
|
return { message, total, jumped: ptr + jumpSize };
|
||||||
const no = row.number.trim();
|
|
||||||
const f = row.first;
|
|
||||||
const s = row.second;
|
|
||||||
const mTotal = f + s;
|
|
||||||
if (mTotal <= 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
total += mTotal;
|
|
||||||
message += `${reqId},${distributorId},${dealerId},${drawId},${date},${no},${f},${s},${mTotal};`;
|
|
||||||
}
|
|
||||||
message = message.slice(0, -1);
|
|
||||||
return { message, total, jumped: ptr + jumpSize };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function postDataToApi(payload: {
|
export async function postDataToApi(payload: {
|
||||||
sessions: Record<string, APISession>;
|
sessions: Record<string, APISession>;
|
||||||
draw: Draw;
|
draw: Draw;
|
||||||
data: PostDataEntry[];
|
data: PostDataEntry[];
|
||||||
users: ApiPostUserWithParent[];
|
users: ApiPostUserWithParent[];
|
||||||
}) {
|
}) {
|
||||||
const responses = [] as APIRespnose<[]>[];
|
const responses = [] as APIRespnose<[]>[];
|
||||||
const responsesIds = [] as { requestId: number; bookId: string }[];
|
const responsesIds = [] as { requestId: number; bookId: string }[];
|
||||||
let failedResponses = 0;
|
let failedResponses = 0;
|
||||||
let successResponses = 0;
|
let successResponses = 0;
|
||||||
|
|
||||||
console.log(`[+] Sending ${payload.data.length} requests...`);
|
console.log(`[+] Sending ${payload.data.length} requests...`);
|
||||||
|
|
||||||
const dataByUser = {} as Record<string, PostDataEntry[]>;
|
const dataByUser = {} as Record<string, PostDataEntry[]>;
|
||||||
for (const row of payload.data) {
|
for (const row of payload.data) {
|
||||||
const userId = row.userId ?? "";
|
const userId = row.userId ?? "";
|
||||||
if (userId.length < 1) {
|
if (userId.length < 1) {
|
||||||
console.log(`[!] User not found for request ${row.userId}`);
|
console.log(`[!] User not found for request ${row.userId}`);
|
||||||
return {
|
return {
|
||||||
ok: false,
|
ok: false,
|
||||||
detail: "User not found to post data with",
|
detail: "User not found to post data with",
|
||||||
errors: [{ message: "User not found for request" }] as ServerError,
|
errors: [
|
||||||
};
|
{ message: "User not found for request" },
|
||||||
|
] as ServerError,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (!dataByUser[userId]) {
|
||||||
|
dataByUser[userId] = [];
|
||||||
|
}
|
||||||
|
dataByUser[userId].push(row);
|
||||||
}
|
}
|
||||||
if (!dataByUser[userId]) {
|
|
||||||
dataByUser[userId] = [];
|
|
||||||
}
|
|
||||||
dataByUser[userId].push(row);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const userPromises = Object.entries(dataByUser).map(
|
const userPromises = Object.entries(dataByUser).map(
|
||||||
async ([userId, userData]) => {
|
async ([userId, userData]) => {
|
||||||
const session = payload.sessions[userId];
|
const session = payload.sessions[userId];
|
||||||
const usr = payload.users.find((u) => u.userId === userId);
|
const usr = payload.users.find((u) => u.userId === userId);
|
||||||
if (!usr) {
|
if (!usr) {
|
||||||
throw new Error(`User ${userId} not found for posting to api`);
|
throw new Error(
|
||||||
|
`User ${userId} not found for posting to api`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const distId = usr.parentDistributor ?? 0;
|
||||||
|
const dealerId = Number(session.userId.split(":")[1]);
|
||||||
|
const drawId = Number(payload.draw.id.split(":")[1]);
|
||||||
|
const date = new Date().toISOString().split("T")[0];
|
||||||
|
|
||||||
|
let ptr = 0;
|
||||||
|
const userResponseIds = [] as {
|
||||||
|
requestId: number;
|
||||||
|
bookId: string;
|
||||||
|
}[];
|
||||||
|
|
||||||
|
while (ptr < userData.length) {
|
||||||
|
let tries = 0;
|
||||||
|
while (tries < 3) {
|
||||||
|
let { message, total, jumped } = buildMessageString(
|
||||||
|
ptr,
|
||||||
|
userData,
|
||||||
|
distId,
|
||||||
|
dealerId,
|
||||||
|
drawId,
|
||||||
|
date,
|
||||||
|
);
|
||||||
|
const res = await mockSendBatchRequest(
|
||||||
|
session,
|
||||||
|
dealerId,
|
||||||
|
payload.draw,
|
||||||
|
total,
|
||||||
|
message,
|
||||||
|
);
|
||||||
|
let rj:
|
||||||
|
| APIRespnose<{
|
||||||
|
bookDtos: {
|
||||||
|
bookId: string;
|
||||||
|
requestId: number;
|
||||||
|
}[];
|
||||||
|
}>
|
||||||
|
| undefined = undefined;
|
||||||
|
try {
|
||||||
|
rj = (await res.json()) as any;
|
||||||
|
} catch (err) {
|
||||||
|
console.log(
|
||||||
|
"Encountered error while parsing post response",
|
||||||
|
);
|
||||||
|
console.log(res.status, err);
|
||||||
|
}
|
||||||
|
if (rj && rj.code === 200 && res.status === 200) {
|
||||||
|
ptr = jumped;
|
||||||
|
userResponseIds.push(
|
||||||
|
...rj.data.bookDtos.map((b) => ({
|
||||||
|
requestId: b.requestId as number,
|
||||||
|
bookId: b.bookId as string,
|
||||||
|
})),
|
||||||
|
);
|
||||||
|
successResponses++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
console.log("Failed to send send post request");
|
||||||
|
console.log(res.status, rj);
|
||||||
|
failedResponses++;
|
||||||
|
tries++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tries >= 3) {
|
||||||
|
if (userResponseIds.length > 0) {
|
||||||
|
const out = await deleteAllBookedEntries({
|
||||||
|
data: userResponseIds,
|
||||||
|
closeTime: payload.draw.closeTime,
|
||||||
|
dealerId,
|
||||||
|
drawId,
|
||||||
|
session,
|
||||||
|
});
|
||||||
|
console.log(await out.text());
|
||||||
|
}
|
||||||
|
throw new Error(
|
||||||
|
`Failed to send data to api for user ${userId}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return userResponseIds;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
// Wait for all user processes to complete
|
||||||
|
const results = await Promise.allSettled(userPromises);
|
||||||
|
|
||||||
|
// Process results
|
||||||
|
let hasErrors = false;
|
||||||
|
results.forEach((result) => {
|
||||||
|
if (result.status === "fulfilled") {
|
||||||
|
responsesIds.push(...result.value);
|
||||||
|
} else {
|
||||||
|
hasErrors = true;
|
||||||
|
console.log(`[!] Error processing user`);
|
||||||
|
console.log(result.reason);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (hasErrors) {
|
||||||
|
return {
|
||||||
|
ok: false,
|
||||||
|
detail: "Failed to post data to API for some users",
|
||||||
|
errors: [
|
||||||
|
{ message: "Failed to post data to API for some users" },
|
||||||
|
] as ServerError,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const distId = usr.parentDistributor ?? 0;
|
console.log(`[+] Finished sending ${payload.data.length} requests`);
|
||||||
const dealerId = Number(session.userId.split(":")[1]);
|
console.log(`[?] Failed responses: ${failedResponses}`);
|
||||||
const drawId = Number(payload.draw.id.split(":")[1]);
|
console.log(`[?] Success responses: ${successResponses}`);
|
||||||
const date = new Date().toISOString().split("T")[0];
|
return {
|
||||||
|
ok: true,
|
||||||
let ptr = 0;
|
detail: "Successfully sent data to api",
|
||||||
const userResponseIds = [] as { requestId: number; bookId: string }[];
|
data: responses,
|
||||||
|
};
|
||||||
while (ptr < userData.length) {
|
} catch (err) {
|
||||||
let tries = 0;
|
console.log(err);
|
||||||
while (tries < 3) {
|
return {
|
||||||
let { message, total, jumped } = buildMessageString(
|
ok: false,
|
||||||
ptr,
|
detail: "Failed to send data to api",
|
||||||
userData,
|
};
|
||||||
distId,
|
|
||||||
dealerId,
|
|
||||||
drawId,
|
|
||||||
date,
|
|
||||||
);
|
|
||||||
const res = await sendBatchRequest(
|
|
||||||
session,
|
|
||||||
dealerId,
|
|
||||||
payload.draw,
|
|
||||||
total,
|
|
||||||
message,
|
|
||||||
);
|
|
||||||
let rj:
|
|
||||||
| APIRespnose<{
|
|
||||||
bookDtos: { bookId: string; requestId: number }[];
|
|
||||||
}>
|
|
||||||
| undefined = undefined;
|
|
||||||
try {
|
|
||||||
rj = (await res.json()) as any;
|
|
||||||
} catch (err) {
|
|
||||||
console.log("Encountered error while parsing post response");
|
|
||||||
console.log(res.status, err);
|
|
||||||
}
|
|
||||||
if (rj && rj.code === 200 && res.status === 200) {
|
|
||||||
ptr = jumped;
|
|
||||||
userResponseIds.push(
|
|
||||||
...rj.data.bookDtos.map((b) => ({
|
|
||||||
requestId: b.requestId as number,
|
|
||||||
bookId: b.bookId as string,
|
|
||||||
})),
|
|
||||||
);
|
|
||||||
successResponses++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
console.log("Failed to send send post request");
|
|
||||||
console.log(res.status, rj);
|
|
||||||
failedResponses++;
|
|
||||||
tries++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tries >= 3) {
|
|
||||||
if (userResponseIds.length > 0) {
|
|
||||||
const out = await deleteAllBookedEntries({
|
|
||||||
data: userResponseIds,
|
|
||||||
closeTime: payload.draw.closeTime,
|
|
||||||
dealerId,
|
|
||||||
drawId,
|
|
||||||
session,
|
|
||||||
});
|
|
||||||
console.log(await out.text());
|
|
||||||
}
|
|
||||||
throw new Error(`Failed to send data to api for user ${userId}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return userResponseIds;
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
// Wait for all user processes to complete
|
|
||||||
const results = await Promise.allSettled(userPromises);
|
|
||||||
|
|
||||||
// Process results
|
|
||||||
let hasErrors = false;
|
|
||||||
results.forEach((result) => {
|
|
||||||
if (result.status === "fulfilled") {
|
|
||||||
responsesIds.push(...result.value);
|
|
||||||
} else {
|
|
||||||
hasErrors = true;
|
|
||||||
console.log(`[!] Error processing user`);
|
|
||||||
console.log(result.reason);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (hasErrors) {
|
|
||||||
return {
|
|
||||||
ok: false,
|
|
||||||
detail: "Failed to post data to API for some users",
|
|
||||||
errors: [
|
|
||||||
{ message: "Failed to post data to API for some users" },
|
|
||||||
] as ServerError,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`[+] Finished sending ${payload.data.length} requests`);
|
|
||||||
console.log(`[?] Failed responses: ${failedResponses}`);
|
|
||||||
console.log(`[?] Success responses: ${successResponses}`);
|
|
||||||
return {
|
|
||||||
ok: true,
|
|
||||||
detail: "Successfully sent data to api",
|
|
||||||
data: responses,
|
|
||||||
};
|
|
||||||
} catch (err) {
|
|
||||||
console.log(err);
|
|
||||||
return {
|
|
||||||
ok: false,
|
|
||||||
detail: "Failed to send data to api",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function sendBatchRequest(
|
async function sendBatchRequest(
|
||||||
session: APISession,
|
session: APISession,
|
||||||
dealerId: number,
|
dealerId: number,
|
||||||
draw: Draw,
|
draw: Draw,
|
||||||
changedBalance: number,
|
changedBalance: number,
|
||||||
body: string,
|
body: string,
|
||||||
) {
|
) {
|
||||||
return Fetch(`${constants.SCRAP_API_URL}/v1/book/add-multiple`, {
|
return Fetch(`${constants.SCRAP_API_URL}/v1/book/add-multiple`, {
|
||||||
agent: new HttpsProxyAgent(`http://${session.ip}`),
|
agent: new HttpsProxyAgent(`http://${session.ip}`),
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
...constants.SCRAP_API_BASE_HEADERS,
|
...constants.SCRAP_API_BASE_HEADERS,
|
||||||
"Content-Type": "application/json;charset=UTF-8",
|
"Content-Type": "application/json;charset=UTF-8",
|
||||||
Authorization: session.sessionToken,
|
Authorization: session.sessionToken,
|
||||||
"User-Agent": getRandomUserAgent(),
|
"User-Agent": getRandomUserAgent(),
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
dealerId,
|
dealerId,
|
||||||
drawId: Number(draw.id.split(":")[1]),
|
drawId: Number(draw.id.split(":")[1]),
|
||||||
closeTime: draw.closeTime,
|
closeTime: draw.closeTime,
|
||||||
date: new Date().toISOString().split("T")[0],
|
date: new Date().toISOString().split("T")[0],
|
||||||
changedBalance,
|
changedBalance,
|
||||||
insertData: body,
|
insertData: body,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function mockSendBatchRequest(
|
async function mockSendBatchRequest(
|
||||||
session: APISession,
|
session: APISession,
|
||||||
dealerId: number,
|
dealerId: number,
|
||||||
draw: Draw,
|
draw: Draw,
|
||||||
changedBalance: number,
|
changedBalance: number,
|
||||||
body: string,
|
body: string,
|
||||||
) {
|
) {
|
||||||
console.log("----- Sending batch request ------");
|
console.log("----- Sending batch request ------");
|
||||||
console.log(session);
|
console.log(session);
|
||||||
console.log(dealerId);
|
console.log(dealerId);
|
||||||
console.log(draw);
|
console.log(draw);
|
||||||
console.log(changedBalance);
|
console.log(changedBalance);
|
||||||
console.log(body);
|
console.log(body);
|
||||||
console.log("----------------------------------");
|
console.log("----------------------------------");
|
||||||
// between 5 to 20 ms
|
// between 5 to 20 ms
|
||||||
await sleep(Math.floor(Math.random() * 1000) + 50);
|
await sleep(Math.floor(Math.random() * 1000) + 50);
|
||||||
// if (Math.random() < 0.005) {
|
// if (Math.random() < 0.005) {
|
||||||
// return new Response(
|
// return new Response(
|
||||||
// JSON.stringify({
|
// JSON.stringify({
|
||||||
// code: 500,
|
// code: 500,
|
||||||
// success: false,
|
// success: false,
|
||||||
// message: "Failed",
|
// message: "Failed",
|
||||||
// data: {},
|
// data: {},
|
||||||
// time: new Date().toISOString(),
|
// time: new Date().toISOString(),
|
||||||
// }),
|
// }),
|
||||||
// {
|
// {
|
||||||
// status: 500,
|
// status: 500,
|
||||||
// headers: { "Content-Type": "application/json" },
|
// headers: { "Content-Type": "application/json" },
|
||||||
// statusText: "Failed",
|
// statusText: "Failed",
|
||||||
// },
|
// },
|
||||||
// );
|
// );
|
||||||
// }
|
// }
|
||||||
return new Response(
|
return new Response(
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
code: 200,
|
code: 200,
|
||||||
success: true,
|
success: true,
|
||||||
message: "Success",
|
message: "Success",
|
||||||
data: {
|
data: {
|
||||||
bookDtos: body.split(";").map((e) => {
|
bookDtos: body.split(";").map((e) => {
|
||||||
return {
|
return {
|
||||||
bookId: getULID(),
|
bookId: getULID(),
|
||||||
requestId: +e.split(",")[0],
|
requestId: +e.split(",")[0],
|
||||||
};
|
};
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
time: new Date().toISOString(),
|
||||||
}),
|
}),
|
||||||
},
|
{
|
||||||
time: new Date().toISOString(),
|
status: 200,
|
||||||
}),
|
headers: { "Content-Type": "application/json" },
|
||||||
{
|
statusText: "OK",
|
||||||
status: 200,
|
},
|
||||||
headers: { "Content-Type": "application/json" },
|
);
|
||||||
statusText: "OK",
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function deleteAllBookedEntries({
|
async function deleteAllBookedEntries({
|
||||||
session,
|
session,
|
||||||
data,
|
data,
|
||||||
dealerId,
|
dealerId,
|
||||||
drawId,
|
drawId,
|
||||||
closeTime,
|
closeTime,
|
||||||
}: {
|
}: {
|
||||||
session: APISession;
|
session: APISession;
|
||||||
data: { bookId: string; requestId: number }[];
|
data: { bookId: string; requestId: number }[];
|
||||||
dealerId: number;
|
dealerId: number;
|
||||||
drawId: number;
|
drawId: number;
|
||||||
closeTime: string;
|
closeTime: string;
|
||||||
}) {
|
}) {
|
||||||
return Fetch(`${constants.SCRAP_API_URL}/v1/book/delete-multiple`, {
|
return Fetch(`${constants.SCRAP_API_URL}/v1/book/delete-multiple`, {
|
||||||
agent: new HttpsProxyAgent(`http://${session.ip}`),
|
agent: new HttpsProxyAgent(`http://${session.ip}`),
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
...constants.SCRAP_API_BASE_HEADERS,
|
...constants.SCRAP_API_BASE_HEADERS,
|
||||||
"Content-Type": "application/json;charset=UTF-8",
|
"Content-Type": "application/json;charset=UTF-8",
|
||||||
Authorization: session.sessionToken,
|
Authorization: session.sessionToken,
|
||||||
"User-Agent": getRandomUserAgent(),
|
"User-Agent": getRandomUserAgent(),
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
bookIds: data.map((e) => e.bookId),
|
bookIds: data.map((e) => e.bookId),
|
||||||
closeTime,
|
closeTime,
|
||||||
dealerId,
|
dealerId,
|
||||||
drawId,
|
drawId,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// export async function postDataToApi(payload: {
|
// export async function postDataToApi(payload: {
|
||||||
|
|||||||
@@ -2,446 +2,462 @@ import { dbApiPostData } from "$lib/server/db/apipostdata.db";
|
|||||||
import { dbApiUser } from "$lib/server/db/apiuser.db";
|
import { dbApiUser } from "$lib/server/db/apiuser.db";
|
||||||
import { getReducedFinalSheet } from "$lib/server/finalsheet.helpers";
|
import { getReducedFinalSheet } from "$lib/server/finalsheet.helpers";
|
||||||
import {
|
import {
|
||||||
adjustRatesIfDuplicatesFound,
|
adjustRatesIfDuplicatesFound,
|
||||||
pairRatesWithNumbers,
|
pairRatesWithNumbers,
|
||||||
removeNumbersWithRepeatingDigits,
|
removeNumbersWithRepeatingDigits,
|
||||||
splitRatesIntoSmallerForRowsWithLargerRates,
|
splitRatesIntoSmallerForRowsWithLargerRates,
|
||||||
spreadRatesForNumbersBetweenUsers,
|
spreadRatesForNumbersBetweenUsers,
|
||||||
} from "$lib/server/postdata/postdata.gen.helpers";
|
} from "$lib/server/postdata/postdata.gen.helpers";
|
||||||
import { getAllSessions } from "$lib/server/utils/session.service";
|
import { getAllSessions } from "$lib/server/utils/session.service";
|
||||||
import { getDefaultTotals, getULID } from "$lib/utils";
|
import { getDefaultTotals, getULID } from "$lib/utils";
|
||||||
import type {
|
import type {
|
||||||
ApiPostUser,
|
ApiPostUser,
|
||||||
ApiPostUserWithParent,
|
ApiPostUserWithParent,
|
||||||
PresetDataEntry,
|
PresetDataEntry,
|
||||||
PostDataEntry,
|
PostDataEntry,
|
||||||
PostDataFilters,
|
PostDataFilters,
|
||||||
PostDataHistoryFilters,
|
PostDataHistoryFilters,
|
||||||
ReducedFinalSheetData,
|
ReducedFinalSheetData,
|
||||||
ReducedFinalSheetRow,
|
ReducedFinalSheetRow,
|
||||||
ServerError,
|
ServerError,
|
||||||
} from "$lib/utils/data.types";
|
} from "$lib/utils/data.types";
|
||||||
import { dbPresetData } from "$lib/server/db/presetdata.db";
|
import { dbPresetData } from "$lib/server/db/presetdata.db";
|
||||||
import { getUsersBalance } from "$lib/server/external/api.scraping.helpers";
|
import { getUsersBalance } from "$lib/server/external/api.scraping.helpers";
|
||||||
|
|
||||||
function filterMatching(
|
function filterMatching(
|
||||||
data: ReducedFinalSheetRow[],
|
data: ReducedFinalSheetRow[],
|
||||||
min: number,
|
min: number,
|
||||||
max: number,
|
max: number,
|
||||||
sheetType: "first" | "second",
|
sheetType: "first" | "second",
|
||||||
) {
|
) {
|
||||||
let abNums = new Set<string>();
|
let abNums = new Set<string>();
|
||||||
let abcNums = new Set<string>();
|
let abcNums = new Set<string>();
|
||||||
|
|
||||||
for (const row of data) {
|
for (const row of data) {
|
||||||
if (row.prize[sheetType] >= min && row.prize[sheetType] <= max) {
|
if (row.prize[sheetType] >= min && row.prize[sheetType] <= max) {
|
||||||
abNums.add(`${row.number[0]}${row.number[1]}`);
|
abNums.add(`${row.number[0]}${row.number[1]}`);
|
||||||
abcNums.add(`${row.number[0]}${row.number[1]}${row.number[2]}`);
|
abcNums.add(`${row.number[0]}${row.number[1]}${row.number[2]}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
return { abNums, abcNums };
|
||||||
return { abNums, abcNums };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function updateBalanceOfPostUsers(users: ApiPostUserWithParent[]) {
|
export async function updateBalanceOfPostUsers(users: ApiPostUserWithParent[]) {
|
||||||
const sessions = await getAllSessions();
|
const sessions = await getAllSessions();
|
||||||
const balances = [] as { id: string; balance: number }[];
|
console.log(sessions);
|
||||||
for (const user of users) {
|
console.log(`Fetching balances`);
|
||||||
const session = sessions.find((e) => e.value.userId === user.id);
|
const balances = [] as { id: string; balance: number }[];
|
||||||
const jwt = session?.value.sessionToken;
|
for (const user of users) {
|
||||||
if (!jwt) {
|
console.log(`Finding ${user.id} in sessions`);
|
||||||
return {
|
const session = sessions.find((e) => e.value.userId.includes(user.id));
|
||||||
ok: false,
|
const jwt = session?.value.sessionToken;
|
||||||
detail: `Session not found for user ${user.userId}`,
|
if (!jwt) {
|
||||||
};
|
return {
|
||||||
|
ok: false,
|
||||||
|
detail: `Session not found for user ${user.userId}`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
const uid = session.value.userId.toString();
|
||||||
|
console.log(`Found ${uid} in session`);
|
||||||
|
const out = await getUsersBalance(+uid.split(":")[1], jwt);
|
||||||
|
if (!out) {
|
||||||
|
return {
|
||||||
|
ok: false,
|
||||||
|
detail: `Error fetching balance for user ${user.userName}`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
balances.push({ id: uid, balance: out });
|
||||||
}
|
}
|
||||||
const out = await getUsersBalance(+user.id.split(":")[1], jwt);
|
console.log(`Updating balances`);
|
||||||
if (!out) {
|
console.log(balances);
|
||||||
return {
|
await dbApiUser.updatePostUsersBalances(balances);
|
||||||
ok: false,
|
return {
|
||||||
detail: `Error fetching balance for user ${user.userName}`,
|
ok: true,
|
||||||
};
|
detail: "",
|
||||||
}
|
data: users.map((u) => {
|
||||||
balances.push({ id: user.id, balance: out });
|
const bal = balances.find((b) => b.id === u.id);
|
||||||
}
|
if (!bal) {
|
||||||
await dbApiUser.updatePostUsersBalances(balances);
|
console.log(`ERROR: Balance not found for user ${u.userName}`);
|
||||||
return {
|
}
|
||||||
ok: true,
|
return { ...u, balance: bal?.balance ?? 0 };
|
||||||
detail: "",
|
}),
|
||||||
data: users.map((u) => {
|
};
|
||||||
const bal = balances.find((b) => b.id === u.id);
|
|
||||||
if (!bal) {
|
|
||||||
console.log(`ERROR: Balance not found for user ${u.userName}`);
|
|
||||||
}
|
|
||||||
return { ...u, balance: bal?.balance ?? 0 };
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchDataForPosting(
|
export async function fetchDataForPosting(
|
||||||
date: string,
|
date: string,
|
||||||
input: PostDataFilters,
|
input: PostDataFilters,
|
||||||
users: ApiPostUser[],
|
users: ApiPostUser[],
|
||||||
) {
|
) {
|
||||||
console.log(`The input ${JSON.stringify(input, null, 2)}`);
|
console.log(`The input ${JSON.stringify(input, null, 2)}`);
|
||||||
const { minPrize, maxPrize } = input;
|
const { minPrize, maxPrize } = input;
|
||||||
const draw = input.draw!;
|
const draw = input.draw!;
|
||||||
const fsData = {
|
const fsData = {
|
||||||
id: getULID(),
|
id: getULID(),
|
||||||
date,
|
date,
|
||||||
drawId: draw.id,
|
drawId: draw.id,
|
||||||
data: [],
|
|
||||||
totals: getDefaultTotals(),
|
|
||||||
} as ReducedFinalSheetData;
|
|
||||||
if (!draw) {
|
|
||||||
return {
|
|
||||||
ok: false,
|
|
||||||
detail: `Draw for the passed draw ID not found`,
|
|
||||||
data: [],
|
|
||||||
users: [],
|
|
||||||
errors: [
|
|
||||||
{ message: `Draw for the passed draw ID not found` },
|
|
||||||
] as ServerError,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const data = await getReducedFinalSheet(fsData);
|
|
||||||
if (!data.ok) {
|
|
||||||
return {
|
|
||||||
ok: false,
|
|
||||||
detail: `Error compiling final sheet`,
|
|
||||||
data: [],
|
|
||||||
users: [],
|
|
||||||
errors: data.errors,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log("[+] Filtering the fs data to get the numbers");
|
|
||||||
const filteredF = filterMatching(fsData.data, minPrize, maxPrize, "first");
|
|
||||||
console.log(
|
|
||||||
`Filtered data: ${filteredF.abNums.size}; ${filteredF.abcNums.size}`,
|
|
||||||
);
|
|
||||||
|
|
||||||
// ------------------------------------------
|
|
||||||
|
|
||||||
let _abNums = new Set<string>(),
|
|
||||||
_abcNums = new Set<string>();
|
|
||||||
for (const each of filteredF.abNums) _abNums.add(each);
|
|
||||||
for (const each of filteredF.abcNums) _abcNums.add(each);
|
|
||||||
let abNums = Array.from(_abNums),
|
|
||||||
abcNums = Array.from(_abcNums);
|
|
||||||
|
|
||||||
if (draw.filterDuplicatesWhilePosting === true) {
|
|
||||||
console.log(`[+] Removing numbers that have repeating digits`);
|
|
||||||
console.log(`[=] Original : AB: ${abNums.length}, ABC: ${abcNums.length}`);
|
|
||||||
abNums = removeNumbersWithRepeatingDigits(abNums);
|
|
||||||
abcNums = removeNumbersWithRepeatingDigits(abcNums);
|
|
||||||
}
|
|
||||||
console.log(`[=] AB: ${abNums.length}, ABC: ${abcNums.length}`);
|
|
||||||
|
|
||||||
console.log(`Fetching preset data`);
|
|
||||||
const presetData = await dbPresetData.getDataGroupedBySheetByDraw(
|
|
||||||
date,
|
|
||||||
+draw.id.split(":")[1],
|
|
||||||
);
|
|
||||||
console.log(`${presetData.all.length} preset entries found`);
|
|
||||||
|
|
||||||
for (let tries = 0; tries < 3; tries++) {
|
|
||||||
console.log(`[✍️] Try ${tries + 1} of generating the result`);
|
|
||||||
const out = await generatePostDataArrayFromBaseInfo(
|
|
||||||
input,
|
|
||||||
users,
|
|
||||||
abNums,
|
|
||||||
abcNums,
|
|
||||||
presetData,
|
|
||||||
);
|
|
||||||
if (out.ok) {
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
if (out.detail.includes("Not enough balance")) {
|
|
||||||
return {
|
|
||||||
ok: false,
|
|
||||||
detail: `Users don't have enough balance to post the data, try reducing the rates`,
|
|
||||||
data: [],
|
data: [],
|
||||||
users: [],
|
totals: getDefaultTotals(),
|
||||||
};
|
} as ReducedFinalSheetData;
|
||||||
|
if (!draw) {
|
||||||
|
return {
|
||||||
|
ok: false,
|
||||||
|
detail: `Draw for the passed draw ID not found`,
|
||||||
|
data: [],
|
||||||
|
users: [],
|
||||||
|
errors: [
|
||||||
|
{ message: `Draw for the passed draw ID not found` },
|
||||||
|
] as ServerError,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
const data = await getReducedFinalSheet(fsData);
|
||||||
|
if (!data.ok) {
|
||||||
|
return {
|
||||||
|
ok: false,
|
||||||
|
detail: `Error compiling final sheet`,
|
||||||
|
data: [],
|
||||||
|
users: [],
|
||||||
|
errors: data.errors,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
console.log("[+] Filtering the fs data to get the numbers");
|
||||||
ok: false,
|
const filteredF = filterMatching(fsData.data, minPrize, maxPrize, "first");
|
||||||
detail: `Could not generate data, please try adjusting the filters`,
|
console.log(
|
||||||
data: [],
|
`Filtered data: ${filteredF.abNums.size}; ${filteredF.abcNums.size}`,
|
||||||
};
|
);
|
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
|
||||||
|
let _abNums = new Set<string>(),
|
||||||
|
_abcNums = new Set<string>();
|
||||||
|
for (const each of filteredF.abNums) _abNums.add(each);
|
||||||
|
for (const each of filteredF.abcNums) _abcNums.add(each);
|
||||||
|
let abNums = Array.from(_abNums),
|
||||||
|
abcNums = Array.from(_abcNums);
|
||||||
|
|
||||||
|
if (draw.filterDuplicatesWhilePosting === true) {
|
||||||
|
console.log(`[+] Removing numbers that have repeating digits`);
|
||||||
|
console.log(
|
||||||
|
`[=] Original : AB: ${abNums.length}, ABC: ${abcNums.length}`,
|
||||||
|
);
|
||||||
|
abNums = removeNumbersWithRepeatingDigits(abNums);
|
||||||
|
abcNums = removeNumbersWithRepeatingDigits(abcNums);
|
||||||
|
}
|
||||||
|
console.log(`[=] AB: ${abNums.length}, ABC: ${abcNums.length}`);
|
||||||
|
|
||||||
|
console.log(`Fetching preset data`);
|
||||||
|
const presetData = await dbPresetData.getDataGroupedBySheetByDraw(
|
||||||
|
date,
|
||||||
|
+draw.id.split(":")[1],
|
||||||
|
);
|
||||||
|
console.log(`${presetData.all.length} preset entries found`);
|
||||||
|
|
||||||
|
for (let tries = 0; tries < 3; tries++) {
|
||||||
|
console.log(`[✍️] Try ${tries + 1} of generating the result`);
|
||||||
|
const out = await generatePostDataArrayFromBaseInfo(
|
||||||
|
input,
|
||||||
|
users,
|
||||||
|
abNums,
|
||||||
|
abcNums,
|
||||||
|
presetData,
|
||||||
|
);
|
||||||
|
if (out.ok) {
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
if (out.detail.includes("Not enough balance")) {
|
||||||
|
return {
|
||||||
|
ok: false,
|
||||||
|
detail: `Users don't have enough balance to post the data, try reducing the rates`,
|
||||||
|
data: [],
|
||||||
|
users: [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
ok: false,
|
||||||
|
detail: `Could not generate data, please try adjusting the filters`,
|
||||||
|
data: [],
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function generatePostDataArrayFromBaseInfo(
|
export async function generatePostDataArrayFromBaseInfo(
|
||||||
input: PostDataFilters,
|
input: PostDataFilters,
|
||||||
users: ApiPostUser[],
|
users: ApiPostUser[],
|
||||||
abNums: string[],
|
abNums: string[],
|
||||||
abcNums: string[],
|
abcNums: string[],
|
||||||
presetData: {
|
presetData: {
|
||||||
all: PostDataEntry[];
|
all: PostDataEntry[];
|
||||||
abData: PresetDataEntry[];
|
abData: PresetDataEntry[];
|
||||||
abcData: PresetDataEntry[];
|
abcData: PresetDataEntry[];
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
console.log("[+] Spreading the rates for the numbers for all post user");
|
console.log("[+] Spreading the rates for the numbers for all post user");
|
||||||
const abData = splitRatesIntoSmallerForRowsWithLargerRates(
|
const abData = splitRatesIntoSmallerForRowsWithLargerRates(
|
||||||
spreadRatesForNumbersBetweenUsers(
|
spreadRatesForNumbersBetweenUsers(
|
||||||
adjustRatesIfDuplicatesFound(
|
adjustRatesIfDuplicatesFound(
|
||||||
pairRatesWithNumbers(abNums, input.twoDigitRates),
|
pairRatesWithNumbers(abNums, input.twoDigitRates),
|
||||||
presetData.abData,
|
presetData.abData,
|
||||||
),
|
),
|
||||||
users.map((u) => u.userId),
|
users.map((u) => u.userId),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
const abcData = splitRatesIntoSmallerForRowsWithLargerRates(
|
const abcData = splitRatesIntoSmallerForRowsWithLargerRates(
|
||||||
spreadRatesForNumbersBetweenUsers(
|
spreadRatesForNumbersBetweenUsers(
|
||||||
adjustRatesIfDuplicatesFound(
|
adjustRatesIfDuplicatesFound(
|
||||||
pairRatesWithNumbers(abcNums, input.threeDigitRates),
|
pairRatesWithNumbers(abcNums, input.threeDigitRates),
|
||||||
presetData.abcData,
|
presetData.abcData,
|
||||||
),
|
),
|
||||||
users.map((u) => u.userId),
|
users.map((u) => u.userId),
|
||||||
),
|
),
|
||||||
);
|
|
||||||
|
|
||||||
// ------------------------------------------
|
|
||||||
|
|
||||||
console.log(`[+] Adding ${abData.length} ab entries to final list`);
|
|
||||||
console.log(`[+] Adding ${abcData.length} abc entries to final list`);
|
|
||||||
|
|
||||||
const result = [] as PostDataEntry[];
|
|
||||||
const alreadyPresent = new Set<string>();
|
|
||||||
for (const each of abData) {
|
|
||||||
alreadyPresent.add(each.number);
|
|
||||||
result.push(each);
|
|
||||||
}
|
|
||||||
for (const each of abcData) {
|
|
||||||
alreadyPresent.add(each.number);
|
|
||||||
result.push(each);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------
|
|
||||||
|
|
||||||
const balanceCounts = {} as Record<string, number>;
|
|
||||||
for (const each of result) {
|
|
||||||
const uid = each.userId ?? "";
|
|
||||||
if (balanceCounts[uid] === undefined) {
|
|
||||||
balanceCounts[uid] = 0;
|
|
||||||
}
|
|
||||||
balanceCounts[uid] += each.first + each.second;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------
|
|
||||||
|
|
||||||
console.log(
|
|
||||||
`[+] Appending up to ${presetData.all.length} entries that are not ab, abc`,
|
|
||||||
);
|
|
||||||
for (const entry of presetData.all) {
|
|
||||||
if (
|
|
||||||
alreadyPresent.has(entry.number) ||
|
|
||||||
(entry.first < 5 && entry.second < 5)
|
|
||||||
) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const randomUserId = users[Math.floor(Math.random() * users.length)].userId;
|
|
||||||
if (balanceCounts[randomUserId] === undefined) {
|
|
||||||
balanceCounts[randomUserId] = 0;
|
|
||||||
}
|
|
||||||
balanceCounts[randomUserId] += entry.first + entry.second;
|
|
||||||
result.push({ ...entry, userId: randomUserId });
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------
|
|
||||||
|
|
||||||
const usersTotalbalance = users.reduce((a, b) => a + (b.balance ?? 0), 0);
|
|
||||||
let totalAmtForPostingData = Object.values(balanceCounts).reduce(
|
|
||||||
(acc, curr) => acc + curr,
|
|
||||||
0,
|
|
||||||
);
|
|
||||||
if (usersTotalbalance < totalAmtForPostingData) {
|
|
||||||
return {
|
|
||||||
ok: false,
|
|
||||||
detail: `Not enough balance to book overall with ${usersTotalbalance} < ${totalAmtForPostingData}`,
|
|
||||||
data: [],
|
|
||||||
users: [],
|
|
||||||
errors: [
|
|
||||||
{ message: `Not enough balance to book overall` },
|
|
||||||
] as ServerError,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function isDistributionUnbalanced() {
|
|
||||||
let out = false;
|
|
||||||
for (const key in balanceCounts) {
|
|
||||||
if (
|
|
||||||
balanceCounts[key] > (users.find((u) => u.userId === key)?.balance ?? 0)
|
|
||||||
) {
|
|
||||||
out = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let tries = 0; tries < 5; tries++) {
|
|
||||||
console.log(
|
|
||||||
`Balance counts start : ${JSON.stringify(balanceCounts, null, 2)}`,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
rebalancePostDataListByBalanceOfUsers(balanceCounts, users, result);
|
// ------------------------------------------
|
||||||
|
|
||||||
console.log(`Balance counts final : ${JSON.stringify(balanceCounts)}`);
|
console.log(`[+] Adding ${abData.length} ab entries to final list`);
|
||||||
|
console.log(`[+] Adding ${abcData.length} abc entries to final list`);
|
||||||
|
|
||||||
let totalAmtForPostingDataAfterRebalance = Object.values(
|
const result = [] as PostDataEntry[];
|
||||||
balanceCounts,
|
const alreadyPresent = new Set<string>();
|
||||||
).reduce((acc, curr) => acc + curr, 0);
|
for (const each of abData) {
|
||||||
|
alreadyPresent.add(each.number);
|
||||||
|
result.push(each);
|
||||||
|
}
|
||||||
|
for (const each of abcData) {
|
||||||
|
alreadyPresent.add(each.number);
|
||||||
|
result.push(each);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
|
||||||
|
const balanceCounts = {} as Record<string, number>;
|
||||||
|
for (const each of result) {
|
||||||
|
const uid = each.userId ?? "";
|
||||||
|
if (balanceCounts[uid] === undefined) {
|
||||||
|
balanceCounts[uid] = 0;
|
||||||
|
}
|
||||||
|
balanceCounts[uid] += each.first + each.second;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
`Total amount for posting data after rebalance: ${totalAmtForPostingDataAfterRebalance}`,
|
`[+] Appending up to ${presetData.all.length} entries that are not ab, abc`,
|
||||||
`Total balance of users: ${JSON.stringify(users.map((u) => ({ un: u.userName, b: u.balance })))}`,
|
|
||||||
);
|
);
|
||||||
|
for (const entry of presetData.all) {
|
||||||
if (!isDistributionUnbalanced()) {
|
if (
|
||||||
console.log(`[+] Distribution is balanced`);
|
alreadyPresent.has(entry.number) ||
|
||||||
break;
|
(entry.first < 5 && entry.second < 5)
|
||||||
|
) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const randomUserId =
|
||||||
|
users[Math.floor(Math.random() * users.length)].userId;
|
||||||
|
if (balanceCounts[randomUserId] === undefined) {
|
||||||
|
balanceCounts[randomUserId] = 0;
|
||||||
|
}
|
||||||
|
balanceCounts[randomUserId] += entry.first + entry.second;
|
||||||
|
result.push({ ...entry, userId: randomUserId });
|
||||||
}
|
}
|
||||||
console.log(`[!] Rebalancing again`);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isDistributionUnbalanced()) {
|
// ------------------------------------------
|
||||||
|
|
||||||
|
const usersTotalbalance = users.reduce((a, b) => a + (b.balance ?? 0), 0);
|
||||||
|
let totalAmtForPostingData = Object.values(balanceCounts).reduce(
|
||||||
|
(acc, curr) => acc + curr,
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
if (usersTotalbalance < totalAmtForPostingData) {
|
||||||
|
return {
|
||||||
|
ok: false,
|
||||||
|
detail: `Not enough balance to book overall with ${usersTotalbalance} < ${totalAmtForPostingData}`,
|
||||||
|
data: [],
|
||||||
|
users: [],
|
||||||
|
errors: [
|
||||||
|
{ message: `Not enough balance to book overall` },
|
||||||
|
] as ServerError,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function isDistributionUnbalanced() {
|
||||||
|
let out = false;
|
||||||
|
for (const key in balanceCounts) {
|
||||||
|
if (
|
||||||
|
balanceCounts[key] >
|
||||||
|
(users.find((u) => u.userId === key)?.balance ?? 0)
|
||||||
|
) {
|
||||||
|
out = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let tries = 0; tries < 5; tries++) {
|
||||||
|
console.log(
|
||||||
|
`Balance counts start : ${JSON.stringify(balanceCounts, null, 2)}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
rebalancePostDataListByBalanceOfUsers(balanceCounts, users, result);
|
||||||
|
|
||||||
|
console.log(`Balance counts final : ${JSON.stringify(balanceCounts)}`);
|
||||||
|
|
||||||
|
let totalAmtForPostingDataAfterRebalance = Object.values(
|
||||||
|
balanceCounts,
|
||||||
|
).reduce((acc, curr) => acc + curr, 0);
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
`Total amount for posting data after rebalance: ${totalAmtForPostingDataAfterRebalance}`,
|
||||||
|
`Total balance of users: ${JSON.stringify(users.map((u) => ({ un: u.userName, b: u.balance })))}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!isDistributionUnbalanced()) {
|
||||||
|
console.log(`[+] Distribution is balanced`);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
console.log(`[!] Rebalancing again`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isDistributionUnbalanced()) {
|
||||||
|
return {
|
||||||
|
ok: false,
|
||||||
|
detail: `Please regenerate dataset as the some users have not enough balance to book their entries`,
|
||||||
|
data: [],
|
||||||
|
users: [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
|
||||||
|
console.log(`[+] Shuffling ${result.length} entries for posting`);
|
||||||
|
shuffleArray(result);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
ok: false,
|
ok: true,
|
||||||
detail: `Please regenerate dataset as the some users have not enough balance to book their entries`,
|
detail: `Fetched the data successfully`,
|
||||||
data: [],
|
data: result,
|
||||||
users: [],
|
users,
|
||||||
|
errors: undefined,
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------
|
|
||||||
|
|
||||||
console.log(`[+] Shuffling ${result.length} entries for posting`);
|
|
||||||
shuffleArray(result);
|
|
||||||
|
|
||||||
return {
|
|
||||||
ok: true,
|
|
||||||
detail: `Fetched the data successfully`,
|
|
||||||
data: result,
|
|
||||||
users,
|
|
||||||
errors: undefined,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function shuffleArray<T>(array: T[]): T[] {
|
function shuffleArray<T>(array: T[]): T[] {
|
||||||
for (let i = array.length - 1; i > 0; i--) {
|
for (let i = array.length - 1; i > 0; i--) {
|
||||||
const j = Math.floor(Math.random() * (i + 1));
|
const j = Math.floor(Math.random() * (i + 1));
|
||||||
[array[i], array[j]] = [array[j], array[i]];
|
[array[i], array[j]] = [array[j], array[i]];
|
||||||
}
|
}
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function rebalancePostDataListByBalanceOfUsers(
|
export function rebalancePostDataListByBalanceOfUsers(
|
||||||
balanceCounts: Record<string, number>,
|
balanceCounts: Record<string, number>,
|
||||||
users: ApiPostUser[],
|
users: ApiPostUser[],
|
||||||
result: PostDataEntry[],
|
result: PostDataEntry[],
|
||||||
) {
|
) {
|
||||||
console.log(
|
|
||||||
`[+] Checking if the users have enough balance to book their assigned data`,
|
|
||||||
);
|
|
||||||
|
|
||||||
for (const user of users) {
|
|
||||||
const usersBalance = user.balance ?? 0;
|
|
||||||
const dueForUser = balanceCounts[user.userId] ?? 0;
|
|
||||||
if (usersBalance === 0) {
|
|
||||||
console.log(`\n[!] ${user.userName} has no balance\n`);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (usersBalance >= dueForUser) {
|
|
||||||
console.log(
|
|
||||||
`[✅] ${user.userName} can book the data of ${usersBalance} > ${dueForUser} `,
|
|
||||||
);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
console.log(
|
console.log(
|
||||||
`[!❎!] ${user.userName} can't book it all ${usersBalance} < ${dueForUser}`,
|
`[+] Checking if the users have enough balance to book their assigned data`,
|
||||||
);
|
);
|
||||||
|
|
||||||
const difference = dueForUser - usersBalance;
|
for (const user of users) {
|
||||||
let differenceLeft = Number(difference); // make a copy
|
const usersBalance = user.balance ?? 0;
|
||||||
const entriesToMove = result
|
const dueForUser = balanceCounts[user.userId] ?? 0;
|
||||||
.filter((r) => {
|
if (usersBalance === 0) {
|
||||||
if (r.userId === user.userId && differenceLeft > 0) {
|
console.log(`\n[!] ${user.userName} has no balance\n`);
|
||||||
differenceLeft -= r.first + r.second;
|
continue;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
})
|
if (usersBalance >= dueForUser) {
|
||||||
.map((r) => r.id);
|
console.log(
|
||||||
console.log(`Have to move ${entriesToMove.length} entries to other users`);
|
`[✅] ${user.userName} can book the data of ${usersBalance} > ${dueForUser} `,
|
||||||
|
);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
console.log(
|
||||||
|
`[!❎!] ${user.userName} can't book it all ${usersBalance} < ${dueForUser}`,
|
||||||
|
);
|
||||||
|
|
||||||
// find a user who has enough balance
|
const difference = dueForUser - usersBalance;
|
||||||
|
let differenceLeft = Number(difference); // make a copy
|
||||||
|
const entriesToMove = result
|
||||||
|
.filter((r) => {
|
||||||
|
if (r.userId === user.userId && differenceLeft > 0) {
|
||||||
|
differenceLeft -= r.first + r.second;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.map((r) => r.id);
|
||||||
|
console.log(
|
||||||
|
`Have to move ${entriesToMove.length} entries to other users`,
|
||||||
|
);
|
||||||
|
|
||||||
const userWithEnoughBalance = users.find((u) => {
|
// find a user who has enough balance
|
||||||
return (
|
|
||||||
(u.balance ?? 0) - balanceCounts[u.userId] >= difference &&
|
const userWithEnoughBalance = users.find((u) => {
|
||||||
u.userId !== user.userId
|
return (
|
||||||
);
|
(u.balance ?? 0) - balanceCounts[u.userId] >= difference &&
|
||||||
});
|
u.userId !== user.userId
|
||||||
if (!userWithEnoughBalance) {
|
);
|
||||||
return {
|
});
|
||||||
ok: false,
|
if (!userWithEnoughBalance) {
|
||||||
detail: `No user found with enough balance to cover balance shortage of ${difference} for ${user.userName}`,
|
return {
|
||||||
data: [],
|
ok: false,
|
||||||
};
|
detail: `No user found with enough balance to cover balance shortage of ${difference} for ${user.userName}`,
|
||||||
|
data: [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
console.log(
|
||||||
|
`Dude has enough balance to take on this other user's expenses ': ${JSON.stringify(userWithEnoughBalance)}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
for (let i = 0; i < result.length; i++) {
|
||||||
|
if (!entriesToMove.includes(result[i].id)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const entry = result[i];
|
||||||
|
let amountMoved = 0;
|
||||||
|
if (entry.userId !== user.userId) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
entry.userId = userWithEnoughBalance.userId;
|
||||||
|
balanceCounts[userWithEnoughBalance.userId] +=
|
||||||
|
entry.first + entry.second;
|
||||||
|
balanceCounts[user.userId] -= entry.first + entry.second;
|
||||||
|
amountMoved += entry.first + entry.second;
|
||||||
|
if (amountMoved >= difference) {
|
||||||
|
// don't move more than the difference'
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(
|
||||||
|
`[+] Moved ${entriesToMove.length} entries to ${userWithEnoughBalance.userName}`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
console.log(
|
|
||||||
`Dude has enough balance to take on this other user's expenses ': ${JSON.stringify(userWithEnoughBalance)}`,
|
|
||||||
);
|
|
||||||
|
|
||||||
for (let i = 0; i < result.length; i++) {
|
|
||||||
if (!entriesToMove.includes(result[i].id)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const entry = result[i];
|
|
||||||
let amountMoved = 0;
|
|
||||||
if (entry.userId !== user.userId) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
entry.userId = userWithEnoughBalance.userId;
|
|
||||||
balanceCounts[userWithEnoughBalance.userId] += entry.first + entry.second;
|
|
||||||
balanceCounts[user.userId] -= entry.first + entry.second;
|
|
||||||
amountMoved += entry.first + entry.second;
|
|
||||||
if (amountMoved >= difference) {
|
|
||||||
// don't move more than the difference'
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
console.log(
|
|
||||||
`[+] Moved ${entriesToMove.length} entries to ${userWithEnoughBalance.userName}`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchPostDataHistory(input: PostDataHistoryFilters) {
|
export async function fetchPostDataHistory(input: PostDataHistoryFilters) {
|
||||||
const { draw, date } = input;
|
const { draw, date } = input;
|
||||||
console.log(`Fetching post data from HISTORY for draw: ${date} - ${draw.id}`);
|
console.log(
|
||||||
const found = await dbApiPostData.getPostDataByDraw(date, draw.id);
|
`Fetching post data from HISTORY for draw: ${date} - ${draw.id}`,
|
||||||
if (!found) {
|
);
|
||||||
return { data: [], users: [], ok: false, detail: "Data not found" };
|
const found = await dbApiPostData.getPostDataByDraw(date, draw.id);
|
||||||
}
|
if (!found) {
|
||||||
console.log(
|
return { data: [], users: [], ok: false, detail: "Data not found" };
|
||||||
`Data found for the passed draw: ${date} - ${draw.id}, returning that`,
|
|
||||||
);
|
|
||||||
const users = await dbApiUser.getAllPostUsers();
|
|
||||||
const uniqueUserIds = [] as string[];
|
|
||||||
for (const each of found) {
|
|
||||||
if (!each.userId || uniqueUserIds.includes(each.userId)) {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
uniqueUserIds.push(each.userId);
|
console.log(
|
||||||
}
|
`Data found for the passed draw: ${date} - ${draw.id}, returning that`,
|
||||||
return {
|
);
|
||||||
data: found,
|
const users = await dbApiUser.getAllPostUsers();
|
||||||
users: users.filter((u) => uniqueUserIds.includes(u.userId)),
|
const uniqueUserIds = [] as string[];
|
||||||
ok: true,
|
for (const each of found) {
|
||||||
detail: "Data found",
|
if (!each.userId || uniqueUserIds.includes(each.userId)) {
|
||||||
};
|
continue;
|
||||||
|
}
|
||||||
|
uniqueUserIds.push(each.userId);
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
data: found,
|
||||||
|
users: users.filter((u) => uniqueUserIds.includes(u.userId)),
|
||||||
|
ok: true,
|
||||||
|
detail: "Data found",
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,108 +7,110 @@ import { z } from "zod";
|
|||||||
import { dbApiUser } from "$lib/server/db/apiuser.db";
|
import { dbApiUser } from "$lib/server/db/apiuser.db";
|
||||||
import type { ServerError } from "$lib/utils/data.types";
|
import type { ServerError } from "$lib/utils/data.types";
|
||||||
import {
|
import {
|
||||||
isSessionValidInStore,
|
isSessionValidInStore,
|
||||||
removeSessionFromStore,
|
removeSessionFromStore,
|
||||||
setSessionToRedis,
|
setSessionToRedis,
|
||||||
} from "$lib/server/utils/session.service";
|
} from "$lib/server/utils/session.service";
|
||||||
|
|
||||||
export const apiAuthRouter = createTRPCRouter({
|
export const apiAuthRouter = createTRPCRouter({
|
||||||
getCaptcha: protectedProcedure.mutation(async () => {
|
getCaptcha: protectedProcedure.mutation(async () => {
|
||||||
try {
|
try {
|
||||||
const uuid = getUUID();
|
const uuid = getUUID();
|
||||||
const res = await fetch(
|
const res = await fetch(
|
||||||
`${constants.SCRAP_API_URL}/verify/image?uuid=${uuid}`,
|
`${constants.SCRAP_API_URL}/verify/image?uuid=${uuid}`,
|
||||||
{
|
{
|
||||||
headers: {
|
headers: {
|
||||||
...constants.SCRAP_API_BASE_HEADERS,
|
...constants.SCRAP_API_BASE_HEADERS,
|
||||||
Accept:
|
Accept: "image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8",
|
||||||
"image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8",
|
},
|
||||||
},
|
},
|
||||||
},
|
);
|
||||||
);
|
const bloob = await res.blob();
|
||||||
const bloob = await res.blob();
|
const imageBuffer = Buffer.from(await bloob.arrayBuffer());
|
||||||
const imageBuffer = Buffer.from(await bloob.arrayBuffer());
|
const base64String = imageBuffer.toString("base64");
|
||||||
const base64String = imageBuffer.toString("base64");
|
return { id: uuid, image: base64String };
|
||||||
return { id: uuid, image: base64String };
|
} catch (err) {
|
||||||
} catch (err) {
|
console.log(err);
|
||||||
console.log(err);
|
throw new TRPCError({
|
||||||
throw new TRPCError({
|
code: "INTERNAL_SERVER_ERROR",
|
||||||
code: "INTERNAL_SERVER_ERROR",
|
message: "Error getting captcha image.",
|
||||||
message: "Error getting captcha image.",
|
});
|
||||||
});
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
|
|
||||||
getNewSession: protectedProcedure
|
|
||||||
.input(
|
|
||||||
z.object({
|
|
||||||
captchaId: z.string().min(1),
|
|
||||||
captchaAnswer: z.string().min(1),
|
|
||||||
userId: z.string().optional(),
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.mutation(async ({ input }) => {
|
|
||||||
console.log("[=] Getting new session... ", input);
|
|
||||||
try {
|
|
||||||
const { captchaId, captchaAnswer } = input;
|
|
||||||
let { userId, userType, password } =
|
|
||||||
await dbApiUser.getRandomDistributor();
|
|
||||||
|
|
||||||
if (input.userId) {
|
|
||||||
let _user = await dbApiUser.getUserById(input.userId);
|
|
||||||
console.log("[=] User :: ", _user?.userId);
|
|
||||||
if (!_user) {
|
|
||||||
return {
|
|
||||||
success: false,
|
|
||||||
errors: [{ message: "User not found." }],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
userId = _user.userId;
|
|
||||||
userType = _user.userType;
|
|
||||||
password = _user.password;
|
|
||||||
}
|
}
|
||||||
console.log(`[=] Getting session token for user ${userId}...`);
|
|
||||||
const token = await getSessionToken({
|
|
||||||
code: captchaAnswer,
|
|
||||||
verifyToken: captchaId,
|
|
||||||
userId: userId,
|
|
||||||
userType: userType,
|
|
||||||
password: password,
|
|
||||||
});
|
|
||||||
console.log("[=] Token Response :: ", JSON.stringify(token, null, 2));
|
|
||||||
if (!token.ok) {
|
|
||||||
return {
|
|
||||||
success: false,
|
|
||||||
errors: [{ message: token.message }],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
await setSessionToRedis(token.message, input.userId ?? "");
|
|
||||||
return { success: true, errors: [] as ServerError };
|
|
||||||
} catch (err) {
|
|
||||||
console.log(err);
|
|
||||||
throw new TRPCError({
|
|
||||||
code: "INTERNAL_SERVER_ERROR",
|
|
||||||
message: "Error getting new session.",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}),
|
}),
|
||||||
|
|
||||||
isApiSessionValid: protectedProcedure
|
getNewSession: protectedProcedure
|
||||||
.input(
|
.input(
|
||||||
z.object({
|
z.object({
|
||||||
checkingUserSession: z.boolean(),
|
captchaId: z.string().min(1),
|
||||||
userId: z.string().optional(),
|
captchaAnswer: z.string().min(1),
|
||||||
}),
|
userId: z.string().optional(),
|
||||||
)
|
}),
|
||||||
.query(async ({ input }) => {
|
)
|
||||||
return { valid: await isSessionValidInStore(input.userId) };
|
.mutation(async ({ input }) => {
|
||||||
}),
|
console.log("[=] Getting new session... ", input);
|
||||||
|
try {
|
||||||
|
const { captchaId, captchaAnswer } = input;
|
||||||
|
let { userId, userType, password } =
|
||||||
|
await dbApiUser.getRandomDistributor();
|
||||||
|
|
||||||
logoutUser: protectedProcedure
|
if (input.userId) {
|
||||||
.input(z.object({ userId: z.string().optional() }))
|
let _user = await dbApiUser.getUserById(input.userId);
|
||||||
.mutation(async ({ input }) => {
|
console.log("[=] User :: ", _user?.userId);
|
||||||
const { userId } = input;
|
if (!_user) {
|
||||||
await removeSessionFromStore(userId);
|
return {
|
||||||
return { success: true, errors: [] as ServerError };
|
success: false,
|
||||||
}),
|
errors: [{ message: "User not found." }],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
userId = _user.userId;
|
||||||
|
userType = _user.userType;
|
||||||
|
password = _user.password;
|
||||||
|
}
|
||||||
|
console.log(`[=] Getting session token for user ${userId}...`);
|
||||||
|
const token = await getSessionToken({
|
||||||
|
code: captchaAnswer,
|
||||||
|
verifyToken: captchaId,
|
||||||
|
userId: userId,
|
||||||
|
userType: userType,
|
||||||
|
password: password,
|
||||||
|
});
|
||||||
|
console.log(
|
||||||
|
"[=] Token Response :: ",
|
||||||
|
JSON.stringify(token, null, 2),
|
||||||
|
);
|
||||||
|
if (!token.ok) {
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
errors: [{ message: token.message }],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
await setSessionToRedis(token.message, input.userId ?? "");
|
||||||
|
return { success: true, errors: [] as ServerError };
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
throw new TRPCError({
|
||||||
|
code: "INTERNAL_SERVER_ERROR",
|
||||||
|
message: "Error getting new session.",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
|
||||||
|
isApiSessionValid: protectedProcedure
|
||||||
|
.input(
|
||||||
|
z.object({
|
||||||
|
checkingUserSession: z.boolean(),
|
||||||
|
userId: z.string().optional(),
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.query(async ({ input }) => {
|
||||||
|
return { valid: await isSessionValidInStore(input.userId) };
|
||||||
|
}),
|
||||||
|
|
||||||
|
logoutUser: protectedProcedure
|
||||||
|
.input(z.object({ userId: z.string().optional() }))
|
||||||
|
.mutation(async ({ input }) => {
|
||||||
|
const { userId } = input;
|
||||||
|
await removeSessionFromStore(userId);
|
||||||
|
return { success: true, errors: [] as ServerError };
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -7,181 +7,192 @@ import { getReducedFinalSheet } from "$lib/server/finalsheet.helpers";
|
|||||||
import { getDefaultTotals, getULID } from "$lib/utils";
|
import { getDefaultTotals, getULID } from "$lib/utils";
|
||||||
import { constants } from "$lib/utils/constants";
|
import { constants } from "$lib/utils/constants";
|
||||||
import {
|
import {
|
||||||
ApiUserTypes,
|
ApiUserTypes,
|
||||||
type APISession,
|
type APISession,
|
||||||
type ReducedFinalSheetData,
|
type ReducedFinalSheetData,
|
||||||
type ServerError,
|
type ServerError,
|
||||||
} from "$lib/utils/data.types";
|
} from "$lib/utils/data.types";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { createTRPCRouter, protectedProcedure } from "../t";
|
import { createTRPCRouter, protectedProcedure } from "../t";
|
||||||
|
|
||||||
const lastFetched = {
|
const lastFetched = {
|
||||||
get: async () => {
|
get: async () => {
|
||||||
const out = await redis.get(constants.LAST_FETCHED_KEY);
|
const out = await redis.get(constants.LAST_FETCHED_KEY);
|
||||||
if (out === null) {
|
if (out === null) {
|
||||||
return "Not fetched yet";
|
return "Not fetched yet";
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
},
|
},
|
||||||
set: async () => {
|
set: async () => {
|
||||||
await redis.set(constants.LAST_FETCHED_KEY, new Date().toISOString());
|
await redis.set(constants.LAST_FETCHED_KEY, new Date().toISOString());
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const apiDataRouter = createTRPCRouter({
|
export const apiDataRouter = createTRPCRouter({
|
||||||
getDealersAndDraws: protectedProcedure.query(async () => {
|
getDealersAndDraws: protectedProcedure.query(async () => {
|
||||||
const draws = await dbDraw.getAllDraws(true);
|
const draws = await dbDraw.getAllDraws(true);
|
||||||
const dealers = await dbApiUser.allUsersOfType(ApiUserTypes.DEALER);
|
const dealers = await dbApiUser.allUsersOfType(ApiUserTypes.DEALER);
|
||||||
const lf = await lastFetched.get();
|
const lf = await lastFetched.get();
|
||||||
return { users: dealers, draws, lastFetched: lf };
|
return { users: dealers, draws, lastFetched: lf };
|
||||||
}),
|
|
||||||
|
|
||||||
refetchData: protectedProcedure
|
|
||||||
.input(
|
|
||||||
z.object({
|
|
||||||
userIds: z.array(z.string()),
|
|
||||||
drawId: z.string(),
|
|
||||||
targetDate: z.string(),
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.mutation(async ({ input }) => {
|
|
||||||
const { userIds, targetDate, drawId } = input;
|
|
||||||
if (userIds.length < 1) {
|
|
||||||
return {
|
|
||||||
detail: "No users selected",
|
|
||||||
success: false,
|
|
||||||
errors: [
|
|
||||||
{ message: "No users selected to refetch data for" },
|
|
||||||
] as ServerError,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const sess = JSON.parse(
|
|
||||||
(await redis.get(constants.SCRAP_API_SESSION_KEY)) ?? "",
|
|
||||||
) as APISession;
|
|
||||||
if (sess === null) {
|
|
||||||
return {
|
|
||||||
detail: "API Session expired",
|
|
||||||
success: false,
|
|
||||||
errors: [
|
|
||||||
{
|
|
||||||
message:
|
|
||||||
"API Session expired, get a new api session and try again",
|
|
||||||
},
|
|
||||||
] as ServerError,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const userIdsInt = userIds.map((x) => parseInt(x.split(":")[1]));
|
|
||||||
const out = await getData(
|
|
||||||
sess.sessionToken,
|
|
||||||
userIdsInt,
|
|
||||||
parseInt(drawId.split(":")[1]),
|
|
||||||
targetDate,
|
|
||||||
);
|
|
||||||
if (!out.ok) {
|
|
||||||
return {
|
|
||||||
success: false,
|
|
||||||
detail: "Error fetching data",
|
|
||||||
errors: [{ message: out.message }] as ServerError,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const dataCount = out.data.length;
|
|
||||||
await dbApiData.upsertData(out.data, targetDate);
|
|
||||||
return {
|
|
||||||
detail: `Scraped ${dataCount} entries for ${userIds.length} users`,
|
|
||||||
success: true,
|
|
||||||
errors: [] as ServerError,
|
|
||||||
};
|
|
||||||
}),
|
}),
|
||||||
|
|
||||||
getDataByFilters: protectedProcedure
|
refetchData: protectedProcedure
|
||||||
.input(
|
.input(
|
||||||
z.object({ date: z.string(), drawId: z.string(), userId: z.string() }),
|
z.object({
|
||||||
)
|
userIds: z.array(z.string()),
|
||||||
.mutation(async ({ input }) => {
|
drawId: z.string(),
|
||||||
const { date, drawId, userId } = input;
|
targetDate: z.string(),
|
||||||
const data = await dbApiData.getBookingEntriesForDealer(
|
}),
|
||||||
date,
|
)
|
||||||
drawId.split(":")[1],
|
.mutation(async ({ input }) => {
|
||||||
userId.split(":")[1],
|
const { userIds, targetDate, drawId } = input;
|
||||||
true,
|
if (userIds.length < 1) {
|
||||||
);
|
return {
|
||||||
return { data };
|
detail: "No users selected",
|
||||||
|
success: false,
|
||||||
|
errors: [
|
||||||
|
{ message: "No users selected to refetch data for" },
|
||||||
|
] as ServerError,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
const sess = JSON.parse(
|
||||||
|
(await redis.get(constants.SCRAP_API_SESSION_KEY)) ?? "",
|
||||||
|
) as APISession;
|
||||||
|
if (sess === null) {
|
||||||
|
return {
|
||||||
|
detail: "API Session expired",
|
||||||
|
success: false,
|
||||||
|
errors: [
|
||||||
|
{
|
||||||
|
message:
|
||||||
|
"API Session expired, get a new api session and try again",
|
||||||
|
},
|
||||||
|
] as ServerError,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
console.log(
|
||||||
|
`Fetching data for ${userIds.length} users for draw ${drawId}`,
|
||||||
|
);
|
||||||
|
const userIdsInt = userIds.map((x) => parseInt(x.split(":")[1]));
|
||||||
|
const out = await getData(
|
||||||
|
sess.sessionToken,
|
||||||
|
userIdsInt,
|
||||||
|
parseInt(drawId.split(":")[1]),
|
||||||
|
targetDate,
|
||||||
|
);
|
||||||
|
if (!out.ok) {
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
detail: "Error fetching data",
|
||||||
|
errors: [{ message: out.message }] as ServerError,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
const dataCount = out.data.length;
|
||||||
|
await dbApiData.upsertData(out.data, targetDate);
|
||||||
|
return {
|
||||||
|
detail: `Scraped ${dataCount} entries for ${userIds.length} users`,
|
||||||
|
success: true,
|
||||||
|
errors: [] as ServerError,
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
|
||||||
|
getDataByFilters: protectedProcedure
|
||||||
|
.input(
|
||||||
|
z.object({
|
||||||
|
date: z.string(),
|
||||||
|
drawId: z.string(),
|
||||||
|
userId: z.string(),
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.mutation(async ({ input }) => {
|
||||||
|
const { date, drawId, userId } = input;
|
||||||
|
const data = await dbApiData.getBookingEntriesForDealer(
|
||||||
|
date,
|
||||||
|
drawId.split(":")[1],
|
||||||
|
userId.split(":")[1],
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
return { data };
|
||||||
|
}),
|
||||||
|
|
||||||
|
getReducedFinalSheet: protectedProcedure
|
||||||
|
.input(z.object({ date: z.string(), drawId: z.string() }))
|
||||||
|
.mutation(async ({ input }) => {
|
||||||
|
const { date, drawId } = input;
|
||||||
|
const draw = await dbDraw.getDraw(drawId);
|
||||||
|
const fsData = {
|
||||||
|
id: getULID(),
|
||||||
|
date,
|
||||||
|
drawId,
|
||||||
|
data: [],
|
||||||
|
totals: getDefaultTotals(),
|
||||||
|
} as ReducedFinalSheetData;
|
||||||
|
if (!draw) {
|
||||||
|
return {
|
||||||
|
ok: false,
|
||||||
|
detail: `Draw for the passed draw ID not found`,
|
||||||
|
data: fsData,
|
||||||
|
errors: [
|
||||||
|
{ message: `Draw for the passed draw ID not found` },
|
||||||
|
] as ServerError,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
console.log("Fetching data");
|
||||||
|
const data = await getReducedFinalSheet(fsData);
|
||||||
|
console.log(data);
|
||||||
|
if (!data.ok) {
|
||||||
|
return {
|
||||||
|
ok: false,
|
||||||
|
detail: `Error compiling final sheet`,
|
||||||
|
data: fsData,
|
||||||
|
errors: data.errors,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
ok: true,
|
||||||
|
detail: `Final sheet for ${date}, draw ${draw.title} has been compiled`,
|
||||||
|
data: fsData,
|
||||||
|
errors: [] as ServerError,
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
|
||||||
|
getFinalSheetRow: protectedProcedure
|
||||||
|
.input(
|
||||||
|
z.object({
|
||||||
|
date: z.string(),
|
||||||
|
drawId: z.string(),
|
||||||
|
number: z.string(),
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.mutation(async ({ input }) => {
|
||||||
|
return {
|
||||||
|
ok: true,
|
||||||
|
data: {},
|
||||||
|
errors: [] as ServerError,
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
|
||||||
|
delDataOlderThan2Weeks: protectedProcedure.mutation(async () => {
|
||||||
|
await dbApiData.deleteDataOlderThan2Weeks();
|
||||||
|
return { ok: true, detail: "Data older than 2 weeks has been deleted" };
|
||||||
}),
|
}),
|
||||||
|
|
||||||
getReducedFinalSheet: protectedProcedure
|
postTestBooking: protectedProcedure
|
||||||
.input(z.object({ date: z.string(), drawId: z.string() }))
|
.input(z.object({ drawId: z.string(), date: z.string() }))
|
||||||
.mutation(async ({ input }) => {
|
.mutation(async () => {
|
||||||
const { date, drawId } = input;
|
return {
|
||||||
const draw = await dbDraw.getDraw(drawId);
|
ok: true,
|
||||||
const fsData = {
|
detail: "API not live",
|
||||||
id: getULID(),
|
errors: [] as ServerError,
|
||||||
date,
|
};
|
||||||
drawId,
|
// console.log("GENERATING TEST DATA :: ", drawId, date);
|
||||||
data: [],
|
// const testData = await getTestBookingData(drawId, date);
|
||||||
totals: getDefaultTotals(),
|
// // console.log(testData);
|
||||||
} as ReducedFinalSheetData;
|
// await dbApiData.upsertData(testData, date);
|
||||||
if (!draw) {
|
// return {
|
||||||
return {
|
// ok: true,
|
||||||
ok: false,
|
// detail: "Test booking committed",
|
||||||
detail: `Draw for the passed draw ID not found`,
|
// errors: [] as ServerError,
|
||||||
data: fsData,
|
// };
|
||||||
errors: [
|
}),
|
||||||
{ message: `Draw for the passed draw ID not found` },
|
|
||||||
] as ServerError,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
console.log("Fetching data");
|
|
||||||
const data = await getReducedFinalSheet(fsData);
|
|
||||||
console.log(data);
|
|
||||||
if (!data.ok) {
|
|
||||||
return {
|
|
||||||
ok: false,
|
|
||||||
detail: `Error compiling final sheet`,
|
|
||||||
data: fsData,
|
|
||||||
errors: data.errors,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
ok: true,
|
|
||||||
detail: `Final sheet for ${date}, draw ${draw.title} has been compiled`,
|
|
||||||
data: fsData,
|
|
||||||
errors: [] as ServerError,
|
|
||||||
};
|
|
||||||
}),
|
|
||||||
|
|
||||||
getFinalSheetRow: protectedProcedure
|
|
||||||
.input(
|
|
||||||
z.object({ date: z.string(), drawId: z.string(), number: z.string() }),
|
|
||||||
)
|
|
||||||
.mutation(async ({ input }) => {
|
|
||||||
return {
|
|
||||||
ok: true,
|
|
||||||
data: {},
|
|
||||||
errors: [] as ServerError,
|
|
||||||
};
|
|
||||||
}),
|
|
||||||
|
|
||||||
delDataOlderThan2Weeks: protectedProcedure.mutation(async () => {
|
|
||||||
await dbApiData.deleteDataOlderThan2Weeks();
|
|
||||||
return { ok: true, detail: "Data older than 2 weeks has been deleted" };
|
|
||||||
}),
|
|
||||||
|
|
||||||
postTestBooking: protectedProcedure
|
|
||||||
.input(z.object({ drawId: z.string(), date: z.string() }))
|
|
||||||
.mutation(async () => {
|
|
||||||
return {
|
|
||||||
ok: true,
|
|
||||||
detail: "API not live",
|
|
||||||
errors: [] as ServerError,
|
|
||||||
};
|
|
||||||
// console.log("GENERATING TEST DATA :: ", drawId, date);
|
|
||||||
// const testData = await getTestBookingData(drawId, date);
|
|
||||||
// // console.log(testData);
|
|
||||||
// await dbApiData.upsertData(testData, date);
|
|
||||||
// return {
|
|
||||||
// ok: true,
|
|
||||||
// detail: "Test booking committed",
|
|
||||||
// errors: [] as ServerError,
|
|
||||||
// };
|
|
||||||
}),
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -4,34 +4,30 @@ import { dbApiUser } from "$lib/server/db/apiuser.db";
|
|||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
export const apiUserRouter = createTRPCRouter({
|
export const apiUserRouter = createTRPCRouter({
|
||||||
getAllDistributors: protectedProcedure.query(async () => {
|
getAllDistributors: protectedProcedure.query(async () => {
|
||||||
return await dbApiUser.allUsersOfType(ApiUserTypes.DISTRIBUTOR);
|
return await dbApiUser.allUsersOfType(ApiUserTypes.DISTRIBUTOR);
|
||||||
}),
|
|
||||||
getAllDealers: protectedProcedure.query(async () => {
|
|
||||||
return await dbApiUser.allUsersOfType(ApiUserTypes.DEALER);
|
|
||||||
}),
|
|
||||||
getAllDistributorsCount: protectedProcedure.query(async () => {
|
|
||||||
return await dbApiUser.getUserTypeCount(ApiUserTypes.DISTRIBUTOR);
|
|
||||||
}),
|
|
||||||
getAllDealersCount: protectedProcedure.query(async () => {
|
|
||||||
return await dbApiUser.getUserTypeCount(ApiUserTypes.DEALER);
|
|
||||||
}),
|
|
||||||
getDistributorsWithTheirChildren: protectedProcedure.query(async () => {
|
|
||||||
const users = await dbApiUser.getAllDistributorsWithTheirChildren();
|
|
||||||
return { users };
|
|
||||||
}),
|
|
||||||
|
|
||||||
getAllDealersPostUserFormat: protectedProcedure.query(async () => {
|
|
||||||
return await dbApiUser.allUsersOfTypeLimitedInfo(ApiUserTypes.DEALER);
|
|
||||||
}),
|
|
||||||
|
|
||||||
getAllPostUsers: protectedProcedure.query(async () => {
|
|
||||||
return await dbApiUser.getAllPostUsers();
|
|
||||||
}),
|
|
||||||
|
|
||||||
setPostDataFlagForUser: protectedProcedure
|
|
||||||
.input(z.object({ users: z.array(zApiPostUser) }))
|
|
||||||
.mutation(async ({ input }) => {
|
|
||||||
await dbApiUser.setPostDataFlagForUsers(input.users);
|
|
||||||
}),
|
}),
|
||||||
|
getAllDealers: protectedProcedure.query(async () => {
|
||||||
|
return await dbApiUser.allUsersOfType(ApiUserTypes.DEALER);
|
||||||
|
}),
|
||||||
|
getAllDistributorsCount: protectedProcedure.query(async () => {
|
||||||
|
return await dbApiUser.getUserTypeCount(ApiUserTypes.DISTRIBUTOR);
|
||||||
|
}),
|
||||||
|
getAllDealersCount: protectedProcedure.query(async () => {
|
||||||
|
return await dbApiUser.getUserTypeCount(ApiUserTypes.DEALER);
|
||||||
|
}),
|
||||||
|
|
||||||
|
getAllDealersPostUserFormat: protectedProcedure.query(async () => {
|
||||||
|
return await dbApiUser.allUsersOfTypeLimitedInfo(ApiUserTypes.DEALER);
|
||||||
|
}),
|
||||||
|
|
||||||
|
getAllPostUsers: protectedProcedure.query(async () => {
|
||||||
|
return await dbApiUser.getAllPostUsers();
|
||||||
|
}),
|
||||||
|
|
||||||
|
setPostDataFlagForUser: protectedProcedure
|
||||||
|
.input(z.object({ users: z.array(zApiPostUser) }))
|
||||||
|
.mutation(async ({ input }) => {
|
||||||
|
await dbApiUser.setPostDataFlagForUsers(input.users);
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -3,70 +3,70 @@ import { createTRPCRouter, protectedProcedure } from "../t";
|
|||||||
import { dbDraw } from "$lib/server/db/apidraw.db";
|
import { dbDraw } from "$lib/server/db/apidraw.db";
|
||||||
import { DEFAULT_TZ } from "$lib/utils/constants";
|
import { DEFAULT_TZ } from "$lib/utils/constants";
|
||||||
import {
|
import {
|
||||||
zBookingEntry,
|
zBookingEntry,
|
||||||
type BookingEntry,
|
type BookingEntry,
|
||||||
type ServerError,
|
type ServerError,
|
||||||
} from "$lib/utils/data.types";
|
} from "$lib/utils/data.types";
|
||||||
import { surreal } from "$lib/server/connectors/surreal.db";
|
import { surreal } from "$lib/server/connectors/surreal.db";
|
||||||
import { parseToDateString } from "$lib/utils/datetime.helper.utils";
|
import { parseToDateString } from "$lib/utils/datetime.helper.utils";
|
||||||
|
|
||||||
function getTodaysTableName() {
|
function getTodaysTableName() {
|
||||||
const today = parseToDateString(new Date());
|
const today = parseToDateString(new Date());
|
||||||
return `booking${today.replaceAll("-", "")}`;
|
return `booking${today.replaceAll("-", "")}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const bookingRouter = createTRPCRouter({
|
export const bookingRouter = createTRPCRouter({
|
||||||
getPanelData: protectedProcedure.query(async () => {
|
getPanelData: protectedProcedure.query(async () => {
|
||||||
const draws = await dbDraw.getAllDraws(true);
|
const draws = await dbDraw.getAllDraws(true);
|
||||||
const timeInDrawsTz = new Date().toLocaleString("en-US", {
|
const timeInDrawsTz = new Date().toLocaleString("en-US", {
|
||||||
timeZone: DEFAULT_TZ,
|
timeZone: DEFAULT_TZ,
|
||||||
});
|
});
|
||||||
return { draws, timeInDrawsTz: timeInDrawsTz };
|
return { draws, timeInDrawsTz: timeInDrawsTz };
|
||||||
}),
|
|
||||||
|
|
||||||
getBookingData: protectedProcedure
|
|
||||||
.input(z.object({ drawId: z.string() }))
|
|
||||||
.mutation(async ({ input }) => {
|
|
||||||
const { drawId } = input;
|
|
||||||
const date = parseToDateString(new Date());
|
|
||||||
const tn = getTodaysTableName();
|
|
||||||
const did = parseInt(drawId.split(":")[1]);
|
|
||||||
const [out] = await surreal.query<[BookingEntry[]]>(
|
|
||||||
`select * from type::table($table) where drawId = $drawId and bookDate = $bookDate order by requestId desc`,
|
|
||||||
{ table: tn, drawId: did, bookDate: date }
|
|
||||||
);
|
|
||||||
return { data: out.result ?? [], errors: [] as ServerError };
|
|
||||||
}),
|
}),
|
||||||
|
|
||||||
syncBooking: protectedProcedure
|
getBookingData: protectedProcedure
|
||||||
.input(z.object({ data: z.array(zBookingEntry) }))
|
.input(z.object({ drawId: z.string() }))
|
||||||
.mutation(async ({ input }) => {
|
.mutation(async ({ input }) => {
|
||||||
const tableName = getTodaysTableName();
|
const { drawId } = input;
|
||||||
const syncedEntriesIds = [] as string[];
|
const date = parseToDateString(new Date());
|
||||||
if (input.data.length > 0) {
|
const tn = getTodaysTableName();
|
||||||
await surreal.insert<BookingEntry>(
|
const did = parseInt(drawId.split(":")[1]);
|
||||||
tableName,
|
const [out] = await surreal.query<[BookingEntry[]]>(
|
||||||
input.data.map((e) => {
|
`select * from type::table($table) where drawId = $drawId and bookDate = $bookDate order by requestId desc`,
|
||||||
syncedEntriesIds.push(`${e.id}`);
|
{ table: tn, drawId: did, bookDate: date },
|
||||||
return {
|
);
|
||||||
...e,
|
return { data: out ?? [], errors: [] as ServerError };
|
||||||
createdAt: new Date().toISOString(),
|
}),
|
||||||
updatedAt: new Date().toISOString(),
|
|
||||||
};
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return { detail: "Add Booking api donezo", syncedEntriesIds };
|
|
||||||
}),
|
|
||||||
|
|
||||||
deleteBooking: protectedProcedure
|
syncBooking: protectedProcedure
|
||||||
.input(z.object({ bookingIds: z.array(z.string()) }))
|
.input(z.object({ data: z.array(zBookingEntry) }))
|
||||||
.mutation(async ({ input }) => {
|
.mutation(async ({ input }) => {
|
||||||
await Promise.all(
|
const tableName = getTodaysTableName();
|
||||||
input.bookingIds.map(async (id) => {
|
const syncedEntriesIds = [] as string[];
|
||||||
await surreal.delete(id);
|
if (input.data.length > 0) {
|
||||||
})
|
await surreal.insert<BookingEntry>(
|
||||||
);
|
tableName,
|
||||||
return { detail: `Deleted ${input.bookingIds.length} Entries` };
|
input.data.map((e) => {
|
||||||
}),
|
syncedEntriesIds.push(`${e.id}`);
|
||||||
|
return {
|
||||||
|
...e,
|
||||||
|
createdAt: new Date().toISOString(),
|
||||||
|
updatedAt: new Date().toISOString(),
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return { detail: "Add Booking api donezo", syncedEntriesIds };
|
||||||
|
}),
|
||||||
|
|
||||||
|
deleteBooking: protectedProcedure
|
||||||
|
.input(z.object({ bookingIds: z.array(z.string()) }))
|
||||||
|
.mutation(async ({ input }) => {
|
||||||
|
await Promise.all(
|
||||||
|
input.bookingIds.map(async (id) => {
|
||||||
|
await surreal.delete(id);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
return { detail: `Deleted ${input.bookingIds.length} Entries` };
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -4,27 +4,28 @@ import { z } from "zod";
|
|||||||
import { zDraw } from "$lib/utils/data.types";
|
import { zDraw } from "$lib/utils/data.types";
|
||||||
|
|
||||||
export const drawRouter = createTRPCRouter({
|
export const drawRouter = createTRPCRouter({
|
||||||
getAllDraws: protectedProcedure.query(async () => {
|
getAllDraws: protectedProcedure.query(async () => {
|
||||||
return await dbDraw.getAllDraws(true);
|
return await dbDraw.getAllDraws(true);
|
||||||
}),
|
|
||||||
|
|
||||||
getCurrentTime: protectedProcedure.query(async () => {
|
|
||||||
const now = new Date();
|
|
||||||
const timezone = "Asia/Karachi";
|
|
||||||
const nowKarachi = new Date(
|
|
||||||
now.toLocaleString("en-US", { timeZone: timezone }),
|
|
||||||
);
|
|
||||||
// console.log(nowKarachi.toLocaleString());
|
|
||||||
return { now: nowKarachi };
|
|
||||||
}),
|
|
||||||
|
|
||||||
savePresetInfoForDraws: protectedProcedure
|
|
||||||
.input(z.object({ draws: z.array(zDraw) }))
|
|
||||||
.mutation(async ({ input }) => {
|
|
||||||
// console.log("savePresetInfoForDraws", input);
|
|
||||||
for (const draw of input.draws) {
|
|
||||||
await dbDraw.updateDrawPresetInfo(draw);
|
|
||||||
}
|
|
||||||
return { success: true };
|
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
getCurrentTime: protectedProcedure.query(async () => {
|
||||||
|
const now = new Date();
|
||||||
|
const timezone = "Asia/Karachi";
|
||||||
|
const nowKarachi = new Date(
|
||||||
|
now.toLocaleString("en-US", { timeZone: timezone }),
|
||||||
|
);
|
||||||
|
// console.log(nowKarachi.toLocaleString());
|
||||||
|
return { now: nowKarachi };
|
||||||
|
}),
|
||||||
|
|
||||||
|
savePresetInfoForDraws: protectedProcedure
|
||||||
|
.input(z.object({ draws: z.array(zDraw) }))
|
||||||
|
.mutation(async ({ input }) => {
|
||||||
|
console.log("Saving preset info for draws");
|
||||||
|
for (const draw of input.draws) {
|
||||||
|
await dbDraw.updateDrawPresetInfo(draw);
|
||||||
|
}
|
||||||
|
console.log("Done saving preset info for draws");
|
||||||
|
return { success: true };
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,265 +1,259 @@
|
|||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
export type Session = {
|
export type Session = {
|
||||||
sId: string;
|
sId: string;
|
||||||
ip: string;
|
ip: string;
|
||||||
userAgent: string;
|
userAgent: string;
|
||||||
username: string;
|
username: string;
|
||||||
userType: string;
|
userType: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type APISession = {
|
export type APISession = {
|
||||||
ip: string;
|
ip: string;
|
||||||
sessionToken: string;
|
sessionToken: string;
|
||||||
userId: string;
|
userId: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const zAuthPayload = z.object({
|
export const zAuthPayload = z.object({
|
||||||
username: z.string().min(4).max(64),
|
username: z.string().min(4).max(64),
|
||||||
password: z.string().min(8).max(64),
|
password: z.string().min(8).max(64),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const zUser = z.object({
|
export const zUser = z.object({
|
||||||
id: z.string().length(16),
|
id: z.string().length(16),
|
||||||
createdAt: z.string(),
|
createdAt: z.string(),
|
||||||
updatedAt: z.string(),
|
updatedAt: z.string(),
|
||||||
username: z.string().min(4).max(64),
|
username: z.string().min(4).max(64),
|
||||||
password: z.string().min(8).max(64),
|
password: z.string().min(8).max(64),
|
||||||
userType: z.string().min(4).max(5),
|
userType: z.string().min(4).max(5),
|
||||||
association: z.string(),
|
association: z.string(),
|
||||||
});
|
});
|
||||||
|
export type User = z.infer<typeof zUser>;
|
||||||
|
|
||||||
export const zLooseUser = z.object({
|
export const zLooseUser = z.object({
|
||||||
id: z.string().length(16).optional(),
|
id: z.string().length(16).optional(),
|
||||||
createdAt: z.string().optional(),
|
createdAt: z.string().optional(),
|
||||||
updatedAt: z.string().optional(),
|
updatedAt: z.string().optional(),
|
||||||
username: z.string().min(4).max(64),
|
username: z.string().min(4).max(64),
|
||||||
password: z.string().min(8).max(64),
|
password: z.string().min(8).max(64),
|
||||||
userType: z.string().min(4).max(5),
|
userType: z.string().min(4).max(5),
|
||||||
association: z.string(),
|
association: z.string(),
|
||||||
});
|
});
|
||||||
|
export type LooseUser = z.infer<typeof zLooseUser>;
|
||||||
|
|
||||||
export const zApiUser = z.object({
|
export const zApiUser = z.object({
|
||||||
id: z.string().length(16),
|
id: z.string().length(16),
|
||||||
userType: z.number(),
|
userType: z.number(),
|
||||||
disableBooking: z.string().nullable().optional(),
|
disableBooking: z.string().nullable().optional(),
|
||||||
sendVoucher: z.string().nullable().optional(),
|
sendVoucher: z.string().nullable().optional(),
|
||||||
voucherGenerated: z.string().nullable().optional(),
|
voucherGenerated: z.string().nullable().optional(),
|
||||||
parentAdmin: z.number(),
|
parentAdmin: z.number(),
|
||||||
parentDistributor: z.number(),
|
parentDistributor: z.number(),
|
||||||
userName: z.string(),
|
userName: z.string(),
|
||||||
userCity: z.string().nullable().optional(),
|
userCity: z.string().nullable().optional(),
|
||||||
userId: z.string(),
|
userId: z.string(),
|
||||||
password: z.string(),
|
password: z.string(),
|
||||||
accessDenied: z.number(),
|
accessDenied: z.number(),
|
||||||
phoneNumber: z.string(),
|
phoneNumber: z.string(),
|
||||||
emailAddress: z.string(),
|
emailAddress: z.string(),
|
||||||
disable: z.number(),
|
disable: z.number(),
|
||||||
commission: z.number(),
|
commission: z.number(),
|
||||||
commissionPangora: z.number(),
|
commissionPangora: z.number(),
|
||||||
allowTitles: z.string(),
|
allowTitles: z.string(),
|
||||||
specialDealer: z.number(),
|
specialDealer: z.number(),
|
||||||
allowBalance: z.number(),
|
allowBalance: z.number(),
|
||||||
balance: z.number(),
|
balance: z.number(),
|
||||||
profitlossShare: z.number(),
|
profitlossShare: z.number(),
|
||||||
shareProfitonly: z.number(),
|
shareProfitonly: z.number(),
|
||||||
allowRemoveold: z.number(),
|
allowRemoveold: z.number(),
|
||||||
removeDays: z.number().nullable().optional(),
|
removeDays: z.number().nullable().optional(),
|
||||||
language: z.number(),
|
language: z.number(),
|
||||||
postData: z.boolean().nullable().optional(),
|
postData: z.boolean().nullable().optional(),
|
||||||
createdAt: z.string().nullable(),
|
createdAt: z.string().nullable(),
|
||||||
updatedAt: z.string().nullable(),
|
updatedAt: z.string().nullable(),
|
||||||
});
|
});
|
||||||
|
export type ApiUser = z.infer<typeof zApiUser>;
|
||||||
|
|
||||||
export const zApiPostUser = z.object({
|
export const zApiPostUser = z.object({
|
||||||
id: z.string(),
|
id: z.string(),
|
||||||
userName: z.string(),
|
userName: z.string(),
|
||||||
userId: z.string(),
|
userId: z.string(),
|
||||||
postData: z.boolean(),
|
postData: z.boolean(),
|
||||||
balance: z.number().optional(),
|
balance: z.number().optional(),
|
||||||
});
|
});
|
||||||
|
export type ApiPostUser = z.infer<typeof zApiPostUser>;
|
||||||
|
|
||||||
export const zLooseApiUser = z.object({
|
export const zLooseApiUser = z.object({
|
||||||
id: z.string().length(16).optional(),
|
id: z.string().length(16).optional(),
|
||||||
userType: z.number().optional(),
|
userType: z.number().optional(),
|
||||||
disableBooking: z.string().nullable().optional(),
|
disableBooking: z.string().nullable().optional(),
|
||||||
sendVoucher: z.string().nullable().optional(),
|
sendVoucher: z.string().nullable().optional(),
|
||||||
voucherGenerated: z.string().nullable().optional(),
|
voucherGenerated: z.string().nullable().optional(),
|
||||||
parentAdmin: z.number(),
|
parentAdmin: z.number(),
|
||||||
parentDistributor: z.number(),
|
parentDistributor: z.number(),
|
||||||
userName: z.string(),
|
userName: z.string(),
|
||||||
userCity: z.string().nullable().optional(),
|
userCity: z.string().nullable().optional(),
|
||||||
userId: z.string().optional(),
|
userId: z.string().optional(),
|
||||||
password: z.string(),
|
password: z.string(),
|
||||||
accessDenied: z.number(),
|
accessDenied: z.number(),
|
||||||
phoneNumber: z.string(),
|
phoneNumber: z.string(),
|
||||||
emailAddress: z.string(),
|
emailAddress: z.string(),
|
||||||
disable: z.number(),
|
disable: z.number(),
|
||||||
commission: z.number(),
|
commission: z.number(),
|
||||||
commissionPangora: z.number(),
|
commissionPangora: z.number(),
|
||||||
allowTitles: z.string(),
|
allowTitles: z.string(),
|
||||||
specialDealer: z.number(),
|
specialDealer: z.number(),
|
||||||
allowBalance: z.number(),
|
allowBalance: z.number(),
|
||||||
balance: z.number(),
|
balance: z.number(),
|
||||||
profitlossShare: z.number(),
|
profitlossShare: z.number(),
|
||||||
shareProfitonly: z.number(),
|
shareProfitonly: z.number(),
|
||||||
allowRemoveold: z.number(),
|
allowRemoveold: z.number(),
|
||||||
removeDays: z.number().nullable().optional(),
|
removeDays: z.number().nullable().optional(),
|
||||||
language: z.number().optional(),
|
language: z.number().optional(),
|
||||||
postData: z.boolean().nullable().optional(),
|
postData: z.boolean().nullable().optional(),
|
||||||
createdAt: z.string().nullable().optional(),
|
createdAt: z.string().nullable().optional(),
|
||||||
updatedAt: z.string().nullable().optional(),
|
updatedAt: z.string().nullable().optional(),
|
||||||
});
|
});
|
||||||
|
export type LooseApiUser = z.infer<typeof zLooseApiUser>;
|
||||||
|
|
||||||
export const zDraw = z.object({
|
export const zDraw = z.object({
|
||||||
id: z.string(),
|
id: z.string(),
|
||||||
title: z.string(),
|
title: z.string(),
|
||||||
closeTime: z.string(),
|
closeTime: z.string(),
|
||||||
filterDuplicatesWhilePosting: z.boolean(),
|
filterDuplicatesWhilePosting: z.boolean(),
|
||||||
drawType: z.number(),
|
drawType: z.number(),
|
||||||
adminId: z.number(),
|
adminId: z.number(),
|
||||||
abRateF: z.coerce.number(),
|
abRateF: z.coerce.number(),
|
||||||
abRateS: z.coerce.number(),
|
abRateS: z.coerce.number(),
|
||||||
abcRateF: z.coerce.number(),
|
abcRateF: z.coerce.number(),
|
||||||
abcRateS: z.coerce.number(),
|
abcRateS: z.coerce.number(),
|
||||||
createdAt: z.string().nullable().optional(),
|
createdAt: z.string().nullable().optional(),
|
||||||
updatedAt: z.string().nullable().optional(),
|
updatedAt: z.string().nullable().optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
export type Draw = z.infer<typeof zDraw>;
|
export type Draw = z.infer<typeof zDraw>;
|
||||||
|
|
||||||
export const zBookingEntry = z.object({
|
export const zBookingEntry = z.object({
|
||||||
id: z.string(),
|
id: z.string(),
|
||||||
distributorId: z.number(),
|
distributorId: z.number(),
|
||||||
dealerId: z.number(),
|
dealerId: z.number(),
|
||||||
drawId: z.number(),
|
drawId: z.number(),
|
||||||
bookDate: z.string(),
|
bookDate: z.string(),
|
||||||
number: z.string(),
|
number: z.string(),
|
||||||
first: z.number(),
|
first: z.number(),
|
||||||
second: z.number(),
|
second: z.number(),
|
||||||
changedBalance: z.number(),
|
changedBalance: z.number(),
|
||||||
sheetName: z.string().nullable().optional(),
|
sheetName: z.string().nullable().optional(),
|
||||||
sheetId: z.string().nullable().optional(),
|
sheetId: z.string().nullable().optional(),
|
||||||
requestId: z.string(),
|
requestId: z.string(),
|
||||||
createdAt: z.string().nullable().optional(),
|
createdAt: z.string().nullable().optional(),
|
||||||
updatedAt: z.string().nullable().optional(),
|
updatedAt: z.string().nullable().optional(),
|
||||||
});
|
});
|
||||||
export type BookingEntry = z.infer<typeof zBookingEntry>;
|
export type BookingEntry = z.infer<typeof zBookingEntry>;
|
||||||
|
|
||||||
export const zPostDataEntry = z.object({
|
export const zPostDataEntry = z.object({
|
||||||
id: z.string(),
|
id: z.string(),
|
||||||
requestId: z.string().nullable().optional(),
|
requestId: z.string().nullable().optional(),
|
||||||
number: z.string(),
|
number: z.string(),
|
||||||
first: z.number(),
|
first: z.number(),
|
||||||
second: z.number(),
|
second: z.number(),
|
||||||
userId: z.string().nullable().optional(),
|
userId: z.string().nullable().optional(),
|
||||||
createdAt: z.string().nullable().optional(),
|
createdAt: z.string().nullable().optional(),
|
||||||
updatedAt: z.string().nullable().optional(),
|
updatedAt: z.string().nullable().optional(),
|
||||||
});
|
});
|
||||||
export type PostDataEntry = z.infer<typeof zPostDataEntry>;
|
export type PostDataEntry = z.infer<typeof zPostDataEntry>;
|
||||||
|
|
||||||
const zPostDataHistory = z.object({
|
const zPostDataHistory = z.object({
|
||||||
id: z.string(),
|
id: z.string(),
|
||||||
data: z.array(zPostDataEntry),
|
data: z.array(zPostDataEntry),
|
||||||
drawId: z.number(),
|
drawId: z.number(),
|
||||||
bookDate: z.string(),
|
bookDate: z.string(),
|
||||||
createdAt: z.string().nullable().optional(),
|
createdAt: z.string().nullable().optional(),
|
||||||
updatedAt: z.string().nullable().optional(),
|
updatedAt: z.string().nullable().optional(),
|
||||||
});
|
});
|
||||||
export type PostDataHistory = z.infer<typeof zPostDataHistory>;
|
export type PostDataHistory = z.infer<typeof zPostDataHistory>;
|
||||||
|
|
||||||
export const zPresetDataEntry = z.object({
|
export const zPresetDataEntry = z.object({
|
||||||
id: z.string(),
|
id: z.string(),
|
||||||
drawId: z.number(),
|
drawId: z.number(),
|
||||||
bookDate: z.string(),
|
bookDate: z.string(),
|
||||||
number: z.string(),
|
number: z.string(),
|
||||||
first: z.number(),
|
first: z.number(),
|
||||||
second: z.number(),
|
second: z.number(),
|
||||||
createdAt: z.string().nullable().optional(),
|
createdAt: z.string().nullable().optional(),
|
||||||
dealerId: z.number().optional().nullable(),
|
dealerId: z.number().optional().nullable(),
|
||||||
});
|
});
|
||||||
export type PresetDataEntry = z.infer<typeof zPresetDataEntry>;
|
export type PresetDataEntry = z.infer<typeof zPresetDataEntry>;
|
||||||
|
|
||||||
export const fsPair = z.object({
|
export const fsPair = z.object({
|
||||||
first: z.number(),
|
first: z.number(),
|
||||||
second: z.number(),
|
second: z.number(),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const zLexiCodeCacheObject = z.object({
|
export const zLexiCodeCacheObject = z.object({
|
||||||
number: z.string(),
|
number: z.string(),
|
||||||
rate: fsPair,
|
rate: fsPair,
|
||||||
prize: fsPair,
|
prize: fsPair,
|
||||||
frequency: fsPair,
|
frequency: fsPair,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const reducedFinalSheetRow = z.object({
|
export const reducedFinalSheetRow = z.object({
|
||||||
id: z.string(),
|
id: z.string(),
|
||||||
number: z.string(),
|
number: z.string(),
|
||||||
frequency: fsPair,
|
frequency: fsPair,
|
||||||
frequencies: z.object({
|
frequencies: z.object({
|
||||||
// a: fsPair,
|
// a: fsPair,
|
||||||
// ab: fsPair,
|
// ab: fsPair,
|
||||||
// abc: fsPair,
|
// abc: fsPair,
|
||||||
// "+abc": fsPair,
|
// "+abc": fsPair,
|
||||||
// "a+bc": fsPair,
|
// "a+bc": fsPair,
|
||||||
// "ab+c": fsPair,
|
// "ab+c": fsPair,
|
||||||
abcd: fsPair,
|
abcd: fsPair,
|
||||||
}),
|
}),
|
||||||
rate: fsPair,
|
rate: fsPair,
|
||||||
prize: fsPair,
|
prize: fsPair,
|
||||||
profit: fsPair,
|
profit: fsPair,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const zfinalSheetRow = z.object({
|
export const zfinalSheetRow = z.object({
|
||||||
id: z.string(),
|
id: z.string(),
|
||||||
number: z.string(),
|
number: z.string(),
|
||||||
frequency: fsPair,
|
frequency: fsPair,
|
||||||
rate: fsPair,
|
rate: fsPair,
|
||||||
prize: fsPair,
|
prize: fsPair,
|
||||||
profit: fsPair,
|
profit: fsPair,
|
||||||
|
|
||||||
a: zLexiCodeCacheObject,
|
a: zLexiCodeCacheObject,
|
||||||
xa: zLexiCodeCacheObject,
|
xa: zLexiCodeCacheObject,
|
||||||
xxa: zLexiCodeCacheObject,
|
xxa: zLexiCodeCacheObject,
|
||||||
xxxa: zLexiCodeCacheObject,
|
xxxa: zLexiCodeCacheObject,
|
||||||
ab: zLexiCodeCacheObject,
|
ab: zLexiCodeCacheObject,
|
||||||
xab: zLexiCodeCacheObject,
|
xab: zLexiCodeCacheObject,
|
||||||
axb: zLexiCodeCacheObject,
|
axb: zLexiCodeCacheObject,
|
||||||
xaxb: zLexiCodeCacheObject,
|
xaxb: zLexiCodeCacheObject,
|
||||||
xxab: zLexiCodeCacheObject,
|
xxab: zLexiCodeCacheObject,
|
||||||
axxb: zLexiCodeCacheObject,
|
axxb: zLexiCodeCacheObject,
|
||||||
abc: zLexiCodeCacheObject,
|
abc: zLexiCodeCacheObject,
|
||||||
xabc: zLexiCodeCacheObject,
|
xabc: zLexiCodeCacheObject,
|
||||||
axbc: zLexiCodeCacheObject,
|
axbc: zLexiCodeCacheObject,
|
||||||
abxc: zLexiCodeCacheObject,
|
abxc: zLexiCodeCacheObject,
|
||||||
abcd: zLexiCodeCacheObject,
|
abcd: zLexiCodeCacheObject,
|
||||||
});
|
});
|
||||||
|
|
||||||
export type ServerError = Array<{
|
export type ServerError = Array<{
|
||||||
message: string;
|
message: string;
|
||||||
value?: string;
|
value?: string;
|
||||||
meta?: any;
|
meta?: any;
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
export const UserTypes = { ADMIN: "ADMIN", USER: "USER" };
|
export const UserTypes = { ADMIN: "ADMIN", USER: "USER" };
|
||||||
|
|
||||||
export const ApiUserTypes = { ADMIN: 1, DISTRIBUTOR: 2, DEALER: 3 };
|
export const ApiUserTypes = { ADMIN: 1, DISTRIBUTOR: 2, DEALER: 3 };
|
||||||
|
|
||||||
export type User = z.infer<typeof zUser>;
|
|
||||||
|
|
||||||
export type LooseUser = z.infer<typeof zLooseUser>;
|
|
||||||
|
|
||||||
export type ApiUser = z.infer<typeof zApiUser>;
|
|
||||||
|
|
||||||
export type ApiPostUser = z.infer<typeof zApiPostUser>;
|
|
||||||
|
|
||||||
export type ApiPostUserWithParent = ApiPostUser & {
|
export type ApiPostUserWithParent = ApiPostUser & {
|
||||||
parentAdmin: number;
|
parentAdmin: number;
|
||||||
parentDistributor: number;
|
parentDistributor: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type LooseApiUser = z.infer<typeof zLooseApiUser>;
|
|
||||||
|
|
||||||
export type LexiCodeCacheObject = z.infer<typeof zLexiCodeCacheObject>;
|
export type LexiCodeCacheObject = z.infer<typeof zLexiCodeCacheObject>;
|
||||||
|
|
||||||
export type SimpleLexiCodeObject = { number: string; lexiCode: string };
|
export type SimpleLexiCodeObject = { number: string; lexiCode: string };
|
||||||
@@ -271,108 +265,108 @@ export type ReducedFinalSheetRow = z.infer<typeof reducedFinalSheetRow>;
|
|||||||
export type FSPair = z.infer<typeof fsPair>;
|
export type FSPair = z.infer<typeof fsPair>;
|
||||||
|
|
||||||
export type FSTotals = {
|
export type FSTotals = {
|
||||||
rate: FSPair;
|
rate: FSPair;
|
||||||
prize: FSPair;
|
prize: FSPair;
|
||||||
commission: FSPair;
|
commission: FSPair;
|
||||||
netRate: FSPair;
|
netRate: FSPair;
|
||||||
frequency: FSPair;
|
frequency: FSPair;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ReducedFinalSheetData = {
|
export type ReducedFinalSheetData = {
|
||||||
id: string;
|
id: string;
|
||||||
date: string;
|
date: string;
|
||||||
drawId: string;
|
drawId: string;
|
||||||
data: Array<ReducedFinalSheetRow>;
|
data: Array<ReducedFinalSheetRow>;
|
||||||
totals: FSTotals;
|
totals: FSTotals;
|
||||||
createdAt?: string;
|
createdAt?: string;
|
||||||
updatedAt?: string;
|
updatedAt?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type FinalSheetData = {
|
export type FinalSheetData = {
|
||||||
id: string;
|
id: string;
|
||||||
date: string;
|
date: string;
|
||||||
drawId: string;
|
drawId: string;
|
||||||
data: Array<FinalSheetRow>;
|
data: Array<FinalSheetRow>;
|
||||||
totals: FSTotals;
|
totals: FSTotals;
|
||||||
createdAt?: string;
|
createdAt?: string;
|
||||||
updatedAt?: string;
|
updatedAt?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type AuthPayload = z.infer<typeof zAuthPayload>;
|
export type AuthPayload = z.infer<typeof zAuthPayload>;
|
||||||
|
|
||||||
export type SessionData = {
|
export type SessionData = {
|
||||||
username: string;
|
username: string;
|
||||||
userType: string;
|
userType: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type BookingInputValues = {
|
export type BookingInputValues = {
|
||||||
number: string;
|
number: string;
|
||||||
default: { first: string; second: string };
|
default: { first: string; second: string };
|
||||||
first: Record<string, string>;
|
first: Record<string, string>;
|
||||||
second: Record<string, string>;
|
second: Record<string, string>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const zPostDataHistoryFilters = z.object({
|
export const zPostDataHistoryFilters = z.object({
|
||||||
date: z.string(),
|
date: z.string(),
|
||||||
draw: zDraw,
|
draw: zDraw,
|
||||||
});
|
});
|
||||||
|
|
||||||
export type PostDataHistoryFilters = z.infer<typeof zPostDataHistoryFilters>;
|
export type PostDataHistoryFilters = z.infer<typeof zPostDataHistoryFilters>;
|
||||||
|
|
||||||
export const zDDFilters = z.object({
|
export const zDDFilters = z.object({
|
||||||
date: z.string(),
|
date: z.string(),
|
||||||
draw: zDraw.optional(),
|
draw: zDraw.optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
export type DDFilters = z.infer<typeof zDDFilters>;
|
export type DDFilters = z.infer<typeof zDDFilters>;
|
||||||
|
|
||||||
export const zDDUserFilters = z.object({
|
export const zDDUserFilters = z.object({
|
||||||
date: z.string(),
|
date: z.string(),
|
||||||
draw: zDraw.optional(),
|
draw: zDraw.optional(),
|
||||||
user: zApiUser.optional(),
|
user: zApiUser.optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
export type DDUserFilters = z.infer<typeof zDDUserFilters>;
|
export type DDUserFilters = z.infer<typeof zDDUserFilters>;
|
||||||
|
|
||||||
export const zPostDataFilters = z.object({
|
export const zPostDataFilters = z.object({
|
||||||
date: z.string(),
|
date: z.string(),
|
||||||
draw: zDraw.optional().nullable(),
|
draw: zDraw.optional().nullable(),
|
||||||
minPrize: z.coerce.number(),
|
minPrize: z.coerce.number(),
|
||||||
maxPrize: z.coerce.number(),
|
maxPrize: z.coerce.number(),
|
||||||
twoDigitRates: fsPair,
|
twoDigitRates: fsPair,
|
||||||
threeDigitRates: fsPair,
|
threeDigitRates: fsPair,
|
||||||
customData: z.string(),
|
customData: z.string(),
|
||||||
});
|
});
|
||||||
|
|
||||||
export type PostDataFilters = z.infer<typeof zPostDataFilters>;
|
export type PostDataFilters = z.infer<typeof zPostDataFilters>;
|
||||||
|
|
||||||
export const DEFAULT_RANDOM_DISTRIBUTOR = {
|
export const DEFAULT_RANDOM_DISTRIBUTOR = {
|
||||||
id: "apiuser:6339",
|
id: "apiuser:6339",
|
||||||
userType: 2,
|
userType: 2,
|
||||||
disableBooking: null,
|
disableBooking: null,
|
||||||
sendVoucher: null,
|
sendVoucher: null,
|
||||||
voucherGenerated: null,
|
voucherGenerated: null,
|
||||||
parentAdmin: 15,
|
parentAdmin: 15,
|
||||||
parentDistributor: 0,
|
parentDistributor: 0,
|
||||||
userName: "Baba Sagar",
|
userName: "Baba Sagar",
|
||||||
userCity: "Shikar pur",
|
userCity: "Shikar pur",
|
||||||
userId: "317XY3",
|
userId: "317XY3",
|
||||||
password: "405613",
|
password: "405613",
|
||||||
accessDenied: 0,
|
accessDenied: 0,
|
||||||
phoneNumber: "",
|
phoneNumber: "",
|
||||||
emailAddress: "",
|
emailAddress: "",
|
||||||
disable: 0,
|
disable: 0,
|
||||||
commission: 20.0,
|
commission: 20.0,
|
||||||
commissionPangora: 20.0,
|
commissionPangora: 20.0,
|
||||||
allowTitles: ",7,8,9,10,11,12,13,14,15,16,30,31,32,",
|
allowTitles: ",7,8,9,10,11,12,13,14,15,16,30,31,32,",
|
||||||
specialDealer: 0,
|
specialDealer: 0,
|
||||||
allowBalance: 1,
|
allowBalance: 1,
|
||||||
balance: 30094.905,
|
balance: 30094.905,
|
||||||
profitlossShare: 50.0,
|
profitlossShare: 50.0,
|
||||||
shareProfitonly: 0,
|
shareProfitonly: 0,
|
||||||
allowRemoveold: 0,
|
allowRemoveold: 0,
|
||||||
removeDays: 30,
|
removeDays: 30,
|
||||||
language: 0,
|
language: 0,
|
||||||
createdAt: new Date().toString(),
|
createdAt: new Date().toString(),
|
||||||
updatedAt: new Date().toString(),
|
updatedAt: new Date().toString(),
|
||||||
} as unknown as ApiUser;
|
} as unknown as ApiUser;
|
||||||
|
|||||||
@@ -2,54 +2,54 @@ import { fail } from "@sveltejs/kit";
|
|||||||
import type { Actions } from "../../$types";
|
import type { Actions } from "../../$types";
|
||||||
import { ApiUserTypes, type ServerError } from "$lib/utils/data.types";
|
import { ApiUserTypes, type ServerError } from "$lib/utils/data.types";
|
||||||
import {
|
import {
|
||||||
getDealers,
|
getDealers,
|
||||||
getDistributors,
|
getDistributors,
|
||||||
} from "$lib/server/external/api.scraping.helpers";
|
} from "$lib/server/external/api.scraping.helpers";
|
||||||
import { dbApiUser } from "$lib/server/db/apiuser.db";
|
import { dbApiUser } from "$lib/server/db/apiuser.db";
|
||||||
import { constants } from "$lib/utils/constants";
|
import { constants } from "$lib/utils/constants";
|
||||||
import fs from "fs";
|
|
||||||
import { getSessionFromStore } from "$lib/server/utils/session.service";
|
import { getSessionFromStore } from "$lib/server/utils/session.service";
|
||||||
|
|
||||||
export const actions = {
|
export const actions = {
|
||||||
refetchDistributors: async () => {
|
refetchDistributors: async () => {
|
||||||
const sess = await getSessionFromStore(constants.SCRAP_API_SESSION_KEY);
|
const sess = await getSessionFromStore(constants.SCRAP_API_SESSION_KEY);
|
||||||
if (!sess) {
|
if (!sess) {
|
||||||
return fail(400, {
|
return fail(400, {
|
||||||
success: false,
|
success: false,
|
||||||
errors: [{ message: "No api session found" }],
|
errors: [{ message: "No api session found" }],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const done = await getDistributors(sess.sessionToken);
|
const done = await getDistributors(sess.sessionToken);
|
||||||
console.log(`[+] ${done.data.length} distributors found`);
|
console.log(`[+] ${done.data.length} distributors found`);
|
||||||
// fs.writeFileSync("distributors.json", JSON.stringify(done.data, null, 2));
|
// fs.writeFileSync("distributors.json", JSON.stringify(done.data, null, 2));
|
||||||
if (!done.ok) {
|
if (!done.ok) {
|
||||||
return fail(400, {
|
return fail(400, {
|
||||||
success: false,
|
success: false,
|
||||||
errors: [{ message: done.message }],
|
errors: [{ message: done.message }],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
await dbApiUser.upsertMany(done.data, true, ApiUserTypes.DISTRIBUTOR);
|
await dbApiUser.upsertMany(done.data, true, ApiUserTypes.DISTRIBUTOR);
|
||||||
return { success: true, errors: [] as ServerError };
|
return { success: true, errors: [] as ServerError };
|
||||||
},
|
},
|
||||||
|
|
||||||
refetchDealers: async () => {
|
refetchDealers: async () => {
|
||||||
const sess = await getSessionFromStore(constants.SCRAP_API_SESSION_KEY);
|
const sess = await getSessionFromStore(constants.SCRAP_API_SESSION_KEY);
|
||||||
if (!sess) {
|
if (!sess) {
|
||||||
return fail(400, {
|
return fail(400, {
|
||||||
success: false,
|
success: false,
|
||||||
errors: [{ message: "No api session found" }],
|
errors: [{ message: "No api session found" }],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const distributor_ids = await dbApiUser.getAllIdsByUserType(
|
const distributor_ids = await dbApiUser.getAllIdsByUserType(
|
||||||
ApiUserTypes.DISTRIBUTOR,
|
ApiUserTypes.DISTRIBUTOR,
|
||||||
);
|
);
|
||||||
const done = await getDealers(sess.sessionToken, distributor_ids);
|
console.log(distributor_ids);
|
||||||
console.log(`[+] ${done.dealers.length} dealers found`);
|
const done = await getDealers(sess.sessionToken, distributor_ids);
|
||||||
// fs.writeFileSync("dealers.json", JSON.stringify(done.dealers, null, 2));
|
console.log(`[+] ${done.dealers.length} dealers found`);
|
||||||
if (done.errors.length > 0) {
|
// fs.writeFileSync("dealers.json", JSON.stringify(done.dealers, null, 2));
|
||||||
return fail(400, { success: false, errors: done.errors });
|
if (done.errors.length > 0) {
|
||||||
}
|
return fail(400, { success: false, errors: done.errors });
|
||||||
await dbApiUser.upsertMany(done.dealers, true, ApiUserTypes.DEALER);
|
}
|
||||||
return { success: true, errors: [] as ServerError };
|
await dbApiUser.upsertMany(done.dealers, true, ApiUserTypes.DEALER);
|
||||||
},
|
return { success: true, errors: [] as ServerError };
|
||||||
|
},
|
||||||
} satisfies Actions;
|
} satisfies Actions;
|
||||||
|
|||||||
@@ -40,6 +40,7 @@
|
|||||||
|
|
||||||
let refetchDataM = api.apiData.refetchData.createMutation({
|
let refetchDataM = api.apiData.refetchData.createMutation({
|
||||||
onSuccess: (o) => {
|
onSuccess: (o) => {
|
||||||
|
console.log(o);
|
||||||
if (!o.success) {
|
if (!o.success) {
|
||||||
for (const each of o.errors) {
|
for (const each of o.errors) {
|
||||||
toast.error(each.message);
|
toast.error(each.message);
|
||||||
@@ -49,6 +50,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
onError: (e) => {
|
onError: (e) => {
|
||||||
|
console.log(e);
|
||||||
toast.error(e.message);
|
toast.error(e.message);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -19,12 +19,12 @@
|
|||||||
let updateDrawFilterM = api.draw.savePresetInfoForDraws.createMutation({
|
let updateDrawFilterM = api.draw.savePresetInfoForDraws.createMutation({
|
||||||
onSuccess: (d) => {
|
onSuccess: (d) => {
|
||||||
console.log(d);
|
console.log(d);
|
||||||
toast("Saved successfully.");
|
toast("Saved successfully");
|
||||||
},
|
},
|
||||||
onError: (e) => {
|
onError: (e) => {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
toast(
|
toast(
|
||||||
"An error occurred while fetching data. Try again after a page refresh.",
|
"An error occurred while fetching data. Try again after a page refresh",
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user