Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions .cursor/rules/prisma-enum-imports.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Prisma Enum Imports

## Rule

**Always import Prisma enums from `@/generated/prisma/enums` instead of `@/generated/prisma/client`.**

Importing enums from `@prisma/client` causes Next.js bundling errors when used in client components because Prisma Client depends on Node.js modules.

## Correct Pattern

```typescript
// ✅ Import enums from enums file
import { ActionType, SystemType } from "@/generated/prisma/enums";
import type { Rule, User } from "@/generated/prisma/client";
```

## Incorrect Pattern

```typescript
// ❌ Don't import enums from client
import { ActionType, SystemType } from "@/generated/prisma/client";
```

## Check Imports

Run `pnpm check-enums` from `apps/web` to verify all enum imports are correct. This runs automatically in CI.
3 changes: 3 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ jobs:
- name: Install dependencies
run: pnpm install

- name: Check Prisma enum imports
run: pnpm -F inbox-zero-ai check-enums

- name: Run tests
run: pnpm -F inbox-zero-ai test
env:
Expand Down
2 changes: 1 addition & 1 deletion apps/web/__tests__/ai-calendar-availability.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { aiGetCalendarAvailability } from "@/utils/ai/calendar/availability";
import type { EmailForLLM } from "@/utils/types";
import { getEmailAccount } from "@/__tests__/helpers";
import type { BusyPeriod } from "@/utils/calendar/availability";
import type { Prisma } from "@prisma/client";
import type { Prisma } from "@/generated/prisma/client";

// Run with: pnpm test-ai calendar-availability

Expand Down
2 changes: 1 addition & 1 deletion apps/web/__tests__/ai-choose-args.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { describe, expect, test, vi } from "vitest";
import type { ParsedMessage } from "@/utils/types";
import { getActionItemsWithAiArgs } from "@/utils/ai/choose-rule/choose-args";
import { getEmailAccount, getAction, getRule } from "@/__tests__/helpers";
import { ActionType } from "@prisma/client";
import { ActionType } from "@/generated/prisma/enums";
import { createScopedLogger } from "@/utils/logger";

// pnpm test-ai ai-choose-args
Expand Down
2 changes: 1 addition & 1 deletion apps/web/__tests__/ai-choose-rule.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { describe, expect, test, vi } from "vitest";
import { aiChooseRule } from "@/utils/ai/choose-rule/ai-choose-rule";
import { ActionType } from "@prisma/client";
import { ActionType } from "@/generated/prisma/enums";
import { getEmail, getEmailAccount, getRule } from "@/__tests__/helpers";

// pnpm test-ai ai-choose-rule
Expand Down
2 changes: 1 addition & 1 deletion apps/web/__tests__/ai-detect-recurring-pattern.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { describe, expect, test, vi, beforeEach } from "vitest";
import { aiDetectRecurringPattern } from "@/utils/ai/choose-rule/ai-detect-recurring-pattern";
import type { EmailForLLM } from "@/utils/types";
import { getRuleName, getRuleConfig } from "@/utils/rule/consts";
import { SystemType } from "@prisma/client";
import { SystemType } from "@/generated/prisma/enums";
import { getEmailAccount } from "@/__tests__/helpers";

// Run with: pnpm test-ai ai-detect-recurring-pattern
Expand Down
2 changes: 1 addition & 1 deletion apps/web/__tests__/ai-extract-knowledge.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { describe, expect, test, vi, beforeEach } from "vitest";
import { aiExtractRelevantKnowledge } from "@/utils/ai/knowledge/extract";
import type { Knowledge } from "@prisma/client";
import type { Knowledge } from "@/generated/prisma/client";
import { getEmailAccount } from "@/__tests__/helpers";

