fix: small adjustments before v0.5

This commit is contained in:
Vasily Zubarev
2025-04-04 11:39:02 +02:00
parent fd6b5632cd
commit 1d53434f94
8 changed files with 27 additions and 21 deletions

View File

@@ -1,5 +1,6 @@
PORT=7331 PORT=7331
SELF_HOSTED_MODE=false SELF_HOSTED_MODE=false
DISABLE_SIGNUP=false
UPLOAD_PATH="./data/uploads" UPLOAD_PATH="./data/uploads"
DATABASE_URL="postgresql://user@localhost:5432/taxhacker" DATABASE_URL="postgresql://user@localhost:5432/taxhacker"
BETTER_AUTH_SECRET="random-secret-key" BETTER_AUTH_SECRET="random-secret-key"

View File

@@ -29,10 +29,6 @@ Built-in system of filters, support for multiple projects, import-export of tran
![Dashboard](docs/screenshots/title.png) ![Dashboard](docs/screenshots/title.png)
> \[!NOTE]
>
> TaxHacker is a single-user app. SaaS or Electron version will probably be developed in the future if anyone is interested.
> \[!IMPORTANT] > \[!IMPORTANT]
> >
> This project is still at a very early stage. Use it at your own risk! **Star Us** to receive notifications about new bugfixes and features from GitHub ⭐️ > This project is still at a very early stage. Use it at your own risk! **Star Us** to receive notifications about new bugfixes and features from GitHub ⭐️
@@ -151,12 +147,12 @@ Configure TaxHacker to suit your needs with these environment variables:
| Variable | Required | Description | Example | | Variable | Required | Description | Example |
|----------|----------|-------------|---------| |----------|----------|-------------|---------|
| `PORT` | No | Port to run the server on | `7331` | | `PORT` | No | Port to run the server on | `7331` |
| `SELF_HOSTED_MODE` | No | Enable self-hosted mode and automatic login | `false` |
| `UPLOAD_PATH` | Yes | Local directory for uploading files | `./data/uploads` | | `UPLOAD_PATH` | Yes | Local directory for uploading files | `./data/uploads` |
| `DATABASE_URL` | Yes | PostgreSQL connection string | `postgresql://postgres:postgres@localhost:5432/taxhacker` | | `DATABASE_URL` | Yes | PostgreSQL connection string | `postgresql://user@localhost:5432/taxhacker` |
| `OPENAI_API_KEY` | No | OpenAI API key for AI features | `sk-...` | | `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` |
| `DISABLE_SIGNUP` | No | Disable new user registration on your instance | `false` |
| `OPENAI_API_KEY` | No | OpenAI API key for AI features. In self-hosted mode you can set it up in settings too. | `sk-...` |
| `RESEND_API_KEY` | No | Resend API key for email notifications | `re_...` | | `RESEND_API_KEY` | No | Resend API key for email notifications | `re_...` |
| `RESEND_AUDIENCE_ID` | No | Resend audience ID for newsletters | `fde8dd49-...` |
| `RESEND_FROM_EMAIL` | No | Email address to send from | `TaxHacker <hello@taxhacker.app>` | | `RESEND_FROM_EMAIL` | No | Email address to send from | `TaxHacker <hello@taxhacker.app>` |

View File

