Files
TaxHacker_s23/prisma/seed.ts
Vasily Zubarev 0b98a2c307 (squash) init
feat: filters, settings, backups

fix: ts compile errors

feat: new dashboard, webp previews and settings

feat: use webp for pdfs

feat: use webp

fix: analyze resets old data

fix: switch to corsproxy

fix: switch to free cors

fix: max upload limit

fix: currency conversion

feat: transaction export

fix: currency conversion

feat: refactor settings actions

feat: new loader

feat: README + LICENSE

doc: update readme

doc: update readme

doc: update readme

doc: update screenshots

ci: bump prisma
2025-03-16 21:29:20 +01:00

491 lines
14 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { PrismaClient } from "@prisma/client"
const prisma = new PrismaClient()
const settings = [
{
code: "app_title",
name: "App Title",
description: "",
value: "TaxHacker",
},
{
code: "default_currency",
name: "Default Currency",
description: "Don't change this setting if you already have multi-currency transactions. I won't recalculate them.",
value: "EUR",
},
{
code: "default_category",
name: "Default Category",
description: "",
value: "other",
},
{
code: "default_project",
name: "Default Project",
description: "",
value: "personal",
},
{
code: "default_type",
name: "Default Type",
description: "",
value: "expense",
},
{
code: "openai_api_key",
name: "ChatGPT API Key",
description: "You can get if from here: https://platform.openai.com/settings/organization/api-keys",
value: "",
},
{
code: "prompt_analyse_new_file",
name: "Prompt for Analyze Transaction",
description:
"Allowed variables: {fields}, {categories}, {categories.code}, {projects}, {projects.code}, {json_structure}",
value: `You are an accountant and invoice analysis assistant.
Extract the following information from the given invoice:
{fields}
Where categories are:
{categories}
And projects are:
{projects}
If you can't find something leave it blank. Return only valid JSON with these fields:
{json_structure}
Return only one object. Do not include any other text in your response!`,
},
{
code: "is_welcome_message_hidden",
name: "Do not show welcome message on dashboard",
description: "",
value: "false",
},
]
const categories = [
{
code: "ads",
name: "Advertisement",
color: "#882727",
llm_prompt: "ads, promos, online ads, etc",
},
{
code: "swag",
name: "Swag and Goods",
color: "#882727",
llm_prompt: "swag, stickers, goods, etc",
},
{ code: "donations", name: "Gifts and Donations", color: "#1e6359", llm_prompt: "donations, gifts, charity" },
{ code: "tools", name: "Equipment and Tools", color: "#c69713", llm_prompt: "equipment, tools" },
{ code: "events", name: "Events and Conferences", color: "#ff8b32", llm_prompt: "events, conferences" },
{ code: "food", name: "Food and Drinks", color: "#d40e70", llm_prompt: "food, drinks, business meals" },
{ code: "insurance", name: "Insurance", color: "#050942", llm_prompt: "insurance, health, life" },
{ code: "invoice", name: "Invoice", color: "#064e85", llm_prompt: "custom invoice, bill" },
{ code: "communication", name: "Mobile and Internet", color: "#0e7d86", llm_prompt: "mobile, internet, phone" },
{ code: "office", name: "Office Supplies", color: "#59b0b9", llm_prompt: "office, supplies, stationery" },
{ code: "online", name: "Online Services", color: "#8753fb", llm_prompt: "online services, saas, subscriptions" },
{ code: "rental", name: "Rental", color: "#050942", llm_prompt: "rental, lease" },
{
code: "education",
name: "Education",
color: "#ee5d6c",
llm_prompt: "education, professional development, trainings",
},
{ code: "salary", name: "Salary", color: "#ce4993", llm_prompt: "salary, wages, etc" },
{ code: "fees", name: "Fees", color: "#6a0d83", llm_prompt: "fees, charges, penalties, etc" },
{ code: "travel", name: "Travel Expenses", color: "#fb9062", llm_prompt: "travel, accommodation, etc" },
{ code: "utility_bills", name: "Utility Bills", color: "#af7e2e", llm_prompt: "bills, electricity, water, etc" },
{
code: "transport",
name: "Transport",
color: "#800000",
llm_prompt: "transportation costs, fuel, car rental, vignettes, etc",
},
{ code: "software", name: "Software", color: "#2b5a1d", llm_prompt: "software, licenses" },
{ code: "other", name: "Other", color: "#121216", llm_prompt: "other, miscellaneous," },
]
const projects = [{ code: "personal", name: "Personal", llm_prompt: "personal", color: "#1e202b" }]
const currencies = [
{ code: "USD", name: "$" },
{ code: "EUR", name: "€" },
{ code: "GBP", name: "£" },
{ code: "INR", name: "₹" },
{ code: "AUD", name: "$" },
{ code: "CAD", name: "$" },
{ code: "SGD", name: "$" },
{ code: "CHF", name: "Fr" },
{ code: "MYR", name: "RM" },
{ code: "JPY", name: "¥" },
{ code: "CNY", name: "¥" },
{ code: "NZD", name: "$" },
{ code: "THB", name: "฿" },
{ code: "HUF", name: "Ft" },
{ code: "AED", name: "د.إ" },
{ code: "HKD", name: "$" },
{ code: "MXN", name: "$" },
{ code: "ZAR", name: "R" },
{ code: "PHP", name: "₱" },
{ code: "SEK", name: "kr" },
{ code: "IDR", name: "Rp" },
{ code: "BRL", name: "R$" },
{ code: "SAR", name: "﷼" },
{ code: "TRY", name: "₺" },
{ code: "KES", name: "KSh" },
{ code: "KRW", name: "₩" },
{ code: "EGP", name: "£" },
{ code: "IQD", name: "ع.د" },
{ code: "NOK", name: "kr" },
{ code: "KWD", name: "د.ك" },
{ code: "RUB", name: "₽" },
{ code: "DKK", name: "kr" },
{ code: "PKR", name: "₨" },
{ code: "ILS", name: "₪" },
{ code: "PLN", name: "zł" },
{ code: "QAR", name: "﷼" },
{ code: "OMR", name: "﷼" },
{ code: "COP", name: "$" },
{ code: "CLP", name: "$" },
{ code: "TWD", name: "NT$" },
{ code: "ARS", name: "$" },
{ code: "CZK", name: "Kč" },
{ code: "VND", name: "₫" },
{ code: "MAD", name: "د.م." },
{ code: "JOD", name: "د.ا" },
{ code: "BHD", name: ".د.ب" },
{ code: "XOF", name: "CFA" },
{ code: "LKR", name: "₨" },
{ code: "UAH", name: "₴" },
{ code: "NGN", name: "₦" },
{ code: "TND", name: "د.ت" },
{ code: "UGX", name: "USh" },
{ code: "RON", name: "lei" },
{ code: "BDT", name: "৳" },
{ code: "PEN", name: "S/" },
{ code: "GEL", name: "₾" },
{ code: "XAF", name: "FCFA" },
{ code: "FJD", name: "$" },
{ code: "VEF", name: "Bs" },
{ code: "VES", name: "Bs.S" },
{ code: "BYN", name: "Br" },
{ code: "UZS", name: "лв" },
{ code: "BGN", name: "лв" },
{ code: "DZD", name: "د.ج" },
{ code: "IRR", name: "﷼" },
{ code: "DOP", name: "RD$" },
{ code: "ISK", name: "kr" },
{ code: "CRC", name: "₡" },
{ code: "SYP", name: "£" },
{ code: "JMD", name: "J$" },
{ code: "LYD", name: "ل.د" },
{ code: "GHS", name: "₵" },
{ code: "MUR", name: "₨" },
{ code: "AOA", name: "Kz" },
{ code: "UYU", name: "$U" },
{ code: "AFN", name: "؋" },
{ code: "LBP", name: "ل.ل" },
{ code: "XPF", name: "₣" },
{ code: "TTD", name: "TT$" },
{ code: "TZS", name: "TSh" },
{ code: "ALL", name: "Lek" },
{ code: "XCD", name: "$" },
{ code: "GTQ", name: "Q" },
{ code: "NPR", name: "₨" },
{ code: "BOB", name: "Bs." },
{ code: "ZWD", name: "Z$" },
{ code: "BBD", name: "$" },
{ code: "CUC", name: "$" },
{ code: "LAK", name: "₭" },
{ code: "BND", name: "$" },
{ code: "BWP", name: "P" },
{ code: "HNL", name: "L" },
{ code: "PYG", name: "₲" },
{ code: "ETB", name: "Br" },
{ code: "NAD", name: "$" },
{ code: "PGK", name: "K" },
{ code: "SDG", name: "ج.س." },
{ code: "MOP", name: "MOP$" },
{ code: "BMD", name: "$" },
{ code: "NIO", name: "C$" },
{ code: "BAM", name: "KM" },
{ code: "KZT", name: "₸" },
{ code: "PAB", name: "B/." },
{ code: "GYD", name: "$" },
{ code: "YER", name: "﷼" },
{ code: "MGA", name: "Ar" },
{ code: "KYD", name: "$" },
{ code: "MZN", name: "MT" },
{ code: "RSD", name: "дин." },
{ code: "SCR", name: "₨" },
{ code: "AMD", name: "֏" },
{ code: "AZN", name: "₼" },
{ code: "SBD", name: "$" },
{ code: "SLL", name: "Le" },
{ code: "TOP", name: "T$" },
{ code: "BZD", name: "BZ$" },
{ code: "GMD", name: "D" },
{ code: "MWK", name: "MK" },
{ code: "BIF", name: "FBu" },
{ code: "HTG", name: "G" },
{ code: "SOS", name: "S" },
{ code: "GNF", name: "FG" },
{ code: "MNT", name: "₮" },
{ code: "MVR", name: "Rf" },
{ code: "CDF", name: "FC" },
{ code: "STN", name: "Db" },
{ code: "TJS", name: "ЅМ" },
{ code: "KPW", name: "₩" },
{ code: "KGS", name: "лв" },
{ code: "LRD", name: "$" },
{ code: "LSL", name: "L" },
{ code: "MMK", name: "K" },
{ code: "GIP", name: "£" },
{ code: "MDL", name: "L" },
{ code: "CUP", name: "₱" },
{ code: "KHR", name: "៛" },
{ code: "MKD", name: "ден" },
{ code: "VUV", name: "VT" },
{ code: "ANG", name: "ƒ" },
{ code: "MRU", name: "UM" },
{ code: "SZL", name: "L" },
{ code: "CVE", name: "$" },
{ code: "SRD", name: "$" },
{ code: "SVC", name: "$" },
{ code: "BSD", name: "$" },
{ code: "RWF", name: "R₣" },
{ code: "AWG", name: "ƒ" },
{ code: "BTN", name: "Nu." },
{ code: "DJF", name: "Fdj" },
{ code: "KMF", name: "CF" },
{ code: "ERN", name: "Nfk" },
{ code: "FKP", name: "£" },
{ code: "SHP", name: "£" },
{ code: "WST", name: "WS$" },
{ code: "JEP", name: "£" },
{ code: "TMT", name: "m" },
{ code: "GGP", name: "£" },
{ code: "IMP", name: "£" },
{ code: "TVD", name: "$" },
{ code: "ZMW", name: "ZK" },
{ code: "ADA", name: "Crypto" },
{ code: "BCH", name: "Crypto" },
{ code: "BTC", name: "Crypto" },
{ code: "CLF", name: "UF" },
{ code: "CNH", name: "¥" },
{ code: "DOGE", name: "Crypto" },
{ code: "DOT", name: "Crypto" },
{ code: "ETH", name: "Crypto" },
{ code: "LINK", name: "Crypto" },
{ code: "LTC", name: "Crypto" },
{ code: "LUNA", name: "Crypto" },
{ code: "SLE", name: "Le" },
{ code: "UNI", name: "Crypto" },
{ code: "XBT", name: "Crypto" },
{ code: "XLM", name: "Crypto" },
{ code: "XRP", name: "Crypto" },
{ code: "ZWL", name: "$" },
]
const fields = [
{
code: "name",
name: "Name",
type: "text",
llm_prompt: "human readable name, summarize what is the invoice about",
isRequired: true,
isExtra: false,
},
{
code: "description",
name: "Description",
type: "text",
llm_prompt: "description of the transaction",
isRequired: false,
isExtra: false,
},
{
code: "merchant",
name: "Merchant",
type: "text",
llm_prompt: "merchant name",
isRequired: false,
isExtra: false,
},
{
code: "type",
name: "Type",
type: "text",
llm_prompt: "",
isRequired: false,
isExtra: false,
},
{
code: "total",
name: "Total",
type: "number",
llm_prompt: "total total of the transaction",
isRequired: false,
isExtra: false,
},
{
code: "currencyCode",
name: "Currency",
type: "text",
llm_prompt: "currency code, ISO 4217 three letter code like USD, EUR, including crypto codes like BTC, ETH, etc",
isRequired: false,
isExtra: false,
},
{
code: "convertedTotal",
name: "Converted Total",
type: "number",
llm_prompt: "",
isRequired: false,
isExtra: false,
},
{
code: "convertedCurrencyCode",
name: "Converted Currency Code",
type: "text",
llm_prompt: "",
isRequired: false,
isExtra: false,
},
{
code: "note",
name: "Note",
type: "text",
llm_prompt: "",
isRequired: false,
isExtra: false,
},
{
code: "categoryCode",
name: "Category",
type: "text",
llm_prompt: "category code, one of: {categories.code}",
isRequired: false,
isExtra: false,
},
{
code: "projectCode",
name: "Project",
type: "select",
llm_prompt: "project code, one of: {projects.code}",
isRequired: false,
isExtra: false,
},
{
code: "issuedAt",
name: "Issued At",
type: "date",
llm_prompt: "issued at date (YYYY-MM-DD format)",
isRequired: false,
isExtra: false,
},
{
code: "text",
name: "Extracted Text",
type: "text",
llm_prompt: "extract all recognised text from the invoice",
isRequired: false,
isExtra: false,
},
{
code: "vat",
name: "VAT Amount",
type: "number",
llm_prompt: "total VAT total in currency of the invoice",
isRequired: false,
isExtra: true,
},
]
async function main() {
// Clean up existing data
// await prisma.category.deleteMany({})
// await prisma.currency.deleteMany({})
// await prisma.field.deleteMany({})
// await prisma.setting.deleteMany({})
// await prisma.project.deleteMany({})
// Seed projects
for (const project of projects) {
await prisma.project.upsert({
where: { code: project.code },
update: { name: project.name, color: project.color, llm_prompt: project.llm_prompt },
create: project,
})
}
// Seed categories
for (const category of categories) {
await prisma.category.upsert({
where: { code: category.code },
update: { name: category.name, color: category.color, llm_prompt: category.llm_prompt },
create: category,
})
}
// Seed currencies
for (const currency of currencies) {
await prisma.currency.upsert({
where: { code: currency.code },
update: { name: currency.name },
create: currency,
})
}
// Seed fields
for (const field of fields) {
await prisma.field.upsert({
where: { code: field.code },
update: {
name: field.name,
type: field.type,
llm_prompt: field.llm_prompt,
isRequired: field.isRequired,
isExtra: field.isExtra,
},
create: field,
})
}
// Seed settings
for (const setting of settings) {
await prisma.setting.upsert({
where: { code: setting.code },
update: { name: setting.name, description: setting.description, value: setting.value },
create: setting,
})
}
await prisma.setting.deleteMany({
where: {
code: {
notIn: settings.map((setting) => setting.code),
},
},
})
console.log("Database seeded successfully")
}
main()
.then(async () => {
await prisma.$disconnect()
})
.catch(async (e) => {
console.error(e)
await prisma.$disconnect()
process.exit(1)
})