const TIMEOUT = 30_000;
Expand Down
4 changes: 2 additions & 2 deletions apps/web/__tests__/ai-process-user-request.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import stripIndent from "strip-indent";
import { processUserRequest } from "@/utils/ai/assistant/process-user-request";
import type { ParsedMessage, ParsedMessageHeaders } from "@/utils/types";
import type { RuleWithRelations } from "@/utils/ai/rule/create-prompt-from-rule";
import type { Category, GroupItem, Prisma } from "@prisma/client";
import { GroupItemType, LogicalOperator } from "@prisma/client";
import type { Category, GroupItem, Prisma } from "@/generated/prisma/client";
import { GroupItemType, LogicalOperator } from "@/generated/prisma/enums";
import { getEmailAccount } from "@/__tests__/helpers";

// pnpm test-ai ai-process-user-request
Expand Down
2 changes: 1 addition & 1 deletion apps/web/__tests__/ai-prompt-to-rules.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { describe, it, expect, vi } from "vitest";
import { aiPromptToRulesOld as aiPromptToRules } from "@/utils/ai/rule/prompt-to-rules-old";
import { createRuleSchema } from "@/utils/ai/rule/create-rule-schema";
import { ActionType } from "@prisma/client";
import { ActionType } from "@/generated/prisma/enums";
import { getEmailAccount } from "@/__tests__/helpers";

// pnpm test-ai ai-prompt-to-rules
Expand Down
2 changes: 1 addition & 1 deletion apps/web/__tests__/determine-thread-status.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
getEmail,
generateSequentialDates,
} from "@/__tests__/helpers";
import { SystemType } from "@prisma/client";
import { SystemType } from "@/generated/prisma/enums";

// Run with: pnpm test-ai determine-thread-status

Expand Down
4 changes: 2 additions & 2 deletions apps/web/__tests__/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { EmailAccountWithAI } from "@/utils/llms/types";
import type { EmailForLLM } from "@/utils/types";
import { ActionType, type Action, LogicalOperator } from "@prisma/client";
import type { Prisma } from "@prisma/client";
import { ActionType, LogicalOperator } from "@/generated/prisma/enums";
import type { Action, Prisma } from "@/generated/prisma/client";

