Fixed a few things lol
All checks were successful
Docker Deploy / build-and-push (push) Successful in 4m11s

This commit is contained in:
2026-01-17 22:19:10 -07:00
parent 0cd77677f2
commit 091766d6e4
10 changed files with 61 additions and 57 deletions

View File

@@ -1,4 +1,4 @@
# Docker Configuration DATA_DIR=./data
IMAGE=ghcr.io/atridad/chronus:latest
APP_PORT=4321
ROOT_DIR=./data ROOT_DIR=./data
APP_PORT=4321
IMAGE=git.atri.dad/atash/chronus:latest

View File

@@ -7,7 +7,7 @@ services:
- NODE_ENV=production - NODE_ENV=production
- HOST=0.0.0.0 - HOST=0.0.0.0
- PORT=4321 - PORT=4321
- ROOT_DIR=/app/data - DATA_DIR=/app/data
volumes: volumes:
- ${ROOT_DIR}:/app/data - ${ROOT_DIR}:/app/data
restart: unless-stopped restart: unless-stopped

View File

@@ -5,13 +5,17 @@ import * as dotenv from "dotenv";
dotenv.config(); dotenv.config();
const rootDir = process.env.ROOT_DIR || process.cwd(); const dataDir = process.env.DATA_DIR;
if (process.env.ROOT_DIR && !fs.existsSync(rootDir)) { if (!dataDir) {
fs.mkdirSync(rootDir, { recursive: true }); throw new Error("DATA_DIR environment variable is not set");
} }
const dbUrl = `file:${path.join(rootDir, "chronus.db")}`; if (!fs.existsSync(dataDir)) {
fs.mkdirSync(dataDir, { recursive: true });
}
const dbUrl = `file:${path.join(dataDir, "chronus.db")}`;
export default defineConfig({ export default defineConfig({
schema: "./src/db/schema.ts", schema: "./src/db/schema.ts",
@@ -19,6 +23,5 @@ export default defineConfig({
dialect: "turso", dialect: "turso",
dbCredentials: { dbCredentials: {
url: dbUrl, url: dbUrl,
authToken: process.env.DATABASE_AUTH_TOKEN,
}, },
}); });

View File

@@ -3,20 +3,25 @@ import { migrate } from "drizzle-orm/libsql/migrator";
import { createClient } from "@libsql/client"; import { createClient } from "@libsql/client";
import path from "path"; import path from "path";
import fs from "fs"; import fs from "fs";
import * as dotenv from "dotenv";
dotenv.config();
async function runMigrate() { async function runMigrate() {
console.log("Running migrations..."); console.log("Running migrations...");
const rootDir = process.env.ROOT_DIR || process.cwd(); const dataDir = process.env.DATA_DIR;
if (process.env.ROOT_DIR && !fs.existsSync(rootDir)) { if (!dataDir) {
fs.mkdirSync(rootDir, { recursive: true }); throw new Error("DATA_DIR environment variable is not set");
} }
const url = `file:${path.join(rootDir, "chronus.db")}`; if (!fs.existsSync(dataDir)) {
console.log(`Using database: ${url}`); fs.mkdirSync(dataDir, { recursive: true });
}
const authToken = process.env.DATABASE_AUTH_TOKEN; const url = `file:${path.join(dataDir, "chronus.db")}`;
console.log(`Using database: ${url}`);
const client = createClient({ const client = createClient({
url, url,

View File

@@ -11,21 +11,22 @@ let _db: Database | null = null;
function initDb(): Database { function initDb(): Database {
if (!_db) { if (!_db) {
const envRootDir = process.env.ROOT_DIR const dataDir = process.env.DATA_DIR
? process.env.ROOT_DIR ? process.env.DATA_DIR
: import.meta.env.ROOT_DIR; : import.meta.env.DATA_DIR;
const rootDir = envRootDir || process.cwd();
if (envRootDir && !fs.existsSync(rootDir)) { if (!dataDir) {
fs.mkdirSync(rootDir, { recursive: true }); throw new Error("DATA_DIR environment variable is not set");
} }
const url = `file:${path.join(rootDir, "chronus.db")}`; if (!fs.existsSync(dataDir)) {
const authToken = process.env.DATABASE_AUTH_TOKEN; fs.mkdirSync(dataDir, { recursive: true });
}
const url = `file:${path.join(dataDir, "chronus.db")}`;
const client = createClient({ const client = createClient({
url, url,
authToken,
}); });
_db = drizzle(client, { schema }); _db = drizzle(client, { schema });

View File

@@ -67,20 +67,16 @@ export const POST: APIRoute = async ({ request, locals, redirect }) => {
const ext = logo.name.split(".").pop() || "png"; const ext = logo.name.split(".").pop() || "png";
const filename = `${organizationId}-${Date.now()}.${ext}`; const filename = `${organizationId}-${Date.now()}.${ext}`;
let uploadDir; const dataDir = process.env.DATA_DIR
? process.env.DATA_DIR
: import.meta.env.DATA_DIR;
const envRootDir = process.env.ROOT_DIR if (!dataDir) {
? process.env.ROOT_DIR throw new Error("DATA_DIR environment variable is not set");
: import.meta.env.ROOT_DIR;
if (envRootDir) {
uploadDir = path.join(envRootDir, "uploads");
} else {
uploadDir =
process.env.UPLOAD_DIR ||
path.join(process.cwd(), "public", "uploads");
} }
const uploadDir = path.join(dataDir, "uploads");
try { try {
await fs.access(uploadDir); await fs.access(uploadDir);
} catch { } catch {

View File

@@ -220,7 +220,7 @@ const isDraft = invoice.status === 'draft';
<!-- Items Table --> <!-- Items Table -->
<div class="mb-8"> <div class="mb-8">
<div class="overflow-x-auto"> <div class="overflow-x-auto">
<table class="w-full min-w-[600px]"> <table class="w-full min-w-150">
<thead> <thead>
<tr class="border-b-2 border-base-200 text-left text-xs font-bold uppercase tracking-wider text-base-content/40"> <tr class="border-b-2 border-base-200 text-left text-xs font-bold uppercase tracking-wider text-base-content/40">
<th class="py-3">Description</th> <th class="py-3">Description</th>

View File

@@ -163,7 +163,7 @@ const getStatusColor = (status: string) => {
<div role="button" tabindex="0" class="btn btn-ghost btn-sm btn-square"> <div role="button" tabindex="0" class="btn btn-ghost btn-sm btn-square">
<Icon name="heroicons:ellipsis-vertical" class="w-5 h-5" /> <Icon name="heroicons:ellipsis-vertical" class="w-5 h-5" />
</div> </div>
<ul tabindex="0" class="dropdown-content menu p-2 shadow-lg bg-base-100 rounded-box w-52 border border-base-200 z-[100]"> <ul tabindex="0" class="dropdown-content menu p-2 shadow-lg bg-base-100 rounded-box w-52 border border-base-200 z-100">
<li> <li>
<a href={`/dashboard/invoices/${invoice.id}`}> <a href={`/dashboard/invoices/${invoice.id}`}>
<Icon name="heroicons:eye" class="w-4 h-4" /> <Icon name="heroicons:eye" class="w-4 h-4" />

View File

@@ -9,19 +9,18 @@ export const GET: APIRoute = async ({ params }) => {
return new Response("Not found", { status: 404 }); return new Response("Not found", { status: 404 });
} }
let uploadDir; const dataDir = process.env.DATA_DIR
? process.env.DATA_DIR
: import.meta.env.DATA_DIR;
const envRootDir = process.env.ROOT_DIR if (!dataDir) {
? process.env.ROOT_DIR return new Response("DATA_DIR environment variable is not set", {
: import.meta.env.ROOT_DIR; status: 500,
});
if (envRootDir) {
uploadDir = path.join(envRootDir, "uploads");
} else {
uploadDir =
process.env.UPLOAD_DIR || path.join(process.cwd(), "public", "uploads");
} }
const uploadDir = path.join(dataDir, "uploads");
const safePath = path.normalize(filePathParam).replace(/^(\.\.[\/\\])+/, ""); const safePath = path.normalize(filePathParam).replace(/^(\.\.[\/\\])+/, "");
const fullPath = path.join(uploadDir, safePath); const fullPath = path.join(uploadDir, safePath);

View File

@@ -294,18 +294,18 @@ export function createInvoiceDocument(props: InvoiceDocumentProps) {
let logoPath; let logoPath;
// Handle uploads directory which might be external to public/ // Handle uploads directory which might be external to public/
if (organization.logoUrl.startsWith("/uploads/")) { if (organization.logoUrl.startsWith("/uploads/")) {
let uploadDir; const dataDir = process.env.DATA_DIR
const envRootDir = process.env.ROOT_DIR ? process.env.DATA_DIR
? process.env.ROOT_DIR : import.meta.env.DATA_DIR;
: import.meta.env.ROOT_DIR;
if (envRootDir) { if (!dataDir) {
uploadDir = join(envRootDir, "uploads"); throw new Error(
} else { "DATA_DIR environment variable is not set",
uploadDir = );
process.env.UPLOAD_DIR ||
join(process.cwd(), "public", "uploads");
} }
const uploadDir = join(dataDir, "uploads");
const filename = organization.logoUrl.replace( const filename = organization.logoUrl.replace(
"/uploads/", "/uploads/",
"", "",