import path from 'path'; import Database from 'better-sqlite3'; import { config as loadEnv } from 'dotenv'; import { buildApp, DEFAULT_CUSTOMERS } from './app'; import { seedAdminUsersFromEnv } from './admin-users'; import { hasRealStripeKey, stripePaymentClient } from './billing/reload'; import { SqliteAdminUserRepo } from './db/admin-user-repo'; import { SqliteCustomerRepo } from './db/customer-repo'; import { SqliteInvoiceRepo } from './db/invoice-repo'; import { SqlitePricingStore } from './db/pricing-store'; import { SqliteSessionRepo } from './db/session-repo'; import { SqliteUsageRepo } from './db/usage-repo'; import { PROJECT_ROOT } from './paths'; import { PaymentClient } from './portal'; loadEnv({ path: path.join(PROJECT_ROOT, '.env') }); const db = new Database(process.env.ZAPPIER_DB ?? path.join(PROJECT_ROOT, 'zappier.db')); const usage = new SqliteUsageRepo(db); const customers = new SqliteCustomerRepo(db, DEFAULT_CUSTOMERS); const pricingStore = new SqlitePricingStore(db); const invoices = new SqliteInvoiceRepo(db); const adminUsers = SqliteAdminUserRepo.seeded(db, seedAdminUsersFromEnv()); const sessions = new SqliteSessionRepo(db); // Real Stripe reloads when a usable key is configured; otherwise a dev client // credits the balance immediately (placeholder key, local development). const payments: PaymentClient = hasRealStripeKey(process.env.STRIPE_SECRET_KEY) ? stripePaymentClient(process.env.STRIPE_SECRET_KEY) : { reload: async (_customer, amountCents) => ({ mode: 'dev', creditedCents: amountCents }), }; const { app } = buildApp({ usage, customers, pricingStore, invoices, adminUsers, sessions, payments }); const port = Number(process.env.PORT ?? 3000); app.listen(port, () => { console.log(`Zappier API listening on http://localhost:${port}`); console.log(`OpenAPI docs at http://localhost:${port}/docs`); console.log(`Customer portal at http://localhost:${port}/portal`); console.log(`Admin console at http://localhost:${port}/admin`); });