diff --git a/README.md b/README.md index 1c87982..680dacf 100644 --- a/README.md +++ b/README.md @@ -131,7 +131,6 @@ services: ports: - "7331:7331" environment: - - NODE_ENV=production - SELF_HOSTED_MODE=true - UPLOAD_PATH=/app/data/uploads - DATABASE_URL=postgresql://postgres:postgres@localhost:5432/taxhacker @@ -146,7 +145,7 @@ Configure TaxHacker to suit your needs with these environment variables: | Variable | Required | Description | Example | |----------|----------|-------------|---------| -| `PORT` | No | Port to run the server on | `7331` | +| `PORT` | No | Port to run the app on | `7331` (default) | | `UPLOAD_PATH` | Yes | Local directory for uploading files | `./data/uploads` | | `DATABASE_URL` | Yes | PostgreSQL connection string | `postgresql://user@localhost:5432/taxhacker` | | `SELF_HOSTED_MODE` | No | Set it to "true" if you're self-hosting the app: it enables auto-login, custom API keys, and more | `false` | diff --git a/app/(app)/unsorted/actions.ts b/app/(app)/unsorted/actions.ts index a49cfac..41de62c 100644 --- a/app/(app)/unsorted/actions.ts +++ b/app/(app)/unsorted/actions.ts @@ -29,6 +29,11 @@ export async function analyzeFileAction( return { success: false, error: "File not found or does not belong to the user" } } + const apiKey = settings.openai_api_key || config.ai.openaiApiKey || "" + if (!apiKey) { + return { success: false, error: "OpenAI API key is not set" } + } + let attachments: AnalyzeAttachment[] = [] try { attachments = await loadAttachmentsForAI(user, file) @@ -46,12 +51,7 @@ export async function analyzeFileAction( const schema = fieldsToJsonSchema(fields) - const results = await analyzeTransaction( - prompt, - schema, - attachments, - settings.openai_api_key || config.ai.openaiApiKey - ) + const results = await analyzeTransaction(prompt, schema, attachments, apiKey) console.log("Analysis results:", results) diff --git a/app/layout.tsx b/app/layout.tsx index 14eff72..cf83a54 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -14,10 +14,32 @@ export const metadata: Metadata = { apple: "/apple-touch-icon.png", }, manifest: "/site.webmanifest", + metadataBase: new URL(config.app.baseURL), + openGraph: { + type: "website", + locale: "en_US", + url: config.app.baseURL, + title: config.app.title, + description: config.app.description, + siteName: config.app.title, + }, + twitter: { + card: "summary_large_image", + title: config.app.title, + description: config.app.description, + }, + robots: { + index: true, + follow: true, + }, } export const viewport: Viewport = { themeColor: "#ffffff", + width: "device-width", + initialScale: 1, + maximumScale: 1, + userScalable: false, } export default async function RootLayout({ children }: { children: React.ReactNode }) { @@ -25,8 +47,9 @@ export default async function RootLayout({ children }: { children: React.ReactNo
+ - {children} + {children} ) } diff --git a/lib/config.ts b/lib/config.ts index 2ec32b9..2c26be3 100644 --- a/lib/config.ts +++ b/lib/config.ts @@ -1,31 +1,50 @@ +import { z } from "zod" + +const envSchema = z.object({ + BASE_URL: z.string().url().default("http://localhost:7331"), + PORT: z.string().default("7331"), + SELF_HOSTED_MODE: z.enum(["true", "false"]).default("false"), + OPENAI_API_KEY: z.string().optional(), + BETTER_AUTH_SECRET: z + .string() + .min(16, "Auth secret must be at least 16 characters") + .default("please-set-your-key-here"), + DISABLE_SIGNUP: z.enum(["true", "false"]).default("false"), + RESEND_API_KEY: z.string().default("please-set-your-resend-api-key-here"), + RESEND_FROM_EMAIL: z.string().default("TaxHacker