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
226 lines
11 KiB
JavaScript
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);
|
|
});
|