Files
Emailsorter/server/bootstrap-v2.mjs
ANDJ abf761db07 Email Sorter Beta
Ich habe soweit automatisiert the Emails sortieren aber ich muss noch schauen was es fur bugs es gibt wenn die app online  ist deswegen wurde ich mit diesen Commit die website veroffentlichen obwohjl es sein konnte  das es noch nicht fertig ist und verkaufs bereit
2026-01-22 19:32:12 +01:00

226 lines
11 KiB
JavaScript

import 'dotenv/config';
import { Client, Databases, ID, Permission, Role } from "node-appwrite";
/**
* EmailSorter Database Bootstrap Script v2
* Creates all required collections for the full EmailSorter app
*/
const requiredEnv = [
"APPWRITE_ENDPOINT",
"APPWRITE_PROJECT_ID",
"APPWRITE_API_KEY",
];
for (const k of requiredEnv) {
if (!process.env[k]) {
console.error(`Missing env var: ${k}`);
process.exit(1);
}
}
const client = new Client()
.setEndpoint(process.env.APPWRITE_ENDPOINT)
.setProject(process.env.APPWRITE_PROJECT_ID)
.setKey(process.env.APPWRITE_API_KEY);
const db = new Databases(client);
const DB_ID = process.env.APPWRITE_DATABASE_ID || 'emailsorter';
const DB_NAME = 'EmailSorter';
// Helper: create database if not exists
async function ensureDatabase() {
try {
await db.get(DB_ID);
console.log("✓ Database exists:", DB_ID);
} catch {
await db.create(DB_ID, DB_NAME);
console.log("✓ Database created:", DB_ID);
}
}
// Helper: create collection if not exists
async function ensureCollection(collectionId, name, permissions = []) {
try {
await db.getCollection(DB_ID, collectionId);
console.log(`✓ Collection exists: ${collectionId}`);
} catch {
await db.createCollection(DB_ID, collectionId, name, permissions, true);
console.log(`✓ Collection created: ${collectionId}`);
}
}
// Helper: create attribute if not exists
async function ensureAttribute(collectionId, key, createFn) {
const attributes = await db.listAttributes(DB_ID, collectionId);
const exists = attributes.attributes?.some(a => a.key === key);
if (exists) {
console.log(` - Attribute exists: ${collectionId}.${key}`);
return;
}
await createFn();
console.log(` + Attribute created: ${collectionId}.${key}`);
// Wait for attribute to be ready
await new Promise(resolve => setTimeout(resolve, 1000));
}
// Permission templates
const PERM_PUBLIC_READ = [Permission.read(Role.any())];
const PERM_AUTHENTICATED = [
Permission.read(Role.users()),
Permission.create(Role.users()),
];
const PERM_SERVER_ONLY = [];
async function setupCollections() {
// ==================== Products ====================
await ensureCollection('products', 'Products', PERM_PUBLIC_READ);
await ensureAttribute('products', 'slug', () =>
db.createStringAttribute(DB_ID, 'products', 'slug', 128, true));
await ensureAttribute('products', 'title', () =>
db.createStringAttribute(DB_ID, 'products', 'title', 256, true));
await ensureAttribute('products', 'description', () =>
db.createStringAttribute(DB_ID, 'products', 'description', 4096, false));
await ensureAttribute('products', 'priceCents', () =>
db.createIntegerAttribute(DB_ID, 'products', 'priceCents', true, 0, 999999999));
await ensureAttribute('products', 'currency', () =>
db.createStringAttribute(DB_ID, 'products', 'currency', 8, true));
await ensureAttribute('products', 'isActive', () =>
db.createBooleanAttribute(DB_ID, 'products', 'isActive', true));
// ==================== Questions ====================
await ensureCollection('questions', 'Questions', PERM_PUBLIC_READ);
await ensureAttribute('questions', 'productId', () =>
db.createStringAttribute(DB_ID, 'questions', 'productId', 64, true));
await ensureAttribute('questions', 'key', () =>
db.createStringAttribute(DB_ID, 'questions', 'key', 64, true));
await ensureAttribute('questions', 'label', () =>
db.createStringAttribute(DB_ID, 'questions', 'label', 256, true));
await ensureAttribute('questions', 'helpText', () =>
db.createStringAttribute(DB_ID, 'questions', 'helpText', 1024, false));
await ensureAttribute('questions', 'type', () =>
db.createStringAttribute(DB_ID, 'questions', 'type', 32, true));
await ensureAttribute('questions', 'required', () =>
db.createBooleanAttribute(DB_ID, 'questions', 'required', true));
await ensureAttribute('questions', 'step', () =>
db.createIntegerAttribute(DB_ID, 'questions', 'step', true, 1, 9999));
await ensureAttribute('questions', 'order', () =>
db.createIntegerAttribute(DB_ID, 'questions', 'order', true, 1, 999999));
await ensureAttribute('questions', 'optionsJson', () =>
db.createStringAttribute(DB_ID, 'questions', 'optionsJson', 8192, false));
await ensureAttribute('questions', 'isActive', () =>
db.createBooleanAttribute(DB_ID, 'questions', 'isActive', true));
// ==================== Submissions ====================
await ensureCollection('submissions', 'Submissions', PERM_AUTHENTICATED);
await ensureAttribute('submissions', 'productId', () =>
db.createStringAttribute(DB_ID, 'submissions', 'productId', 64, true));
await ensureAttribute('submissions', 'status', () =>
db.createStringAttribute(DB_ID, 'submissions', 'status', 32, true));
await ensureAttribute('submissions', 'customerEmail', () =>
db.createEmailAttribute(DB_ID, 'submissions', 'customerEmail', false));
await ensureAttribute('submissions', 'customerName', () =>
db.createStringAttribute(DB_ID, 'submissions', 'customerName', 256, false));
await ensureAttribute('submissions', 'finalSummaryJson', () =>
db.createStringAttribute(DB_ID, 'submissions', 'finalSummaryJson', 16384, false));
await ensureAttribute('submissions', 'priceCents', () =>
db.createIntegerAttribute(DB_ID, 'submissions', 'priceCents', true, 0, 999999999));
await ensureAttribute('submissions', 'currency', () =>
db.createStringAttribute(DB_ID, 'submissions', 'currency', 8, true));
// ==================== Answers ====================
await ensureCollection('answers', 'Answers', PERM_AUTHENTICATED);
await ensureAttribute('answers', 'submissionId', () =>
db.createStringAttribute(DB_ID, 'answers', 'submissionId', 64, true));
await ensureAttribute('answers', 'answersJson', () =>
db.createStringAttribute(DB_ID, 'answers', 'answersJson', 16384, true));
// ==================== Orders ====================
await ensureCollection('orders', 'Orders', PERM_SERVER_ONLY);
await ensureAttribute('orders', 'submissionId', () =>
db.createStringAttribute(DB_ID, 'orders', 'submissionId', 64, true));
await ensureAttribute('orders', 'orderDataJson', () =>
db.createStringAttribute(DB_ID, 'orders', 'orderDataJson', 16384, true));
// ==================== Email Accounts ====================
await ensureCollection('email_accounts', 'Email Accounts', PERM_AUTHENTICATED);
await ensureAttribute('email_accounts', 'userId', () =>
db.createStringAttribute(DB_ID, 'email_accounts', 'userId', 64, true));
await ensureAttribute('email_accounts', 'provider', () =>
db.createStringAttribute(DB_ID, 'email_accounts', 'provider', 32, true));
await ensureAttribute('email_accounts', 'email', () =>
db.createEmailAttribute(DB_ID, 'email_accounts', 'email', true));
await ensureAttribute('email_accounts', 'accessToken', () =>
db.createStringAttribute(DB_ID, 'email_accounts', 'accessToken', 4096, false));
await ensureAttribute('email_accounts', 'refreshToken', () =>
db.createStringAttribute(DB_ID, 'email_accounts', 'refreshToken', 4096, false));
await ensureAttribute('email_accounts', 'expiresAt', () =>
db.createIntegerAttribute(DB_ID, 'email_accounts', 'expiresAt', false));
await ensureAttribute('email_accounts', 'isActive', () =>
db.createBooleanAttribute(DB_ID, 'email_accounts', 'isActive', true));
await ensureAttribute('email_accounts', 'lastSync', () =>
db.createDatetimeAttribute(DB_ID, 'email_accounts', 'lastSync', false));
// ==================== Email Stats ====================
await ensureCollection('email_stats', 'Email Stats', PERM_AUTHENTICATED);
await ensureAttribute('email_stats', 'userId', () =>
db.createStringAttribute(DB_ID, 'email_stats', 'userId', 64, true));
await ensureAttribute('email_stats', 'totalSorted', () =>
db.createIntegerAttribute(DB_ID, 'email_stats', 'totalSorted', true, 0));
await ensureAttribute('email_stats', 'todaySorted', () =>
db.createIntegerAttribute(DB_ID, 'email_stats', 'todaySorted', true, 0));
await ensureAttribute('email_stats', 'weekSorted', () =>
db.createIntegerAttribute(DB_ID, 'email_stats', 'weekSorted', true, 0));
await ensureAttribute('email_stats', 'categoriesJson', () =>
db.createStringAttribute(DB_ID, 'email_stats', 'categoriesJson', 4096, false));
await ensureAttribute('email_stats', 'timeSavedMinutes', () =>
db.createIntegerAttribute(DB_ID, 'email_stats', 'timeSavedMinutes', true, 0));
// ==================== Subscriptions ====================
await ensureCollection('subscriptions', 'Subscriptions', PERM_AUTHENTICATED);
await ensureAttribute('subscriptions', 'userId', () =>
db.createStringAttribute(DB_ID, 'subscriptions', 'userId', 64, true));
await ensureAttribute('subscriptions', 'stripeCustomerId', () =>
db.createStringAttribute(DB_ID, 'subscriptions', 'stripeCustomerId', 128, false));
await ensureAttribute('subscriptions', 'stripeSubscriptionId', () =>
db.createStringAttribute(DB_ID, 'subscriptions', 'stripeSubscriptionId', 128, false));
await ensureAttribute('subscriptions', 'plan', () =>
db.createStringAttribute(DB_ID, 'subscriptions', 'plan', 32, true));
await ensureAttribute('subscriptions', 'status', () =>
db.createStringAttribute(DB_ID, 'subscriptions', 'status', 32, true));
await ensureAttribute('subscriptions', 'currentPeriodEnd', () =>
db.createDatetimeAttribute(DB_ID, 'subscriptions', 'currentPeriodEnd', false));
await ensureAttribute('subscriptions', 'cancelAtPeriodEnd', () =>
db.createBooleanAttribute(DB_ID, 'subscriptions', 'cancelAtPeriodEnd', false));
// ==================== User Preferences ====================
await ensureCollection('user_preferences', 'User Preferences', PERM_AUTHENTICATED);
await ensureAttribute('user_preferences', 'userId', () =>
db.createStringAttribute(DB_ID, 'user_preferences', 'userId', 64, true));
await ensureAttribute('user_preferences', 'preferencesJson', () =>
db.createStringAttribute(DB_ID, 'user_preferences', 'preferencesJson', 16384, false));
}
async function main() {
console.log('\n========================================');
console.log(' EmailSorter Database Bootstrap v2');
console.log('========================================\n');
await ensureDatabase();
console.log('\n--- Setting up collections ---\n');
await setupCollections();
console.log('\n========================================');
console.log(' ✓ Bootstrap complete!');
console.log(` Database ID: ${DB_ID}`);
console.log('========================================\n');
console.log('Add this to your .env file:');
console.log(`APPWRITE_DATABASE_ID=${DB_ID}\n`);
}
main().catch((e) => {
console.error('Bootstrap failed:', e);
process.exit(1);
});