fix(number-fields): избегаем потери точности длинных чисел
- number-поля теперь рендерятся как text + inputMode=numeric, чтобы браузер не округлял значения через input type=number - пробелы при вставке в number-поля удаляются - бэкенд нормализует значения number-полей в строку перед сохранением - добавлен хелпер normalizeFieldValueForStorage Closes: искажение расчётного счёта и других длинных числовых полей
This commit is contained in:
480
server/storage.ts
Normal file
480
server/storage.ts
Normal file
@@ -0,0 +1,480 @@
|
||||
// Public entry point for the storage layer.
|
||||
// Implementation is split into domain modules under server/storage/
|
||||
|
||||
import { users, organizations, userSessions, invitations, userCustomFields, userCustomValues, forms, formTabs, formFields, formStatuses, statusTransitions, tasks, taskFieldValues, fieldHistory, taskMessages, userNotifications, messageReads, bookmarkFolders, bookmarks, bots, botSubscriptions, botSessions, dataTables, dataTableRows, dataTablePermissions, externalServices, regularTableRows, fieldTemplates, customTabModules, taskTabValues, deviceTokens, userPresence, webPushSubscriptions, customPages, type User, type Organization, type UserSession, type Invitation, type InsertUser, type InsertOrganization, type InsertUserSession, type InsertInvitation, type UserWithOrganization, type UserCustomField, type UserCustomValue, type CreateUserCustomField, type UpdateUserCustomField, type UserProfileTab, type UserProfileField, type UserProfileFieldValue, type UserProfileAuditLog, type InsertUserProfileTab, type InsertUserProfileField, type InsertUserProfileFieldValue, type InsertUserProfileAuditLog, userProfileAuditLog, type Form, type FormTab, type FormField, type FormStatus, type StatusTransition, type Task, type TaskFieldValue, type FieldHistory, type TaskMessage, type TaskMessageWithAuthor, type UserNotification, type MessageRead, type InsertMessageRead, type BookmarkFolder, type Bookmark, type InsertForm, type InsertFormTab, type InsertFormField, type InsertFormStatus, type InsertStatusTransition, type InsertTask, type InsertTaskFieldValue, type InsertFieldHistory, type InsertTaskMessage, type InsertUserNotification, type InsertBookmarkFolder, type InsertBookmark, type Bot, type BotSubscription, type BotSession, type InsertBot, type InsertBotSubscription, type InsertBotSession, type BotWithSubscriptions, type DataTable, type DataTableRow, type DataTablePermission, type DataTableAccessRule, type InsertDataTableAccessRule, type InsertDataTable, type InsertDataTableRow, type InsertDataTablePermission, type DataTableWithRows, type DataTableFull, type ExternalService, type InsertExternalService, type RegularTableRow, type InsertRegularTableRow, type FieldTemplate, type InsertFieldTemplate, type CustomTabModule, type InsertCustomTabModule, type TaskTabValue, type InsertTaskTabValue, type DeviceToken, type InsertDeviceToken, type UserPresence, type InsertUserPresence, type WebPushSubscription, type CustomPage, type InsertCustomPage } from "@shared/schema";
|
||||
import { organizationApiKeys, type OrganizationApiKey } from "@shared/schema";
|
||||
import { automations, type Automation, type InsertAutomation } from "@shared/schema";
|
||||
import { taskRelations, type TaskRelation, type InsertTaskRelation } from "@shared/schema";
|
||||
import { taskReminders, type TaskReminder, type InsertTaskReminder } from "@shared/schema";
|
||||
import { ragSettings, type RagSetting } from "@shared/schema";
|
||||
import { llmProviders, type LlmProvider, type InsertLlmProvider } from "@shared/schema";
|
||||
import { systemConfig } from "@shared/schema";
|
||||
import { taskAuditLog, type TaskAuditLog, type InsertTaskAuditLog } from "@shared/schema";
|
||||
import { taskRoles, type TaskRole, taskUserAccess, type TaskUserAccess, roleMembers, roles, taskAssignees, type TaskAssignee } from "@shared/schema";
|
||||
import { userOfflineSubscriptions, type UserOfflineSubscription, type InsertUserOfflineSubscription } from "@shared/schema";
|
||||
import { db } from "./db";
|
||||
import { eq, and, or, desc, asc, exists, isNull, isNotNull, sql, ilike, inArray, lte } from "drizzle-orm";
|
||||
import { alias } from "drizzle-orm/pg-core";
|
||||
import crypto from "crypto";
|
||||
import { formatUserName } from "./utils/formatUserName";
|
||||
|
||||
export interface RelatedTreeNode {
|
||||
id: number;
|
||||
title: string;
|
||||
formId: number;
|
||||
formName: string;
|
||||
fieldName: string;
|
||||
isFinal: boolean;
|
||||
statusName: string | null;
|
||||
statusColor: string | null;
|
||||
nodes: RelatedTreeNode[];
|
||||
}
|
||||
|
||||
export interface IStorage {
|
||||
// Organizations
|
||||
getOrganization(id: number): Promise<Organization | undefined>;
|
||||
getOrganizationBySlug(slug: string): Promise<Organization | undefined>;
|
||||
createOrganization(organization: InsertOrganization): Promise<Organization>;
|
||||
|
||||
// Users
|
||||
getUser(id: number): Promise<User | undefined>;
|
||||
getUserWithOrganization(id: number): Promise<UserWithOrganization | undefined>;
|
||||
getUserByEmail(email: string, organizationId?: number): Promise<User | undefined>;
|
||||
getUserByEmailAndSlug(email: string, slug: string): Promise<UserWithOrganization | undefined>;
|
||||
getUsersByOrganization(organizationId: number): Promise<User[]>;
|
||||
listUsers(organizationId: number, options?: import('./storage/users.storage').ListUsersOptions): Promise<import('./storage/users.storage').ListUsersResult>;
|
||||
getLinkedTasksForUser(userId: number, organizationId: number): Promise<
|
||||
Array<{
|
||||
task: Task;
|
||||
form: { id: number; name: string };
|
||||
status: FormStatus | null;
|
||||
field: FormField;
|
||||
}>
|
||||
>;
|
||||
getUserByResetPasswordToken(token: string): Promise<User | undefined>;
|
||||
createUser(insertUser: InsertUser): Promise<User>;
|
||||
updateUser(id: number, updates: Partial<User>): Promise<User>;
|
||||
deleteUser(id: number): Promise<void>;
|
||||
|
||||
// User offline subscriptions
|
||||
getUserOfflineSubscriptions(userId: number, organizationId: number): Promise<UserOfflineSubscription[]>;
|
||||
getUserOfflineSubscription(userId: number, formId: number): Promise<UserOfflineSubscription | undefined>;
|
||||
upsertUserOfflineSubscription(subscription: InsertUserOfflineSubscription): Promise<UserOfflineSubscription>;
|
||||
deleteUserOfflineSubscription(userId: number, formId: number): Promise<void>;
|
||||
|
||||
// User sessions
|
||||
createUserSession(session: InsertUserSession): Promise<UserSession>;
|
||||
getUserSessionByToken(refreshToken: string): Promise<UserSession | undefined>;
|
||||
getUserSessionByParentToken(parentRefreshToken: string): Promise<UserSession | undefined>;
|
||||
getActiveSessionInFamily(familyId: string): Promise<UserSession | undefined>;
|
||||
markSessionReplaced(refreshToken: string, replacedByToken: string): Promise<void>;
|
||||
revokeSession(refreshToken: string): Promise<void>;
|
||||
revokeSessionFamily(familyId: string): Promise<void>;
|
||||
revokeAllUserSessions(userId: number): Promise<void>;
|
||||
deleteUserSession(refreshToken: string): Promise<void>;
|
||||
deleteUserSessions(userId: number): Promise<void>;
|
||||
|
||||
// Invitations
|
||||
createInvitation(invitation: InsertInvitation): Promise<Invitation>;
|
||||
getInvitationByToken(token: string): Promise<Invitation | undefined>;
|
||||
getInvitationsByOrganization(organizationId: number): Promise<Invitation[]>;
|
||||
markInvitationAsUsed(token: string): Promise<Invitation>;
|
||||
deleteInvitation(id: number, organizationId: number): Promise<void>;
|
||||
|
||||
// User Custom Fields
|
||||
getUserCustomFields(organizationId: number): Promise<UserCustomField[]>;
|
||||
getUserCustomField(id: number, organizationId: number): Promise<UserCustomField | undefined>;
|
||||
createUserCustomField(organizationId: number, field: CreateUserCustomField): Promise<UserCustomField>;
|
||||
updateUserCustomField(id: number, organizationId: number, updates: UpdateUserCustomField): Promise<UserCustomField>;
|
||||
deleteUserCustomField(id: number, organizationId: number): Promise<void>;
|
||||
reorderUserCustomFields(organizationId: number, fieldIds: number[]): Promise<void>;
|
||||
|
||||
// User Custom Values
|
||||
getUserCustomValues(userId: number, organizationId: number): Promise<UserCustomValue[]>;
|
||||
setUserCustomValue(userId: number, fieldId: number, value: string | null, organizationId: number): Promise<UserCustomValue>;
|
||||
setUserCustomValues(userId: number, values: Array<{ fieldId: number; value: string | null }>, organizationId: number): Promise<void>;
|
||||
|
||||
// User Profile Tabs
|
||||
getUserProfileTabs(organizationId: number): Promise<UserProfileTab[]>;
|
||||
getUserProfileTabsByCreationOrder(organizationId: number): Promise<UserProfileTab[]>;
|
||||
bulkSaveUserProfileTabs(organizationId: number, tabs: Array<{ id?: number; name: string; code: string; position?: number; displayOrder?: number }>): Promise<UserProfileTab[]>;
|
||||
|
||||
// User Profile Fields
|
||||
getUserProfileFields(organizationId: number): Promise<UserProfileField[]>;
|
||||
getUserProfileFieldsByCreationOrder(organizationId: number): Promise<UserProfileField[]>;
|
||||
getUserProfileFieldById(id: number, organizationId: number): Promise<UserProfileField | undefined>;
|
||||
bulkSaveUserProfileFields(organizationId: number, fieldIdsToDelete: number[], fields: Array<{ id?: number; name: string; code: string; type: string; isRequired?: boolean; placeholder?: string | null; defaultValue?: string | null; validationRules?: unknown; options?: unknown; position?: number | null; displayOrder?: number | null; tabId?: number | null; linkedFormId?: number | null; companyAutofill?: unknown; maxFileCount?: number | null; maxFileSizeMB?: number | null; autoProlongation?: boolean | null; autoProlongationLabel?: string | null }>): Promise<UserProfileField[]>;
|
||||
|
||||
// User Profile Field Values
|
||||
getUserProfileFieldValues(userId: number): Promise<UserProfileFieldValue[]>;
|
||||
getUserProfileFieldValue(userId: number, fieldId: number): Promise<UserProfileFieldValue | undefined>;
|
||||
createUserProfileFieldValue(insertValue: InsertUserProfileFieldValue): Promise<UserProfileFieldValue>;
|
||||
createUserProfileFieldValueWithAudit(insertValue: InsertUserProfileFieldValue, organizationId: number, changedBy: number): Promise<UserProfileFieldValue>;
|
||||
updateUserProfileFieldValue(userId: number, fieldId: number, updates: Partial<UserProfileFieldValue>): Promise<UserProfileFieldValue>;
|
||||
updateUserProfileFieldValueWithAudit(userId: number, fieldId: number, updates: Partial<UserProfileFieldValue>, organizationId: number, changedBy: number): Promise<UserProfileFieldValue>;
|
||||
deleteUserProfileFieldValue(userId: number, fieldId: number): Promise<void>;
|
||||
deleteUserProfileFieldValueWithAudit(userId: number, fieldId: number, organizationId: number, changedBy: number): Promise<void>;
|
||||
getUserProfileDetail(userId: number, organizationId: number): Promise<{ user: any; tabs: UserProfileTab[]; fields: UserProfileField[]; fieldValues: UserProfileFieldValue[] }>;
|
||||
|
||||
// User Profile Audit Log
|
||||
getUserProfileAuditLog(userId: number, organizationId: number): Promise<UserProfileAuditLog[]>;
|
||||
createUserProfileAuditLog(insertValue: InsertUserProfileAuditLog): Promise<UserProfileAuditLog>;
|
||||
|
||||
// Forms
|
||||
getForm(id: number, organizationId: number): Promise<Form | undefined>;
|
||||
getFormsByOrganization(organizationId: number): Promise<Form[]>;
|
||||
createForm(insertForm: InsertForm): Promise<Form>;
|
||||
updateForm(id: number, organizationId: number, updates: Partial<Form>): Promise<Form>;
|
||||
deleteForm(id: number, organizationId: number): Promise<void>;
|
||||
getTasksCountByForm(formId: number): Promise<{ total: number; active: number; completed: number }>;
|
||||
getTaskCountsByStatus(formId: number, organizationId: number): Promise<Array<{ statusId: number; name: string; color: string; count: number }>>;
|
||||
getFormsWithOfflineCache(organizationId: number): Promise<Form[]>;
|
||||
getOfflineCacheConfig(id: number, organizationId: number): Promise<Form['offlineCache']>;
|
||||
updateFormOfflineCache(id: number, organizationId: number, config: Form['offlineCache']): Promise<Form>;
|
||||
|
||||
// Form Tabs
|
||||
getFormTabs(formId: number, organizationId: number): Promise<FormTab[]>;
|
||||
getFormTabsByCreationOrder(formId: number, organizationId: number): Promise<FormTab[]>;
|
||||
getFormTab(id: number, formId: number, organizationId: number): Promise<FormTab | undefined>;
|
||||
createFormTab(insertTab: InsertFormTab): Promise<FormTab>;
|
||||
updateFormTab(id: number, formId: number, organizationId: number, updates: Partial<FormTab>): Promise<FormTab>;
|
||||
deleteFormTab(id: number, formId: number, organizationId: number): Promise<void>;
|
||||
bulkSaveFormTabs(formId: number, organizationId: number, tabs: Array<{ id?: number; name: string; code: string; type: string; tableColumns?: unknown }>): Promise<FormTab[]>;
|
||||
|
||||
// Form Fields
|
||||
getFormFields(formId: number, organizationId: number): Promise<FormField[]>;
|
||||
getFormFieldsByCreationOrder(formId: number, organizationId: number): Promise<FormField[]>;
|
||||
getFormFieldById(id: number, organizationId: number): Promise<FormField | undefined>;
|
||||
createFormField(insertField: InsertFormField): Promise<FormField>;
|
||||
updateFormField(id: number, formId: number, organizationId: number, updates: Partial<FormField>): Promise<FormField>;
|
||||
deleteFormField(id: number, formId: number, organizationId: number): Promise<void>;
|
||||
bulkSaveFormFields(formId: number, organizationId: number, fieldIdsToDelete: number[], fields: Array<{ id?: number; name: string; code: string; type: string; isRequired?: boolean; placeholder?: string | null; defaultValue?: string | null; validationRules?: unknown; options?: unknown; tabId?: number | null; linkedFormId?: number | null; taskRelationType?: string | null; companyAutofill?: unknown; maxFileCount?: number | null; maxFileSizeMB?: number | null; linkToUserProfile?: boolean | null }>): Promise<FormField[]>;
|
||||
|
||||
// Form Statuses
|
||||
getFormStatuses(formId: number, organizationId: number): Promise<FormStatus[]>;
|
||||
createFormStatus(insertStatus: InsertFormStatus): Promise<FormStatus>;
|
||||
updateFormStatus(id: number, formId: number, organizationId: number, updates: Partial<FormStatus>): Promise<FormStatus>;
|
||||
deleteFormStatus(id: number, formId: number, organizationId: number): Promise<void>;
|
||||
bulkSaveFormStatuses(formId: number, organizationId: number, statusIdsToDelete: number[], statuses: Array<{ id?: number; name: string; color?: string; isInitial?: boolean; isFinal?: boolean }>): Promise<FormStatus[]>;
|
||||
|
||||
// Status Transitions
|
||||
getStatusTransitions(formId: number, organizationId: number): Promise<StatusTransition[]>;
|
||||
createStatusTransition(insertTransition: InsertStatusTransition): Promise<StatusTransition>;
|
||||
updateStatusTransition(id: number, formId: number, organizationId: number, updates: Partial<StatusTransition>): Promise<StatusTransition>;
|
||||
deleteStatusTransition(id: number, formId: number, organizationId: number): Promise<void>;
|
||||
|
||||
// Tasks
|
||||
getTask(id: number, organizationId: number): Promise<Task | undefined>;
|
||||
getTaskDetail(id: number, organizationId: number): Promise<{
|
||||
task: Task;
|
||||
form: Form;
|
||||
fields: FormField[];
|
||||
statuses: FormStatus[];
|
||||
tabs: FormTab[];
|
||||
transitions: StatusTransition[];
|
||||
fieldValues: TaskFieldValue[];
|
||||
subtasks: Task[];
|
||||
messages: TaskMessageWithAuthor[];
|
||||
users: User[];
|
||||
hasRelations: boolean;
|
||||
assignees: Array<TaskAssignee & { user: { id: number; firstName: string | null; lastName: string | null; email: string } }>;
|
||||
} | null>;
|
||||
getTasksByForm(formId: number, organizationId: number): Promise<Task[]>;
|
||||
getTasksWithFieldsByForm(formId: number, organizationId: number): Promise<Task[]>;
|
||||
getTasksWithFieldsByFormOptimized(formId: number, organizationId: number, options?: { limit?: number; offset?: number; assignedTo?: number }): Promise<{ tasks: Task[]; total: number }>;
|
||||
getTasksByOrganization(organizationId: number, options?: {
|
||||
limit?: number;
|
||||
offset?: number;
|
||||
sortBy?: 'updatedAt' | 'createdAt';
|
||||
order?: 'asc' | 'desc';
|
||||
statusId?: number;
|
||||
assignedTo?: number;
|
||||
minimal?: boolean;
|
||||
}): Promise<Task[] | Partial<Task>[]>;
|
||||
createTask(insertTask: InsertTask): Promise<Task>;
|
||||
updateTask(id: number, organizationId: number, updates: Partial<Task>): Promise<Task>;
|
||||
updateTaskIfNotModified(id: number, organizationId: number, updates: Partial<Task>, requiredUpdatedAt: Date): Promise<Task | null>;
|
||||
deleteTask(id: number, organizationId: number): Promise<void>;
|
||||
searchTasksByKeyword(organizationId: number, query: string, limit?: number): Promise<Pick<Task, 'id' | 'title' | 'description' | 'formId' | 'currentStatusId'>[]>;
|
||||
|
||||
// Task Field Values
|
||||
getTaskFieldValues(taskId: number, organizationId: number): Promise<TaskFieldValue[]>;
|
||||
createTaskFieldValue(insertValue: InsertTaskFieldValue): Promise<TaskFieldValue>;
|
||||
updateTaskFieldValue(taskId: number, fieldId: number, organizationId: number, updates: Partial<TaskFieldValue>): Promise<TaskFieldValue>;
|
||||
bulkUpsertTaskFieldValues(taskId: number, formId: number, updates: Array<{ fieldId: number; value: unknown }>): Promise<TaskFieldValue[]>;
|
||||
deleteTaskFieldValue(taskId: number, fieldId: number, organizationId: number): Promise<void>;
|
||||
|
||||
// Field History
|
||||
getFieldHistory(taskId: number, fieldId: number, organizationId: number): Promise<FieldHistory[]>;
|
||||
createFieldHistory(insertHistory: InsertFieldHistory): Promise<FieldHistory>;
|
||||
|
||||
// Task Messages (Chat)
|
||||
getTaskMessages(taskId: number, organizationId: number): Promise<TaskMessageWithAuthor[]>;
|
||||
getTaskMessage(messageId: number, organizationId: number): Promise<TaskMessageWithAuthor | undefined>;
|
||||
createTaskMessage(insertMessage: any, organizationId: number): Promise<any>;
|
||||
updateTaskMessage(id: number, organizationId: number, updates: Partial<TaskMessage>): Promise<TaskMessage>;
|
||||
deleteTaskMessage(id: number, organizationId: number): Promise<void>;
|
||||
|
||||
// Message Reads (Read Receipts)
|
||||
markMessageAsRead(messageId: number, userId: number, organizationId: number): Promise<MessageRead>;
|
||||
getMessageReads(messageId: number, organizationId: number): Promise<MessageRead[]>;
|
||||
getMessageReadsByUser(userId: number, organizationId: number): Promise<MessageRead[]>;
|
||||
isMessageReadByUser(messageId: number, userId: number, organizationId: number): Promise<boolean>;
|
||||
|
||||
// Bookmark Folders
|
||||
getBookmarkFolder(id: number, organizationId: number, userId: number): Promise<BookmarkFolder | undefined>;
|
||||
getBookmarkFoldersByOrganization(organizationId: number, userId: number): Promise<BookmarkFolder[]>;
|
||||
getBookmarkFoldersByParent(parentId: number | null, organizationId: number, userId: number): Promise<BookmarkFolder[]>;
|
||||
createBookmarkFolder(insertFolder: InsertBookmarkFolder): Promise<BookmarkFolder>;
|
||||
updateBookmarkFolder(id: number, organizationId: number, updates: Partial<BookmarkFolder>, userId: number): Promise<BookmarkFolder>;
|
||||
deleteBookmarkFolder(id: number, organizationId: number, userId: number): Promise<void>;
|
||||
normalizeBookmarkFolderPositions(organizationId: number, userId: number): Promise<void>;
|
||||
batchUpdateBookmarkFolderPositions(items: { id: number; position: number }[], organizationId: number, userId: number): Promise<void>;
|
||||
|
||||
// Bookmarks
|
||||
getBookmark(id: number, organizationId: number, userId: number): Promise<Bookmark | undefined>;
|
||||
getBookmarksByFolder(folderId: number | null, organizationId: number, userId: number): Promise<Bookmark[]>;
|
||||
getBookmarksByOrganization(organizationId: number, userId: number): Promise<Bookmark[]>;
|
||||
createBookmark(insertBookmark: InsertBookmark): Promise<Bookmark>;
|
||||
updateBookmark(id: number, organizationId: number, updates: Partial<Bookmark>, userId: number): Promise<Bookmark>;
|
||||
deleteBookmark(id: number, organizationId: number, userId: number): Promise<void>;
|
||||
normalizeBookmarkPositions(organizationId: number, userId: number): Promise<void>;
|
||||
batchUpdateBookmarkPositions(items: { id: number; position: number }[], organizationId: number, userId: number): Promise<void>;
|
||||
|
||||
// User Notifications
|
||||
getUserNotifications(userId: number, organizationId: number, isRead?: boolean): Promise<UserNotification[]>;
|
||||
createUserNotification(insertNotification: InsertUserNotification): Promise<UserNotification>;
|
||||
markNotificationAsRead(id: number, userId: number, organizationId: number): Promise<UserNotification>;
|
||||
markAllNotificationsAsRead(userId: number, organizationId: number): Promise<void>;
|
||||
markTaskNotificationsAsRead(taskId: number, userId: number, organizationId: number): Promise<void>;
|
||||
deleteNotification(id: number, userId: number, organizationId: number): Promise<void>;
|
||||
|
||||
// User Search
|
||||
searchUsers(query: string, organizationId: number, limit?: number): Promise<User[]>;
|
||||
|
||||
// Bots
|
||||
getBot(id: number, organizationId: number): Promise<Bot | undefined>;
|
||||
getBotByLogin(login: string, organizationId: number): Promise<Bot | undefined>;
|
||||
getBotsByOrganization(organizationId: number): Promise<Bot[]>;
|
||||
getBotWithSubscriptions(id: number, organizationId: number): Promise<BotWithSubscriptions | undefined>;
|
||||
searchBots(query: string, organizationId: number, limit?: number): Promise<Bot[]>;
|
||||
createBot(insertBot: InsertBot): Promise<Bot>;
|
||||
updateBot(id: number, organizationId: number, updates: Partial<Bot>): Promise<Bot>;
|
||||
deleteBot(id: number, organizationId: number): Promise<void>;
|
||||
|
||||
// Bot Subscriptions
|
||||
getBotSubscriptions(botId: number, organizationId: number): Promise<BotSubscription[]>;
|
||||
getBotSubscriptionsByForm(formId: number, organizationId: number): Promise<BotSubscription[]>;
|
||||
getBotSubscriptionsByStatus(statusId: number, organizationId: number): Promise<BotSubscription[]>;
|
||||
getBotSubscriptionsByTransition(transitionId: number, organizationId: number): Promise<BotSubscription[]>;
|
||||
createBotSubscription(insertSubscription: InsertBotSubscription): Promise<BotSubscription>;
|
||||
updateBotSubscription(id: number, organizationId: number, updates: Partial<BotSubscription>): Promise<BotSubscription>;
|
||||
deleteBotSubscription(id: number, organizationId: number): Promise<void>;
|
||||
|
||||
// Bot Sessions
|
||||
createBotSession(session: InsertBotSession): Promise<BotSession>;
|
||||
getBotSessionByToken(refreshToken: string): Promise<BotSession | undefined>;
|
||||
deleteBotSession(refreshToken: string): Promise<void>;
|
||||
deleteBotSessions(botId: number): Promise<void>;
|
||||
|
||||
// Data Tables
|
||||
getDataTable(id: number, organizationId: number): Promise<DataTable | undefined>;
|
||||
getDataTablesByOrganization(organizationId: number): Promise<DataTable[]>;
|
||||
getDataTablesWithAccess(userId: number, organizationId: number): Promise<DataTable[]>;
|
||||
getDataTableFull(id: number, organizationId: number): Promise<DataTableFull | undefined>;
|
||||
createDataTable(table: InsertDataTable & { organizationId: number; createdBy: number }): Promise<DataTable>;
|
||||
updateDataTable(id: number, organizationId: number, updates: Partial<DataTable>): Promise<DataTable>;
|
||||
deleteDataTable(id: number, organizationId: number): Promise<void>;
|
||||
|
||||
// Data Table Rows
|
||||
getDataTableRows(tableId: number, organizationId: number): Promise<DataTableRow[]>;
|
||||
getDataTableRow(id: number, tableId: number, organizationId: number): Promise<DataTableRow | undefined>;
|
||||
createDataTableRow(row: InsertDataTableRow): Promise<DataTableRow>;
|
||||
updateDataTableRow(id: number, tableId: number, organizationId: number, updates: Partial<DataTableRow>): Promise<DataTableRow>;
|
||||
deleteDataTableRow(id: number, tableId: number, organizationId: number): Promise<void>;
|
||||
bulkCreateDataTableRows(tableId: number, rows: { values: string[] }[]): Promise<DataTableRow[]>;
|
||||
bulkDeleteDataTableRows(tableId: number, organizationId: number): Promise<void>;
|
||||
applyDataTableSync(tableId: number, deleted: { id: number }[], added: { values: string[]; position: number }[], reordered: { id: number; newPosition: number }[], positionUpdates: { id: number; position: number }[]): Promise<void>;
|
||||
applyDataTableDiff(tableId: number, upsertRows: { values: string[] }[], deleteKeys: string[], currentRows: DataTableRow[]): Promise<{ added: DataTableRow[]; updated: DataTableRow[]; deleted: DataTableRow[] }>;
|
||||
|
||||
// Data Table Permissions
|
||||
getDataTablePermissions(tableId: number, organizationId: number): Promise<(DataTablePermission & { user: { id: number; firstName: string; lastName: string; email: string } })[]>;
|
||||
getDataTablePermission(tableId: number, userId: number): Promise<DataTablePermission | undefined>;
|
||||
getUserTableRole(tableId: number, userId: number, createdBy: number, organizationId?: number): Promise<'admin' | 'editor' | 'reader' | null>;
|
||||
setDataTablePermission(permission: InsertDataTablePermission): Promise<DataTablePermission>;
|
||||
deleteDataTablePermission(tableId: number, userId: number): Promise<void>;
|
||||
|
||||
// Data Table Access Rules
|
||||
getDataTableAccessRules(tableId: number, organizationId: number): Promise<DataTableAccessRule[]>;
|
||||
createDataTableAccessRule(data: InsertDataTableAccessRule): Promise<DataTableAccessRule>;
|
||||
deleteDataTableAccessRule(id: number, organizationId: number): Promise<void>;
|
||||
getLinkedFormsForTable(tableId: number, organizationId: number): Promise<{ id: number; name: string }[]>;
|
||||
|
||||
// External Services
|
||||
getExternalServices(organizationId: number): Promise<ExternalService[]>;
|
||||
getExternalService(id: number, organizationId: number): Promise<ExternalService | undefined>;
|
||||
getExternalServiceByType(serviceType: string, organizationId: number): Promise<ExternalService | undefined>;
|
||||
createExternalService(service: InsertExternalService): Promise<ExternalService>;
|
||||
updateExternalService(id: number, organizationId: number, updates: Partial<ExternalService>): Promise<ExternalService>;
|
||||
deleteExternalService(id: number, organizationId: number): Promise<void>;
|
||||
|
||||
// Regular Table Rows (for type='table' tabs)
|
||||
getRegularTableRows(taskId: number, tabId: number): Promise<RegularTableRow[]>;
|
||||
getRegularTableRow(id: number, taskId: number, tabId: number): Promise<RegularTableRow | undefined>;
|
||||
createRegularTableRow(row: InsertRegularTableRow): Promise<RegularTableRow>;
|
||||
updateRegularTableRow(id: number, taskId: number, tabId: number, updates: Partial<RegularTableRow>): Promise<RegularTableRow>;
|
||||
deleteRegularTableRow(id: number, taskId: number, tabId: number): Promise<void>;
|
||||
|
||||
// Field Templates
|
||||
getFieldTemplates(organizationId: number): Promise<FieldTemplate[]>;
|
||||
getFieldTemplate(id: number, organizationId: number): Promise<FieldTemplate | undefined>;
|
||||
getFieldTemplateByCode(code: string, organizationId: number): Promise<FieldTemplate | undefined>;
|
||||
createFieldTemplate(field: InsertFieldTemplate): Promise<FieldTemplate>;
|
||||
updateFieldTemplate(id: number, organizationId: number, updates: Partial<FieldTemplate>): Promise<FieldTemplate>;
|
||||
deleteFieldTemplate(id: number, organizationId: number): Promise<void>;
|
||||
|
||||
// Custom Tab Modules
|
||||
getCustomTabModules(organizationId: number): Promise<CustomTabModule[]>;
|
||||
getCustomTabModule(id: number, organizationId: number): Promise<CustomTabModule | undefined>;
|
||||
getCustomTabModuleByType(type: string, organizationId: number): Promise<CustomTabModule | undefined>;
|
||||
createCustomTabModule(module: InsertCustomTabModule): Promise<CustomTabModule>;
|
||||
updateCustomTabModule(id: number, organizationId: number, updates: Partial<CustomTabModule>): Promise<CustomTabModule>;
|
||||
deleteCustomTabModule(id: number, organizationId: number): Promise<void>;
|
||||
getFormIdsByTabModuleType(type: string, organizationId: number): Promise<number[]>;
|
||||
getFormTabByModuleType(formId: number, type: string, organizationId: number): Promise<FormTab | undefined>;
|
||||
// Custom JS Pages
|
||||
getCustomPages(organizationId: number): Promise<CustomPage[]>;
|
||||
getCustomPage(id: number, organizationId: number): Promise<CustomPage | undefined>;
|
||||
getCustomPageBySlug(slug: string, organizationId: number): Promise<CustomPage | undefined>;
|
||||
createCustomPage(page: InsertCustomPage): Promise<CustomPage>;
|
||||
updateCustomPage(id: number, organizationId: number, updates: Partial<InsertCustomPage>): Promise<CustomPage>;
|
||||
deleteCustomPage(id: number, organizationId: number): Promise<void>;
|
||||
|
||||
// Automations
|
||||
getAutomations(organizationId: number): Promise<Automation[]>;
|
||||
getOfflineAutomations(organizationId: number): Promise<Automation[]>;
|
||||
getAutomation(id: number, organizationId: number): Promise<Automation | undefined>;
|
||||
createAutomation(automation: InsertAutomation): Promise<Automation>;
|
||||
updateAutomation(id: number, organizationId: number, updates: Partial<InsertAutomation>): Promise<Automation>;
|
||||
deleteAutomation(id: number, organizationId: number): Promise<void>;
|
||||
|
||||
// Task Tab Values (per-task data for custom modules)
|
||||
getTaskTabValues(taskId: number, tabId: number): Promise<TaskTabValue | undefined>;
|
||||
getTaskTabValuesByTask(taskId: number): Promise<TaskTabValue[]>;
|
||||
upsertTaskTabValues(taskId: number, tabId: number, values: Record<string, any>): Promise<TaskTabValue>;
|
||||
|
||||
// Organization API Keys (MCP)
|
||||
createApiKey(organizationId: number, createdBy: number, label: string): Promise<{ key: string; record: OrganizationApiKey }>;
|
||||
listApiKeys(organizationId: number): Promise<OrganizationApiKey[]>;
|
||||
deleteApiKey(id: number, organizationId: number): Promise<void>;
|
||||
getApiKeyByHash(rawKey: string): Promise<OrganizationApiKey | undefined>;
|
||||
getApiKeyByLegacyHash(rawKey: string): Promise<OrganizationApiKey | undefined>;
|
||||
touchApiKey(id: number): Promise<void>;
|
||||
|
||||
// Task Relations
|
||||
upsertTaskRelation(data: { parentTaskId: number; childTaskId: number; fieldId?: number | null; organizationId: number }): Promise<TaskRelation>;
|
||||
|
||||
// Task Roles
|
||||
getTaskRoles(taskId: number, organizationId: number): Promise<Array<TaskRole & { role: { id: number; name: string; parentId: number | null } }>>;
|
||||
addTaskRole(taskId: number, roleId: number, organizationId: number): Promise<TaskRole>;
|
||||
removeTaskRole(taskId: number, roleId: number, organizationId: number): Promise<void>;
|
||||
|
||||
// Task Assignees (multiple users)
|
||||
getTaskAssignees(taskId: number, organizationId: number): Promise<Array<TaskAssignee & { user: { id: number; firstName: string | null; lastName: string | null; email: string } }>>;
|
||||
addTaskAssignee(taskId: number, userId: number, organizationId: number): Promise<TaskAssignee>;
|
||||
removeTaskAssignee(taskId: number, userId: number, organizationId: number): Promise<void>;
|
||||
|
||||
// Task User Access
|
||||
getTaskUserAccess(taskId: number, organizationId: number): Promise<Array<TaskUserAccess & { user: { id: number; firstName: string | null; lastName: string | null; email: string } }>>;
|
||||
recordTaskInteraction(taskId: number, userId: number, organizationId: number, grantedVia: string, roleId?: number | null): Promise<void>;
|
||||
recordTaskInteractionAuto(taskId: number, userId: number, organizationId: number): Promise<void>;
|
||||
upsertTaskUserAccess(taskId: number, userId: number, organizationId: number, grantedVia: string): Promise<void>;
|
||||
recordTransitionAccess(taskId: number, userId: number, organizationId: number, roleId: number | null, statusId: number): Promise<void>;
|
||||
revokeTaskUserAccess(taskId: number, userId: number, organizationId: number): Promise<void>;
|
||||
canUserAccessTask(taskId: number, userId: number, organizationId: number, appRole: string): Promise<boolean>;
|
||||
getAccessibleTaskIds(userId: number, organizationId: number, appRole: string): Promise<Set<number> | null>;
|
||||
resolveTaskAccessGrant(taskId: number, userId: number, organizationId: number): Promise<{ grantedVia: string; roleId: number | null }>;
|
||||
|
||||
// Form Access Rules
|
||||
getFormAccessRules(formId: number, organizationId: number): Promise<import('@shared/schema').FormAccessRule[]>;
|
||||
createFormAccessRule(data: import('@shared/schema').InsertFormAccessRule): Promise<import('@shared/schema').FormAccessRule>;
|
||||
updateFormAccessRule(id: number, organizationId: number, updates: Partial<Pick<import('@shared/schema').FormAccessRule, 'accessLevel'>>): Promise<import('@shared/schema').FormAccessRule>;
|
||||
deleteFormAccessRule(id: number, organizationId: number): Promise<void>;
|
||||
transferFormOwnership(formId: number, organizationId: number, newAuthorId: number): Promise<void>;
|
||||
canUserAccessForm(userId: number, formId: number, organizationId: number, requiredLevel?: 'participate' | 'view_all' | 'admin'): Promise<boolean>;
|
||||
|
||||
deleteTaskRelationByField(fieldId: number, taskId: number, organizationId: number): Promise<void>;
|
||||
getTaskRelations(taskId: number, organizationId: number): Promise<TaskRelation[]>;
|
||||
|
||||
// Task Reminders
|
||||
getTaskReminders(taskId: number, organizationId: number): Promise<TaskReminder[]>;
|
||||
createTaskReminder(data: InsertTaskReminder): Promise<TaskReminder>;
|
||||
deleteTaskReminder(id: number, organizationId: number): Promise<void>;
|
||||
getDueReminders(): Promise<TaskReminder[]>;
|
||||
markReminderSent(id: number): Promise<void>;
|
||||
getUsersByRole(role: string, organizationId: number): Promise<User[]>;
|
||||
getUsersByOrgRoleId(roleId: number, organizationId: number): Promise<User[]>;
|
||||
|
||||
// Task Audit Log
|
||||
addTaskAuditLog(entry: InsertTaskAuditLog): Promise<TaskAuditLog>;
|
||||
getTaskAuditLog(taskId: number, organizationId: number): Promise<TaskAuditLog[]>;
|
||||
|
||||
// Roles
|
||||
getRoles(organizationId: number): Promise<(import('@shared/schema').Role & { memberCount: number; members: { id: number; userId: number; user: { id: number; firstName: string; lastName: string; email: string } }[]; manager: { id: number; firstName: string; lastName: string; middleName: string | null; email: string } | null })[]>;
|
||||
getRole(id: number, organizationId: number): Promise<import('@shared/schema').Role | undefined>;
|
||||
createRole(data: { organizationId: number; name: string; description?: string | null; parentId?: number | null; managerId?: number | null }): Promise<import('@shared/schema').Role>;
|
||||
updateRole(id: number, organizationId: number, updates: { name?: string; description?: string | null; parentId?: number | null; managerId?: number | null }): Promise<import('@shared/schema').Role>;
|
||||
deleteRole(id: number, organizationId: number): Promise<void>;
|
||||
getRoleMembers(roleId: number, organizationId: number): Promise<(import('@shared/schema').Role & { members: { id: number; userId: number; user: { id: number; firstName: string; lastName: string; email: string } }[]; manager: { id: number; firstName: string; lastName: string; middleName: string | null; email: string } | null })>;
|
||||
addRoleMember(roleId: number, userId: number, organizationId: number): Promise<void>;
|
||||
removeRoleMember(roleId: number, userId: number, organizationId: number): Promise<void>;
|
||||
getRoleMembersByRole(roleId: number): Promise<{ id: number; userId: number; createdAt: Date | null }[]>;
|
||||
getUserRoles(userId: number, organizationId: number): Promise<import('@shared/schema').Role[]>;
|
||||
|
||||
// Super Admins
|
||||
getSuperAdminByEmail(email: string): Promise<import('@shared/schema').SuperAdmin | undefined>;
|
||||
getSuperAdminById(id: number): Promise<import('@shared/schema').SuperAdmin | undefined>;
|
||||
getAllSuperAdmins(): Promise<import('@shared/schema').SuperAdmin[]>;
|
||||
createSuperAdmin(data: import('@shared/schema').InsertSuperAdmin): Promise<import('@shared/schema').SuperAdmin>;
|
||||
deleteSuperAdmin(id: number): Promise<void>;
|
||||
getSuperAdminCount(): Promise<number>;
|
||||
updateSuperAdminLastLogin(id: number): Promise<void>;
|
||||
updateSuperAdminPassword(id: number, passwordHash: string): Promise<void>;
|
||||
getAllOrganizationsWithStats(): Promise<Array<import('@shared/schema').Organization & { totalUsers: number; activeUsers: number; totalTasks: number; lastActivity: Date | null; billingBalance: string; billingCurrency: string }>>;
|
||||
updateOrganization(id: number, updates: Partial<import('@shared/schema').Organization>): Promise<import('@shared/schema').Organization>;
|
||||
getOrganizationDetailedStats(organizationId: number): Promise<{ forms: number; tasks: number; totalUsers: number; activeUsers: number; lastActivity: Date | null }>;
|
||||
|
||||
// Billing
|
||||
getBillingSettings(organizationId: number): Promise<import('@shared/schema').OrganizationBilling | null>;
|
||||
getOrCreateBillingSettings(organizationId: number): Promise<import('@shared/schema').OrganizationBilling>;
|
||||
updateBillingSettings(organizationId: number, updates: Partial<import('@shared/schema').OrganizationBilling>): Promise<import('@shared/schema').OrganizationBilling>;
|
||||
addBillingCredit(organizationId: number, amount: number, description: string, createdBy?: number): Promise<import('@shared/schema').BillingTransaction>;
|
||||
getBillingTransactions(organizationId: number, limit?: number): Promise<import('@shared/schema').BillingTransaction[]>;
|
||||
setBillingBlocked(organizationId: number, blocked: boolean): Promise<void>;
|
||||
getBillingSummary(organizationId: number): Promise<{ balance: string; pricePerUser: string; currency: string; nextBillingDate: string | null; billingBlocked: boolean; activeUsers: number; estimatedCharge: string }>;
|
||||
processBillingCycle(): Promise<void>;
|
||||
|
||||
// RAG Settings
|
||||
getRagSettings(organizationId: number): Promise<RagSetting | undefined>;
|
||||
upsertRagSettings(organizationId: number, updates: Partial<Omit<RagSetting, 'organizationId' | 'updatedAt'>>): Promise<RagSetting>;
|
||||
|
||||
// LLM Providers
|
||||
getLlmProviders(organizationId: number): Promise<LlmProvider[]>;
|
||||
getLlmProvider(id: number, organizationId: number): Promise<LlmProvider | undefined>;
|
||||
createLlmProvider(data: InsertLlmProvider): Promise<LlmProvider>;
|
||||
updateLlmProvider(id: number, organizationId: number, updates: Partial<Omit<LlmProvider, 'id' | 'organizationId' | 'createdAt'>>): Promise<LlmProvider>;
|
||||
deleteLlmProvider(id: number, organizationId: number): Promise<void>;
|
||||
|
||||
// System Config
|
||||
getSystemConfig(key: string): Promise<string | null>;
|
||||
setSystemConfig(key: string, value: string): Promise<void>;
|
||||
|
||||
// Web Push
|
||||
registerWebPushSubscription(userId: number, organizationId: number, endpoint: string, subscription: string): Promise<void>;
|
||||
unregisterWebPushSubscription(endpoint: string): Promise<void>;
|
||||
getWebPushSubscriptions(userId: number, organizationId: number): Promise<any[]>;
|
||||
getWebPushSubscriptionsByOrganization(organizationId: number): Promise<any[]>;
|
||||
clearAllWebPushSubscriptions(): Promise<number>;
|
||||
}
|
||||
|
||||
export { DatabaseStorage, storage } from "./storage/index";
|
||||
Reference in New Issue
Block a user