fix(deploy): resolve Docker startup and CSRF issues
- Rename TASKPLANER_DATA_DIR to DATA_DIR (avoid adapter-node envPrefix conflict) - Add TASKPLANER_ORIGIN for CSRF protection in docker-compose.yml - Add automatic database schema initialization on startup - Add Playwright E2E tests for Docker deployment verification - Update .env.example with correct variable names Fixes container restart loop and 403 errors on form submission. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -4,7 +4,7 @@ import * as schema from './schema';
|
||||
import { existsSync, mkdirSync } from 'fs';
|
||||
import { dirname, join } from 'path';
|
||||
|
||||
const DATA_DIR = process.env.TASKPLANER_DATA_DIR || './data';
|
||||
const DATA_DIR = process.env.DATA_DIR || './data';
|
||||
const DB_PATH = join(DATA_DIR, 'taskplaner.db');
|
||||
|
||||
// Ensure data directory exists
|
||||
@@ -18,6 +18,49 @@ const sqlite = new Database(DB_PATH);
|
||||
// Enable WAL mode for better concurrent read performance
|
||||
sqlite.pragma('journal_mode = WAL');
|
||||
|
||||
// Initialize schema if tables don't exist
|
||||
const tableExists = sqlite
|
||||
.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='entries'")
|
||||
.get();
|
||||
|
||||
if (!tableExists) {
|
||||
sqlite.exec(`
|
||||
CREATE TABLE entries (
|
||||
id TEXT PRIMARY KEY,
|
||||
title TEXT,
|
||||
content TEXT NOT NULL,
|
||||
type TEXT NOT NULL DEFAULT 'thought' CHECK(type IN ('task', 'thought')),
|
||||
status TEXT DEFAULT 'open' CHECK(status IN ('open', 'done', 'archived')),
|
||||
pinned INTEGER DEFAULT 0,
|
||||
due_date TEXT,
|
||||
created_at TEXT NOT NULL,
|
||||
updated_at TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE images (
|
||||
id TEXT PRIMARY KEY,
|
||||
entry_id TEXT NOT NULL REFERENCES entries(id) ON DELETE CASCADE,
|
||||
filename TEXT NOT NULL,
|
||||
ext TEXT NOT NULL,
|
||||
created_at TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE tags (
|
||||
id TEXT PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
created_at TEXT NOT NULL
|
||||
);
|
||||
CREATE UNIQUE INDEX tagNameUniqueIndex ON tags(lower(name));
|
||||
|
||||
CREATE TABLE entry_tags (
|
||||
entry_id TEXT NOT NULL REFERENCES entries(id) ON DELETE CASCADE,
|
||||
tag_id TEXT NOT NULL REFERENCES tags(id) ON DELETE CASCADE,
|
||||
PRIMARY KEY (entry_id, tag_id)
|
||||
);
|
||||
`);
|
||||
console.log('Database schema initialized');
|
||||
}
|
||||
|
||||
export const db = drizzle(sqlite, { schema });
|
||||
|
||||
export { schema };
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { mkdir, writeFile, unlink } from 'node:fs/promises';
|
||||
import { join } from 'node:path';
|
||||
|
||||
const DATA_DIR = process.env.TASKPLANER_DATA_DIR || './data';
|
||||
const DATA_DIR = process.env.DATA_DIR || './data';
|
||||
export const UPLOAD_DIR = join(DATA_DIR, 'uploads');
|
||||
export const ORIGINALS_DIR = join(DATA_DIR, 'uploads/originals');
|
||||
export const THUMBNAILS_DIR = join(DATA_DIR, 'uploads/thumbnails');
|
||||
|
||||
Reference in New Issue
Block a user