option for more emails,fix jmap service,add table email accounts

This commit is contained in:
richardtekula
2025-11-19 13:15:45 +01:00
parent 97f437c1c4
commit 1e7c1eab90
18 changed files with 1991 additions and 1299 deletions

View File

@@ -5,8 +5,15 @@ import { NotFoundError } from '../utils/errors.js';
/**
* Get all emails for a user (only from added contacts)
* If emailAccountId is provided, filter by that account
*/
export const getUserEmails = async (userId) => {
export const getUserEmails = async (userId, emailAccountId = null) => {
const conditions = [eq(emails.userId, userId)];
if (emailAccountId) {
conditions.push(eq(emails.emailAccountId, emailAccountId));
}
const userEmails = await db
.select({
id: emails.id,
@@ -21,6 +28,7 @@ export const getUserEmails = async (userId) => {
isRead: emails.isRead,
date: emails.date,
createdAt: emails.createdAt,
emailAccountId: emails.emailAccountId,
contact: {
id: contacts.id,
email: contacts.email,
@@ -29,7 +37,7 @@ export const getUserEmails = async (userId) => {
})
.from(emails)
.leftJoin(contacts, eq(emails.contactId, contacts.id))
.where(eq(emails.userId, userId))
.where(and(...conditions))
.orderBy(desc(emails.date));
return userEmails;
@@ -54,27 +62,31 @@ export const getEmailThread = async (userId, threadId) => {
/**
* Search emails (from, to, subject)
* If emailAccountId is provided, filter by that account
*/
export const searchEmails = async (userId, query) => {
export const searchEmails = async (userId, query, emailAccountId = null) => {
if (!query || query.trim().length < 2) {
throw new Error('Search term must be at least 2 characters');
}
const searchPattern = `%${query}%`;
const conditions = [
eq(emails.userId, userId),
or(
like(emails.from, searchPattern),
like(emails.to, searchPattern),
like(emails.subject, searchPattern)
),
];
if (emailAccountId) {
conditions.push(eq(emails.emailAccountId, emailAccountId));
}
const results = await db
.select()
.from(emails)
.where(
and(
eq(emails.userId, userId),
or(
like(emails.from, searchPattern),
like(emails.to, searchPattern),
like(emails.subject, searchPattern)
)
)
)
.where(and(...conditions))
.orderBy(desc(emails.date))
.limit(50);
@@ -83,14 +95,34 @@ export const searchEmails = async (userId, query) => {
/**
* Get unread email count
* Returns total count and counts per email account
*/
export const getUnreadCount = async (userId) => {
const result = await db
// Get total unread count
const totalResult = await db
.select({ count: sql`count(*)::int` })
.from(emails)
.where(and(eq(emails.userId, userId), eq(emails.isRead, false)));
return result[0]?.count || 0;
const totalUnread = totalResult[0]?.count || 0;
// Get unread count per email account
const accountCounts = await db
.select({
emailAccountId: emails.emailAccountId,
count: sql`count(*)::int`,
})
.from(emails)
.where(and(eq(emails.userId, userId), eq(emails.isRead, false)))
.groupBy(emails.emailAccountId);
return {
totalUnread,
accounts: accountCounts.map((ac) => ({
emailAccountId: ac.emailAccountId,
unreadCount: ac.count,
})),
};
};
/**