Refactor data handlers + misc fixes

This refactors the data handlers into a more standard/understood model-like architecture, to prepare for a new, more robust config system.

It also fixes a problem with creating new Notes and uploading new Photos via the web interface (related to #58).

Finally, it speeds up docker builds by sending in less files, which aren't necessary or will be built anyway.

This is all in preparation to allow building #13 more robustly.
This commit is contained in:
Bruno Bernardino
2025-05-24 08:24:10 +01:00
parent e1193a2770
commit 6cfb62d1a2
61 changed files with 1822 additions and 1774 deletions

View File

@@ -1,7 +1,7 @@
import { Handlers } from 'fresh/server.ts';
import { DashboardLink, FreshContextState } from '/lib/types.ts';
import { getDashboardByUserId, updateDashboard } from '/lib/data/dashboard.ts';
import { DashboardModel } from '/lib/models/dashboard.ts';
interface Data {}
@@ -19,7 +19,7 @@ export const handler: Handlers<Data, FreshContextState> = {
return new Response('Unauthorized', { status: 401 });
}
const userDashboard = await getDashboardByUserId(context.state.user.id);
const userDashboard = await DashboardModel.getByUserId(context.state.user.id);
if (!userDashboard) {
return new Response('Not found', { status: 404 });
@@ -30,7 +30,7 @@ export const handler: Handlers<Data, FreshContextState> = {
if (typeof requestBody.links !== 'undefined') {
userDashboard.data.links = requestBody.links;
await updateDashboard(userDashboard);
await DashboardModel.update(userDashboard);
}
const responseBody: ResponseBody = { success: true };

View File

@@ -1,7 +1,7 @@
import { Handlers } from 'fresh/server.ts';
import { FreshContextState } from '/lib/types.ts';
import { getDashboardByUserId, updateDashboard } from '/lib/data/dashboard.ts';
import { DashboardModel } from '/lib/models/dashboard.ts';
interface Data {}
@@ -19,7 +19,7 @@ export const handler: Handlers<Data, FreshContextState> = {
return new Response('Unauthorized', { status: 401 });
}
const userDashboard = await getDashboardByUserId(context.state.user.id);
const userDashboard = await DashboardModel.getByUserId(context.state.user.id);
if (!userDashboard) {
return new Response('Not found', { status: 404 });
@@ -30,7 +30,7 @@ export const handler: Handlers<Data, FreshContextState> = {
if (typeof requestBody.notes !== 'undefined' && userDashboard.data.notes !== requestBody.notes) {
userDashboard.data.notes = requestBody.notes;
await updateDashboard(userDashboard);
await DashboardModel.update(userDashboard);
}
const responseBody: ResponseBody = { success: true };

View File

@@ -1,7 +1,7 @@
import { Handlers } from 'fresh/server.ts';
import { Budget, FreshContextState } from '/lib/types.ts';
import { createBudget, getBudgets } from '/lib/data/expenses.ts';
import { BudgetModel } from '/lib/models/expenses.ts';
interface Data {}
@@ -33,7 +33,7 @@ export const handler: Handlers<Data, FreshContextState> = {
}
try {
const newBudget = await createBudget(
const newBudget = await BudgetModel.create(
context.state.user.id,
requestBody.name,
requestBody.month,
@@ -48,7 +48,7 @@ export const handler: Handlers<Data, FreshContextState> = {
return new Response(`${error}`, { status: 500 });
}
const newBudgets = await getBudgets(context.state.user.id, requestBody.currentMonth);
const newBudgets = await BudgetModel.list(context.state.user.id, requestBody.currentMonth);
const responseBody: ResponseBody = { success: true, newBudgets };

View File

@@ -1,7 +1,7 @@
import { Handlers } from 'fresh/server.ts';
import { Budget, Expense, FreshContextState } from '/lib/types.ts';
import { createExpense, getBudgets, getExpenses } from '/lib/data/expenses.ts';
import { BudgetModel, ExpenseModel } from '/lib/models/expenses.ts';
interface Data {}
@@ -52,7 +52,7 @@ export const handler: Handlers<Data, FreshContextState> = {
}
try {
const newExpense = await createExpense(
const newExpense = await ExpenseModel.create(
context.state.user.id,
requestBody.cost,
requestBody.description,
@@ -69,9 +69,9 @@ export const handler: Handlers<Data, FreshContextState> = {
return new Response(`${error}`, { status: 500 });
}
const newExpenses = await getExpenses(context.state.user.id, requestBody.month);
const newExpenses = await ExpenseModel.list(context.state.user.id, requestBody.month);
const newBudgets = await getBudgets(context.state.user.id, requestBody.month);
const newBudgets = await BudgetModel.list(context.state.user.id, requestBody.month);
const responseBody: ResponseBody = { success: true, newExpenses, newBudgets };

View File

@@ -1,7 +1,7 @@
import { Handlers } from 'fresh/server.ts';
import { FreshContextState } from '/lib/types.ts';
import { getExpenseSuggestions } from '/lib/data/expenses.ts';
import { ExpenseModel } from '/lib/models/expenses.ts';
interface Data {}
@@ -26,7 +26,7 @@ export const handler: Handlers<Data, FreshContextState> = {
return new Response('Bad request', { status: 400 });
}
const suggestions = await getExpenseSuggestions(
const suggestions = await ExpenseModel.listSuggestions(
context.state.user.id,
requestBody.name,
);

View File

@@ -1,7 +1,7 @@
import { Handlers } from 'fresh/server.ts';
import { Budget, FreshContextState } from '/lib/types.ts';
import { deleteBudget, getBudgetById, getBudgets } from '/lib/data/expenses.ts';
import { BudgetModel } from '/lib/models/expenses.ts';
interface Data {}
@@ -29,20 +29,20 @@ export const handler: Handlers<Data, FreshContextState> = {
return new Response('Bad request', { status: 400 });
}
const budget = await getBudgetById(context.state.user.id, requestBody.id);
const budget = await BudgetModel.getById(context.state.user.id, requestBody.id);
if (!budget) {
return new Response('Not found', { status: 404 });
}
try {
await deleteBudget(context.state.user.id, requestBody.id);
await BudgetModel.delete(context.state.user.id, requestBody.id);
} catch (error) {
console.error(error);
return new Response(`${error}`, { status: 500 });
}
const newBudgets = await getBudgets(context.state.user.id, requestBody.currentMonth);
const newBudgets = await BudgetModel.list(context.state.user.id, requestBody.currentMonth);
const responseBody: ResponseBody = { success: true, newBudgets };

View File

@@ -1,7 +1,7 @@
import { Handlers } from 'fresh/server.ts';
import { Budget, Expense, FreshContextState } from '/lib/types.ts';
import { deleteExpense, getBudgets, getExpenseById, getExpenses } from '/lib/data/expenses.ts';
import { BudgetModel, ExpenseModel } from '/lib/models/expenses.ts';
interface Data {}
@@ -30,22 +30,22 @@ export const handler: Handlers<Data, FreshContextState> = {
return new Response('Bad request', { status: 400 });
}
const expense = await getExpenseById(context.state.user.id, requestBody.id);
const expense = await ExpenseModel.getById(context.state.user.id, requestBody.id);
if (!expense) {
return new Response('Not found', { status: 404 });
}
try {
await deleteExpense(context.state.user.id, requestBody.id);
await ExpenseModel.delete(context.state.user.id, requestBody.id);
} catch (error) {
console.error(error);
return new Response(`${error}`, { status: 500 });
}
const newExpenses = await getExpenses(context.state.user.id, requestBody.month);
const newExpenses = await ExpenseModel.list(context.state.user.id, requestBody.month);
const newBudgets = await getBudgets(context.state.user.id, requestBody.month);
const newBudgets = await BudgetModel.list(context.state.user.id, requestBody.month);
const responseBody: ResponseBody = { success: true, newExpenses, newBudgets };

View File

@@ -1,7 +1,7 @@
import { Handlers } from 'fresh/server.ts';
import { Budget, Expense, FreshContextState } from '/lib/types.ts';
import { getAllBudgetsForExport, getAllExpensesForExport } from '/lib/data/expenses.ts';
import { BudgetModel, ExpenseModel } from '/lib/models/expenses.ts';
interface Data {}
@@ -21,9 +21,9 @@ export const handler: Handlers<Data, FreshContextState> = {
return new Response('Unauthorized', { status: 401 });
}
const newExpenses = await getAllExpensesForExport(context.state.user.id);
const newExpenses = await ExpenseModel.getAllForExport(context.state.user.id);
const newBudgets = await getAllBudgetsForExport(context.state.user.id);
const newBudgets = await BudgetModel.getAllForExport(context.state.user.id);
const responseBody: ResponseBody = { success: true, jsonContents: { expenses: newExpenses, budgets: newBudgets } };

View File

@@ -2,13 +2,7 @@ import { Handlers } from 'fresh/server.ts';
import { Budget, Expense, FreshContextState } from '/lib/types.ts';
import { concurrentPromises } from '/lib/utils/misc.ts';
import {
createBudget,
createExpense,
deleteAllBudgetsAndExpenses,
getBudgets,
getExpenses,
} from '/lib/data/expenses.ts';
import { BudgetModel, deleteAllBudgetsAndExpenses, ExpenseModel } from '/lib/models/expenses.ts';
interface Data {}
@@ -47,14 +41,14 @@ export const handler: Handlers<Data, FreshContextState> = {
try {
await concurrentPromises(
requestBody.budgets.map((budget) => () =>
createBudget(context.state.user!.id, budget.name, budget.month, budget.value)
BudgetModel.create(context.state.user!.id, budget.name, budget.month, budget.value)
),
5,
);
await concurrentPromises(
requestBody.expenses.map((expense) => () =>
createExpense(
ExpenseModel.create(
context.state.user!.id,
expense.cost,
expense.description,
@@ -71,9 +65,9 @@ export const handler: Handlers<Data, FreshContextState> = {
return new Response(`${error}`, { status: 500 });
}
const newExpenses = await getExpenses(context.state.user.id, requestBody.month);
const newExpenses = await ExpenseModel.list(context.state.user.id, requestBody.month);
const newBudgets = await getBudgets(context.state.user.id, requestBody.month);
const newBudgets = await BudgetModel.list(context.state.user.id, requestBody.month);
const responseBody: ResponseBody = { success: true, newExpenses, newBudgets };

View File

@@ -1,7 +1,7 @@
import { Handlers } from 'fresh/server.ts';
import { Budget, FreshContextState } from '/lib/types.ts';
import { getBudgetById, getBudgets, updateBudget } from '/lib/data/expenses.ts';
import { BudgetModel } from '/lib/models/expenses.ts';
interface Data {}
@@ -34,7 +34,7 @@ export const handler: Handlers<Data, FreshContextState> = {
return new Response('Bad request', { status: 400 });
}
const budget = await getBudgetById(context.state.user.id, requestBody.id);
const budget = await BudgetModel.getById(context.state.user.id, requestBody.id);
if (!budget) {
return new Response('Not found', { status: 404 });
@@ -45,13 +45,13 @@ export const handler: Handlers<Data, FreshContextState> = {
budget.value = requestBody.value;
try {
await updateBudget(budget);
await BudgetModel.update(budget);
} catch (error) {
console.error(error);
return new Response(`${error}`, { status: 500 });
}
const newBudgets = await getBudgets(context.state.user.id, requestBody.currentMonth);
const newBudgets = await BudgetModel.list(context.state.user.id, requestBody.currentMonth);
const responseBody: ResponseBody = { success: true, newBudgets };

View File

@@ -1,7 +1,7 @@
import { Handlers } from 'fresh/server.ts';
import { Budget, Expense, FreshContextState } from '/lib/types.ts';
import { getBudgets, getExpenseById, getExpenses, updateExpense } from '/lib/data/expenses.ts';
import { BudgetModel, ExpenseModel } from '/lib/models/expenses.ts';
interface Data {}
@@ -36,7 +36,7 @@ export const handler: Handlers<Data, FreshContextState> = {
return new Response('Bad request', { status: 400 });
}
const expense = await getExpenseById(context.state.user.id, requestBody.id);
const expense = await ExpenseModel.getById(context.state.user.id, requestBody.id);
if (!expense) {
return new Response('Not found', { status: 404 });
@@ -65,15 +65,15 @@ export const handler: Handlers<Data, FreshContextState> = {
expense.is_recurring = requestBody.is_recurring;
try {
await updateExpense(expense);
await ExpenseModel.update(expense);
} catch (error) {
console.error(error);
return new Response(`${error}`, { status: 500 });
}
const newExpenses = await getExpenses(context.state.user.id, requestBody.month);
const newExpenses = await ExpenseModel.list(context.state.user.id, requestBody.month);
const newBudgets = await getBudgets(context.state.user.id, requestBody.month);
const newBudgets = await BudgetModel.list(context.state.user.id, requestBody.month);
const responseBody: ResponseBody = { success: true, newExpenses, newBudgets };

View File

@@ -1,7 +1,7 @@
import { Handlers } from 'fresh/server.ts';
import { Directory, FreshContextState } from '/lib/types.ts';
import { createDirectory, getDirectories } from '/lib/data/files.ts';
import { DirectoryModel } from '/lib/models/files.ts';
interface Data {}
@@ -30,13 +30,13 @@ export const handler: Handlers<Data, FreshContextState> = {
return new Response('Bad Request', { status: 400 });
}
const createdDirectory = await createDirectory(
const createdDirectory = await DirectoryModel.create(
context.state.user.id,
requestBody.parentPath,
requestBody.name.trim(),
);
const newDirectories = await getDirectories(context.state.user.id, requestBody.parentPath);
const newDirectories = await DirectoryModel.list(context.state.user.id, requestBody.parentPath);
const responseBody: ResponseBody = { success: createdDirectory, newDirectories };

View File

@@ -1,7 +1,7 @@
import { Handlers } from 'fresh/server.ts';
import { Directory, FreshContextState } from '/lib/types.ts';
import { deleteDirectoryOrFile, getDirectories } from '/lib/data/files.ts';
import { DirectoryModel } from '/lib/models/files.ts';
interface Data {}
@@ -30,13 +30,13 @@ export const handler: Handlers<Data, FreshContextState> = {
return new Response('Bad Request', { status: 400 });
}
const deletedDirectory = await deleteDirectoryOrFile(
const deletedDirectory = await DirectoryModel.delete(
context.state.user.id,
requestBody.parentPath,
requestBody.name.trim(),
);
const newDirectories = await getDirectories(context.state.user.id, requestBody.parentPath);
const newDirectories = await DirectoryModel.list(context.state.user.id, requestBody.parentPath);
const responseBody: ResponseBody = { success: deletedDirectory, newDirectories };

View File

@@ -1,7 +1,7 @@
import { Handlers } from 'fresh/server.ts';
import { DirectoryFile, FreshContextState } from '/lib/types.ts';
import { deleteDirectoryOrFile, getFiles } from '/lib/data/files.ts';
import { FileModel } from '/lib/models/files.ts';
interface Data {}
@@ -30,13 +30,13 @@ export const handler: Handlers<Data, FreshContextState> = {
return new Response('Bad Request', { status: 400 });
}
const deletedFile = await deleteDirectoryOrFile(
const deletedFile = await FileModel.delete(
context.state.user.id,
requestBody.parentPath,
requestBody.name.trim(),
);
const newFiles = await getFiles(context.state.user.id, requestBody.parentPath);
const newFiles = await FileModel.list(context.state.user.id, requestBody.parentPath);
const responseBody: ResponseBody = { success: deletedFile, newFiles };

View File

@@ -1,7 +1,7 @@
import { Handlers } from 'fresh/server.ts';
import { Directory, FreshContextState } from '/lib/types.ts';
import { getDirectories } from '/lib/data/files.ts';
import { DirectoryModel } from '/lib/models/files.ts';
interface Data {}
@@ -29,7 +29,7 @@ export const handler: Handlers<Data, FreshContextState> = {
return new Response('Bad Request', { status: 400 });
}
const directories = await getDirectories(
const directories = await DirectoryModel.list(
context.state.user.id,
requestBody.parentPath,
);

View File

@@ -1,7 +1,7 @@
import { Handlers } from 'fresh/server.ts';
import { DirectoryFile, FreshContextState } from '/lib/types.ts';
import { getFiles } from '/lib/data/files.ts';
import { FileModel } from '/lib/models/files.ts';
interface Data {}
@@ -28,7 +28,7 @@ export const handler: Handlers<Data, FreshContextState> = {
return new Response('Bad Request', { status: 400 });
}
const files = await getFiles(
const files = await FileModel.list(
context.state.user.id,
requestBody.parentPath,
);

View File

@@ -1,7 +1,7 @@
import { Handlers } from 'fresh/server.ts';
import { Directory, FreshContextState } from '/lib/types.ts';
import { getDirectories, renameDirectoryOrFile } from '/lib/data/files.ts';
import { DirectoryModel } from '/lib/models/files.ts';
interface Data {}
@@ -33,7 +33,7 @@ export const handler: Handlers<Data, FreshContextState> = {
return new Response('Bad Request', { status: 400 });
}
const movedDirectory = await renameDirectoryOrFile(
const movedDirectory = await DirectoryModel.rename(
context.state.user.id,
requestBody.oldParentPath,
requestBody.newParentPath,
@@ -41,7 +41,7 @@ export const handler: Handlers<Data, FreshContextState> = {
requestBody.name.trim(),
);
const newDirectories = await getDirectories(context.state.user.id, requestBody.oldParentPath);
const newDirectories = await DirectoryModel.list(context.state.user.id, requestBody.oldParentPath);
const responseBody: ResponseBody = { success: movedDirectory, newDirectories };

View File

@@ -1,7 +1,7 @@
import { Handlers } from 'fresh/server.ts';
import { DirectoryFile, FreshContextState } from '/lib/types.ts';
import { getFiles, renameDirectoryOrFile } from '/lib/data/files.ts';
import { FileModel } from '/lib/models/files.ts';
interface Data {}
@@ -33,7 +33,7 @@ export const handler: Handlers<Data, FreshContextState> = {
return new Response('Bad Request', { status: 400 });
}
const movedFile = await renameDirectoryOrFile(
const movedFile = await FileModel.rename(
context.state.user.id,
requestBody.oldParentPath,
requestBody.newParentPath,
@@ -41,7 +41,7 @@ export const handler: Handlers<Data, FreshContextState> = {
requestBody.name.trim(),
);
const newFiles = await getFiles(context.state.user.id, requestBody.oldParentPath);
const newFiles = await FileModel.list(context.state.user.id, requestBody.oldParentPath);
const responseBody: ResponseBody = { success: movedFile, newFiles };

View File

@@ -1,7 +1,7 @@
import { Handlers } from 'fresh/server.ts';
import { Directory, FreshContextState } from '/lib/types.ts';
import { getDirectories, renameDirectoryOrFile } from '/lib/data/files.ts';
import { DirectoryModel } from '/lib/models/files.ts';
interface Data {}
@@ -32,7 +32,7 @@ export const handler: Handlers<Data, FreshContextState> = {
return new Response('Bad Request', { status: 400 });
}
const movedDirectory = await renameDirectoryOrFile(
const movedDirectory = await DirectoryModel.rename(
context.state.user.id,
requestBody.parentPath,
requestBody.parentPath,
@@ -40,7 +40,7 @@ export const handler: Handlers<Data, FreshContextState> = {
requestBody.newName.trim(),
);
const newDirectories = await getDirectories(context.state.user.id, requestBody.parentPath);
const newDirectories = await DirectoryModel.list(context.state.user.id, requestBody.parentPath);
const responseBody: ResponseBody = { success: movedDirectory, newDirectories };

View File

@@ -1,7 +1,7 @@
import { Handlers } from 'fresh/server.ts';
import { DirectoryFile, FreshContextState } from '/lib/types.ts';
import { getFiles, renameDirectoryOrFile } from '/lib/data/files.ts';
import { FileModel } from '/lib/models/files.ts';
interface Data {}
@@ -32,7 +32,7 @@ export const handler: Handlers<Data, FreshContextState> = {
return new Response('Bad Request', { status: 400 });
}
const movedFile = await renameDirectoryOrFile(
const movedFile = await FileModel.rename(
context.state.user.id,
requestBody.parentPath,
requestBody.parentPath,
@@ -40,7 +40,7 @@ export const handler: Handlers<Data, FreshContextState> = {
requestBody.newName.trim(),
);
const newFiles = await getFiles(context.state.user.id, requestBody.parentPath);
const newFiles = await FileModel.list(context.state.user.id, requestBody.parentPath);
const responseBody: ResponseBody = { success: movedFile, newFiles };

View File

@@ -1,7 +1,7 @@
import { Handlers } from 'fresh/server.ts';
import { Directory, DirectoryFile, FreshContextState } from '/lib/types.ts';
import { searchFilesAndDirectories } from '/lib/data/files.ts';
import { searchFilesAndDirectories } from '/lib/models/files.ts';
interface Data {}

View File

@@ -1,7 +1,7 @@
import { Handlers } from 'fresh/server.ts';
import { Directory, DirectoryFile, FreshContextState } from '/lib/types.ts';
import { createFile, getDirectories, getFiles } from '/lib/data/files.ts';
import { DirectoryModel, FileModel } from '/lib/models/files.ts';
interface Data {}
@@ -33,10 +33,10 @@ export const handler: Handlers<Data, FreshContextState> = {
const fileContents = typeof contents === 'string' ? contents : await contents.arrayBuffer();
const createdFile = await createFile(context.state.user.id, parentPath, name.trim(), fileContents);
const createdFile = await FileModel.create(context.state.user.id, parentPath, name.trim(), fileContents);
const newFiles = await getFiles(context.state.user.id, pathInView);
const newDirectories = await getDirectories(context.state.user.id, pathInView);
const newFiles = await FileModel.list(context.state.user.id, pathInView);
const newDirectories = await DirectoryModel.list(context.state.user.id, pathInView);
const responseBody: ResponseBody = { success: createdFile, newFiles, newDirectories };

View File

@@ -1,7 +1,7 @@
import { Handlers } from 'fresh/server.ts';
import { FreshContextState, NewsFeed } from '/lib/types.ts';
import { createNewsFeed, getNewsFeeds } from '/lib/data/news.ts';
import { FeedModel } from '/lib/models/news.ts';
import { fetchNewArticles } from '/crons/news.ts';
interface Data {}
@@ -24,7 +24,7 @@ export const handler: Handlers<Data, FreshContextState> = {
const requestBody = await request.clone().json() as RequestBody;
if (requestBody.feedUrl) {
const newFeed = await createNewsFeed(context.state.user.id, requestBody.feedUrl);
const newFeed = await FeedModel.create(context.state.user.id, requestBody.feedUrl);
if (!newFeed) {
return new Response('Not found', { status: 404 });
@@ -33,7 +33,7 @@ export const handler: Handlers<Data, FreshContextState> = {
await fetchNewArticles();
const newFeeds = await getNewsFeeds(context.state.user.id);
const newFeeds = await FeedModel.list(context.state.user.id);
const responseBody: ResponseBody = { success: true, newFeeds };

View File

@@ -1,7 +1,7 @@
import { Handlers } from 'fresh/server.ts';
import { FreshContextState, NewsFeed } from '/lib/types.ts';
import { deleteNewsFeed, getNewsFeed, getNewsFeeds } from '/lib/data/news.ts';
import { FeedModel } from '/lib/models/news.ts';
interface Data {}
@@ -23,16 +23,16 @@ export const handler: Handlers<Data, FreshContextState> = {
const requestBody = await request.clone().json() as RequestBody;
if (requestBody.feedId) {
const newsFeed = await getNewsFeed(requestBody.feedId, context.state.user.id);
const newsFeed = await FeedModel.get(requestBody.feedId, context.state.user.id);
if (!newsFeed) {
return new Response('Not found', { status: 404 });
}
await deleteNewsFeed(requestBody.feedId, context.state.user.id);
await FeedModel.delete(requestBody.feedId, context.state.user.id);
}
const newFeeds = await getNewsFeeds(context.state.user.id);
const newFeeds = await FeedModel.list(context.state.user.id);
const responseBody: ResponseBody = { success: true, newFeeds };

View File

@@ -2,7 +2,7 @@ import { Handlers } from 'fresh/server.ts';
import { FreshContextState, NewsFeed } from '/lib/types.ts';
import { concurrentPromises } from '/lib/utils/misc.ts';
import { createNewsFeed, getNewsFeeds } from '/lib/data/news.ts';
import { FeedModel } from '/lib/models/news.ts';
import { fetchNewArticles } from '/crons/news.ts';
interface Data {}
@@ -30,14 +30,14 @@ export const handler: Handlers<Data, FreshContextState> = {
}
await concurrentPromises(
requestBody.feedUrls.map((feedUrl) => () => createNewsFeed(context.state.user!.id, feedUrl)),
requestBody.feedUrls.map((feedUrl) => () => FeedModel.create(context.state.user!.id, feedUrl)),
5,
);
}
await fetchNewArticles();
const newFeeds = await getNewsFeeds(context.state.user.id);
const newFeeds = await FeedModel.list(context.state.user.id);
const responseBody: ResponseBody = { success: true, newFeeds };

View File

@@ -1,7 +1,7 @@
import { Handlers } from 'fresh/server.ts';
import { FreshContextState } from '/lib/types.ts';
import { getNewsArticle, markAllArticlesRead, updateNewsArticle } from '/lib/data/news.ts';
import { ArticleModel } from '/lib/models/news.ts';
interface Data {}
@@ -23,9 +23,9 @@ export const handler: Handlers<Data, FreshContextState> = {
if (requestBody.articleId) {
if (requestBody.articleId === 'all') {
await markAllArticlesRead(context.state.user.id);
await ArticleModel.markAllRead(context.state.user.id);
} else {
const article = await getNewsArticle(requestBody.articleId, context.state.user.id);
const article = await ArticleModel.get(requestBody.articleId, context.state.user.id);
if (!article) {
return new Response('Not found', { status: 404 });
@@ -33,7 +33,7 @@ export const handler: Handlers<Data, FreshContextState> = {
article.is_read = true;
await updateNewsArticle(article);
await ArticleModel.update(article);
}
}

View File

@@ -1,7 +1,7 @@
import { Handlers } from 'fresh/server.ts';
import { FreshContextState, NewsFeedArticle } from '/lib/types.ts';
import { getNewsArticles, getNewsFeeds } from '/lib/data/news.ts';
import { ArticleModel, FeedModel } from '/lib/models/news.ts';
import { fetchNewArticles } from '/crons/news.ts';
interface Data {}
@@ -19,7 +19,7 @@ export const handler: Handlers<Data, FreshContextState> = {
return new Response('Unauthorized', { status: 401 });
}
const newsFeeds = await getNewsFeeds(context.state.user.id);
const newsFeeds = await FeedModel.list(context.state.user.id);
if (!newsFeeds.length) {
return new Response('Not found', { status: 404 });
@@ -27,7 +27,7 @@ export const handler: Handlers<Data, FreshContextState> = {
await fetchNewArticles(true);
const newArticles = await getNewsArticles(context.state.user.id);
const newArticles = await ArticleModel.list(context.state.user.id);
const responseBody: ResponseBody = { success: true, newArticles };

View File

@@ -1,7 +1,7 @@
import { Handlers } from 'fresh/server.ts';
import { FreshContextState } from '/lib/types.ts';
import { getFile, updateFile } from '/lib/data/files.ts';
import { FileModel } from '/lib/models/files.ts';
interface Data {}
@@ -42,7 +42,7 @@ export const handler: Handlers<Data, FreshContextState> = {
return new Response('Not Found', { status: 404 });
}
const fileResult = await getFile(
const fileResult = await FileModel.get(
context.state.user.id,
requestBody.currentPath,
decodeURIComponent(requestBody.fileName),
@@ -52,7 +52,7 @@ export const handler: Handlers<Data, FreshContextState> = {
return new Response('Not Found', { status: 404 });
}
const updatedFile = await updateFile(
const updatedFile = await FileModel.update(
context.state.user.id,
requestBody.currentPath,
decodeURIComponent(requestBody.fileName),

View File

@@ -1,7 +1,7 @@
import { Handlers, PageProps } from 'fresh/server.ts';
import { Dashboard, FreshContextState } from '/lib/types.ts';
import { createDashboard, getDashboardByUserId } from '/lib/data/dashboard.ts';
import { DashboardModel } from '/lib/models/dashboard.ts';
import Notes from '/islands/dashboard/Notes.tsx';
import Links from '/islands/dashboard/Links.tsx';
@@ -15,10 +15,10 @@ export const handler: Handlers<Data, FreshContextState> = {
return new Response('Redirect', { status: 303, headers: { 'Location': `/login` } });
}
let userDashboard = await getDashboardByUserId(context.state.user.id);
let userDashboard = await DashboardModel.getByUserId(context.state.user.id);
if (!userDashboard) {
userDashboard = await createDashboard(context.state.user.id);
userDashboard = await DashboardModel.create(context.state.user.id);
}
return await context.render({ userDashboard });

View File

@@ -11,7 +11,7 @@ import {
getProperDestinationPath,
getPropertyNames,
} from '/lib/utils/webdav.ts';
import { ensureUserPathIsValidAndSecurelyAccessible, getFile } from '/lib/data/files.ts';
import { ensureUserPathIsValidAndSecurelyAccessible, FileModel } from '/lib/models/files.ts';
interface Data {}
@@ -53,7 +53,7 @@ export const handler: Handler<Data, FreshContextState> = async (request, context
if (request.method === 'GET') {
try {
const fileResult = await getFile(userId, filePath);
const fileResult = await FileModel.get(userId, filePath);
if (!fileResult.success) {
return new Response('Not Found', { status: 404 });

View File

@@ -2,7 +2,7 @@ import { Handlers, PageProps } from 'fresh/server.ts';
import { Budget, Expense, FreshContextState, SupportedCurrencySymbol } from '/lib/types.ts';
import { isAppEnabled } from '/lib/config.ts';
import { generateMonthlyBudgetsAndExpenses, getBudgets, getExpenses } from '/lib/data/expenses.ts';
import { BudgetModel, ExpenseModel, generateMonthlyBudgetsAndExpenses } from '/lib/models/expenses.ts';
import ExpensesWrapper from '/islands/expenses/ExpensesWrapper.tsx';
interface Data {
@@ -41,16 +41,16 @@ export const handler: Handlers<Data, FreshContextState> = {
initialMonth = nextMonth;
}
let userBudgets = await getBudgets(context.state.user.id, initialMonth);
let userBudgets = await BudgetModel.list(context.state.user.id, initialMonth);
let userExpenses = await getExpenses(context.state.user.id, initialMonth);
let userExpenses = await ExpenseModel.list(context.state.user.id, initialMonth);
// If there are no budgets or expenses, and the selected month is in the future, generate the month's budgets and expenses
if (userBudgets.length === 0 && userExpenses.length === 0 && initialMonth >= currentMonth) {
await generateMonthlyBudgetsAndExpenses(context.state.user.id, initialMonth);
userBudgets = await getBudgets(context.state.user.id, initialMonth);
userExpenses = await getExpenses(context.state.user.id, initialMonth);
userBudgets = await BudgetModel.list(context.state.user.id, initialMonth);
userExpenses = await ExpenseModel.list(context.state.user.id, initialMonth);
}
const currency = context.state.user.extra.expenses_currency || '$';

View File

@@ -1,7 +1,7 @@
import { Handlers, PageProps } from 'fresh/server.ts';
import { Directory, DirectoryFile, FreshContextState } from '/lib/types.ts';
import { getDirectories, getFiles } from '/lib/data/files.ts';
import { DirectoryModel, FileModel } from '/lib/models/files.ts';
import FilesWrapper from '/islands/files/FilesWrapper.tsx';
interface Data {
@@ -30,9 +30,9 @@ export const handler: Handlers<Data, FreshContextState> = {
currentPath = `${currentPath}/`;
}
const userDirectories = await getDirectories(context.state.user.id, currentPath);
const userDirectories = await DirectoryModel.list(context.state.user.id, currentPath);
const userFiles = await getFiles(context.state.user.id, currentPath);
const userFiles = await FileModel.list(context.state.user.id, currentPath);
return await context.render({ userDirectories, userFiles, currentPath });
},

View File

@@ -1,7 +1,7 @@
import { Handlers } from 'fresh/server.ts';
import { FreshContextState } from '/lib/types.ts';
import { getFile } from '/lib/data/files.ts';
import { FileModel } from '/lib/models/files.ts';
interface Data {}
@@ -31,7 +31,7 @@ export const handler: Handlers<Data, FreshContextState> = {
currentPath = `${currentPath}/`;
}
const fileResult = await getFile(context.state.user.id, currentPath, decodeURIComponent(fileName));
const fileResult = await FileModel.get(context.state.user.id, currentPath, decodeURIComponent(fileName));
if (!fileResult.success) {
return new Response('Not Found', { status: 404 });

View File

@@ -3,7 +3,7 @@ import { Handlers, PageProps } from 'fresh/server.ts';
import { generateHash, helpEmail, validateEmail } from '/lib/utils/misc.ts';
import { createSessionResponse, PASSWORD_SALT } from '/lib/auth.ts';
import { FormField, generateFieldHtml, getFormDataField } from '/lib/form-utils.tsx';
import { createVerificationCode, getUserByEmail, updateUser, validateVerificationCode } from '/lib/data/user.ts';
import { UserModel, VerificationCodeModel } from '/lib/models/user.ts';
import { sendVerifyEmailEmail } from '/lib/providers/brevo.ts';
import { FreshContextState } from '/lib/types.ts';
import { isEmailEnabled } from '/lib/config.ts';
@@ -61,7 +61,7 @@ export const handler: Handlers<Data, FreshContextState> = {
const hashedPassword = await generateHash(`${password}:${PASSWORD_SALT}`, 'SHA-256');
const user = await getUserByEmail(email);
const user = await UserModel.getByEmail(email);
if (!user || user.hashed_password !== hashedPassword) {
throw new Error('Email not found or invalid password.');
@@ -70,24 +70,24 @@ export const handler: Handlers<Data, FreshContextState> = {
if (!isEmailEnabled() && !user.extra.is_email_verified) {
user.extra.is_email_verified = true;
await updateUser(user);
await UserModel.update(user);
}
if (!user.extra.is_email_verified) {
const code = getFormDataField(formData, 'verification-code');
if (!code) {
const verificationCode = await createVerificationCode(user, user.email, 'email');
const verificationCode = await VerificationCodeModel.create(user, user.email, 'email');
await sendVerifyEmailEmail(user.email, verificationCode);
throw new Error('Email not verified. New code sent to verify your email.');
} else {
await validateVerificationCode(user, user.email, code, 'email');
await VerificationCodeModel.validate(user, user.email, code, 'email');
user.extra.is_email_verified = true;
await updateUser(user);
await UserModel.update(user);
}
}

View File

@@ -2,7 +2,7 @@ import { Handlers, PageProps } from 'fresh/server.ts';
import { FreshContextState, NewsFeedArticle } from '/lib/types.ts';
import { isAppEnabled } from '/lib/config.ts';
import { getNewsArticles } from '/lib/data/news.ts';
import { ArticleModel } from '/lib/models/news.ts';
import Articles from '/islands/news/Articles.tsx';
interface Data {
@@ -19,7 +19,7 @@ export const handler: Handlers<Data, FreshContextState> = {
return new Response('Redirect', { status: 303, headers: { 'Location': `/dashboard` } });
}
const userArticles = await getNewsArticles(context.state.user.id);
const userArticles = await ArticleModel.list(context.state.user.id);
return await context.render({ userArticles });
},

View File

@@ -1,7 +1,7 @@
import { Handlers, PageProps } from 'fresh/server.ts';
import { FreshContextState, NewsFeed } from '/lib/types.ts';
import { getNewsFeeds } from '/lib/data/news.ts';
import { FeedModel } from '/lib/models/news.ts';
import Feeds from '/islands/news/Feeds.tsx';
interface Data {
@@ -14,7 +14,7 @@ export const handler: Handlers<Data, FreshContextState> = {
return new Response('Redirect', { status: 303, headers: { 'Location': `/login` } });
}
const userFeeds = await getNewsFeeds(context.state.user.id);
const userFeeds = await FeedModel.list(context.state.user.id);
return await context.render({ userFeeds });
},

View File

@@ -2,7 +2,7 @@ import { Handlers, PageProps } from 'fresh/server.ts';
import { Directory, DirectoryFile, FreshContextState } from '/lib/types.ts';
import { isAppEnabled } from '/lib/config.ts';
import { getDirectories, getFiles } from '/lib/data/files.ts';
import { DirectoryModel, FileModel } from '/lib/models/files.ts';
import NotesWrapper from '/islands/notes/NotesWrapper.tsx';
interface Data {
@@ -35,9 +35,9 @@ export const handler: Handlers<Data, FreshContextState> = {
currentPath = `${currentPath}/`;
}
const userDirectories = await getDirectories(context.state.user.id, currentPath);
const userDirectories = await DirectoryModel.list(context.state.user.id, currentPath);
const userFiles = await getFiles(context.state.user.id, currentPath);
const userFiles = await FileModel.list(context.state.user.id, currentPath);
const userNotes = userFiles.filter((file) => file.file_name.endsWith('.md'));

View File

@@ -1,7 +1,7 @@
import { Handlers, PageProps } from 'fresh/server.ts';
import { FreshContextState } from '/lib/types.ts';
import { getFile } from '/lib/data/files.ts';
import { FileModel } from '/lib/models/files.ts';
import Note from '/islands/notes/Note.tsx';
interface Data {
@@ -41,7 +41,7 @@ export const handler: Handlers<Data, FreshContextState> = {
return new Response('Not Found', { status: 404 });
}
const fileResult = await getFile(context.state.user.id, currentPath, decodeURIComponent(fileName));
const fileResult = await FileModel.get(context.state.user.id, currentPath, decodeURIComponent(fileName));
if (!fileResult.success) {
return new Response('Not Found', { status: 404 });

View File

@@ -2,7 +2,7 @@ import { Handlers, PageProps } from 'fresh/server.ts';
import { Directory, DirectoryFile, FreshContextState } from '/lib/types.ts';
import { isAppEnabled } from '/lib/config.ts';
import { getDirectories, getFiles } from '/lib/data/files.ts';
import { DirectoryModel, FileModel } from '/lib/models/files.ts';
import { PHOTO_EXTENSIONS } from '/lib/utils/photos.ts';
import PhotosWrapper from '/islands/photos/PhotosWrapper.tsx';
@@ -36,9 +36,9 @@ export const handler: Handlers<Data, FreshContextState> = {
currentPath = `${currentPath}/`;
}
const userDirectories = await getDirectories(context.state.user.id, currentPath);
const userDirectories = await DirectoryModel.list(context.state.user.id, currentPath);
const userFiles = await getFiles(context.state.user.id, currentPath);
const userFiles = await FileModel.list(context.state.user.id, currentPath);
const userPhotos = userFiles.filter((file) => {
const lowercaseFileName = file.file_name.toLowerCase();

View File

@@ -2,7 +2,7 @@ import { Handlers } from 'fresh/server.ts';
import { resize } from 'https://deno.land/x/deno_image@0.0.4/mod.ts';
import { FreshContextState } from '/lib/types.ts';
import { getFile } from '/lib/data/files.ts';
import { FileModel } from '/lib/models/files.ts';
interface Data {}
@@ -37,7 +37,7 @@ export const handler: Handlers<Data, FreshContextState> = {
currentPath = `${currentPath}/`;
}
const fileResult = await getFile(context.state.user.id, currentPath, decodeURIComponent(fileName));
const fileResult = await FileModel.get(context.state.user.id, currentPath, decodeURIComponent(fileName));
if (!fileResult.success) {
return new Response('Not Found', { status: 404 });

View File

@@ -2,13 +2,7 @@ import { Handlers, PageProps } from 'fresh/server.ts';
import { currencyMap, FreshContextState, SupportedCurrencySymbol } from '/lib/types.ts';
import { PASSWORD_SALT } from '/lib/auth.ts';
import {
createVerificationCode,
deleteUser,
getUserByEmail,
updateUser,
validateVerificationCode,
} from '/lib/data/user.ts';
import { UserModel, VerificationCodeModel } from '/lib/models/user.ts';
import { convertFormDataToObject, generateHash, validateEmail } from '/lib/utils/misc.ts';
import { getFormDataField } from '/lib/form-utils.tsx';
import { sendVerifyEmailEmail } from '/lib/providers/brevo.ts';
@@ -72,14 +66,14 @@ export const handler: Handlers<Data, FreshContextState> = {
throw new Error(`New email is the same as the current email.`);
}
const matchingUser = await getUserByEmail(email);
const matchingUser = await UserModel.getByEmail(email);
if (matchingUser) {
throw new Error('Email is already in use.');
}
if (action === 'change-email' && isEmailEnabled()) {
const verificationCode = await createVerificationCode(user, email, 'email');
const verificationCode = await VerificationCodeModel.create(user, email, 'email');
await sendVerifyEmailEmail(email, verificationCode);
@@ -89,12 +83,12 @@ export const handler: Handlers<Data, FreshContextState> = {
if (isEmailEnabled()) {
const code = getFormDataField(formData, 'verification-code');
await validateVerificationCode(user, email, code, 'email');
await VerificationCodeModel.validate(user, email, code, 'email');
}
user.email = email;
await updateUser(user);
await UserModel.update(user);
successTitle = 'Email updated!';
successMessage = 'Email updated successfully.';
@@ -120,7 +114,7 @@ export const handler: Handlers<Data, FreshContextState> = {
user.hashed_password = hashedNewPassword;
await updateUser(user);
await UserModel.update(user);
successTitle = 'Password changed!';
successMessage = 'Password changed successfully.';
@@ -139,7 +133,7 @@ export const handler: Handlers<Data, FreshContextState> = {
user.extra.dav_hashed_password = hashedNewDavPassword;
await updateUser(user);
await UserModel.update(user);
successTitle = 'DAV Password changed!';
successMessage = 'DAV Password changed successfully.';
@@ -152,7 +146,7 @@ export const handler: Handlers<Data, FreshContextState> = {
throw new Error('Invalid current password.');
}
await deleteUser(user.id);
await UserModel.delete(user.id);
return new Response('Account deleted successfully', {
status: 303,
@@ -167,7 +161,7 @@ export const handler: Handlers<Data, FreshContextState> = {
user.extra.expenses_currency = newCurrencySymbol;
await updateUser(user);
await UserModel.update(user);
successTitle = 'Currency changed!';
successMessage = 'Currency changed successfully.';

View File

@@ -3,7 +3,7 @@ import { Handlers, PageProps } from 'fresh/server.ts';
import { generateHash, helpEmail, validateEmail } from '/lib/utils/misc.ts';
import { PASSWORD_SALT } from '/lib/auth.ts';
import { FormField, generateFieldHtml, getFormDataField } from '/lib/form-utils.tsx';
import { createUser, createVerificationCode, getUserByEmail, updateUser } from '/lib/data/user.ts';
import { UserModel, VerificationCodeModel } from '/lib/models/user.ts';
import { sendVerifyEmailEmail } from '/lib/providers/brevo.ts';
import { isEmailEnabled, isSignupAllowed } from '/lib/config.ts';
import { FreshContextState } from '/lib/types.ts';
@@ -54,7 +54,7 @@ export const handler: Handlers<Data, FreshContextState> = {
throw new Error(`Password is too short.`);
}
const existingUser = await getUserByEmail(email);
const existingUser = await UserModel.getByEmail(email);
if (existingUser) {
throw new Error('Email is already in use. Perhaps you want to login instead?');
@@ -62,10 +62,10 @@ export const handler: Handlers<Data, FreshContextState> = {
const hashedPassword = await generateHash(`${password}:${PASSWORD_SALT}`, 'SHA-256');
const user = await createUser(email, hashedPassword);
const user = await UserModel.create(email, hashedPassword);
if (isEmailEnabled()) {
const verificationCode = await createVerificationCode(user, user.email, 'email');
const verificationCode = await VerificationCodeModel.create(user, user.email, 'email');
await sendVerifyEmailEmail(user.email, verificationCode);
}