type EmailAccountSelect = {
id: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { TagIcon } from "lucide-react";
import type { CreateRuleBody } from "@/utils/actions/rule.validation";
import { ActionType } from "@prisma/client";
import { ActionType } from "@/generated/prisma/enums";
import { CardBasic } from "@/components/ui/card";
import {
ACTION_TYPE_TEXT_COLORS,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ActionType } from "@prisma/client";
import { ActionType } from "@/generated/prisma/enums";
import { Card, CardContent } from "@/components/ui/card";
import { getActionIcon } from "@/utils/action-display";
import { SectionHeader } from "@/components/Typography";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { Button } from "@/components/ui/button";
import { getExamplePrompts } from "@/app/(app)/[emailAccountId]/assistant/examples";
import { getActionIcon } from "@/utils/action-display";
import { getActionColor } from "@/components/PlanBadge";
import { ActionType } from "@prisma/client";
import { ActionType } from "@/generated/prisma/enums";
import type { Color } from "@/components/Badge";
import { cn } from "@/utils";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,9 @@ import { capitalCase } from "capital-case";
import { HoverCard } from "@/components/HoverCard";
import { Badge } from "@/components/Badge";
import { conditionTypesToString } from "@/utils/condition";
import {
type ActionType,
ExecutedRuleStatus,
type Rule,
LogicalOperator,
} from "@prisma/client";
import { ExecutedRuleStatus, LogicalOperator } from "@/generated/prisma/enums";
import type { ActionType } from "@/generated/prisma/enums";
import type { Rule } from "@/generated/prisma/client";
import { Button } from "@/components/ui/button";
import { MessageText } from "@/components/Typography";
import { EyeIcon } from "lucide-react";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { LoadingContent } from "@/components/LoadingContent";
import { useRule } from "@/hooks/useRule";
import type { CreateRuleBody } from "@/utils/actions/rule.validation";
import { useDialogState } from "@/hooks/useDialogState";
import { ActionType, LogicalOperator } from "@prisma/client";
import { ActionType, LogicalOperator } from "@/generated/prisma/enums";
import { ConditionType } from "@/utils/config";
import type { RulesResponse } from "@/app/api/user/rules/route";

Expand Down
6 changes: 5 additions & 1 deletion apps/web/app/(app)/[emailAccountId]/assistant/RuleForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@ import { Button } from "@/components/ui/button";
import { ErrorMessage, Input, Label } from "@/components/Input";
import { toastError, toastSuccess } from "@/components/Toast";
import { TypographyH3 } from "@/components/Typography";
import { ActionType, LogicalOperator, SystemType } from "@prisma/client";
import {
ActionType,
LogicalOperator,
SystemType,
} from "@/generated/prisma/enums";
import { ConditionType, type CoreConditionType } from "@/utils/config";
import {
createRuleAction,
Expand Down
3 changes: 2 additions & 1 deletion apps/web/app/(app)/[emailAccountId]/assistant/Rules.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ import { Badge } from "@/components/Badge";
import { getActionColor } from "@/components/PlanBadge";
import { toastError } from "@/components/Toast";
import { useRules } from "@/hooks/useRules";
import { type ActionType, LogicalOperator, SystemType } from "@prisma/client";
import { LogicalOperator, SystemType } from "@/generated/prisma/enums";
import type { ActionType } from "@/generated/prisma/client";
import { useAction } from "next-safe-action/hooks";
import { useAccount } from "@/providers/EmailAccountProvider";
import { prefixPath } from "@/utils/path";
Expand Down
2 changes: 1 addition & 1 deletion apps/web/app/(app)/[emailAccountId]/assistant/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
FileTextIcon,
FolderInputIcon,
} from "lucide-react";
import { ActionType } from "@prisma/client";
import { ActionType } from "@/generated/prisma/enums";

const ACTION_TYPE_COLORS = {
[ActionType.LABEL]: "bg-blue-500",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ import {
addGroupItemAction,
deleteGroupItemAction,
} from "@/utils/actions/group";
import { type GroupItem, GroupItemType } from "@prisma/client";
import { GroupItemType } from "@/generated/prisma/enums";
import type { GroupItem } from "@/generated/prisma/client";
import { Input } from "@/components/Input";
import { Select } from "@/components/Select";
import { zodResolver } from "@hookform/resolvers/zod";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import { ConfirmDialog } from "@/components/ConfirmDialog";
import { KnowledgeForm } from "@/app/(app)/[emailAccountId]/assistant/knowledge/KnowledgeForm";
import { useAccount } from "@/providers/EmailAccountProvider";
import type { GetKnowledgeResponse } from "@/app/api/knowledge/route";
import type { Knowledge } from "@prisma/client";
import type { Knowledge } from "@/generated/prisma/client";

export function KnowledgeBase() {
const { emailAccountId } = useAccount();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {
} from "@/utils/actions/knowledge";
import { toastError, toastSuccess } from "@/components/Toast";
import type { GetKnowledgeResponse } from "@/app/api/knowledge/route";
import { PremiumTier, type Knowledge } from "@prisma/client";
import type { Knowledge } from "@/generated/prisma/client";
import { Tiptap, type TiptapHandle } from "@/components/editor/Tiptap";
import { Label } from "@/components/ui/label";
import { cn } from "@/utils";
Expand All @@ -46,7 +46,7 @@ export function KnowledgeForm({

const hasFullAccess = hasTierAccess({
tier: tier || null,
minimumTier: PremiumTier.BUSINESS_PLUS_MONTHLY,
minimumTier: "BUSINESS_PLUS_MONTHLY",
});

const {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { ParsedMessage } from "@/utils/types";
import type { GroupItem, Prisma } from "@prisma/client";
import type { GroupItem, Prisma } from "@/generated/prisma/client";

export type RuleWithGroup = Prisma.RuleGetPayload<{
include: { group: { include: { items: true } } };
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { RuleForm } from "@/app/(app)/[emailAccountId]/assistant/RuleForm";
import { getEmptyCondition } from "@/utils/condition";
import { ActionType } from "@prisma/client";
import { ActionType } from "@/generated/prisma/enums";
import type { CoreConditionType } from "@/utils/config";

export default async function CreateRulePage(props: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { enableDraftRepliesAction } from "@/utils/actions/rule";
import { toastError } from "@/components/Toast";
import { useAccount } from "@/providers/EmailAccountProvider";
import { useRules } from "@/hooks/useRules";
import { ActionType, SystemType } from "@prisma/client";
import { ActionType, SystemType } from "@/generated/prisma/enums";
import { LoadingContent } from "@/components/LoadingContent";
import { Skeleton } from "@/components/ui/skeleton";
import { SettingCard } from "@/components/SettingCard";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import { extractEmailAddress, extractNameFromEmail } from "@/utils/email";
import type { RowProps } from "@/app/(app)/[emailAccountId]/bulk-unsubscribe/types";
import { Button } from "@/components/ui/button";
import { ButtonLoader } from "@/components/Loading";
import { NewsletterStatus } from "@prisma/client";
import { NewsletterStatus } from "@/generated/prisma/enums";
import { Badge } from "@/components/ui/badge";

export function BulkUnsubscribeMobile({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { formatStat } from "@/utils/stats";
import { LoadingContent } from "@/components/LoadingContent";
import { Skeleton } from "@/components/ui/skeleton";
import type { NewsletterSummaryResponse } from "@/app/api/user/stats/newsletters/summary/route";
import { NewsletterStatus } from "@prisma/client";
import { NewsletterStatus } from "@/generated/prisma/enums";

export function BulkUnsubscribeSummary() {
const { data, isLoading, error } = useSWR<
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ import {
PremiumTooltip,
PremiumTooltipContent,
} from "@/components/PremiumAlert";
import { NewsletterStatus } from "@prisma/client";
import { NewsletterStatus } from "@/generated/prisma/enums";
import { toastError, toastSuccess } from "@/components/Toast";
import { createFilterAction } from "@/utils/actions/mail";
import { getGmailSearchUrl } from "@/utils/url";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import type { PostHog } from "posthog-js/react";
import { onAutoArchive, onDeleteFilter } from "@/utils/actions/client";
import { setNewsletterStatusAction } from "@/utils/actions/unsubscriber";
import { decrementUnsubscribeCreditAction } from "@/utils/actions/premium";
import { NewsletterStatus } from "@prisma/client";
import { NewsletterStatus } from "@/generated/prisma/enums";
import { cleanUnsubscribeLink } from "@/utils/parse/parseHtml.client";
import { captureException } from "@/utils/error";
import { addToArchiveSenderQueue } from "@/store/archive-sender-queue";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { NewsletterStatsResponse } from "@/app/api/user/stats/newsletters/route";
import type { NewsletterStatus } from "@prisma/client";
import type { NewsletterStatus } from "@/generated/prisma/enums";
import type { EmailLabel } from "@/providers/EmailProvider";
import type { UserResponse } from "@/app/api/user/me/route";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { parseAsStringEnum, useQueryState } from "nuqs";
import { TypographyH3 } from "@/components/Typography";
import { useStep } from "@/app/(app)/[emailAccountId]/clean/useStep";
import { ButtonListSurvey } from "@/components/ButtonListSurvey";
import { CleanAction } from "@prisma/client";
import { CleanAction } from "@/generated/prisma/enums";

export function ActionSelectionStep() {
const { onNext } = useStep();
Expand Down
2 changes: 1 addition & 1 deletion apps/web/app/(app)/[emailAccountId]/clean/CleanRun.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { EmailFirehose } from "@/app/(app)/[emailAccountId]/clean/EmailFirehose"
import { PreviewBatch } from "@/app/(app)/[emailAccountId]/clean/PreviewBatch";
import { Card } from "@/components/ui/card";
import type { getThreadsByJobId } from "@/utils/redis/clean";
import type { CleanupJob } from "@prisma/client";
import type { CleanupJob } from "@/generated/prisma/client";

export function CleanRun({
isPreviewBatch,
Expand Down
2 changes: 1 addition & 1 deletion apps/web/app/(app)/[emailAccountId]/clean/CleanStats.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ArchiveIcon, InboxIcon } from "lucide-react";
import { Card, CardContent } from "@/components/ui/card";
import { cn } from "@/utils";
import { CleanAction } from "@prisma/client";
import { CleanAction } from "@/generated/prisma/enums";

export function CleanStats({
stats,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { Button } from "@/components/ui/button";
import { Badge } from "@/components/Badge";
import { cleanInboxAction } from "@/utils/actions/clean";
import { toastError } from "@/components/Toast";
import { CleanAction } from "@prisma/client";
import { CleanAction } from "@/generated/prisma/enums";
import { PREVIEW_RUN_COUNT } from "@/app/(app)/[emailAccountId]/clean/consts";
import { HistoryIcon, SettingsIcon } from "lucide-react";
import { useAccount } from "@/providers/EmailAccountProvider";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { EmailItem } from "./EmailFirehoseItem";
import { useEmailStream } from "./useEmailStream";
import type { CleanThread } from "@/utils/redis/clean.types";
import { CleanAction } from "@prisma/client";
import { CleanAction } from "@/generated/prisma/enums";
import { useAccount } from "@/providers/EmailAccountProvider";

export function EmailFirehose({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
} from "@/utils/actions/clean";
import { toastError } from "@/components/Toast";
import { getGmailUrl } from "@/utils/url";
import { CleanAction } from "@prisma/client";
import { CleanAction } from "@/generated/prisma/enums";

type Status = "markedDone" | "markingDone" | "keep" | "labelled" | "processing";

Expand Down
2 changes: 1 addition & 1 deletion apps/web/app/(app)/[emailAccountId]/clean/IntroStep.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { SectionDescription } from "@/components/Typography";
import { TypographyH3 } from "@/components/Typography";
import { Button } from "@/components/ui/button";
import { useStep } from "@/app/(app)/[emailAccountId]/clean/useStep";
import { CleanAction } from "@prisma/client";
import { CleanAction } from "@/generated/prisma/enums";
import { PremiumAlertWithData } from "@/components/PremiumAlert";

export function IntroStep({
Expand Down
3 changes: 2 additions & 1 deletion apps/web/app/(app)/[emailAccountId]/clean/PreviewBatch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import {
CardTitle,
} from "@/components/ui/card";
import { cleanInboxAction } from "@/utils/actions/clean";
import { CleanAction, type CleanupJob } from "@prisma/client";
import { CleanAction } from "@/generated/prisma/enums";
import type { CleanupJob } from "@/generated/prisma/client";
import { PREVIEW_RUN_COUNT } from "@/app/(app)/[emailAccountId]/clean/consts";
import { useAccount } from "@/providers/EmailAccountProvider";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { TimeRangeStep } from "@/app/(app)/[emailAccountId]/clean/TimeRangeStep"
import { ConfirmationStep } from "@/app/(app)/[emailAccountId]/clean/ConfirmationStep";
import { getUnhandledCount } from "@/utils/assess";
import { CleanStep } from "@/app/(app)/[emailAccountId]/clean/types";
import { CleanAction } from "@prisma/client";
import { CleanAction } from "@/generated/prisma/enums";
import { createEmailProvider } from "@/utils/email/provider";
import { checkUserOwnsEmailAccount } from "@/utils/email-account";
import prisma from "@/utils/prisma";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { DateCell } from "@/app/(app)/[emailAccountId]/assistant/DateCell";
import { TablePagination } from "@/components/TablePagination";
import { AlertBasic } from "@/components/Alert";
import { useSearchParams } from "next/navigation";
import { ColdEmailStatus } from "@prisma/client";
import { ColdEmailStatus } from "@/generated/prisma/enums";
import { ViewEmailButton } from "@/components/ViewEmailButton";
import { EmailMessageCellWithData } from "@/components/EmailMessageCell";
import { useAccount } from "@/providers/EmailAccountProvider";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ThreadTrackerType } from "@prisma/client";
import { ThreadTrackerType } from "@/generated/prisma/enums";
import { ReplyTrackerEmails } from "./ReplyTrackerEmails";
import { getPaginatedThreadTrackers } from "./fetch-trackers";
import type { TimeRange } from "./date-filter";
Expand Down
Loading
Loading