@@ -30,11 +30,6 @@ export async function restoreBackupAction(prevState: any, formData: FormData) {
return { success: false, error: "Bad zip archive" } return { success: false, error: "Bad zip archive" }
} }
if (REMOVE_EXISTING_DATA) {
await cleanupUserTables(user.id)
await fs.rm(userUploadsDirectory, { recursive: true, force: true })
}
// Check metadata and start restoring // Check metadata and start restoring
try { try {
const metadataFile = zip.file("data/metadata.json") const metadataFile = zip.file("data/metadata.json")
@@ -58,6 +53,12 @@ export async function restoreBackupAction(prevState: any, formData: FormData) {
console.warn("No metadata found in backup, assuming legacy format") console.warn("No metadata found in backup, assuming legacy format")
} }
// Remove existing data
if (REMOVE_EXISTING_DATA) {
await cleanupUserTables(user.id)
await fs.rm(userUploadsDirectory, { recursive: true, force: true })
}
const counters: Record<string, number> = {} const counters: Record<string, number> = {}
// Restore tables // Restore tables

View File

@@ -31,22 +31,25 @@ export default function BackupSettingsPage() {
<Card className="flex flex-col gap-2 mt-16 p-5 bg-red-100 max-w-xl"> <Card className="flex flex-col gap-2 mt-16 p-5 bg-red-100 max-w-xl">
<h2 className="text-xl font-semibold">Restore from a backup</h2> <h2 className="text-xl font-semibold">Restore from a backup</h2>
<p className="text-sm text-muted-foreground"> <p className="text-sm text-muted-foreground">
This action will delete all existing data from your current database and remove all uploaded files. Be This action is irreversible. Restoring from a backup will delete all existing data from your current
careful and make a backup first! database and remove all uploaded files. Be careful and make a backup first!
</p> </p>
<form action={restoreBackup}> <form action={restoreBackup}>
<div className="flex flex-col gap-4 pt-4"> <div className="flex flex-col gap-4 pt-4">
<input type="hidden" name="removeExistingData" value="true" />
<label> <label>
<input type="file" name="file" /> <input type="file" name="file" required />
</label>
<label className="flex flex-row gap-2 items-center">
<input type="checkbox" name="removeExistingData" required />
<span className="text-red-500">I undestand that it will permanently delete all existing data</span>
</label> </label>
<Button type="submit" variant="destructive" disabled={restorePending}> <Button type="submit" variant="destructive" disabled={restorePending}>
{restorePending ? ( {restorePending ? (
<> <>
<Loader2 className="animate-spin" /> Restoring from backup... <Loader2 className="animate-spin" /> Restoring from backup... (it can take a while)
</> </>
) : ( ) : (
"Delete existing data and restore from backup" "Restore from backup"
)} )}
</Button> </Button>
</div> </div>

View File

@@ -50,7 +50,7 @@ export async function analyzeFileAction(
prompt, prompt,
schema, schema,
attachments, attachments,
config.selfHosted.isEnabled ? settings.openai_api_key : process.env.OPENAI_API_KEY || "" settings.openai_api_key || config.ai.openaiApiKey
) )
console.log("Analysis results:", results) console.log("Analysis results:", results)

View File

@@ -45,7 +45,7 @@ export default async function SelfHostedWelcomePage() {
<form action={selfHostedGetStartedAction} className="flex flex-col gap-8 pt-8"> <form action={selfHostedGetStartedAction} className="flex flex-col gap-8 pt-8">
<div> <div>
<FormInput title="OpenAI API Key" name="openai_api_key" /> <FormInput title="OpenAI API Key" name="openai_api_key" defaultValue={config.ai.openaiApiKey} />
<small className="text-xs text-muted-foreground"> <small className="text-xs text-muted-foreground">
Get your API key from{" "} Get your API key from{" "}

View File

@@ -7,6 +7,8 @@ services:
environment: environment:
- NODE_ENV=production - NODE_ENV=production
- BASE_URL=https://taxhacker.app - BASE_URL=https://taxhacker.app
- DISABLE_SIGNUP=true
- SELF_HOSTED_MODE=false
- UPLOAD_PATH=/app/data/uploads - UPLOAD_PATH=/app/data/uploads
env_file: env_file:
- .env - .env

View File

@@ -13,6 +13,9 @@ const config = {
redirectUrl: "/self-hosted/redirect", redirectUrl: "/self-hosted/redirect",
welcomeUrl: "/self-hosted", welcomeUrl: "/self-hosted",
}, },
ai: {
openaiApiKey: process.env.OPENAI_API_KEY || "",
},
auth: { auth: {
secret: process.env.BETTER_AUTH_SECRET || "please-set-secret", secret: process.env.BETTER_AUTH_SECRET || "please-set-secret",
loginUrl: "/enter", loginUrl: "/enter",