fix: rename data -> models

This commit is contained in:
Vasily Zubarev
2025-03-22 10:39:47 +01:00
parent ac8f848d94
commit 9ca7d9c712
50 changed files with 103 additions and 98 deletions

View File

@@ -1,6 +1,6 @@
PORT=7331
UPLOAD_PATH="./uploads"
DATABASE_URL="file:./db.sqlite"
UPLOAD_PATH="./data/uploads"
DATABASE_URL="file:../data/db.sqlite"
PROMPT_ANALYSE_NEW_FILE="You are an accountant and invoice analysis assistant.
Extract the following information from the given invoice:

4
.gitignore vendored
View File

@@ -1,7 +1,7 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# uploads
/uploads/*
# data directory
/data/*
# dependencies
/node_modules

View File

@@ -1,7 +1,7 @@
import { ExportFields, ExportFilters, exportImportFieldsMapping } from "@/data/export_and_import"
import { getFields } from "@/data/fields"
import { getFilesByTransactionId } from "@/data/files"
import { getTransactions } from "@/data/transactions"
import { ExportFields, ExportFilters, exportImportFieldsMapping } from "@/models/export_and_import"
import { getFields } from "@/models/fields"
import { getFilesByTransactionId } from "@/models/files"
import { getTransactions } from "@/models/transactions"
import { format } from "@fast-csv/format"
import { formatDate } from "date-fns"
import fs from "fs"

View File

@@ -1,7 +1,7 @@
"use server"
import { createFile } from "@/data/files"
import { FILE_UNSORTED_UPLOAD_PATH, getUnsortedFileUploadPath } from "@/lib/files"
import { createFile } from "@/models/files"
import { existsSync } from "fs"
import { mkdir, writeFile } from "fs/promises"
import { revalidatePath } from "next/cache"

View File

@@ -1,4 +1,4 @@
import { getFileById } from "@/data/files"
import { getFileById } from "@/models/files"
import fs from "fs/promises"
import { NextResponse } from "next/server"
@@ -16,12 +16,11 @@ export async function GET(request: Request, { params }: { params: Promise<{ file
if (!file) {
return new NextResponse("File not found", { status: 404 })
}
// Check if file exists
try {
await fs.access(file.path)
} catch {
return new NextResponse("File not found on disk", { status: 404 })
return new NextResponse(`File not found on disk: ${file.path}`, { status: 404 })
}
// Read file

View File

@@ -1,6 +1,6 @@
import { getFileById } from "@/data/files"
import { resizeImage } from "@/lib/images"
import { pdfToImages } from "@/lib/pdf"
import { getFileById } from "@/models/files"
import fs from "fs/promises"
import { NextResponse } from "next/server"
import path from "path"
@@ -27,7 +27,7 @@ export async function GET(request: Request, { params }: { params: Promise<{ file
try {
await fs.access(file.path)
} catch {
return new NextResponse("File not found on disk", { status: 404 })
return new NextResponse(`File not found on disk: ${file.path}`, { status: 404 })
}
let previewPath = file.path

View File

@@ -1,7 +1,7 @@
"use server"
import { exportImportFieldsMapping } from "@/data/export_and_import"
import { createTransaction } from "@/data/transactions"
import { exportImportFieldsMapping } from "@/models/export_and_import"
import { createTransaction } from "@/models/transactions"
import { parse } from "@fast-csv/parse"
import { revalidatePath } from "next/cache"

View File

@@ -1,5 +1,5 @@
import { ImportCSVTable } from "@/components/import/csv"
import { getFields } from "@/data/fields"
import { getFields } from "@/models/fields"
export default async function CSVImportPage() {
const fields = await getFields()

View File

@@ -3,8 +3,8 @@ import MobileMenu from "@/components/sidebar/mobile-menu"
import { AppSidebar } from "@/components/sidebar/sidebar"
import { SidebarInset, SidebarProvider } from "@/components/ui/sidebar"
import { Toaster } from "@/components/ui/sonner"
import { getUnsortedFilesCount } from "@/data/files"
import { getSettings } from "@/data/settings"
import { getUnsortedFilesCount } from "@/models/files"
import { getSettings } from "@/models/settings"
import type { Metadata, Viewport } from "next"
import { NotificationProvider } from "./context"
import "./globals.css"

View File

@@ -3,9 +3,9 @@ import { StatsWidget } from "@/components/dashboard/stats-widget"
import DashboardUnsortedWidget from "@/components/dashboard/unsorted-widget"
import { WelcomeWidget } from "@/components/dashboard/welcome-widget"
import { Separator } from "@/components/ui/separator"
import { getUnsortedFiles } from "@/data/files"
import { getSettings } from "@/data/settings"
import { TransactionFilters } from "@/data/transactions"
import { getUnsortedFiles } from "@/models/files"
import { getSettings } from "@/models/settings"
import { TransactionFilters } from "@/models/transactions"
export default async function Home({ searchParams }: { searchParams: Promise<TransactionFilters> }) {
const filters = await searchParams

View File

@@ -1,12 +1,12 @@
"use server"
import { createCategory, deleteCategory, updateCategory } from "@/data/categories"
import { createCurrency, deleteCurrency, updateCurrency } from "@/data/currencies"
import { createField, deleteField, updateField } from "@/data/fields"
import { createProject, deleteProject, updateProject } from "@/data/projects"
import { updateSettings } from "@/data/settings"
import { settingsFormSchema } from "@/forms/settings"
import { codeFromName } from "@/lib/utils"
import { createCategory, deleteCategory, updateCategory } from "@/models/categories"
import { createCurrency, deleteCurrency, updateCurrency } from "@/models/currencies"
import { createField, deleteField, updateField } from "@/models/fields"
import { createProject, deleteProject, updateProject } from "@/models/projects"
import { updateSettings } from "@/models/settings"
import { revalidatePath } from "next/cache"
import { redirect } from "next/navigation"

View File

@@ -1,7 +1,7 @@
import { addCategoryAction, deleteCategoryAction, editCategoryAction } from "@/app/settings/actions"
import { CrudTable } from "@/components/settings/crud"
import { getCategories } from "@/data/categories"
import { randomHexColor } from "@/lib/utils"
import { getCategories } from "@/models/categories"
export default async function CategoriesSettingsPage() {
const categories = await getCategories()

View File

@@ -1,6 +1,6 @@
import { addCurrencyAction, deleteCurrencyAction, editCurrencyAction } from "@/app/settings/actions"
import { CrudTable } from "@/components/settings/crud"
import { getCurrencies } from "@/data/currencies"
import { getCurrencies } from "@/models/currencies"
export default async function CurrenciesSettingsPage() {
const currencies = await getCurrencies()

View File

@@ -1,6 +1,6 @@
import { addFieldAction, deleteFieldAction, editFieldAction } from "@/app/settings/actions"
import { CrudTable } from "@/components/settings/crud"
import { getFields } from "@/data/fields"
import { getFields } from "@/models/fields"
export default async function FieldsSettingsPage() {
const fields = await getFields()

View File

@@ -1,6 +1,6 @@
import LLMSettingsForm from "@/components/settings/llm-settings-form"
import { getFields } from "@/data/fields"
import { getSettings } from "@/data/settings"
import { getFields } from "@/models/fields"
import { getSettings } from "@/models/settings"
export default async function LlmSettingsPage() {
const settings = await getSettings()

View File

@@ -1,7 +1,7 @@
import GlobalSettingsForm from "@/components/settings/global-settings-form"
import { getCategories } from "@/data/categories"
import { getCurrencies } from "@/data/currencies"
import { getSettings } from "@/data/settings"
import { getCategories } from "@/models/categories"
import { getCurrencies } from "@/models/currencies"
import { getSettings } from "@/models/settings"
export default async function SettingsPage() {
const settings = await getSettings()

View File

@@ -1,7 +1,7 @@
import { addProjectAction, deleteProjectAction, editProjectAction } from "@/app/settings/actions"
import { CrudTable } from "@/components/settings/crud"
import { getProjects } from "@/data/projects"
import { randomHexColor } from "@/lib/utils"
import { getProjects } from "@/models/projects"
export default async function ProjectsSettingsPage() {
const projects = await getProjects()

View File

@@ -1,4 +1,4 @@
import { getTransactionById } from "@/data/transactions"
import { getTransactionById } from "@/models/transactions"
import { notFound } from "next/navigation"
export default async function TransactionLayout({

View File

@@ -2,13 +2,13 @@ import { FormTextarea } from "@/components/forms/simple"
import TransactionEditForm from "@/components/transactions/edit"
import TransactionFiles from "@/components/transactions/transaction-files"
import { Card } from "@/components/ui/card"
import { getCategories } from "@/data/categories"
import { getCurrencies } from "@/data/currencies"
import { getFields } from "@/data/fields"
import { getFilesByTransactionId } from "@/data/files"
import { getProjects } from "@/data/projects"
import { getSettings } from "@/data/settings"
import { getTransactionById } from "@/data/transactions"
import { getCategories } from "@/models/categories"
import { getCurrencies } from "@/models/currencies"
import { getFields } from "@/models/fields"
import { getFilesByTransactionId } from "@/models/files"
import { getProjects } from "@/models/projects"
import { getSettings } from "@/models/settings"
import { getTransactionById } from "@/models/transactions"
import { notFound } from "next/navigation"
export default async function TransactionPage({ params }: { params: Promise<{ transactionId: string }> }) {

View File

@@ -1,6 +1,8 @@
"use server"
import { createFile, deleteFile } from "@/data/files"
import { transactionFormSchema } from "@/forms/transactions"
import { FILE_UPLOAD_PATH, getTransactionFileUploadPath } from "@/lib/files"
import { createFile, deleteFile } from "@/models/files"
import {
bulkDeleteTransactions,
createTransaction,
@@ -8,9 +10,7 @@ import {
getTransactionById,
updateTransaction,
updateTransactionFiles,
} from "@/data/transactions"
import { transactionFormSchema } from "@/forms/transactions"
import { FILE_UPLOAD_PATH, getTransactionFileUploadPath } from "@/lib/files"
} from "@/models/transactions"
import { existsSync } from "fs"
import { mkdir, writeFile } from "fs/promises"
import { revalidatePath } from "next/cache"

View File

@@ -4,10 +4,10 @@ import { TransactionSearchAndFilters } from "@/components/transactions/filters"
import { TransactionList } from "@/components/transactions/list"
import { NewTransactionDialog } from "@/components/transactions/new"
import { Button } from "@/components/ui/button"
import { getCategories } from "@/data/categories"
import { getFields } from "@/data/fields"
import { getProjects } from "@/data/projects"
import { getTransactions, TransactionFilters } from "@/data/transactions"
import { getCategories } from "@/models/categories"
import { getFields } from "@/models/fields"
import { getProjects } from "@/models/projects"
import { getTransactions, TransactionFilters } from "@/models/transactions"
import { Download, Plus, Upload } from "lucide-react"
import { Metadata } from "next"

View File

@@ -1,9 +1,9 @@
"use server"
import { deleteFile, getFileById, updateFile } from "@/data/files"
import { createTransaction, updateTransactionFiles } from "@/data/transactions"
import { transactionFormSchema } from "@/forms/transactions"
import { getTransactionFileUploadPath } from "@/lib/files"
import { deleteFile, getFileById, updateFile } from "@/models/files"
import { createTransaction, updateTransactionFiles } from "@/models/transactions"
import { mkdir, rename } from "fs/promises"
import { revalidatePath } from "next/cache"
import path from "path"

View File

@@ -4,12 +4,12 @@ import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"
import { Button } from "@/components/ui/button"
import { Card } from "@/components/ui/card"
import AnalyzeForm from "@/components/unsorted/analyze-form"
import { getCategories } from "@/data/categories"
import { getCurrencies } from "@/data/currencies"
import { getFields } from "@/data/fields"
import { getUnsortedFiles } from "@/data/files"
import { getProjects } from "@/data/projects"
import { getSettings } from "@/data/settings"
import { getCategories } from "@/models/categories"
import { getCurrencies } from "@/models/currencies"
import { getFields } from "@/models/fields"
import { getUnsortedFiles } from "@/models/files"
import { getProjects } from "@/models/projects"
import { getSettings } from "@/models/settings"
import { FileText, PartyPopper, Settings, Upload } from "lucide-react"
import { Metadata } from "next"
import Link from "next/link"

View File

@@ -2,11 +2,11 @@
import { useNotification } from "@/app/context"
import { uploadFilesAction } from "@/app/files/actions"
import { FormError } from "@/components/forms/error"
import { FILE_ACCEPTED_MIMETYPES } from "@/lib/files"
import { Camera, Loader2 } from "lucide-react"
import { useRouter } from "next/navigation"
import { startTransition, useState } from "react"
import { FormError } from "../forms/error"
export default function DashboardDropZoneWidget() {
const router = useRouter()

View File

@@ -1,9 +1,9 @@
"use client"
import { TransactionFilters } from "@/data/transactions"
import { DateRangePicker } from "@/components/forms/date-range-picker"
import { useTransactionFilters } from "@/hooks/use-transaction-filters"
import { TransactionFilters } from "@/models/transactions"
import { format } from "date-fns"
import { DateRangePicker } from "../forms/date-range-picker"
export function FiltersWidget({
defaultFilters,

View File

@@ -1,7 +1,7 @@
import { Badge } from "@/components/ui/badge"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { ProjectStats } from "@/data/stats"
import { formatCurrency } from "@/lib/utils"
import { ProjectStats } from "@/models/stats"
import { Project } from "@prisma/client"
import { Plus } from "lucide-react"
import Link from "next/link"

View File

@@ -1,11 +1,11 @@
import { getProjects } from "@/data/projects"
import { getDashboardStats, getProjectStats } from "@/data/stats"
import { TransactionFilters } from "@/data/transactions"
import { FiltersWidget } from "@/components/dashboard/filters-widget"
import { ProjectsWidget } from "@/components/dashboard/projects-widget"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { formatCurrency } from "@/lib/utils"
import { getProjects } from "@/models/projects"
import { getDashboardStats, getProjectStats } from "@/models/stats"
import { TransactionFilters } from "@/models/transactions"
import { ArrowDown, ArrowUp, BicepsFlexed } from "lucide-react"
import { Card, CardContent, CardHeader, CardTitle } from "../ui/card"
import { FiltersWidget } from "./filters-widget"
import { ProjectsWidget } from "./projects-widget"
export async function StatsWidget({ filters }: { filters: TransactionFilters }) {
const projects = await getProjects()

View File

@@ -1,6 +1,6 @@
import { Button } from "@/components/ui/button"
import { Card, CardDescription, CardTitle } from "@/components/ui/card"
import { getSettings, updateSettings } from "@/data/settings"
import { getSettings, updateSettings } from "@/models/settings"
import { Banknote, ChartBarStacked, FolderOpenDot, Key, TextCursorInput, X } from "lucide-react"
import { revalidatePath } from "next/cache"
import Link from "next/link"

View File

@@ -1,5 +1,8 @@
"use client"
import { DateRangePicker } from "@/components/forms/date-range-picker"
import { FormSelectCategory } from "@/components/forms/select-category"
import { FormSelectProject } from "@/components/forms/select-project"
import { Button } from "@/components/ui/button"
import {
Dialog,
@@ -16,9 +19,6 @@ import { Category, Field, Project } from "@prisma/client"
import { formatDate } from "date-fns"
import { useRouter } from "next/navigation"
import { useState } from "react"
import { DateRangePicker } from "../forms/date-range-picker"
import { FormSelectCategory } from "../forms/select-category"
import { FormSelectProject } from "../forms/select-project"
const deselectedFields = ["files", "text"]

View File

@@ -1,12 +1,12 @@
"use client"
import { parseCSVAction, saveTransactionsAction } from "@/app/import/csv/actions"
import { FormError } from "@/components/forms/error"
import { Button } from "@/components/ui/button"
import { Field } from "@prisma/client"
import { Loader2, Play, Upload } from "lucide-react"
import { useRouter } from "next/navigation"
import { startTransition, useActionState, useEffect, useState } from "react"
import { parseCSVAction, saveTransactionsAction } from "../../app/import/csv/actions"
import { FormError } from "../forms/error"
const MAX_PREVIEW_ROWS = 100

View File

@@ -1,6 +1,7 @@
"use client"
import { saveSettingsAction } from "@/app/settings/actions"
import { FormError } from "@/components/forms/error"
import { FormSelectCategory } from "@/components/forms/select-category"
import { FormSelectCurrency } from "@/components/forms/select-currency"
import { FormSelectType } from "@/components/forms/select-type"
@@ -9,7 +10,6 @@ import { Button } from "@/components/ui/button"
import { Category, Currency } from "@prisma/client"
import { CircleCheckBig } from "lucide-react"
import { useActionState } from "react"
import { FormError } from "../forms/error"
export default function GlobalSettingsForm({
settings,

View File

@@ -2,14 +2,14 @@
import { fieldsToJsonSchema } from "@/app/ai/schema"
import { saveSettingsAction } from "@/app/settings/actions"
import { FormError } from "@/components/forms/error"
import { FormInput, FormTextarea } from "@/components/forms/simple"
import { Button } from "@/components/ui/button"
import { Card, CardTitle } from "@/components/ui/card"
import { Field } from "@prisma/client"
import { CircleCheckBig, Edit } from "lucide-react"
import Link from "next/link"
import { useActionState } from "react"
import { FormError } from "../forms/error"
import { Card, CardTitle } from "../ui/card"
export default function LLMSettingsForm({ settings, fields }: { settings: Record<string, string>; fields: Field[] }) {
const [saveState, saveAction, pending] = useActionState(saveSettingsAction, null)

View File

@@ -1,8 +1,8 @@
"use client"
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
import { useSidebar } from "@/components/ui/sidebar"
import Link from "next/link"
import { Avatar, AvatarFallback, AvatarImage } from "../ui/avatar"
import { useSidebar } from "../ui/sidebar"
export default function MobileMenu({
settings,

View File

@@ -1,9 +1,9 @@
"use client"
import { SidebarMenuItem } from "@/components/ui/sidebar"
import { cn } from "@/lib/utils"
import { usePathname } from "next/navigation"
import { ComponentProps } from "react"
import { SidebarMenuItem } from "../ui/sidebar"
export function SidebarMenuItemWithHighlight({
href,

View File

@@ -1,6 +1,7 @@
"use client"
import { createTransactionAction } from "@/app/transactions/actions"
import { FormError } from "@/components/forms/error"
import { FormSelectCategory } from "@/components/forms/select-category"
import { FormSelectCurrency } from "@/components/forms/select-currency"
import { FormSelectProject } from "@/components/forms/select-project"
@@ -13,7 +14,6 @@ import { Import, Loader2 } from "lucide-react"
import Link from "next/link"
import { useRouter } from "next/navigation"
import { useActionState, useEffect, useState } from "react"
import { FormError } from "../forms/error"
export default function TransactionCreateForm({
categories,

View File

@@ -1,6 +1,7 @@
"use client"
import { deleteTransactionAction, saveTransactionAction } from "@/app/transactions/actions"
import { FormError } from "@/components/forms/error"
import { FormSelectCategory } from "@/components/forms/select-category"
import { FormSelectCurrency } from "@/components/forms/select-currency"
import { FormSelectProject } from "@/components/forms/select-project"
@@ -12,7 +13,6 @@ import { format } from "date-fns"
import { Loader2 } from "lucide-react"
import { useRouter } from "next/navigation"
import { startTransition, useActionState, useEffect, useState } from "react"
import { FormError } from "../forms/error"
export default function TransactionEditForm({
transaction,

View File

@@ -4,8 +4,8 @@ import { DateRangePicker } from "@/components/forms/date-range-picker"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
import { TransactionFilters } from "@/data/transactions"
import { isFiltered, useTransactionFilters } from "@/hooks/use-transaction-filters"
import { TransactionFilters } from "@/models/transactions"
import { Category, Project } from "@prisma/client"
import { X } from "lucide-react"

View File

@@ -6,10 +6,10 @@ import {
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog"
import { getCategories } from "@/data/categories"
import { getCurrencies } from "@/data/currencies"
import { getProjects } from "@/data/projects"
import { getSettings } from "@/data/settings"
import { getCategories } from "@/models/categories"
import { getCurrencies } from "@/models/currencies"
import { getProjects } from "@/models/projects"
import { getSettings } from "@/models/settings"
import TransactionCreateForm from "./create"
export async function NewTransactionDialog({ children }: { children: React.ReactNode }) {

View File

@@ -4,6 +4,7 @@ import { analyzeTransaction, retrieveAllAttachmentsForAI } from "@/app/ai/analyz
import { useNotification } from "@/app/context"
import { deleteUnsortedFileAction, saveFileAsTransactionAction } from "@/app/unsorted/actions"
import { FormConvertCurrency } from "@/components/forms/convert-currency"
import { FormError } from "@/components/forms/error"
import { FormSelectCategory } from "@/components/forms/select-category"
import { FormSelectCurrency } from "@/components/forms/select-currency"
import { FormSelectProject } from "@/components/forms/select-project"
@@ -13,7 +14,6 @@ import { Button } from "@/components/ui/button"
import { Category, Currency, Field, File, Project } from "@prisma/client"
import { Brain, Loader2 } from "lucide-react"
import { startTransition, useActionState, useMemo, useState } from "react"
import { FormError } from "../forms/error"
export default function AnalyzeForm({
file,

View File

@@ -1,4 +1,4 @@
import { TransactionFilters } from "@/data/transactions"
import { TransactionFilters } from "@/models/transactions"
import { format } from "date-fns"
import { useRouter, useSearchParams } from "next/navigation"
import { useEffect, useState } from "react"

View File

@@ -63,11 +63,17 @@ export const updateFile = async (id: string, data: any) => {
export const deleteFile = async (id: string) => {
const file = await getFileById(id)
if (file) {
if (!file) {
return
}
try {
await unlink(path.resolve(file.path))
} catch (error) {
console.error("Error deleting file:", error)
}
return await prisma.file.delete({
where: { id },
})
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "taxhacker",
"version": "0.1.0",
"version": "0.2.0",
"private": true,
"type": "module",
"scripts": {