create-efc-app 0.3.5 → 0.3.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +485 -222
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/scaffold.ts"],"sourcesContent":["import * as p from '@clack/prompts';\nimport pc from 'picocolors';\nimport { spawn } from 'node:child_process';\nimport { scaffold, type ScaffoldOptions } from './scaffold.js';\n\nfunction cancel(msg = 'Cancelled'): never {\n p.cancel(msg);\n process.exit(0);\n}\n\nasync function main(): Promise<void> {\n console.log();\n p.intro(pc.bgCyan(pc.black(' create-efc-app ')));\n\n const projectName = await p.text({\n message: 'Project name:',\n placeholder: 'my-api',\n defaultValue: 'my-api',\n validate: (v) => (!v.trim() ? 'Project name is required' : undefined),\n });\n if (p.isCancel(projectName)) cancel();\n\n const language = await p.select({\n message: 'Language:',\n options: [\n { value: 'typescript', label: 'TypeScript', hint: 'recommended' },\n { value: 'javascript', label: 'JavaScript' },\n ],\n });\n if (p.isCancel(language)) cancel();\n\n const database = await p.select({\n message: 'Database:',\n options: [\n { value: 'mongodb', label: 'MongoDB', hint: 'Mongoose' },\n { value: 'postgresql', label: 'PostgreSQL', hint: 'Drizzle ORM' },\n ],\n });\n if (p.isCancel(database)) cancel();\n\n const authStrategy = await p.select({\n message: 'Authentication strategy:',\n options: [\n { value: 'http-only', label: 'http-only', hint: 'secure cookie — recommended for SSR' },\n { value: 'localStorage', label: 'localStorage', hint: 'bearer token — for SPAs' },\n ],\n });\n if (p.isCancel(authStrategy)) cancel();\n\n const features = await p.multiselect({\n message: 'Features: (space to toggle, enter to confirm)',\n options: [\n { value: 'cluster', label: 'Multi-core clustering', hint: 'Node cluster module' },\n { value: 'tasks', label: 'Background tasks', hint: 'BullMQ / pg-boss' },\n { value: 'routeDocs', label: 'API route documentation', hint: 'meta exports + dashboard' },\n { value: 'userPortal', label: 'User portal', hint: 'auth, profile, billing routes' },\n { value: 'adminPortal',label: 'Admin portal', hint: 'dashboard, user mgmt, analytics' },\n { value: 'rbac', label: 'Role-based access control', hint: 'requireRole middleware' },\n { value: 'mailer', label: 'Mailer', hint: 'nodemailer + SMTP' },\n ],\n initialValues: ['cluster', 'tasks', 'routeDocs', 'userPortal', 'adminPortal', 'rbac'],\n required: false,\n });\n if (p.isCancel(features)) cancel();\n\n const selected = new Set(features as string[]);\n\n let taskBackend: ScaffoldOptions['taskBackend'];\n if (selected.has('tasks')) {\n const backend = await p.select({\n message: 'Task queue backend:',\n options: [\n { value: 'bullmq', label: 'BullMQ', hint: 'Redis' },\n { value: 'pg-boss', label: 'pg-boss', hint: 'PostgreSQL' },\n ],\n });\n if (p.isCancel(backend)) cancel();\n taskBackend = backend as ScaffoldOptions['taskBackend'];\n }\n\n let smtpProvider: ScaffoldOptions['smtpProvider'];\n let smtpHost: string | undefined;\n let smtpPort: string | undefined;\n let smtpUser: string | undefined;\n let smtpPass: string | undefined;\n if (selected.has('mailer')) {\n const provider = await p.select({\n message: 'Email provider:',\n options: [\n { value: 'gmail', label: 'Gmail', hint: 'smtp.gmail.com, preconfigured' },\n { value: 'custom', label: 'Other (custom SMTP)', hint: \"you'll provide host + port\" },\n ],\n });\n if (p.isCancel(provider)) cancel();\n smtpProvider = provider as ScaffoldOptions['smtpProvider'];\n\n if (smtpProvider === 'custom') {\n const host = await p.text({\n message: 'SMTP host:',\n placeholder: 'smtp.mailtrap.io',\n validate: (v) => (!v.trim() ? 'SMTP host is required' : undefined),\n });\n if (p.isCancel(host)) cancel();\n smtpHost = host as string;\n\n const port = await p.text({\n message: 'SMTP port:',\n placeholder: '587',\n defaultValue: '587',\n });\n if (p.isCancel(port)) cancel();\n smtpPort = port as string;\n }\n\n const user = await p.text({\n message: smtpProvider === 'gmail' ? 'Gmail address:' : 'SMTP username / email:',\n placeholder: 'you@example.com',\n validate: (v) => (!v.trim() ? 'Email is required' : undefined),\n });\n if (p.isCancel(user)) cancel();\n smtpUser = user as string;\n\n if (smtpProvider === 'gmail') {\n p.note(\n 'Google no longer accepts your regular account password for SMTP.\\n' +\n \"Generate a 16-character App Password: Google Account -> Security -> 2-Step Verification -> App passwords.\\n\" +\n \"Enter it below without spaces (not your Gmail login password).\",\n 'Gmail app password required',\n );\n }\n\n const pass = await p.password({\n message: smtpProvider === 'gmail' ? 'Gmail app password (16 characters):' : 'SMTP password:',\n validate: (v) => {\n if (!v.trim()) return 'Password is required';\n if (smtpProvider === 'gmail' && v.replace(/\\s/g, '').length !== 16) {\n return 'Gmail app passwords are 16 characters — this looks like a regular password, not an app password';\n }\n return undefined;\n },\n });\n if (p.isCancel(pass)) cancel();\n smtpPass = (pass as string).replace(/\\s/g, '');\n }\n\n const opts: ScaffoldOptions = {\n projectName: projectName as string,\n language: language as ScaffoldOptions['language'],\n database: database as ScaffoldOptions['database'],\n authStrategy: authStrategy as ScaffoldOptions['authStrategy'],\n cluster: selected.has('cluster'),\n tasks: selected.has('tasks'),\n routeDocs: selected.has('routeDocs'),\n userPortal: selected.has('userPortal'),\n adminPortal: selected.has('adminPortal'),\n rbac: selected.has('rbac'),\n mailer: selected.has('mailer'),\n ...(taskBackend !== undefined && { taskBackend }),\n ...(smtpProvider !== undefined && { smtpProvider }),\n ...(smtpHost !== undefined && { smtpHost }),\n ...(smtpPort !== undefined && { smtpPort }),\n ...(smtpUser !== undefined && { smtpUser }),\n ...(smtpPass !== undefined && { smtpPass }),\n };\n\n const spinner = p.spinner();\n spinner.start('Scaffolding project…');\n\n try {\n await scaffold(opts);\n spinner.stop('Project created');\n } catch (err) {\n spinner.stop('Failed to scaffold project');\n console.error(err);\n process.exit(1);\n }\n\n spinner.start('Installing dependencies…');\n await npmInstall(projectName as string);\n spinner.stop('Dependencies installed');\n\n spinner.start('Installing efc CLI globally…');\n await npmInstallGlobal().catch(() => { /* non-fatal */ });\n spinner.stop('efc CLI ready');\n\n p.outro(\n pc.green(`\\nYour project is ready!\\n\\n`) +\n pc.dim(` cd ${projectName as string}\\n`) +\n pc.dim(` efc start dev\\n`) +\n pc.dim(`\\n (or: npm run dev)\\n`),\n );\n}\n\nfunction npmInstall(projectDir: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const child = spawn('npm', ['install'], { cwd: projectDir, stdio: 'ignore' });\n child.on('exit', (code) => (code === 0 ? resolve() : reject(new Error('npm install failed'))));\n });\n}\n\nfunction npmInstallGlobal(): Promise<void> {\n return new Promise((resolve, reject) => {\n const child = spawn('npm', ['install', '-g', 'express-file-cluster'], { stdio: 'ignore' });\n child.on('exit', (code) => (code === 0 ? resolve() : reject(new Error('global install failed'))));\n });\n}\n\nmain().catch((err) => {\n console.error(err);\n process.exit(1);\n});\n","import fs from 'fs-extra';\nimport path from 'node:path';\nimport crypto from 'node:crypto';\n\nexport interface ScaffoldOptions {\n projectName: string;\n language: 'typescript' | 'javascript';\n database: 'mongodb' | 'postgresql';\n authStrategy: 'http-only' | 'localStorage';\n cluster: boolean;\n tasks: boolean;\n taskBackend?: 'bullmq' | 'pg-boss';\n routeDocs: boolean;\n userPortal: boolean;\n adminPortal: boolean;\n rbac: boolean;\n mailer: boolean;\n smtpProvider?: 'gmail' | 'custom';\n smtpHost?: string;\n smtpPort?: string;\n smtpUser?: string;\n smtpPass?: string;\n}\n\nexport async function scaffold(opts: ScaffoldOptions): Promise<void> {\n const dest = path.resolve(process.cwd(), opts.projectName);\n await fs.ensureDir(dest);\n\n await writePackageJson(dest, opts);\n await writeTsConfig(dest, opts);\n await writeEfcConfig(dest, opts);\n await writeEntryPoint(dest, opts);\n await writeGitignore(dest);\n await writeEnvFiles(dest, opts);\n await writeExampleRoute(dest, opts);\n if (opts.rbac) await writeRequireRoleMiddleware(dest, opts);\n if (opts.userPortal) await writeUserModel(dest, opts);\n if (opts.adminPortal) await writeAdminModel(dest, opts);\n await writeAuthRoutes(dest, opts);\n if (opts.adminPortal) await writeAdminRoutes(dest, opts);\n if (opts.userPortal) await writeUserRoutes(dest, opts);\n if (opts.tasks) await writeExampleTask(dest, opts);\n // Extended models\n if (opts.userPortal) await writeSessionModel(dest, opts);\n if (opts.userPortal) await writeNotificationModel(dest, opts);\n if (opts.userPortal) await writeFileModel(dest, opts);\n if (opts.userPortal || opts.adminPortal) await writeSupportTicketModel(dest, opts);\n if (opts.adminPortal) await writeAuditLogModel(dest, opts);\n if (opts.userPortal) await writeSubscriptionModel(dest, opts);\n if (opts.adminPortal) await writePlanModel(dest, opts);\n if (opts.userPortal) await writeInvoiceModel(dest, opts);\n if (opts.userPortal) await writeApiKeyModel(dest, opts);\n if (opts.rbac) await writeRoleModel(dest, opts);\n if (opts.adminPortal) await writeFAQModel(dest, opts);\n if (opts.adminPortal) await writeBlogModel(dest, opts);\n if (opts.adminPortal) await writeCategoryModel(dest, opts);\n if (opts.adminPortal) await writeCouponModel(dest, opts);\n // Extended routes\n if (opts.userPortal) await writeAuthExtendedRoutes(dest, opts);\n if (opts.userPortal) await writeUserExtendedRoutes(dest, opts);\n if (opts.userPortal) await writeUserBillingRoutes(dest, opts);\n if (opts.userPortal) await writeSupportRoutes(dest, opts);\n if (opts.adminPortal) await writeAdminExtendedRoutes(dest, opts);\n}\n\nasync function writePackageJson(dest: string, opts: ScaffoldOptions): Promise<void> {\n const deps: Record<string, string> = {\n 'express-file-cluster': '^0.2.1',\n };\n if (opts.database === 'mongodb') deps['mongoose'] = '^8.0.0';\n if (opts.database === 'postgresql') {\n deps['pg'] = '^8.0.0';\n deps['drizzle-orm'] = '^0.33.0';\n }\n if (opts.tasks && opts.taskBackend === 'bullmq') deps['bullmq'] = '^5.0.0';\n if (opts.tasks && opts.taskBackend === 'pg-boss') deps['pg-boss'] = '^10.0.0';\n if (opts.mailer) deps['nodemailer'] = '^6.9.0';\n if (opts.database === 'mongodb') deps['bcrypt'] = '^5.1.0';\n\n const devDeps: Record<string, string> = {\n vitest: '^4.1.9',\n };\n if (opts.language === 'typescript') {\n devDeps['typescript'] = '^5.5.0';\n devDeps['@types/node'] = '^22.0.0';\n devDeps['@types/express'] = '^4.17.21';\n devDeps['tsup'] = '^8.2.0';\n devDeps['tsx'] = '^4.0.0';\n if (opts.mailer) devDeps['@types/nodemailer'] = '^6.4.0';\n if (opts.database === 'mongodb') devDeps['@types/bcrypt'] = '^5.0.0';\n }\n\n const pkg = {\n name: opts.projectName,\n version: '0.1.0',\n type: 'module',\n scripts: {\n dev: 'efc start dev',\n build: 'efc build prod',\n start: 'efc start prod',\n test: 'efc run tests',\n },\n dependencies: deps,\n devDependencies: devDeps,\n };\n\n await fs.writeJson(path.join(dest, 'package.json'), pkg, { spaces: 2 });\n}\n\nasync function writeTsConfig(dest: string, opts: ScaffoldOptions): Promise<void> {\n if (opts.language !== 'typescript') return;\n const config = {\n compilerOptions: {\n target: 'ES2022',\n module: 'NodeNext',\n moduleResolution: 'NodeNext',\n strict: true,\n esModuleInterop: true,\n skipLibCheck: true,\n outDir: './dist',\n rootDir: './src',\n },\n include: ['src/**/*'],\n exclude: ['node_modules', 'dist'],\n };\n await fs.writeJson(path.join(dest, 'tsconfig.json'), config, { spaces: 2 });\n}\n\nasync function writeEfcConfig(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const tasks = opts.tasks\n ? `{ backend: '${opts.taskBackend ?? 'bullmq'}', concurrency: 5 }`\n : 'false';\n\n const content = `import type { EFCConfig } from 'express-file-cluster';\n\n// Structural config only — runtime values (PORT, DATABASE_URL, JWT_SECRET, etc.) are read from .env\nconst config: EFCConfig = {\n authStrategy: '${opts.authStrategy}',\n tasks: ${tasks},\n globalMiddlewares: [],\n};\n\nexport default config;\n`;\n await fs.outputFile(path.join(dest, `efc.config.${ext}`), content);\n}\n\nasync function writeEntryPoint(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const taskLine = opts.tasks ? ` tasks: { backend: '${opts.taskBackend ?? 'bullmq'}' },\\n` : '';\n const content = `import { ignite, gracefulShutdown } from 'express-file-cluster';\n\n// PORT, DATABASE_URL, JWT_SECRET, CORS_ORIGINS are read from .env automatically\nignite({\n cluster: ${opts.cluster},\n${taskLine}}).then(gracefulShutdown).catch(console.error);\n`;\n await fs.outputFile(path.join(dest, 'src', `index.${ext}`), content);\n}\n\nasync function writeGitignore(dest: string): Promise<void> {\n await fs.outputFile(\n path.join(dest, '.gitignore'),\n 'node_modules/\\ndist/\\n.env\\n.env.local\\n*.log\\n',\n );\n}\n\nasync function writeEnvFiles(dest: string, opts: ScaffoldOptions): Promise<void> {\n const secret = crypto.randomBytes(64).toString('hex');\n const projectName = path.basename(dest);\n const dbUrl =\n opts.database === 'mongodb'\n ? `mongodb://localhost:27017/${projectName}`\n : `postgresql://localhost:5432/${projectName}`;\n const dbExampleUrl =\n opts.database === 'mongodb'\n ? `mongodb://localhost:27017/${projectName}`\n : `postgresql://user:password@localhost:5432/${projectName}`;\n\n const isGmail = opts.mailer && opts.smtpProvider !== 'custom';\n const resolvedHost = isGmail ? 'smtp.gmail.com' : opts.smtpHost ?? 'smtp.gmail.com';\n const resolvedPort = isGmail ? '465' : opts.smtpPort ?? '587';\n const passComment = isGmail\n ? ' # Gmail App Password (16 chars) — NOT your regular Gmail password. Generate at: Google Account > Security > 2-Step Verification > App passwords'\n : '';\n\n const smtpVars = opts.mailer\n ? `\\nSMTP_HOST=${resolvedHost}\\nSMTP_PORT=${resolvedPort}\\nSMTP_USER=${opts.smtpUser ?? ''}\\nSMTP_PASS=${opts.smtpPass ?? ''}${passComment}\\nSMTP_FROM=${opts.smtpUser ?? 'noreply@example.com'}\\n`\n : '';\n const smtpExample = opts.mailer\n ? `\\nSMTP_HOST=${resolvedHost}\\nSMTP_PORT=${resolvedPort}\\nSMTP_USER=your@email.com\\nSMTP_PASS=${isGmail ? 'your_16_char_app_password' : 'your_smtp_password'}${passComment}\\nSMTP_FROM=noreply@yourapp.com\\n`\n : '';\n const dotenv = `PORT=3000\\nNODE_ENV=development\\nDATABASE_URL=${dbUrl}\\nJWT_SECRET=${secret}\\nREDIS_URL=redis://localhost:6379\\nCORS_ORIGINS=http://localhost:3000${smtpVars}`;\n const example = `PORT=3000\\nNODE_ENV=development\\nDATABASE_URL=${dbExampleUrl}\\nJWT_SECRET=<generate with: openssl rand -hex 64>\\nREDIS_URL=redis://localhost:6379\\nCORS_ORIGINS=http://localhost:3000,https://yourapp.com${smtpExample}`;\n await fs.outputFile(path.join(dest, '.env'), dotenv);\n await fs.outputFile(path.join(dest, '.env.example'), example);\n}\n\nasync function writeExampleRoute(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const metaTs = opts.routeDocs\n ? `import type { RouteMeta } from 'express-file-cluster';\\n\\nexport const meta: RouteMeta = {\\n description: 'Health check — returns server status and current timestamp.',\\n response: { status: 200, body: { status: 'OK', timestamp: '2024-01-01T00:00:00.000Z' } },\\n};\\n\\n`\n : '';\n const metaJs = opts.routeDocs\n ? `export const meta = {\\n description: 'Health check — returns server status and current timestamp.',\\n response: { status: 200, body: { status: 'OK', timestamp: '2024-01-01T00:00:00.000Z' } },\\n};\\n\\n`\n : '';\n const content =\n opts.language === 'typescript'\n ? `import type { Request, Response } from 'express';\\n${metaTs}export const GET = async (_req: Request, res: Response) => {\\n res.json({ status: 'OK', timestamp: new Date().toISOString() });\\n};\\n`\n : `${metaJs}export const GET = async (_req, res) => {\\n res.json({ status: 'OK', timestamp: new Date().toISOString() });\\n};\\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', `health.${ext}`), content);\n}\n\nasync function writeExampleTask(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n\n const tsMailer = `import { defineTask } from 'express-file-cluster/tasks';\nimport nodemailer from 'nodemailer';\n\ninterface SendEmailPayload {\n to: string;\n subject: string;\n body: string;\n}\n\nconst transporter = nodemailer.createTransport({\n host: process.env.SMTP_HOST,\n port: Number(process.env.SMTP_PORT ?? 587),\n secure: Number(process.env.SMTP_PORT) === 465,\n auth: {\n user: process.env.SMTP_USER,\n pass: process.env.SMTP_PASS,\n },\n});\n\nexport default defineTask<SendEmailPayload>(async (payload) => {\n await transporter.sendMail({\n from: process.env.SMTP_FROM ?? process.env.SMTP_USER,\n to: payload.to,\n subject: payload.subject,\n html: payload.body,\n });\n});\n`;\n\n const jsMailer = `import { defineTask } from 'express-file-cluster/tasks';\nimport nodemailer from 'nodemailer';\n\nconst transporter = nodemailer.createTransport({\n host: process.env.SMTP_HOST,\n port: Number(process.env.SMTP_PORT ?? 587),\n secure: Number(process.env.SMTP_PORT) === 465,\n auth: {\n user: process.env.SMTP_USER,\n pass: process.env.SMTP_PASS,\n },\n});\n\nexport default defineTask(async (payload) => {\n await transporter.sendMail({\n from: process.env.SMTP_FROM ?? process.env.SMTP_USER,\n to: payload.to,\n subject: payload.subject,\n html: payload.body,\n });\n});\n`;\n\n const tsStub = `import { defineTask } from 'express-file-cluster/tasks';\n\ninterface SendEmailPayload {\n to: string;\n subject: string;\n body: string;\n}\n\nexport default defineTask<SendEmailPayload>(async (payload) => {\n // TODO: wire up your mailer\n console.log('[SendEmail] Sending to', payload.to);\n});\n`;\n\n const jsStub = `import { defineTask } from 'express-file-cluster/tasks';\n\nexport default defineTask(async (payload) => {\n // TODO: wire up your mailer\n console.log('[SendEmail] Sending to', payload.to);\n});\n`;\n\n const content = opts.mailer\n ? opts.language === 'typescript' ? tsMailer : jsMailer\n : opts.language === 'typescript' ? tsStub : jsStub;\n\n await fs.outputFile(path.join(dest, 'src', 'tasks', `SendEmail.${ext}`), content);\n}\n\nasync function writeUserModel(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const ts = opts.language === 'typescript';\n\n const content = opts.database === 'mongodb'\n ? ts\n ? `import { defineModel } from 'express-file-cluster';\n\nexport interface UserDocument {\n name: string;\n email: string;\n password: string;\n role: string;\n avatar?: string;\n isVerified: boolean;\n isActive: boolean;\n}\n\nexport const User = defineModel<UserDocument>('User', {\n name: { type: 'string', required: true },\n email: { type: 'string', required: true, unique: true },\n password: { type: 'string', required: true },\n role: { type: 'string', required: true, default: 'user' },\n avatar: { type: 'string' },\n isVerified: { type: 'boolean', default: false },\n isActive: { type: 'boolean', default: true },\n});\n`\n : `import { defineModel } from 'express-file-cluster';\n\nexport const User = defineModel('User', {\n name: { type: 'string', required: true },\n email: { type: 'string', required: true, unique: true },\n password: { type: 'string', required: true },\n role: { type: 'string', required: true, default: 'user' },\n avatar: { type: 'string' },\n isVerified: { type: 'boolean', default: false },\n isActive: { type: 'boolean', default: true },\n});\n`\n : ts\n ? `// TODO: define your Drizzle schema for User\n// import { pgTable, serial, text, boolean, timestamp } from 'drizzle-orm/pg-core';\n//\n// export const users = pgTable('users', {\n// id: serial('id').primaryKey(),\n// name: text('name').notNull(),\n// email: text('email').notNull().unique(),\n// password: text('password').notNull(),\n// role: text('role').notNull().default('user'),\n// avatar: text('avatar'),\n// isVerified: boolean('is_verified').notNull().default(false),\n// isActive: boolean('is_active').notNull().default(true),\n// createdAt: timestamp('created_at').defaultNow(),\n// updatedAt: timestamp('updated_at').defaultNow(),\n// });\nexport {};\n`\n : `// TODO: define your Drizzle schema for User\nexport {};\n`;\n\n await fs.outputFile(path.join(dest, 'src', 'model', `User.${ext}`), content);\n}\n\nasync function writeAdminModel(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const ts = opts.language === 'typescript';\n\n const content = opts.database === 'mongodb'\n ? ts\n ? `import { defineModel } from 'express-file-cluster';\n\nexport interface AdminDocument {\n name: string;\n email: string;\n password: string;\n role: string;\n permissions: string[];\n isActive: boolean;\n}\n\nexport const Admin = defineModel<AdminDocument>('Admin', {\n name: { type: 'string', required: true },\n email: { type: 'string', required: true, unique: true },\n password: { type: 'string', required: true },\n role: { type: 'string', required: true, default: 'admin' },\n permissions: { type: 'array', default: [] },\n isActive: { type: 'boolean', default: true },\n});\n`\n : `import { defineModel } from 'express-file-cluster';\n\nexport const Admin = defineModel('Admin', {\n name: { type: 'string', required: true },\n email: { type: 'string', required: true, unique: true },\n password: { type: 'string', required: true },\n role: { type: 'string', required: true, default: 'admin' },\n permissions: { type: 'array', default: [] },\n isActive: { type: 'boolean', default: true },\n});\n`\n : ts\n ? `// TODO: define your Drizzle schema for Admin\n// import { pgTable, serial, text, boolean, timestamp } from 'drizzle-orm/pg-core';\n//\n// export const admins = pgTable('admins', {\n// id: serial('id').primaryKey(),\n// name: text('name').notNull(),\n// email: text('email').notNull().unique(),\n// password: text('password').notNull(),\n// role: text('role').notNull().default('admin'),\n// permissions: text('permissions').array().notNull().default([]),\n// isActive: boolean('is_active').notNull().default(true),\n// createdAt: timestamp('created_at').defaultNow(),\n// updatedAt: timestamp('updated_at').defaultNow(),\n// });\nexport {};\n`\n : `// TODO: define your Drizzle schema for Admin\nexport {};\n`;\n\n await fs.outputFile(path.join(dest, 'src', 'model', `Admin.${ext}`), content);\n}\n\nasync function writeAuthRoutes(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const ts = opts.language === 'typescript';\n\n const loginMeta = opts.routeDocs\n ? ts\n ? `import type { RouteMeta } from 'express-file-cluster';\\n\\nexport const meta: RouteMeta = {\\n description: 'Authenticate a user and issue a JWT.',\\n request: { body: { email: 'user@example.com', password: 'user' } },\\n response: { status: 200, body: { message: 'Logged in as user' } },\\n};\\n\\n`\n : `export const meta = {\\n description: 'Authenticate a user and issue a JWT.',\\n request: { body: { email: 'user@example.com', password: 'user' } },\\n response: { status: 200, body: { message: 'Logged in as user' } },\\n};\\n\\n`\n : '';\n\n const loginDbImports = opts.database === 'mongodb'\n ? ts\n ? `import bcrypt from 'bcrypt';\\nimport { User } from '../../model/User.js';\\nimport { Admin } from '../../model/Admin.js';\\n`\n : `import bcrypt from 'bcrypt';\\nimport { User } from '../../model/User.js';\\nimport { Admin } from '../../model/Admin.js';\\n`\n : '';\n\n const loginContent = opts.database === 'mongodb'\n ? ts\n ? `import { issueToken } from 'express-file-cluster/auth';\nimport type { Request, Response } from 'express';\n${loginDbImports}${loginMeta}export const POST = async (req: Request, res: Response) => {\n const { email, password } = req.body;\n if (!email || !password) return res.status(400).json({ error: 'email and password are required' });\n\n const admin = await Admin.findOne({ email });\n if (admin) {\n const match = await bcrypt.compare(password, admin.password);\n if (!match) return res.status(401).json({ error: 'Invalid credentials' });\n if (!admin.isActive) return res.status(403).json({ error: 'Account suspended' });\n await issueToken(res, { id: admin.id, role: admin.role, email: admin.email });\n return res.json({ message: 'Logged in as admin' });\n }\n\n const user = await User.findOne({ email });\n if (!user) return res.status(401).json({ error: 'Invalid credentials' });\n const match = await bcrypt.compare(password, user.password);\n if (!match) return res.status(401).json({ error: 'Invalid credentials' });\n if (!user.isActive) return res.status(403).json({ error: 'Account suspended' });\n await issueToken(res, { id: user.id, role: user.role, email: user.email });\n res.json({ message: 'Logged in' });\n};\n`\n : `import { issueToken } from 'express-file-cluster/auth';\n${loginDbImports}${loginMeta}export const POST = async (req, res) => {\n const { email, password } = req.body;\n if (!email || !password) return res.status(400).json({ error: 'email and password are required' });\n\n const admin = await Admin.findOne({ email });\n if (admin) {\n const match = await bcrypt.compare(password, admin.password);\n if (!match) return res.status(401).json({ error: 'Invalid credentials' });\n if (!admin.isActive) return res.status(403).json({ error: 'Account suspended' });\n await issueToken(res, { id: admin.id, role: admin.role, email: admin.email });\n return res.json({ message: 'Logged in as admin' });\n }\n\n const user = await User.findOne({ email });\n if (!user) return res.status(401).json({ error: 'Invalid credentials' });\n const match = await bcrypt.compare(password, user.password);\n if (!match) return res.status(401).json({ error: 'Invalid credentials' });\n if (!user.isActive) return res.status(403).json({ error: 'Account suspended' });\n await issueToken(res, { id: user.id, role: user.role, email: user.email });\n res.json({ message: 'Logged in' });\n};\n`\n : ts\n ? `import { issueToken } from 'express-file-cluster/auth';\nimport type { Request, Response } from 'express';\n${loginMeta}export const POST = async (req: Request, res: Response) => {\n const { email, password } = req.body;\n // TODO: look up user in DB and compare password\n res.status(401).json({ error: 'Invalid credentials' });\n};\n`\n : `import { issueToken } from 'express-file-cluster/auth';\n${loginMeta}export const POST = async (req, res) => {\n const { email, password } = req.body;\n // TODO: look up user in DB and compare password\n res.status(401).json({ error: 'Invalid credentials' });\n};\n`;\n\n const logoutMeta = opts.routeDocs\n ? ts\n ? `import type { RouteMeta } from 'express-file-cluster';\\n\\nexport const meta: RouteMeta = {\\n description: 'Clear the auth cookie and log the user out.',\\n response: { status: 200, body: { message: 'Logged out successfully' } },\\n};\\n\\n`\n : `export const meta = {\\n description: 'Clear the auth cookie and log the user out.',\\n response: { status: 200, body: { message: 'Logged out successfully' } },\\n};\\n\\n`\n : '';\n\n const logoutContent = ts\n ? `import { revokeToken } from 'express-file-cluster/auth';\nimport type { Request, Response } from 'express';\n${logoutMeta}export const POST = async (_req: Request, res: Response) => {\n revokeToken(res);\n res.json({ message: 'Logged out successfully' });\n};\n`\n : `import { revokeToken } from 'express-file-cluster/auth';\n${logoutMeta}export const POST = async (_req, res) => {\n revokeToken(res);\n res.json({ message: 'Logged out successfully' });\n};\n`;\n\n await fs.outputFile(path.join(dest, 'src', 'api', 'auth', `login.${ext}`), loginContent);\n await fs.outputFile(path.join(dest, 'src', 'api', 'auth', `logout.${ext}`), logoutContent);\n\n if (!opts.userPortal) return;\n\n const registerMeta = opts.routeDocs\n ? ts\n ? `import type { RouteMeta } from 'express-file-cluster';\\n\\nexport const meta: RouteMeta = {\\n description: 'Register a new user account.',\\n request: { body: { name: 'Jane Doe', email: 'jane@example.com', password: 'secret' } },\\n response: { status: 201, body: { message: 'Account created successfully' } },\\n};\\n\\n`\n : `export const meta = {\\n description: 'Register a new user account.',\\n request: { body: { name: 'Jane Doe', email: 'jane@example.com', password: 'secret' } },\\n response: { status: 201, body: { message: 'Account created successfully' } },\\n};\\n\\n`\n : '';\n\n const registerDbImports = opts.database === 'mongodb'\n ? ts\n ? `import bcrypt from 'bcrypt';\\nimport { User } from '../../model/User.js';\\n`\n : `import bcrypt from 'bcrypt';\\nimport { User } from '../../model/User.js';\\n`\n : '';\n\n const registerContent = opts.database === 'mongodb'\n ? ts\n ? `import type { Request, Response } from 'express';\n${registerDbImports}${registerMeta}export const POST = async (req: Request, res: Response) => {\n const { name, email, password } = req.body;\n if (!name || !email || !password) {\n return res.status(400).json({ error: 'name, email and password are required' });\n }\n const existing = await User.findOne({ email });\n if (existing) return res.status(409).json({ error: 'Email already in use' });\n const hashed = await bcrypt.hash(password, 10);\n const user = await User.create({ name, email, password: hashed });\n const { password: _, ...safe } = user;\n res.status(201).json({ message: 'Account created successfully', user: safe });\n};\n`\n : `${registerDbImports}${registerMeta}export const POST = async (req, res) => {\n const { name, email, password } = req.body;\n if (!name || !email || !password) {\n return res.status(400).json({ error: 'name, email and password are required' });\n }\n const existing = await User.findOne({ email });\n if (existing) return res.status(409).json({ error: 'Email already in use' });\n const hashed = await bcrypt.hash(password, 10);\n const user = await User.create({ name, email, password: hashed });\n const { password: _, ...safe } = user;\n res.status(201).json({ message: 'Account created successfully', user: safe });\n};\n`\n : ts\n ? `import type { Request, Response } from 'express';\n${registerMeta}export const POST = async (req: Request, res: Response) => {\n const { name, email, password } = req.body;\n if (!name || !email || !password) {\n return res.status(400).json({ error: 'name, email and password are required' });\n }\n // TODO: hash password and persist to DB\n res.status(201).json({ message: 'Account created successfully' });\n};\n`\n : `${registerMeta}export const POST = async (req, res) => {\n const { name, email, password } = req.body;\n if (!name || !email || !password) {\n return res.status(400).json({ error: 'name, email and password are required' });\n }\n // TODO: hash password and persist to DB\n res.status(201).json({ message: 'Account created successfully' });\n};\n`;\n\n const meMeta = opts.routeDocs\n ? ts\n ? `import type { RouteMeta } from 'express-file-cluster';\\n\\nexport const meta: RouteMeta = {\\n description: 'Return the currently authenticated user.',\\n response: { status: 200, body: { user: { id: '1', role: 'user', email: 'user@example.com' } } },\\n};\\n\\n`\n : `export const meta = {\\n description: 'Return the currently authenticated user.',\\n response: { status: 200, body: { user: { id: '1', role: 'user', email: 'user@example.com' } } },\\n};\\n\\n`\n : '';\n\n const requireRoleImport = opts.rbac\n ? ts\n ? `import { requireRole } from '../../middleware/requireRole.js';\\n`\n : `import { requireRole } from '../../middleware/requireRole.js';\\n`\n : '';\n const meMiddlewares = opts.rbac\n ? `export const middlewares = [requireAuth, requireRole('user', 'admin')];\\n\\n`\n : `export const middlewares = [requireAuth];\\n\\n`;\n\n const meContent = ts\n ? `import { requireAuth } from 'express-file-cluster/auth';\n${requireRoleImport}import type { Request, Response } from 'express';\n${meMeta}${meMiddlewares}export const GET = async (req: Request, res: Response) => {\n res.json({ user: (req as any).user });\n};\n`\n : `import { requireAuth } from 'express-file-cluster/auth';\n${requireRoleImport}${meMeta}${meMiddlewares}export const GET = async (req, res) => {\n res.json({ user: req.user });\n};\n`;\n\n await fs.outputFile(path.join(dest, 'src', 'api', 'auth', `register.${ext}`), registerContent);\n await fs.outputFile(path.join(dest, 'src', 'api', 'auth', `me.${ext}`), meContent);\n}\n\nasync function writeRequireRoleMiddleware(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const content =\n opts.language === 'typescript'\n ? `import type { Request, Response, NextFunction } from 'express';\n\nexport function requireRole(...roles: string[]) {\n return (req: Request, res: Response, next: NextFunction) => {\n const user = (req as any).user;\n if (!user) return res.status(401).json({ error: 'Unauthorized' });\n if (!roles.includes(user.role)) return res.status(403).json({ error: 'Forbidden' });\n next();\n };\n}\n`\n : `export function requireRole(...roles) {\n return (req, res, next) => {\n const user = req.user;\n if (!user) return res.status(401).json({ error: 'Unauthorized' });\n if (!roles.includes(user.role)) return res.status(403).json({ error: 'Forbidden' });\n next();\n };\n}\n`;\n await fs.outputFile(path.join(dest, 'src', 'middleware', `requireRole.${ext}`), content);\n}\n\nasync function writeAdminRoutes(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const ts = opts.language === 'typescript';\n\n const requireRoleImport = opts.rbac\n ? `import { requireRole } from '../../middleware/requireRole.js';\\n`\n : '';\n const usersRequireRoleImport = opts.rbac\n ? `import { requireRole } from '../../../middleware/requireRole.js';\\n`\n : '';\n const middlewares = opts.rbac\n ? `export const middlewares = [requireAuth, requireRole('admin')];\\n`\n : `export const middlewares = [requireAuth];\\n`;\n const roleGuard = opts.rbac\n ? ''\n : ts\n ? ` const user = (req as any).user;\\n if (user?.role !== 'admin') {\\n return res.status(403).json({ error: 'Forbidden: Admin access required' });\\n }\\n\\n`\n : ` const user = req.user;\\n if (user?.role !== 'admin') {\\n return res.status(403).json({ error: 'Forbidden: Admin access required' });\\n }\\n\\n`;\n\n const dashboardMeta = opts.routeDocs\n ? ts\n ? `import type { RouteMeta } from 'express-file-cluster';\\n\\nexport const meta: RouteMeta = {\\n description: 'Admin dashboard stats. Requires admin role.',\\n response: { status: 200, body: { stats: { users: 120, revenue: 5000 } } },\\n};\\n\\n`\n : `export const meta = {\\n description: 'Admin dashboard stats. Requires admin role.',\\n response: { status: 200, body: { stats: { users: 120, revenue: 5000 } } },\\n};\\n\\n`\n : '';\n\n const dashboardDbImport = opts.database === 'mongodb'\n ? `import { User } from '../../model/User.js';\\n`\n : '';\n\n const dashboardContent = opts.database === 'mongodb'\n ? ts\n ? `import { requireAuth } from 'express-file-cluster/auth';\n${requireRoleImport}import type { Request, Response } from 'express';\n${dashboardDbImport}${dashboardMeta}${middlewares}\nexport const GET = async (_req: Request, res: Response) => {\n${roleGuard} const [totalUsers, activeUsers, verifiedUsers] = await Promise.all([\n User.count({}),\n User.count({ isActive: true }),\n User.count({ isVerified: true }),\n ]);\n res.json({ stats: { totalUsers, activeUsers, verifiedUsers } });\n};\n`\n : `import { requireAuth } from 'express-file-cluster/auth';\n${requireRoleImport}${dashboardDbImport}${dashboardMeta}${middlewares}\nexport const GET = async (_req, res) => {\n${roleGuard} const [totalUsers, activeUsers, verifiedUsers] = await Promise.all([\n User.count({}),\n User.count({ isActive: true }),\n User.count({ isVerified: true }),\n ]);\n res.json({ stats: { totalUsers, activeUsers, verifiedUsers } });\n};\n`\n : ts\n ? `import { requireAuth } from 'express-file-cluster/auth';\n${requireRoleImport}import type { Request, Response } from 'express';\n${dashboardMeta}${middlewares}\nexport const GET = async (_req: Request, res: Response) => {\n${roleGuard} // TODO: aggregate stats from DB\n res.json({ stats: { users: 0 } });\n};\n`\n : `import { requireAuth } from 'express-file-cluster/auth';\n${requireRoleImport}${dashboardMeta}${middlewares}\nexport const GET = async (_req, res) => {\n${roleGuard} // TODO: aggregate stats from DB\n res.json({ stats: { users: 0 } });\n};\n`;\n\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', `dashboard.${ext}`), dashboardContent);\n\n // Admin user management routes\n const usersListMeta = opts.routeDocs\n ? ts\n ? `import type { RouteMeta } from 'express-file-cluster';\\n\\nexport const meta: RouteMeta = {\\n description: 'List all users (admin only).',\\n response: { status: 200, body: { users: [], total: 0 } },\\n};\\n\\n`\n : `export const meta = {\\n description: 'List all users (admin only).',\\n response: { status: 200, body: { users: [], total: 0 } },\\n};\\n\\n`\n : '';\n\n const adminUsersDbImport = opts.database === 'mongodb'\n ? ts\n ? `import bcrypt from 'bcrypt';\\nimport { User } from '../../../model/User.js';\\n`\n : `import bcrypt from 'bcrypt';\\nimport { User } from '../../../model/User.js';\\n`\n : '';\n\n const usersListContent = opts.database === 'mongodb'\n ? ts\n ? `import { requireAuth } from 'express-file-cluster/auth';\n${usersRequireRoleImport}import type { Request, Response } from 'express';\n${adminUsersDbImport}${usersListMeta}${middlewares}\nexport const GET = async (req: Request, res: Response) => {\n${roleGuard} const page = Math.max(1, Number(req.query.page) || 1);\n const limit = Math.min(100, Number(req.query.limit) || 20);\n const [all, total] = await Promise.all([User.find({}), User.count({})]);\n const users = all.slice((page - 1) * limit, page * limit).map(({ password: _, ...u }) => u);\n res.json({ users, total, page, limit });\n};\n\nexport const POST = async (req: Request, res: Response) => {\n${roleGuard} const { name, email, password, role } = req.body;\n if (!name || !email || !password) return res.status(400).json({ error: 'name, email and password are required' });\n const existing = await User.findOne({ email });\n if (existing) return res.status(409).json({ error: 'Email already in use' });\n const hashed = await bcrypt.hash(password, 10);\n const user = await User.create({ name, email, password: hashed, role: role ?? 'user' });\n const { password: _, ...safe } = user;\n res.status(201).json({ message: 'User created', user: safe });\n};\n`\n : `import { requireAuth } from 'express-file-cluster/auth';\n${usersRequireRoleImport}${adminUsersDbImport}${usersListMeta}${middlewares}\nexport const GET = async (req, res) => {\n${roleGuard} const page = Math.max(1, Number(req.query.page) || 1);\n const limit = Math.min(100, Number(req.query.limit) || 20);\n const [all, total] = await Promise.all([User.find({}), User.count({})]);\n const users = all.slice((page - 1) * limit, page * limit).map(({ password: _, ...u }) => u);\n res.json({ users, total, page, limit });\n};\n\nexport const POST = async (req, res) => {\n${roleGuard} const { name, email, password, role } = req.body;\n if (!name || !email || !password) return res.status(400).json({ error: 'name, email and password are required' });\n const existing = await User.findOne({ email });\n if (existing) return res.status(409).json({ error: 'Email already in use' });\n const hashed = await bcrypt.hash(password, 10);\n const user = await User.create({ name, email, password: hashed, role: role ?? 'user' });\n const { password: _, ...safe } = user;\n res.status(201).json({ message: 'User created', user: safe });\n};\n`\n : ts\n ? `import { requireAuth } from 'express-file-cluster/auth';\n${usersRequireRoleImport}import type { Request, Response } from 'express';\n${usersListMeta}${middlewares}\nexport const GET = async (_req: Request, res: Response) => {\n${roleGuard} // TODO: fetch users from DB with pagination\n res.json({ users: [], total: 0 });\n};\n\nexport const POST = async (req: Request, res: Response) => {\n${roleGuard} const { name, email, role } = req.body;\n if (!name || !email) return res.status(400).json({ error: 'name and email are required' });\n // TODO: create user in DB\n res.status(201).json({ message: 'User created', user: { id: 'new-id', name, email, role: role ?? 'user' } });\n};\n`\n : `import { requireAuth } from 'express-file-cluster/auth';\n${usersRequireRoleImport}${usersListMeta}${middlewares}\nexport const GET = async (_req, res) => {\n${roleGuard} // TODO: fetch users from DB with pagination\n res.json({ users: [], total: 0 });\n};\n\nexport const POST = async (req, res) => {\n${roleGuard} const { name, email, role } = req.body;\n if (!name || !email) return res.status(400).json({ error: 'name and email are required' });\n // TODO: create user in DB\n res.status(201).json({ message: 'User created', user: { id: 'new-id', name, email, role: role ?? 'user' } });\n};\n`;\n\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'users', `index.${ext}`), usersListContent);\n\n const userByIdMeta = opts.routeDocs\n ? ts\n ? `import type { RouteMeta } from 'express-file-cluster';\\n\\nexport const meta: RouteMeta = {\\n description: 'Get, update, or delete a single user by ID (admin only).',\\n};\\n\\n`\n : `export const meta = {\\n description: 'Get, update, or delete a single user by ID (admin only).',\\n};\\n\\n`\n : '';\n\n const adminUserByIdDbImport = opts.database === 'mongodb'\n ? `import { User } from '../../../model/User.js';\\n`\n : '';\n\n const userByIdContent = opts.database === 'mongodb'\n ? ts\n ? `import { requireAuth } from 'express-file-cluster/auth';\n${usersRequireRoleImport}import type { Request, Response } from 'express';\n${adminUserByIdDbImport}${userByIdMeta}${middlewares}\nexport const GET = async (req: Request, res: Response) => {\n${roleGuard} const { id } = req.params;\n const user = await User.findById(id);\n if (!user) return res.status(404).json({ error: 'User not found' });\n const { password: _, ...safe } = user;\n res.json({ user: safe });\n};\n\nexport const PUT = async (req: Request, res: Response) => {\n${roleGuard} const { id } = req.params;\n const { name, email, role, isActive } = req.body;\n const updated = await User.update(id, { name, email, role, isActive });\n if (!updated) return res.status(404).json({ error: 'User not found' });\n const { password: _, ...safe } = updated;\n res.json({ message: 'User updated', user: safe });\n};\n\nexport const DELETE = async (req: Request, res: Response) => {\n${roleGuard} const { id } = req.params;\n const user = await User.findById(id);\n if (!user) return res.status(404).json({ error: 'User not found' });\n await User.delete(id);\n res.json({ message: \\`User \\${id} deleted\\` });\n};\n`\n : `import { requireAuth } from 'express-file-cluster/auth';\n${usersRequireRoleImport}${adminUserByIdDbImport}${userByIdMeta}${middlewares}\nexport const GET = async (req, res) => {\n${roleGuard} const { id } = req.params;\n const user = await User.findById(id);\n if (!user) return res.status(404).json({ error: 'User not found' });\n const { password: _, ...safe } = user;\n res.json({ user: safe });\n};\n\nexport const PUT = async (req, res) => {\n${roleGuard} const { id } = req.params;\n const { name, email, role, isActive } = req.body;\n const updated = await User.update(id, { name, email, role, isActive });\n if (!updated) return res.status(404).json({ error: 'User not found' });\n const { password: _, ...safe } = updated;\n res.json({ message: 'User updated', user: safe });\n};\n\nexport const DELETE = async (req, res) => {\n${roleGuard} const { id } = req.params;\n const user = await User.findById(id);\n if (!user) return res.status(404).json({ error: 'User not found' });\n await User.delete(id);\n res.json({ message: \\`User \\${id} deleted\\` });\n};\n`\n : ts\n ? `import { requireAuth } from 'express-file-cluster/auth';\n${usersRequireRoleImport}import type { Request, Response } from 'express';\n${userByIdMeta}${middlewares}\nexport const GET = async (req: Request, res: Response) => {\n${roleGuard} const { id } = req.params;\n // TODO: fetch user from DB\n res.json({ user: { id } });\n};\n\nexport const PUT = async (req: Request, res: Response) => {\n${roleGuard} const { id } = req.params;\n // TODO: update user in DB\n res.json({ message: 'User updated', user: { id, ...req.body } });\n};\n\nexport const DELETE = async (req: Request, res: Response) => {\n${roleGuard} const { id } = req.params;\n // TODO: delete user from DB\n res.json({ message: \\`User \\${id} deleted\\` });\n};\n`\n : `import { requireAuth } from 'express-file-cluster/auth';\n${usersRequireRoleImport}${userByIdMeta}${middlewares}\nexport const GET = async (req, res) => {\n${roleGuard} const { id } = req.params;\n // TODO: fetch user from DB\n res.json({ user: { id } });\n};\n\nexport const PUT = async (req, res) => {\n${roleGuard} const { id } = req.params;\n // TODO: update user in DB\n res.json({ message: 'User updated', user: { id, ...req.body } });\n};\n\nexport const DELETE = async (req, res) => {\n${roleGuard} const { id } = req.params;\n // TODO: delete user from DB\n res.json({ message: \\`User \\${id} deleted\\` });\n};\n`;\n\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'users', `[id].${ext}`), userByIdContent);\n}\n\nasync function writeUserRoutes(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const ts = opts.language === 'typescript';\n\n const requireRoleImport = opts.rbac\n ? `import { requireRole } from '../../middleware/requireRole.js';\\n`\n : '';\n const middlewares = opts.rbac\n ? `export const middlewares = [requireAuth, requireRole('user', 'admin')];\\n`\n : `export const middlewares = [requireAuth];\\n`;\n\n const profileMeta = opts.routeDocs\n ? ts\n ? `import type { RouteMeta } from 'express-file-cluster';\\n\\nexport const meta: RouteMeta = {\\n description: \"View or update the authenticated user's profile.\",\\n response: { status: 200, body: { user: { id: '1', role: 'user', email: 'user@example.com' } } },\\n};\\n\\n`\n : `export const meta = {\\n description: \"View or update the authenticated user's profile.\",\\n response: { status: 200, body: { user: { id: '1', role: 'user', email: 'user@example.com' } } },\\n};\\n\\n`\n : '';\n\n const profileDbImport = opts.database === 'mongodb'\n ? `import { User } from '../../model/User.js';\\n`\n : '';\n\n const profileContent = opts.database === 'mongodb'\n ? ts\n ? `import { requireAuth } from 'express-file-cluster/auth';\n${requireRoleImport}import type { Request, Response } from 'express';\n${profileDbImport}${profileMeta}${middlewares}\nexport const GET = async (req: Request, res: Response) => {\n const { id } = (req as any).user;\n const user = await User.findById(id);\n if (!user) return res.status(404).json({ error: 'User not found' });\n const { password: _, ...safe } = user;\n res.json({ user: safe });\n};\n\nexport const PUT = async (req: Request, res: Response) => {\n const { id } = (req as any).user;\n const { name, email } = req.body;\n const updated = await User.update(id, { name, email });\n if (!updated) return res.status(404).json({ error: 'User not found' });\n const { password: _, ...safe } = updated;\n res.json({ message: 'Profile updated', user: safe });\n};\n`\n : `import { requireAuth } from 'express-file-cluster/auth';\n${requireRoleImport}${profileDbImport}${profileMeta}${middlewares}\nexport const GET = async (req, res) => {\n const { id } = req.user;\n const user = await User.findById(id);\n if (!user) return res.status(404).json({ error: 'User not found' });\n const { password: _, ...safe } = user;\n res.json({ user: safe });\n};\n\nexport const PUT = async (req, res) => {\n const { id } = req.user;\n const { name, email } = req.body;\n const updated = await User.update(id, { name, email });\n if (!updated) return res.status(404).json({ error: 'User not found' });\n const { password: _, ...safe } = updated;\n res.json({ message: 'Profile updated', user: safe });\n};\n`\n : ts\n ? `import { requireAuth } from 'express-file-cluster/auth';\n${requireRoleImport}import type { Request, Response } from 'express';\n${profileMeta}${middlewares}\nexport const GET = async (req: Request, res: Response) => {\n res.json({ user: (req as any).user });\n};\n\nexport const PUT = async (req: Request, res: Response) => {\n const { name, email } = req.body;\n // TODO: update user in DB\n res.json({ message: 'Profile updated', user: { ...(req as any).user, name, email } });\n};\n`\n : `import { requireAuth } from 'express-file-cluster/auth';\n${requireRoleImport}${profileMeta}${middlewares}\nexport const GET = async (req, res) => {\n res.json({ user: req.user });\n};\n\nexport const PUT = async (req, res) => {\n const { name, email } = req.body;\n // TODO: update user in DB\n res.json({ message: 'Profile updated', user: { ...req.user, name, email } });\n};\n`;\n\n await fs.outputFile(path.join(dest, 'src', 'api', 'user', `profile.${ext}`), profileContent);\n}\n\n// ─── META HELPER ─────────────────────────────────────────────────────────\n\nfunction mkMeta(opts: ScaffoldOptions, description: string, body: string, req?: string): string {\n if (!opts.routeDocs) return '';\n const reqLine = req ? ` request: { body: ${req} },\\n` : '';\n return opts.language === 'typescript'\n ? `import type { RouteMeta } from 'express-file-cluster';\\n\\nexport const meta: RouteMeta = {\\n description: '${description}',\\n${reqLine} response: { status: 200, body: ${body} },\\n};\\n\\n`\n : `export const meta = {\\n description: '${description}',\\n${reqLine} response: { status: 200, body: ${body} },\\n};\\n\\n`;\n}\n\n// ─── EXTENDED MODEL WRITERS ───────────────────────────────────────────────\n\nasync function writeSessionModel(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const ts = opts.language === 'typescript';\n const content = opts.database === 'mongodb'\n ? ts\n ? `import { defineModel } from 'express-file-cluster';\n\nexport interface SessionDocument {\n userId: string;\n token: string;\n ip: string;\n userAgent: string;\n expiresAt: Date;\n isActive: boolean;\n}\n\nexport const Session = defineModel<SessionDocument>('Session', {\n userId: { type: 'string', required: true },\n token: { type: 'string', required: true, unique: true },\n ip: { type: 'string', required: true },\n userAgent: { type: 'string', required: true },\n expiresAt: { type: 'date', required: true },\n isActive: { type: 'boolean', default: true },\n});\n`\n : `import { defineModel } from 'express-file-cluster';\n\nexport const Session = defineModel('Session', {\n userId: { type: 'string', required: true },\n token: { type: 'string', required: true, unique: true },\n ip: { type: 'string', required: true },\n userAgent: { type: 'string', required: true },\n expiresAt: { type: 'date', required: true },\n isActive: { type: 'boolean', default: true },\n});\n`\n : ts\n ? `// TODO: define your Drizzle schema for Session\n// import { pgTable, serial, text, boolean, timestamp } from 'drizzle-orm/pg-core';\n//\n// export const sessions = pgTable('sessions', {\n// id: serial('id').primaryKey(),\n// userId: text('user_id').notNull(),\n// token: text('token').notNull().unique(),\n// ip: text('ip').notNull(),\n// userAgent: text('user_agent').notNull(),\n// expiresAt: timestamp('expires_at').notNull(),\n// isActive: boolean('is_active').notNull().default(true),\n// });\nexport {};\n`\n : `// TODO: define your Drizzle schema for Session\nexport {};\n`;\n await fs.outputFile(path.join(dest, 'src', 'model', `Session.${ext}`), content);\n}\n\nasync function writeNotificationModel(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const ts = opts.language === 'typescript';\n const content = opts.database === 'mongodb'\n ? ts\n ? `import { defineModel } from 'express-file-cluster';\n\nexport interface NotificationDocument {\n userId: string;\n title: string;\n message: string;\n type: string;\n isRead: boolean;\n link?: string;\n}\n\nexport const Notification = defineModel<NotificationDocument>('Notification', {\n userId: { type: 'string', required: true },\n title: { type: 'string', required: true },\n message: { type: 'string', required: true },\n type: { type: 'string', required: true, default: 'info' },\n isRead: { type: 'boolean', default: false },\n link: { type: 'string' },\n});\n`\n : `import { defineModel } from 'express-file-cluster';\n\nexport const Notification = defineModel('Notification', {\n userId: { type: 'string', required: true },\n title: { type: 'string', required: true },\n message: { type: 'string', required: true },\n type: { type: 'string', required: true, default: 'info' },\n isRead: { type: 'boolean', default: false },\n link: { type: 'string' },\n});\n`\n : ts\n ? `// TODO: define your Drizzle schema for Notification\n// import { pgTable, serial, text, boolean, timestamp } from 'drizzle-orm/pg-core';\n//\n// export const notifications = pgTable('notifications', {\n// id: serial('id').primaryKey(),\n// userId: text('user_id').notNull(),\n// title: text('title').notNull(),\n// message: text('message').notNull(),\n// type: text('type').notNull().default('info'),\n// isRead: boolean('is_read').notNull().default(false),\n// link: text('link'),\n// createdAt: timestamp('created_at').defaultNow(),\n// });\nexport {};\n`\n : `// TODO: define your Drizzle schema for Notification\nexport {};\n`;\n await fs.outputFile(path.join(dest, 'src', 'model', `Notification.${ext}`), content);\n}\n\nasync function writeFileModel(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const ts = opts.language === 'typescript';\n const content = opts.database === 'mongodb'\n ? ts\n ? `import { defineModel } from 'express-file-cluster';\n\nexport interface FileDocument {\n userId: string;\n filename: string;\n originalName: string;\n mimeType: string;\n size: number;\n url: string;\n isPublic: boolean;\n}\n\nexport const File = defineModel<FileDocument>('File', {\n userId: { type: 'string', required: true },\n filename: { type: 'string', required: true },\n originalName: { type: 'string', required: true },\n mimeType: { type: 'string', required: true },\n size: { type: 'number', required: true },\n url: { type: 'string', required: true },\n isPublic: { type: 'boolean', default: false },\n});\n`\n : `import { defineModel } from 'express-file-cluster';\n\nexport const File = defineModel('File', {\n userId: { type: 'string', required: true },\n filename: { type: 'string', required: true },\n originalName: { type: 'string', required: true },\n mimeType: { type: 'string', required: true },\n size: { type: 'number', required: true },\n url: { type: 'string', required: true },\n isPublic: { type: 'boolean', default: false },\n});\n`\n : ts\n ? `// TODO: define your Drizzle schema for File\n// import { pgTable, serial, text, boolean, integer, timestamp } from 'drizzle-orm/pg-core';\n//\n// export const files = pgTable('files', {\n// id: serial('id').primaryKey(),\n// userId: text('user_id').notNull(),\n// filename: text('filename').notNull(),\n// originalName: text('original_name').notNull(),\n// mimeType: text('mime_type').notNull(),\n// size: integer('size').notNull(),\n// url: text('url').notNull(),\n// isPublic: boolean('is_public').notNull().default(false),\n// createdAt: timestamp('created_at').defaultNow(),\n// });\nexport {};\n`\n : `// TODO: define your Drizzle schema for File\nexport {};\n`;\n await fs.outputFile(path.join(dest, 'src', 'model', `File.${ext}`), content);\n}\n\nasync function writeSupportTicketModel(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const ts = opts.language === 'typescript';\n const content = opts.database === 'mongodb'\n ? ts\n ? `import { defineModel } from 'express-file-cluster';\n\nexport interface SupportTicketDocument {\n userId: string;\n subject: string;\n message: string;\n status: string;\n priority: string;\n assignedTo?: string;\n}\n\nexport const SupportTicket = defineModel<SupportTicketDocument>('SupportTicket', {\n userId: { type: 'string', required: true },\n subject: { type: 'string', required: true },\n message: { type: 'string', required: true },\n status: { type: 'string', required: true, default: 'open' },\n priority: { type: 'string', required: true, default: 'normal' },\n assignedTo: { type: 'string' },\n});\n`\n : `import { defineModel } from 'express-file-cluster';\n\nexport const SupportTicket = defineModel('SupportTicket', {\n userId: { type: 'string', required: true },\n subject: { type: 'string', required: true },\n message: { type: 'string', required: true },\n status: { type: 'string', required: true, default: 'open' },\n priority: { type: 'string', required: true, default: 'normal' },\n assignedTo: { type: 'string' },\n});\n`\n : ts\n ? `// TODO: define your Drizzle schema for SupportTicket\n// import { pgTable, serial, text, timestamp } from 'drizzle-orm/pg-core';\n//\n// export const supportTickets = pgTable('support_tickets', {\n// id: serial('id').primaryKey(),\n// userId: text('user_id').notNull(),\n// subject: text('subject').notNull(),\n// message: text('message').notNull(),\n// status: text('status').notNull().default('open'),\n// priority: text('priority').notNull().default('normal'),\n// assignedTo: text('assigned_to'),\n// createdAt: timestamp('created_at').defaultNow(),\n// updatedAt: timestamp('updated_at').defaultNow(),\n// });\nexport {};\n`\n : `// TODO: define your Drizzle schema for SupportTicket\nexport {};\n`;\n await fs.outputFile(path.join(dest, 'src', 'model', `SupportTicket.${ext}`), content);\n}\n\nasync function writeAuditLogModel(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const ts = opts.language === 'typescript';\n const content = opts.database === 'mongodb'\n ? ts\n ? `import { defineModel } from 'express-file-cluster';\n\nexport interface AuditLogDocument {\n adminId: string;\n action: string;\n entity: string;\n entityId: string;\n metadata?: Record<string, unknown>;\n ip: string;\n}\n\nexport const AuditLog = defineModel<AuditLogDocument>('AuditLog', {\n adminId: { type: 'string', required: true },\n action: { type: 'string', required: true },\n entity: { type: 'string', required: true },\n entityId: { type: 'string', required: true },\n metadata: { type: 'object' },\n ip: { type: 'string', required: true },\n});\n`\n : `import { defineModel } from 'express-file-cluster';\n\nexport const AuditLog = defineModel('AuditLog', {\n adminId: { type: 'string', required: true },\n action: { type: 'string', required: true },\n entity: { type: 'string', required: true },\n entityId: { type: 'string', required: true },\n metadata: { type: 'object' },\n ip: { type: 'string', required: true },\n});\n`\n : ts\n ? `// TODO: define your Drizzle schema for AuditLog\n// import { pgTable, serial, text, jsonb, timestamp } from 'drizzle-orm/pg-core';\n//\n// export const auditLogs = pgTable('audit_logs', {\n// id: serial('id').primaryKey(),\n// adminId: text('admin_id').notNull(),\n// action: text('action').notNull(),\n// entity: text('entity').notNull(),\n// entityId: text('entity_id').notNull(),\n// metadata: jsonb('metadata'),\n// ip: text('ip').notNull(),\n// createdAt: timestamp('created_at').defaultNow(),\n// });\nexport {};\n`\n : `// TODO: define your Drizzle schema for AuditLog\nexport {};\n`;\n await fs.outputFile(path.join(dest, 'src', 'model', `AuditLog.${ext}`), content);\n}\n\nasync function writeSubscriptionModel(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const ts = opts.language === 'typescript';\n const content = opts.database === 'mongodb'\n ? ts\n ? `import { defineModel } from 'express-file-cluster';\n\nexport interface SubscriptionDocument {\n userId: string;\n planId: string;\n status: string;\n startDate: Date;\n endDate: Date;\n cancelledAt?: Date;\n}\n\nexport const Subscription = defineModel<SubscriptionDocument>('Subscription', {\n userId: { type: 'string', required: true },\n planId: { type: 'string', required: true },\n status: { type: 'string', required: true, default: 'active' },\n startDate: { type: 'date', required: true },\n endDate: { type: 'date', required: true },\n cancelledAt: { type: 'date' },\n});\n`\n : `import { defineModel } from 'express-file-cluster';\n\nexport const Subscription = defineModel('Subscription', {\n userId: { type: 'string', required: true },\n planId: { type: 'string', required: true },\n status: { type: 'string', required: true, default: 'active' },\n startDate: { type: 'date', required: true },\n endDate: { type: 'date', required: true },\n cancelledAt: { type: 'date' },\n});\n`\n : ts\n ? `// TODO: define your Drizzle schema for Subscription\n// import { pgTable, serial, text, timestamp } from 'drizzle-orm/pg-core';\n//\n// export const subscriptions = pgTable('subscriptions', {\n// id: serial('id').primaryKey(),\n// userId: text('user_id').notNull(),\n// planId: text('plan_id').notNull(),\n// status: text('status').notNull().default('active'),\n// startDate: timestamp('start_date').notNull(),\n// endDate: timestamp('end_date').notNull(),\n// cancelledAt: timestamp('cancelled_at'),\n// createdAt: timestamp('created_at').defaultNow(),\n// });\nexport {};\n`\n : `// TODO: define your Drizzle schema for Subscription\nexport {};\n`;\n await fs.outputFile(path.join(dest, 'src', 'model', `Subscription.${ext}`), content);\n}\n\nasync function writePlanModel(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const ts = opts.language === 'typescript';\n const content = opts.database === 'mongodb'\n ? ts\n ? `import { defineModel } from 'express-file-cluster';\n\nexport interface PlanDocument {\n name: string;\n description: string;\n price: number;\n interval: string;\n features: string[];\n isActive: boolean;\n}\n\nexport const Plan = defineModel<PlanDocument>('Plan', {\n name: { type: 'string', required: true },\n description: { type: 'string', required: true },\n price: { type: 'number', required: true },\n interval: { type: 'string', required: true, default: 'monthly' },\n features: { type: 'array', default: [] },\n isActive: { type: 'boolean', default: true },\n});\n`\n : `import { defineModel } from 'express-file-cluster';\n\nexport const Plan = defineModel('Plan', {\n name: { type: 'string', required: true },\n description: { type: 'string', required: true },\n price: { type: 'number', required: true },\n interval: { type: 'string', required: true, default: 'monthly' },\n features: { type: 'array', default: [] },\n isActive: { type: 'boolean', default: true },\n});\n`\n : ts\n ? `// TODO: define your Drizzle schema for Plan\n// import { pgTable, serial, text, numeric, boolean, timestamp } from 'drizzle-orm/pg-core';\n//\n// export const plans = pgTable('plans', {\n// id: serial('id').primaryKey(),\n// name: text('name').notNull(),\n// description: text('description').notNull(),\n// price: numeric('price').notNull(),\n// interval: text('interval').notNull().default('monthly'),\n// features: text('features').array().notNull().default([]),\n// isActive: boolean('is_active').notNull().default(true),\n// createdAt: timestamp('created_at').defaultNow(),\n// });\nexport {};\n`\n : `// TODO: define your Drizzle schema for Plan\nexport {};\n`;\n await fs.outputFile(path.join(dest, 'src', 'model', `Plan.${ext}`), content);\n}\n\nasync function writeInvoiceModel(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const ts = opts.language === 'typescript';\n const content = opts.database === 'mongodb'\n ? ts\n ? `import { defineModel } from 'express-file-cluster';\n\nexport interface InvoiceDocument {\n userId: string;\n subscriptionId: string;\n amount: number;\n currency: string;\n status: string;\n paidAt?: Date;\n}\n\nexport const Invoice = defineModel<InvoiceDocument>('Invoice', {\n userId: { type: 'string', required: true },\n subscriptionId: { type: 'string', required: true },\n amount: { type: 'number', required: true },\n currency: { type: 'string', required: true, default: 'USD' },\n status: { type: 'string', required: true, default: 'pending' },\n paidAt: { type: 'date' },\n});\n`\n : `import { defineModel } from 'express-file-cluster';\n\nexport const Invoice = defineModel('Invoice', {\n userId: { type: 'string', required: true },\n subscriptionId: { type: 'string', required: true },\n amount: { type: 'number', required: true },\n currency: { type: 'string', required: true, default: 'USD' },\n status: { type: 'string', required: true, default: 'pending' },\n paidAt: { type: 'date' },\n});\n`\n : ts\n ? `// TODO: define your Drizzle schema for Invoice\n// import { pgTable, serial, text, numeric, timestamp } from 'drizzle-orm/pg-core';\n//\n// export const invoices = pgTable('invoices', {\n// id: serial('id').primaryKey(),\n// userId: text('user_id').notNull(),\n// subscriptionId: text('subscription_id').notNull(),\n// amount: numeric('amount').notNull(),\n// currency: text('currency').notNull().default('USD'),\n// status: text('status').notNull().default('pending'),\n// paidAt: timestamp('paid_at'),\n// createdAt: timestamp('created_at').defaultNow(),\n// });\nexport {};\n`\n : `// TODO: define your Drizzle schema for Invoice\nexport {};\n`;\n await fs.outputFile(path.join(dest, 'src', 'model', `Invoice.${ext}`), content);\n}\n\nasync function writeApiKeyModel(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const ts = opts.language === 'typescript';\n const content = opts.database === 'mongodb'\n ? ts\n ? `import { defineModel } from 'express-file-cluster';\n\nexport interface ApiKeyDocument {\n userId: string;\n name: string;\n key: string;\n lastUsed?: Date;\n expiresAt?: Date;\n isActive: boolean;\n}\n\nexport const ApiKey = defineModel<ApiKeyDocument>('ApiKey', {\n userId: { type: 'string', required: true },\n name: { type: 'string', required: true },\n key: { type: 'string', required: true, unique: true },\n lastUsed: { type: 'date' },\n expiresAt:{ type: 'date' },\n isActive: { type: 'boolean', default: true },\n});\n`\n : `import { defineModel } from 'express-file-cluster';\n\nexport const ApiKey = defineModel('ApiKey', {\n userId: { type: 'string', required: true },\n name: { type: 'string', required: true },\n key: { type: 'string', required: true, unique: true },\n lastUsed: { type: 'date' },\n expiresAt: { type: 'date' },\n isActive: { type: 'boolean', default: true },\n});\n`\n : ts\n ? `// TODO: define your Drizzle schema for ApiKey\n// import { pgTable, serial, text, boolean, timestamp } from 'drizzle-orm/pg-core';\n//\n// export const apiKeys = pgTable('api_keys', {\n// id: serial('id').primaryKey(),\n// userId: text('user_id').notNull(),\n// name: text('name').notNull(),\n// key: text('key').notNull().unique(),\n// lastUsed: timestamp('last_used'),\n// expiresAt: timestamp('expires_at'),\n// isActive: boolean('is_active').notNull().default(true),\n// createdAt: timestamp('created_at').defaultNow(),\n// });\nexport {};\n`\n : `// TODO: define your Drizzle schema for ApiKey\nexport {};\n`;\n await fs.outputFile(path.join(dest, 'src', 'model', `ApiKey.${ext}`), content);\n}\n\nasync function writeRoleModel(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const ts = opts.language === 'typescript';\n const content = opts.database === 'mongodb'\n ? ts\n ? `import { defineModel } from 'express-file-cluster';\n\nexport interface RoleDocument {\n name: string;\n description: string;\n permissions: string[];\n}\n\nexport const Role = defineModel<RoleDocument>('Role', {\n name: { type: 'string', required: true, unique: true },\n description: { type: 'string', required: true },\n permissions: { type: 'array', default: [] },\n});\n`\n : `import { defineModel } from 'express-file-cluster';\n\nexport const Role = defineModel('Role', {\n name: { type: 'string', required: true, unique: true },\n description: { type: 'string', required: true },\n permissions: { type: 'array', default: [] },\n});\n`\n : ts\n ? `// TODO: define your Drizzle schema for Role\n// import { pgTable, serial, text, timestamp } from 'drizzle-orm/pg-core';\n//\n// export const roles = pgTable('roles', {\n// id: serial('id').primaryKey(),\n// name: text('name').notNull().unique(),\n// description: text('description').notNull(),\n// permissions: text('permissions').array().notNull().default([]),\n// createdAt: timestamp('created_at').defaultNow(),\n// });\nexport {};\n`\n : `// TODO: define your Drizzle schema for Role\nexport {};\n`;\n await fs.outputFile(path.join(dest, 'src', 'model', `Role.${ext}`), content);\n}\n\nasync function writeFAQModel(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const ts = opts.language === 'typescript';\n const content = opts.database === 'mongodb'\n ? ts\n ? `import { defineModel } from 'express-file-cluster';\n\nexport interface FAQDocument {\n question: string;\n answer: string;\n category: string;\n order: number;\n isPublished: boolean;\n}\n\nexport const FAQ = defineModel<FAQDocument>('FAQ', {\n question: { type: 'string', required: true },\n answer: { type: 'string', required: true },\n category: { type: 'string', required: true, default: 'general' },\n order: { type: 'number', default: 0 },\n isPublished: { type: 'boolean', default: false },\n});\n`\n : `import { defineModel } from 'express-file-cluster';\n\nexport const FAQ = defineModel('FAQ', {\n question: { type: 'string', required: true },\n answer: { type: 'string', required: true },\n category: { type: 'string', required: true, default: 'general' },\n order: { type: 'number', default: 0 },\n isPublished: { type: 'boolean', default: false },\n});\n`\n : ts\n ? `// TODO: define your Drizzle schema for FAQ\n// import { pgTable, serial, text, boolean, integer, timestamp } from 'drizzle-orm/pg-core';\n//\n// export const faqs = pgTable('faqs', {\n// id: serial('id').primaryKey(),\n// question: text('question').notNull(),\n// answer: text('answer').notNull(),\n// category: text('category').notNull().default('general'),\n// order: integer('order').notNull().default(0),\n// isPublished: boolean('is_published').notNull().default(false),\n// createdAt: timestamp('created_at').defaultNow(),\n// });\nexport {};\n`\n : `// TODO: define your Drizzle schema for FAQ\nexport {};\n`;\n await fs.outputFile(path.join(dest, 'src', 'model', `FAQ.${ext}`), content);\n}\n\nasync function writeBlogModel(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const ts = opts.language === 'typescript';\n const content = opts.database === 'mongodb'\n ? ts\n ? `import { defineModel } from 'express-file-cluster';\n\nexport interface BlogDocument {\n title: string;\n slug: string;\n content: string;\n authorId: string;\n category: string;\n tags: string[];\n status: string;\n publishedAt?: Date;\n}\n\nexport const Blog = defineModel<BlogDocument>('Blog', {\n title: { type: 'string', required: true },\n slug: { type: 'string', required: true, unique: true },\n content: { type: 'string', required: true },\n authorId: { type: 'string', required: true },\n category: { type: 'string', required: true, default: 'general' },\n tags: { type: 'array', default: [] },\n status: { type: 'string', required: true, default: 'draft' },\n publishedAt: { type: 'date' },\n});\n`\n : `import { defineModel } from 'express-file-cluster';\n\nexport const Blog = defineModel('Blog', {\n title: { type: 'string', required: true },\n slug: { type: 'string', required: true, unique: true },\n content: { type: 'string', required: true },\n authorId: { type: 'string', required: true },\n category: { type: 'string', required: true, default: 'general' },\n tags: { type: 'array', default: [] },\n status: { type: 'string', required: true, default: 'draft' },\n publishedAt: { type: 'date' },\n});\n`\n : ts\n ? `// TODO: define your Drizzle schema for Blog\n// import { pgTable, serial, text, timestamp } from 'drizzle-orm/pg-core';\n//\n// export const blogs = pgTable('blogs', {\n// id: serial('id').primaryKey(),\n// title: text('title').notNull(),\n// slug: text('slug').notNull().unique(),\n// content: text('content').notNull(),\n// authorId: text('author_id').notNull(),\n// category: text('category').notNull().default('general'),\n// tags: text('tags').array().notNull().default([]),\n// status: text('status').notNull().default('draft'),\n// publishedAt: timestamp('published_at'),\n// createdAt: timestamp('created_at').defaultNow(),\n// updatedAt: timestamp('updated_at').defaultNow(),\n// });\nexport {};\n`\n : `// TODO: define your Drizzle schema for Blog\nexport {};\n`;\n await fs.outputFile(path.join(dest, 'src', 'model', `Blog.${ext}`), content);\n}\n\nasync function writeCategoryModel(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const ts = opts.language === 'typescript';\n const content = opts.database === 'mongodb'\n ? ts\n ? `import { defineModel } from 'express-file-cluster';\n\nexport interface CategoryDocument {\n name: string;\n slug: string;\n description?: string;\n parentId?: string;\n}\n\nexport const Category = defineModel<CategoryDocument>('Category', {\n name: { type: 'string', required: true },\n slug: { type: 'string', required: true, unique: true },\n description: { type: 'string' },\n parentId: { type: 'string' },\n});\n`\n : `import { defineModel } from 'express-file-cluster';\n\nexport const Category = defineModel('Category', {\n name: { type: 'string', required: true },\n slug: { type: 'string', required: true, unique: true },\n description: { type: 'string' },\n parentId: { type: 'string' },\n});\n`\n : ts\n ? `// TODO: define your Drizzle schema for Category\n// import { pgTable, serial, text, timestamp } from 'drizzle-orm/pg-core';\n//\n// export const categories = pgTable('categories', {\n// id: serial('id').primaryKey(),\n// name: text('name').notNull(),\n// slug: text('slug').notNull().unique(),\n// description: text('description'),\n// parentId: text('parent_id'),\n// createdAt: timestamp('created_at').defaultNow(),\n// });\nexport {};\n`\n : `// TODO: define your Drizzle schema for Category\nexport {};\n`;\n await fs.outputFile(path.join(dest, 'src', 'model', `Category.${ext}`), content);\n}\n\nasync function writeCouponModel(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const ts = opts.language === 'typescript';\n const content = opts.database === 'mongodb'\n ? ts\n ? `import { defineModel } from 'express-file-cluster';\n\nexport interface CouponDocument {\n code: string;\n type: string;\n value: number;\n maxUses: number;\n usedCount: number;\n expiresAt?: Date;\n isActive: boolean;\n}\n\nexport const Coupon = defineModel<CouponDocument>('Coupon', {\n code: { type: 'string', required: true, unique: true },\n type: { type: 'string', required: true, default: 'percent' },\n value: { type: 'number', required: true },\n maxUses: { type: 'number', default: 0 },\n usedCount: { type: 'number', default: 0 },\n expiresAt: { type: 'date' },\n isActive: { type: 'boolean', default: true },\n});\n`\n : `import { defineModel } from 'express-file-cluster';\n\nexport const Coupon = defineModel('Coupon', {\n code: { type: 'string', required: true, unique: true },\n type: { type: 'string', required: true, default: 'percent' },\n value: { type: 'number', required: true },\n maxUses: { type: 'number', default: 0 },\n usedCount: { type: 'number', default: 0 },\n expiresAt: { type: 'date' },\n isActive: { type: 'boolean', default: true },\n});\n`\n : ts\n ? `// TODO: define your Drizzle schema for Coupon\n// import { pgTable, serial, text, numeric, integer, boolean, timestamp } from 'drizzle-orm/pg-core';\n//\n// export const coupons = pgTable('coupons', {\n// id: serial('id').primaryKey(),\n// code: text('code').notNull().unique(),\n// type: text('type').notNull().default('percent'),\n// value: numeric('value').notNull(),\n// maxUses: integer('max_uses').notNull().default(0),\n// usedCount: integer('used_count').notNull().default(0),\n// expiresAt: timestamp('expires_at'),\n// isActive: boolean('is_active').notNull().default(true),\n// createdAt: timestamp('created_at').defaultNow(),\n// });\nexport {};\n`\n : `// TODO: define your Drizzle schema for Coupon\nexport {};\n`;\n await fs.outputFile(path.join(dest, 'src', 'model', `Coupon.${ext}`), content);\n}\n\n// ─── EXTENDED ROUTE WRITERS ───────────────────────────────────────────────\n\nasync function writeAuthExtendedRoutes(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const ts = opts.language === 'typescript';\n // requireRole import paths: auth/* = 2 levels, auth/subdir/* = 3 levels\n const rr2 = opts.rbac ? `import { requireRole } from '../../middleware/requireRole.js';\\n` : '';\n const rr3 = opts.rbac ? `import { requireRole } from '../../../middleware/requireRole.js';\\n` : '';\n const mwUser2 = opts.rbac\n ? `export const middlewares = [requireAuth, requireRole('user', 'admin')];\\n`\n : `export const middlewares = [requireAuth];\\n`;\n const mwUser3 = mwUser2;\n const reqT = ts ? `import type { Request, Response } from 'express';\\n` : '';\n const RA = `import { requireAuth } from 'express-file-cluster/auth';\\n`;\n\n // refresh.ts\n const refreshMeta = mkMeta(opts, 'Refresh the JWT and issue a new token.', `{ message: 'Token refreshed' }`);\n const refreshContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${refreshMeta}export const POST = async (_req: Request, res: Response) => {\n // TODO: validate refresh token, issue new JWT\n res.json({ message: 'Token refreshed' });\n};\n`\n : `${RA}${refreshMeta}export const POST = async (_req, res) => {\n // TODO: validate refresh token, issue new JWT\n res.json({ message: 'Token refreshed' });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'auth', `refresh.${ext}`), refreshContent);\n\n // verify-email.ts\n const veMeta = mkMeta(opts, 'Verify email address via token or resend verification email.', `{ message: 'Email verified' }`);\n const veContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${veMeta}export const GET = async (req: Request, res: Response) => {\n const { token } = req.query;\n // TODO: verify token and mark user as verified\n res.json({ message: 'Email verified' });\n};\n\nexport const POST = async (_req: Request, res: Response) => {\n // TODO: resend verification email\n res.json({ message: 'Verification email sent' });\n};\n`\n : `${RA}${veMeta}export const GET = async (req, res) => {\n const { token } = req.query;\n // TODO: verify token and mark user as verified\n res.json({ message: 'Email verified' });\n};\n\nexport const POST = async (_req, res) => {\n // TODO: resend verification email\n res.json({ message: 'Verification email sent' });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'auth', `verify-email.${ext}`), veContent);\n\n // forgot-password.ts\n const fpMeta = mkMeta(opts, 'Send a password reset email to the given address.', `{ message: 'Reset email sent' }`, `{ email: 'user@example.com' }`);\n const fpContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${fpMeta}export const POST = async (req: Request, res: Response) => {\n const { email } = req.body;\n if (!email) return res.status(400).json({ error: 'email is required' });\n // TODO: generate reset token and send email\n res.json({ message: 'Reset email sent' });\n};\n`\n : `${RA}${fpMeta}export const POST = async (req, res) => {\n const { email } = req.body;\n if (!email) return res.status(400).json({ error: 'email is required' });\n // TODO: generate reset token and send email\n res.json({ message: 'Reset email sent' });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'auth', `forgot-password.${ext}`), fpContent);\n\n // reset-password.ts\n const rpMeta = mkMeta(opts, 'Reset password using a valid reset token.', `{ message: 'Password reset successfully' }`, `{ token: 'reset-token', password: 'newpassword' }`);\n const rpContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${rpMeta}export const POST = async (req: Request, res: Response) => {\n const { token, password } = req.body;\n if (!token || !password) return res.status(400).json({ error: 'token and password are required' });\n // TODO: validate token, hash and update password\n res.json({ message: 'Password reset successfully' });\n};\n`\n : `${RA}${rpMeta}export const POST = async (req, res) => {\n const { token, password } = req.body;\n if (!token || !password) return res.status(400).json({ error: 'token and password are required' });\n // TODO: validate token, hash and update password\n res.json({ message: 'Password reset successfully' });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'auth', `reset-password.${ext}`), rpContent);\n\n // change-password.ts (protected)\n const cpMeta = mkMeta(opts, 'Change password for the authenticated user.', `{ message: 'Password changed successfully' }`, `{ oldPassword: 'current', newPassword: 'newpassword' }`);\n const cpContent = ts\n ? `${RA}${rr2}import type { Request, Response } from 'express';\n${cpMeta}${mwUser2}\nexport const POST = async (req: Request, res: Response) => {\n const { oldPassword, newPassword } = req.body;\n if (!oldPassword || !newPassword) return res.status(400).json({ error: 'oldPassword and newPassword are required' });\n // TODO: verify old password, hash and update new password\n res.json({ message: 'Password changed successfully' });\n};\n`\n : `${RA}${rr2}${cpMeta}${mwUser2}\nexport const POST = async (req, res) => {\n const { oldPassword, newPassword } = req.body;\n if (!oldPassword || !newPassword) return res.status(400).json({ error: 'oldPassword and newPassword are required' });\n // TODO: verify old password, hash and update new password\n res.json({ message: 'Password changed successfully' });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'auth', `change-password.${ext}`), cpContent);\n\n // 2fa/setup.ts\n const tfaSetupMeta = mkMeta(opts, 'Get 2FA QR code (GET) or enable 2FA with a verified TOTP code (POST).', `{ message: '2FA enabled' }`);\n const tfaSetupContent = ts\n ? `${RA}${rr3}import type { Request, Response } from 'express';\n${tfaSetupMeta}${mwUser3}\nexport const GET = async (req: Request, res: Response) => {\n // TODO: generate TOTP secret and return QR code URL\n res.json({ qrCode: 'otpauth://totp/...', secret: 'BASE32SECRET' });\n};\n\nexport const POST = async (req: Request, res: Response) => {\n const { code } = req.body;\n if (!code) return res.status(400).json({ error: 'code is required' });\n // TODO: verify TOTP code and enable 2FA\n res.json({ message: '2FA enabled' });\n};\n`\n : `${RA}${rr3}${tfaSetupMeta}${mwUser3}\nexport const GET = async (req, res) => {\n // TODO: generate TOTP secret and return QR code URL\n res.json({ qrCode: 'otpauth://totp/...', secret: 'BASE32SECRET' });\n};\n\nexport const POST = async (req, res) => {\n const { code } = req.body;\n if (!code) return res.status(400).json({ error: 'code is required' });\n // TODO: verify TOTP code and enable 2FA\n res.json({ message: '2FA enabled' });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'auth', '2fa', `setup.${ext}`), tfaSetupContent);\n\n // 2fa/verify.ts\n const tfaVerifyMeta = mkMeta(opts, 'Verify a TOTP code during login.', `{ message: '2FA verified' }`);\n const tfaVerifyContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${tfaVerifyMeta}export const POST = async (req: Request, res: Response) => {\n const { code } = req.body;\n if (!code) return res.status(400).json({ error: 'code is required' });\n // TODO: verify TOTP code\n res.json({ message: '2FA verified' });\n};\n`\n : `${RA}${tfaVerifyMeta}export const POST = async (req, res) => {\n const { code } = req.body;\n if (!code) return res.status(400).json({ error: 'code is required' });\n // TODO: verify TOTP code\n res.json({ message: '2FA verified' });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'auth', '2fa', `verify.${ext}`), tfaVerifyContent);\n\n // 2fa/disable.ts\n const tfaDisableMeta = mkMeta(opts, 'Disable 2FA for the authenticated user.', `{ message: '2FA disabled' }`);\n const tfaDisableContent = ts\n ? `${RA}${rr3}import type { Request, Response } from 'express';\n${tfaDisableMeta}${mwUser3}\nexport const POST = async (req: Request, res: Response) => {\n const { code } = req.body;\n if (!code) return res.status(400).json({ error: 'code is required' });\n // TODO: verify code and disable 2FA\n res.json({ message: '2FA disabled' });\n};\n`\n : `${RA}${rr3}${tfaDisableMeta}${mwUser3}\nexport const POST = async (req, res) => {\n const { code } = req.body;\n if (!code) return res.status(400).json({ error: 'code is required' });\n // TODO: verify code and disable 2FA\n res.json({ message: '2FA disabled' });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'auth', '2fa', `disable.${ext}`), tfaDisableContent);\n\n // sessions/index.ts\n const sessListMeta = mkMeta(opts, 'List all active sessions for the authenticated user.', `{ sessions: [] }`);\n const sessListContent = ts\n ? `${RA}${rr3}import type { Request, Response } from 'express';\n${sessListMeta}${mwUser3}\nexport const GET = async (req: Request, res: Response) => {\n // TODO: fetch sessions for req.user.id\n res.json({ sessions: [] });\n};\n`\n : `${RA}${rr3}${sessListMeta}${mwUser3}\nexport const GET = async (req, res) => {\n // TODO: fetch sessions for req.user.id\n res.json({ sessions: [] });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'auth', 'sessions', `index.${ext}`), sessListContent);\n\n // sessions/[id].ts\n const sessRevokeContent = ts\n ? `${RA}${rr3}import type { Request, Response } from 'express';\n${mwUser3}\nexport const DELETE = async (req: Request, res: Response) => {\n const { id } = req.params;\n // TODO: revoke session by id\n res.json({ message: \\`Session \\${id} revoked\\` });\n};\n`\n : `${RA}${rr3}${mwUser3}\nexport const DELETE = async (req, res) => {\n const { id } = req.params;\n // TODO: revoke session by id\n res.json({ message: \\`Session \\${id} revoked\\` });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'auth', 'sessions', `[id].${ext}`), sessRevokeContent);\n}\n\nasync function writeUserExtendedRoutes(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const ts = opts.language === 'typescript';\n // user/* = 2 levels up to src/, user/subdir/* = 3 levels\n const rr2 = opts.rbac ? `import { requireRole } from '../../middleware/requireRole.js';\\n` : '';\n const rr3 = opts.rbac ? `import { requireRole } from '../../../middleware/requireRole.js';\\n` : '';\n const mw2 = opts.rbac\n ? `export const middlewares = [requireAuth, requireRole('user', 'admin')];\\n`\n : `export const middlewares = [requireAuth];\\n`;\n const mw3 = mw2;\n const RA = `import { requireAuth } from 'express-file-cluster/auth';\\n`;\n const user = ts ? `(req as any).user` : `req.user`;\n\n // avatar.ts\n const avatarMeta = mkMeta(opts, 'Upload (POST) or remove (DELETE) the authenticated user avatar.', `{ message: 'Avatar updated', url: 'https://...' }`);\n const avatarContent = ts\n ? `${RA}${rr2}import type { Request, Response } from 'express';\n${avatarMeta}${mw2}\nexport const POST = async (req: Request, res: Response) => {\n // TODO: handle multipart upload, store file, update user.avatar\n res.json({ message: 'Avatar updated', url: 'https://example.com/avatar.jpg' });\n};\n\nexport const DELETE = async (req: Request, res: Response) => {\n // TODO: remove avatar and clear user.avatar\n res.json({ message: 'Avatar removed' });\n};\n`\n : `${RA}${rr2}${avatarMeta}${mw2}\nexport const POST = async (req, res) => {\n // TODO: handle multipart upload, store file, update user.avatar\n res.json({ message: 'Avatar updated', url: 'https://example.com/avatar.jpg' });\n};\n\nexport const DELETE = async (req, res) => {\n // TODO: remove avatar and clear user.avatar\n res.json({ message: 'Avatar removed' });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'user', `avatar.${ext}`), avatarContent);\n\n // settings.ts\n const settingsMeta = mkMeta(opts, 'Get or update account settings (notifications, language, theme, privacy).', `{ settings: { notifications: true, language: 'en', theme: 'system' } }`);\n const settingsContent = ts\n ? `${RA}${rr2}import type { Request, Response } from 'express';\n${settingsMeta}${mw2}\nexport const GET = async (req: Request, res: Response) => {\n // TODO: fetch user settings from DB\n res.json({ settings: { notifications: true, language: 'en', theme: 'system', privacy: 'public' } });\n};\n\nexport const PUT = async (req: Request, res: Response) => {\n const { notifications, language, theme, privacy } = req.body;\n // TODO: update user settings in DB\n res.json({ message: 'Settings updated', settings: { notifications, language, theme, privacy } });\n};\n`\n : `${RA}${rr2}${settingsMeta}${mw2}\nexport const GET = async (req, res) => {\n // TODO: fetch user settings from DB\n res.json({ settings: { notifications: true, language: 'en', theme: 'system', privacy: 'public' } });\n};\n\nexport const PUT = async (req, res) => {\n const { notifications, language, theme, privacy } = req.body;\n // TODO: update user settings in DB\n res.json({ message: 'Settings updated', settings: { notifications, language, theme, privacy } });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'user', `settings.${ext}`), settingsContent);\n\n // account.ts\n const accountMeta = mkMeta(opts, 'Delete account (DELETE) or download personal data (GET).', `{ message: 'Account deleted' }`);\n const accountContent = ts\n ? `${RA}${rr2}import type { Request, Response } from 'express';\n${accountMeta}${mw2}\nexport const GET = async (req: Request, res: Response) => {\n // TODO: compile and return personal data export\n res.json({ data: { user: ${user}, exportedAt: new Date().toISOString() } });\n};\n\nexport const DELETE = async (req: Request, res: Response) => {\n const { password } = req.body;\n if (!password) return res.status(400).json({ error: 'password confirmation required' });\n // TODO: verify password, schedule account deletion\n res.json({ message: 'Account scheduled for deletion' });\n};\n`\n : `${RA}${rr2}${accountMeta}${mw2}\nexport const GET = async (req, res) => {\n // TODO: compile and return personal data export\n res.json({ data: { user: ${user}, exportedAt: new Date().toISOString() } });\n};\n\nexport const DELETE = async (req, res) => {\n const { password } = req.body;\n if (!password) return res.status(400).json({ error: 'password confirmation required' });\n // TODO: verify password, schedule account deletion\n res.json({ message: 'Account scheduled for deletion' });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'user', `account.${ext}`), accountContent);\n\n // dashboard.ts\n const dashMeta = mkMeta(opts, 'Personal dashboard: stats, recent activity, and quick actions.', `{ stats: {}, recentActivity: [], quickActions: [] }`);\n const dashContent = ts\n ? `${RA}${rr2}import type { Request, Response } from 'express';\n${dashMeta}${mw2}\nexport const GET = async (req: Request, res: Response) => {\n // TODO: aggregate personal stats and activity\n res.json({ stats: {}, recentActivity: [], quickActions: [] });\n};\n`\n : `${RA}${rr2}${dashMeta}${mw2}\nexport const GET = async (req, res) => {\n // TODO: aggregate personal stats and activity\n res.json({ stats: {}, recentActivity: [], quickActions: [] });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'user', `dashboard.${ext}`), dashContent);\n\n // activity.ts\n const actMeta = mkMeta(opts, 'Paginated activity history for the authenticated user.', `{ activities: [], total: 0, page: 1, limit: 20 }`);\n const actContent = ts\n ? `${RA}${rr2}import type { Request, Response } from 'express';\n${actMeta}${mw2}\nexport const GET = async (req: Request, res: Response) => {\n const { page = 1, limit = 20 } = req.query;\n // TODO: fetch paginated activity log\n res.json({ activities: [], total: 0, page: Number(page), limit: Number(limit) });\n};\n`\n : `${RA}${rr2}${actMeta}${mw2}\nexport const GET = async (req, res) => {\n const { page = 1, limit = 20 } = req.query;\n // TODO: fetch paginated activity log\n res.json({ activities: [], total: 0, page: Number(page), limit: Number(limit) });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'user', `activity.${ext}`), actContent);\n\n // notifications/index.ts\n const notifListMeta = mkMeta(opts, 'List notifications (GET) or mark all as read (POST).', `{ notifications: [], total: 0, unread: 0 }`);\n const notifListContent = ts\n ? `${RA}${rr3}import type { Request, Response } from 'express';\n${notifListMeta}${mw3}\nexport const GET = async (req: Request, res: Response) => {\n // TODO: fetch notifications for user\n res.json({ notifications: [], total: 0, unread: 0 });\n};\n\nexport const POST = async (req: Request, res: Response) => {\n // TODO: mark all notifications as read\n res.json({ message: 'All notifications marked as read' });\n};\n`\n : `${RA}${rr3}${notifListMeta}${mw3}\nexport const GET = async (req, res) => {\n // TODO: fetch notifications for user\n res.json({ notifications: [], total: 0, unread: 0 });\n};\n\nexport const POST = async (req, res) => {\n // TODO: mark all notifications as read\n res.json({ message: 'All notifications marked as read' });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'user', 'notifications', `index.${ext}`), notifListContent);\n\n // notifications/[id].ts\n const notifByIdContent = ts\n ? `${RA}${rr3}import type { Request, Response } from 'express';\n${mw3}\nexport const GET = async (req: Request, res: Response) => {\n const { id } = req.params;\n // TODO: fetch notification by id\n res.json({ notification: { id } });\n};\n\nexport const PATCH = async (req: Request, res: Response) => {\n const { id } = req.params;\n // TODO: mark notification as read\n res.json({ message: 'Notification marked as read', id });\n};\n\nexport const DELETE = async (req: Request, res: Response) => {\n const { id } = req.params;\n // TODO: delete notification\n res.json({ message: \\`Notification \\${id} deleted\\` });\n};\n`\n : `${RA}${rr3}${mw3}\nexport const GET = async (req, res) => {\n const { id } = req.params;\n // TODO: fetch notification by id\n res.json({ notification: { id } });\n};\n\nexport const PATCH = async (req, res) => {\n const { id } = req.params;\n // TODO: mark notification as read\n res.json({ message: 'Notification marked as read', id });\n};\n\nexport const DELETE = async (req, res) => {\n const { id } = req.params;\n // TODO: delete notification\n res.json({ message: \\`Notification \\${id} deleted\\` });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'user', 'notifications', `[id].${ext}`), notifByIdContent);\n\n // files/index.ts\n const filesListMeta = mkMeta(opts, 'List uploaded files with storage usage (GET) or upload a new file (POST).', `{ files: [], total: 0, storageUsed: 0 }`);\n const filesListContent = ts\n ? `${RA}${rr3}import type { Request, Response } from 'express';\n${filesListMeta}${mw3}\nexport const GET = async (req: Request, res: Response) => {\n // TODO: fetch user files and compute storage usage\n res.json({ files: [], total: 0, storageUsed: 0 });\n};\n\nexport const POST = async (req: Request, res: Response) => {\n // TODO: handle multipart upload, persist file record\n res.status(201).json({ message: 'File uploaded', file: { id: 'new-id' } });\n};\n`\n : `${RA}${rr3}${filesListMeta}${mw3}\nexport const GET = async (req, res) => {\n // TODO: fetch user files and compute storage usage\n res.json({ files: [], total: 0, storageUsed: 0 });\n};\n\nexport const POST = async (req, res) => {\n // TODO: handle multipart upload, persist file record\n res.status(201).json({ message: 'File uploaded', file: { id: 'new-id' } });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'user', 'files', `index.${ext}`), filesListContent);\n\n // files/[id].ts\n const fileByIdContent = ts\n ? `${RA}${rr3}import type { Request, Response } from 'express';\n${mw3}\nexport const GET = async (req: Request, res: Response) => {\n const { id } = req.params;\n // TODO: stream or redirect to file download/preview URL\n res.json({ file: { id, url: 'https://...' } });\n};\n\nexport const DELETE = async (req: Request, res: Response) => {\n const { id } = req.params;\n // TODO: delete file from storage and DB\n res.json({ message: \\`File \\${id} deleted\\` });\n};\n`\n : `${RA}${rr3}${mw3}\nexport const GET = async (req, res) => {\n const { id } = req.params;\n // TODO: stream or redirect to file download/preview URL\n res.json({ file: { id, url: 'https://...' } });\n};\n\nexport const DELETE = async (req, res) => {\n const { id } = req.params;\n // TODO: delete file from storage and DB\n res.json({ message: \\`File \\${id} deleted\\` });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'user', 'files', `[id].${ext}`), fileByIdContent);\n\n // favorites/index.ts\n const favListContent = ts\n ? `${RA}${rr3}import type { Request, Response } from 'express';\n${mw3}\nexport const GET = async (req: Request, res: Response) => {\n // TODO: fetch user favorites\n res.json({ favorites: [] });\n};\n\nexport const POST = async (req: Request, res: Response) => {\n const { entityId, entityType } = req.body;\n if (!entityId || !entityType) return res.status(400).json({ error: 'entityId and entityType are required' });\n // TODO: add to favorites\n res.status(201).json({ message: 'Added to favorites' });\n};\n`\n : `${RA}${rr3}${mw3}\nexport const GET = async (req, res) => {\n // TODO: fetch user favorites\n res.json({ favorites: [] });\n};\n\nexport const POST = async (req, res) => {\n const { entityId, entityType } = req.body;\n if (!entityId || !entityType) return res.status(400).json({ error: 'entityId and entityType are required' });\n // TODO: add to favorites\n res.status(201).json({ message: 'Added to favorites' });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'user', 'favorites', `index.${ext}`), favListContent);\n\n // favorites/[id].ts\n const favByIdContent = ts\n ? `${RA}${rr3}import type { Request, Response } from 'express';\n${mw3}\nexport const DELETE = async (req: Request, res: Response) => {\n const { id } = req.params;\n // TODO: remove from favorites\n res.json({ message: \\`Removed favorite \\${id}\\` });\n};\n`\n : `${RA}${rr3}${mw3}\nexport const DELETE = async (req, res) => {\n const { id } = req.params;\n // TODO: remove from favorites\n res.json({ message: \\`Removed favorite \\${id}\\` });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'user', 'favorites', `[id].${ext}`), favByIdContent);\n\n // bookmarks/index.ts\n const bkListContent = ts\n ? `${RA}${rr3}import type { Request, Response } from 'express';\n${mw3}\nexport const GET = async (req: Request, res: Response) => {\n // TODO: fetch user bookmarks\n res.json({ bookmarks: [] });\n};\n\nexport const POST = async (req: Request, res: Response) => {\n const { url, title } = req.body;\n if (!url) return res.status(400).json({ error: 'url is required' });\n // TODO: save bookmark\n res.status(201).json({ message: 'Bookmark saved' });\n};\n`\n : `${RA}${rr3}${mw3}\nexport const GET = async (req, res) => {\n // TODO: fetch user bookmarks\n res.json({ bookmarks: [] });\n};\n\nexport const POST = async (req, res) => {\n const { url, title } = req.body;\n if (!url) return res.status(400).json({ error: 'url is required' });\n // TODO: save bookmark\n res.status(201).json({ message: 'Bookmark saved' });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'user', 'bookmarks', `index.${ext}`), bkListContent);\n\n // bookmarks/[id].ts\n const bkByIdContent = ts\n ? `${RA}${rr3}import type { Request, Response } from 'express';\n${mw3}\nexport const DELETE = async (req: Request, res: Response) => {\n const { id } = req.params;\n // TODO: delete bookmark\n res.json({ message: \\`Bookmark \\${id} removed\\` });\n};\n`\n : `${RA}${rr3}${mw3}\nexport const DELETE = async (req, res) => {\n const { id } = req.params;\n // TODO: delete bookmark\n res.json({ message: \\`Bookmark \\${id} removed\\` });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'user', 'bookmarks', `[id].${ext}`), bkByIdContent);\n\n // search.ts\n const searchMeta = mkMeta(opts, 'Search with filters, sort, and pagination.', `{ results: [], total: 0, page: 1, limit: 20 }`);\n const searchContent = ts\n ? `${RA}${rr2}import type { Request, Response } from 'express';\n${searchMeta}${mw2}\nexport const GET = async (req: Request, res: Response) => {\n const { q, filter, sort, page = 1, limit = 20 } = req.query;\n // TODO: implement search\n res.json({ results: [], total: 0, page: Number(page), limit: Number(limit) });\n};\n`\n : `${RA}${rr2}${searchMeta}${mw2}\nexport const GET = async (req, res) => {\n const { q, filter, sort, page = 1, limit = 20 } = req.query;\n // TODO: implement search\n res.json({ results: [], total: 0, page: Number(page), limit: Number(limit) });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'user', `search.${ext}`), searchContent);\n\n // api-keys/index.ts\n const akListMeta = mkMeta(opts, 'List API keys (GET) or create a new one (POST).', `{ apiKeys: [] }`);\n const akListContent = ts\n ? `${RA}${rr3}import type { Request, Response } from 'express';\n${akListMeta}${mw3}\nexport const GET = async (req: Request, res: Response) => {\n // TODO: fetch api keys for user\n res.json({ apiKeys: [] });\n};\n\nexport const POST = async (req: Request, res: Response) => {\n const { name } = req.body;\n if (!name) return res.status(400).json({ error: 'name is required' });\n // TODO: generate and store API key\n res.status(201).json({ message: 'API key created', key: 'efc_...' });\n};\n`\n : `${RA}${rr3}${akListMeta}${mw3}\nexport const GET = async (req, res) => {\n // TODO: fetch api keys for user\n res.json({ apiKeys: [] });\n};\n\nexport const POST = async (req, res) => {\n const { name } = req.body;\n if (!name) return res.status(400).json({ error: 'name is required' });\n // TODO: generate and store API key\n res.status(201).json({ message: 'API key created', key: 'efc_...' });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'user', 'api-keys', `index.${ext}`), akListContent);\n\n // api-keys/[id].ts\n const akByIdContent = ts\n ? `${RA}${rr3}import type { Request, Response } from 'express';\n${mw3}\nexport const DELETE = async (req: Request, res: Response) => {\n const { id } = req.params;\n // TODO: revoke and delete API key\n res.json({ message: \\`API key \\${id} revoked\\` });\n};\n`\n : `${RA}${rr3}${mw3}\nexport const DELETE = async (req, res) => {\n const { id } = req.params;\n // TODO: revoke and delete API key\n res.json({ message: \\`API key \\${id} revoked\\` });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'user', 'api-keys', `[id].${ext}`), akByIdContent);\n}\n\nasync function writeUserBillingRoutes(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const ts = opts.language === 'typescript';\n // user/billing/* = 3 levels, user/billing/subdir/* = 4 levels\n const rr3 = opts.rbac ? `import { requireRole } from '../../../middleware/requireRole.js';\\n` : '';\n const rr4 = opts.rbac ? `import { requireRole } from '../../../../middleware/requireRole.js';\\n` : '';\n const mw3 = opts.rbac\n ? `export const middlewares = [requireAuth, requireRole('user', 'admin')];\\n`\n : `export const middlewares = [requireAuth];\\n`;\n const mw4 = mw3;\n const RA = `import { requireAuth } from 'express-file-cluster/auth';\\n`;\n\n // billing/plans.ts\n const plansMeta = mkMeta(opts, 'List all available subscription plans.', `{ plans: [] }`);\n const plansContent = ts\n ? `${RA}${rr3}import type { Request, Response } from 'express';\n${plansMeta}${mw3}\nexport const GET = async (_req: Request, res: Response) => {\n // TODO: fetch active plans from DB\n res.json({ plans: [] });\n};\n`\n : `${RA}${rr3}${plansMeta}${mw3}\nexport const GET = async (_req, res) => {\n // TODO: fetch active plans from DB\n res.json({ plans: [] });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'user', 'billing', `plans.${ext}`), plansContent);\n\n // billing/subscription.ts\n const subMeta = mkMeta(opts, 'Get current subscription (GET), subscribe to a plan (POST), or cancel (DELETE).', `{ subscription: null }`);\n const subContent = ts\n ? `${RA}${rr3}import type { Request, Response } from 'express';\n${subMeta}${mw3}\nexport const GET = async (req: Request, res: Response) => {\n // TODO: fetch current subscription for user\n res.json({ subscription: null });\n};\n\nexport const POST = async (req: Request, res: Response) => {\n const { planId } = req.body;\n if (!planId) return res.status(400).json({ error: 'planId is required' });\n // TODO: create subscription via payment gateway\n res.status(201).json({ message: 'Subscribed', subscription: { planId } });\n};\n\nexport const DELETE = async (req: Request, res: Response) => {\n // TODO: cancel subscription at period end\n res.json({ message: 'Subscription cancelled' });\n};\n`\n : `${RA}${rr3}${subMeta}${mw3}\nexport const GET = async (req, res) => {\n // TODO: fetch current subscription for user\n res.json({ subscription: null });\n};\n\nexport const POST = async (req, res) => {\n const { planId } = req.body;\n if (!planId) return res.status(400).json({ error: 'planId is required' });\n // TODO: create subscription via payment gateway\n res.status(201).json({ message: 'Subscribed', subscription: { planId } });\n};\n\nexport const DELETE = async (req, res) => {\n // TODO: cancel subscription at period end\n res.json({ message: 'Subscription cancelled' });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'user', 'billing', `subscription.${ext}`), subContent);\n\n // billing/payment-methods/index.ts\n const pmListContent = ts\n ? `${RA}${rr4}import type { Request, Response } from 'express';\n${mw4}\nexport const GET = async (req: Request, res: Response) => {\n // TODO: fetch payment methods for user\n res.json({ paymentMethods: [] });\n};\n\nexport const POST = async (req: Request, res: Response) => {\n const { token } = req.body;\n if (!token) return res.status(400).json({ error: 'payment token is required' });\n // TODO: attach payment method via payment gateway\n res.status(201).json({ message: 'Payment method added' });\n};\n`\n : `${RA}${rr4}${mw4}\nexport const GET = async (req, res) => {\n // TODO: fetch payment methods for user\n res.json({ paymentMethods: [] });\n};\n\nexport const POST = async (req, res) => {\n const { token } = req.body;\n if (!token) return res.status(400).json({ error: 'payment token is required' });\n // TODO: attach payment method via payment gateway\n res.status(201).json({ message: 'Payment method added' });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'user', 'billing', 'payment-methods', `index.${ext}`), pmListContent);\n\n // billing/payment-methods/[id].ts\n const pmByIdContent = ts\n ? `${RA}${rr4}import type { Request, Response } from 'express';\n${mw4}\nexport const DELETE = async (req: Request, res: Response) => {\n const { id } = req.params;\n // TODO: detach payment method from payment gateway\n res.json({ message: \\`Payment method \\${id} removed\\` });\n};\n`\n : `${RA}${rr4}${mw4}\nexport const DELETE = async (req, res) => {\n const { id } = req.params;\n // TODO: detach payment method from payment gateway\n res.json({ message: \\`Payment method \\${id} removed\\` });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'user', 'billing', 'payment-methods', `[id].${ext}`), pmByIdContent);\n\n // billing/invoices/index.ts\n const invListMeta = mkMeta(opts, 'List all invoices for the authenticated user.', `{ invoices: [], total: 0 }`);\n const invListContent = ts\n ? `${RA}${rr4}import type { Request, Response } from 'express';\n${invListMeta}${mw4}\nexport const GET = async (req: Request, res: Response) => {\n // TODO: fetch invoices for user\n res.json({ invoices: [], total: 0 });\n};\n`\n : `${RA}${rr4}${invListMeta}${mw4}\nexport const GET = async (req, res) => {\n // TODO: fetch invoices for user\n res.json({ invoices: [], total: 0 });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'user', 'billing', 'invoices', `index.${ext}`), invListContent);\n\n // billing/invoices/[id].ts\n const invByIdContent = ts\n ? `${RA}${rr4}import type { Request, Response } from 'express';\n${mw4}\nexport const GET = async (req: Request, res: Response) => {\n const { id } = req.params;\n // TODO: return invoice PDF URL or inline data\n res.json({ invoice: { id, downloadUrl: 'https://...' } });\n};\n`\n : `${RA}${rr4}${mw4}\nexport const GET = async (req, res) => {\n const { id } = req.params;\n // TODO: return invoice PDF URL or inline data\n res.json({ invoice: { id, downloadUrl: 'https://...' } });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'user', 'billing', 'invoices', `[id].${ext}`), invByIdContent);\n}\n\nasync function writeSupportRoutes(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const ts = opts.language === 'typescript';\n // support/tickets/* = 3 levels\n const rr3 = opts.rbac ? `import { requireRole } from '../../../middleware/requireRole.js';\\n` : '';\n const mw3 = opts.rbac\n ? `export const middlewares = [requireAuth, requireRole('user', 'admin')];\\n`\n : `export const middlewares = [requireAuth];\\n`;\n const RA = `import { requireAuth } from 'express-file-cluster/auth';\\n`;\n\n // support/tickets/index.ts\n const ticketListMeta = mkMeta(opts, 'List own support tickets (GET) or create a new one (POST).', `{ tickets: [], total: 0 }`, `{ subject: 'Issue with login', message: 'I cannot log in', priority: 'normal' }`);\n const ticketListContent = ts\n ? `${RA}${rr3}import type { Request, Response } from 'express';\n${ticketListMeta}${mw3}\nexport const GET = async (req: Request, res: Response) => {\n // TODO: fetch tickets for current user\n res.json({ tickets: [], total: 0 });\n};\n\nexport const POST = async (req: Request, res: Response) => {\n const { subject, message, priority } = req.body;\n if (!subject || !message) return res.status(400).json({ error: 'subject and message are required' });\n // TODO: create support ticket in DB\n res.status(201).json({ message: 'Ticket created', ticket: { id: 'new-id', subject, status: 'open' } });\n};\n`\n : `${RA}${rr3}${ticketListMeta}${mw3}\nexport const GET = async (req, res) => {\n // TODO: fetch tickets for current user\n res.json({ tickets: [], total: 0 });\n};\n\nexport const POST = async (req, res) => {\n const { subject, message, priority } = req.body;\n if (!subject || !message) return res.status(400).json({ error: 'subject and message are required' });\n // TODO: create support ticket in DB\n res.status(201).json({ message: 'Ticket created', ticket: { id: 'new-id', subject, status: 'open' } });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'support', 'tickets', `index.${ext}`), ticketListContent);\n\n // support/tickets/[id].ts\n const ticketByIdMeta = mkMeta(opts, 'View a support ticket (GET) or add a reply / close it (PUT).', `{ ticket: { id: '1', subject: 'Issue', status: 'open', replies: [] } }`);\n const ticketByIdContent = ts\n ? `${RA}${rr3}import type { Request, Response } from 'express';\n${ticketByIdMeta}${mw3}\nexport const GET = async (req: Request, res: Response) => {\n const { id } = req.params;\n // TODO: fetch ticket by id, verify ownership\n res.json({ ticket: { id, subject: '', status: 'open', replies: [] } });\n};\n\nexport const PUT = async (req: Request, res: Response) => {\n const { id } = req.params;\n const { reply, status } = req.body;\n // TODO: add reply or update status\n res.json({ message: 'Ticket updated', ticket: { id, status: status ?? 'open' } });\n};\n`\n : `${RA}${rr3}${ticketByIdMeta}${mw3}\nexport const GET = async (req, res) => {\n const { id } = req.params;\n // TODO: fetch ticket by id, verify ownership\n res.json({ ticket: { id, subject: '', status: 'open', replies: [] } });\n};\n\nexport const PUT = async (req, res) => {\n const { id } = req.params;\n const { reply, status } = req.body;\n // TODO: add reply or update status\n res.json({ message: 'Ticket updated', ticket: { id, status: status ?? 'open' } });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'support', 'tickets', `[id].${ext}`), ticketByIdContent);\n}\n\nasync function writeAdminExtendedRoutes(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const ts = opts.language === 'typescript';\n // depth: admin/subdir/* = 3, admin/subdir/subdir/* = 4, admin/users/[id]/* = 4\n const rr3 = opts.rbac ? `import { requireRole } from '../../../middleware/requireRole.js';\\n` : '';\n const rr4 = opts.rbac ? `import { requireRole } from '../../../../middleware/requireRole.js';\\n` : '';\n const mwAdmin3 = opts.rbac\n ? `export const middlewares = [requireAuth, requireRole('admin')];\\n`\n : `export const middlewares = [requireAuth];\\n`;\n const mwAdmin4 = mwAdmin3;\n const roleGuard = opts.rbac\n ? ''\n : ts\n ? ` const user = (req as any).user;\\n if (user?.role !== 'admin') return res.status(403).json({ error: 'Forbidden' });\\n`\n : ` const user = req.user;\\n if (user?.role !== 'admin') return res.status(403).json({ error: 'Forbidden' });\\n`;\n const RA = `import { requireAuth } from 'express-file-cluster/auth';\\n`;\n\n // ── Analytics ──────────────────────────────────────────────────────────\n\n // admin/analytics/index.ts\n const analyticsOverviewMeta = mkMeta(opts, 'Analytics overview: users, revenue, traffic.', `{ users: {}, revenue: {}, traffic: {} }`);\n const analyticsOverviewContent = ts\n ? `${RA}${rr3}import type { Request, Response } from 'express';\n${analyticsOverviewMeta}${mwAdmin3}\nexport const GET = async (req: Request, res: Response) => {\n${roleGuard} // TODO: aggregate analytics overview\n res.json({ users: {}, revenue: {}, traffic: {} });\n};\n`\n : `${RA}${rr3}${analyticsOverviewMeta}${mwAdmin3}\nexport const GET = async (req, res) => {\n${roleGuard} // TODO: aggregate analytics overview\n res.json({ users: {}, revenue: {}, traffic: {} });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'analytics', `index.${ext}`), analyticsOverviewContent);\n\n const analyticsUsersMeta = mkMeta(opts, 'User analytics: registrations, active users, churn.', `{ registrations: [], activeUsers: 0, churn: 0 }`);\n const analyticsUsersContent = ts\n ? `${RA}${rr3}import type { Request, Response } from 'express';\n${analyticsUsersMeta}${mwAdmin3}\nexport const GET = async (req: Request, res: Response) => {\n${roleGuard} const { period = '30d' } = req.query;\n // TODO: fetch user analytics for period\n res.json({ registrations: [], activeUsers: 0, churn: 0, period });\n};\n`\n : `${RA}${rr3}${analyticsUsersMeta}${mwAdmin3}\nexport const GET = async (req, res) => {\n${roleGuard} const { period = '30d' } = req.query;\n // TODO: fetch user analytics for period\n res.json({ registrations: [], activeUsers: 0, churn: 0, period });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'analytics', `users.${ext}`), analyticsUsersContent);\n\n const analyticsRevenueMeta = mkMeta(opts, 'Revenue analytics: MRR, ARR, payment history.', `{ mrr: 0, arr: 0, history: [] }`);\n const analyticsRevenueContent = ts\n ? `${RA}${rr3}import type { Request, Response } from 'express';\n${analyticsRevenueMeta}${mwAdmin3}\nexport const GET = async (req: Request, res: Response) => {\n${roleGuard} const { period = '30d' } = req.query;\n // TODO: fetch revenue analytics for period\n res.json({ mrr: 0, arr: 0, history: [], period });\n};\n`\n : `${RA}${rr3}${analyticsRevenueMeta}${mwAdmin3}\nexport const GET = async (req, res) => {\n${roleGuard} const { period = '30d' } = req.query;\n // TODO: fetch revenue analytics for period\n res.json({ mrr: 0, arr: 0, history: [], period });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'analytics', `revenue.${ext}`), analyticsRevenueContent);\n\n const analyticsTrafficMeta = mkMeta(opts, 'Traffic analytics: page views, devices, countries.', `{ pageViews: 0, devices: {}, countries: {} }`);\n const analyticsTrafficContent = ts\n ? `${RA}${rr3}import type { Request, Response } from 'express';\n${analyticsTrafficMeta}${mwAdmin3}\nexport const GET = async (req: Request, res: Response) => {\n${roleGuard} const { period = '30d' } = req.query;\n // TODO: fetch traffic analytics for period\n res.json({ pageViews: 0, devices: {}, countries: {}, period });\n};\n`\n : `${RA}${rr3}${analyticsTrafficMeta}${mwAdmin3}\nexport const GET = async (req, res) => {\n${roleGuard} const { period = '30d' } = req.query;\n // TODO: fetch traffic analytics for period\n res.json({ pageViews: 0, devices: {}, countries: {}, period });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'analytics', `traffic.${ext}`), analyticsTrafficContent);\n\n // ── User Actions ──────────────────────────────────────────────────────\n\n // admin/users/[id]/suspend.ts\n const suspendContent = ts\n ? `${RA}${rr4}import type { Request, Response } from 'express';\n${mwAdmin4}\nexport const POST = async (req: Request, res: Response) => {\n${roleGuard} const { id } = req.params;\n const { reason } = req.body;\n // TODO: set user.isActive = false, log audit event\n res.json({ message: \\`User \\${id} suspended\\`, reason });\n};\n`\n : `${RA}${rr4}${mwAdmin4}\nexport const POST = async (req, res) => {\n${roleGuard} const { id } = req.params;\n const { reason } = req.body;\n // TODO: set user.isActive = false, log audit event\n res.json({ message: \\`User \\${id} suspended\\`, reason });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'users', '[id]', `suspend.${ext}`), suspendContent);\n\n // admin/users/[id]/activate.ts\n const activateContent = ts\n ? `${RA}${rr4}import type { Request, Response } from 'express';\n${mwAdmin4}\nexport const POST = async (req: Request, res: Response) => {\n${roleGuard} const { id } = req.params;\n // TODO: set user.isActive = true, log audit event\n res.json({ message: \\`User \\${id} activated\\` });\n};\n`\n : `${RA}${rr4}${mwAdmin4}\nexport const POST = async (req, res) => {\n${roleGuard} const { id } = req.params;\n // TODO: set user.isActive = true, log audit event\n res.json({ message: \\`User \\${id} activated\\` });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'users', '[id]', `activate.${ext}`), activateContent);\n\n // admin/users/[id]/verify.ts\n const verifyUserContent = ts\n ? `${RA}${rr4}import type { Request, Response } from 'express';\n${mwAdmin4}\nexport const POST = async (req: Request, res: Response) => {\n${roleGuard} const { id } = req.params;\n // TODO: set user.isVerified = true\n res.json({ message: \\`User \\${id} verified\\` });\n};\n`\n : `${RA}${rr4}${mwAdmin4}\nexport const POST = async (req, res) => {\n${roleGuard} const { id } = req.params;\n // TODO: set user.isVerified = true\n res.json({ message: \\`User \\${id} verified\\` });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'users', '[id]', `verify.${ext}`), verifyUserContent);\n\n // admin/users/export.ts\n const exportMeta = mkMeta(opts, 'Export all users as CSV.', `{ csv: '...' }`);\n const exportContent = ts\n ? `${RA}${rr3}import type { Request, Response } from 'express';\n${exportMeta}${mwAdmin3}\nexport const GET = async (_req: Request, res: Response) => {\n${roleGuard} // TODO: generate CSV of all users and stream response\n res.setHeader('Content-Type', 'text/csv');\n res.setHeader('Content-Disposition', 'attachment; filename=\"users.csv\"');\n res.send('id,name,email,role,createdAt\\\\n');\n};\n`\n : `${RA}${rr3}${exportMeta}${mwAdmin3}\nexport const GET = async (_req, res) => {\n${roleGuard} // TODO: generate CSV of all users and stream response\n res.setHeader('Content-Type', 'text/csv');\n res.setHeader('Content-Disposition', 'attachment; filename=\"users.csv\"');\n res.send('id,name,email,role,createdAt\\\\n');\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'users', `export.${ext}`), exportContent);\n\n // ── Admins ────────────────────────────────────────────────────────────\n\n // admin/admins/index.ts\n const adminsListMeta = mkMeta(opts, 'List all admins (GET) or create a new admin (POST).', `{ admins: [], total: 0 }`);\n const adminsListContent = ts\n ? `${RA}${rr3}import type { Request, Response } from 'express';\n${adminsListMeta}${mwAdmin3}\nexport const GET = async (_req: Request, res: Response) => {\n${roleGuard} // TODO: fetch admins from DB\n res.json({ admins: [], total: 0 });\n};\n\nexport const POST = async (req: Request, res: Response) => {\n${roleGuard} const { name, email, role } = req.body;\n if (!name || !email) return res.status(400).json({ error: 'name and email are required' });\n // TODO: create admin account\n res.status(201).json({ message: 'Admin created', admin: { id: 'new-id', name, email, role: role ?? 'admin' } });\n};\n`\n : `${RA}${rr3}${adminsListMeta}${mwAdmin3}\nexport const GET = async (_req, res) => {\n${roleGuard} // TODO: fetch admins from DB\n res.json({ admins: [], total: 0 });\n};\n\nexport const POST = async (req, res) => {\n${roleGuard} const { name, email, role } = req.body;\n if (!name || !email) return res.status(400).json({ error: 'name and email are required' });\n // TODO: create admin account\n res.status(201).json({ message: 'Admin created', admin: { id: 'new-id', name, email, role: role ?? 'admin' } });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'admins', `index.${ext}`), adminsListContent);\n\n // admin/admins/[id].ts\n const adminByIdContent = ts\n ? `${RA}${rr3}import type { Request, Response } from 'express';\n${mwAdmin3}\nexport const GET = async (req: Request, res: Response) => {\n${roleGuard} const { id } = req.params;\n // TODO: fetch admin by id\n res.json({ admin: { id } });\n};\n\nexport const PUT = async (req: Request, res: Response) => {\n${roleGuard} const { id } = req.params;\n // TODO: update admin record\n res.json({ message: 'Admin updated', admin: { id, ...req.body } });\n};\n\nexport const DELETE = async (req: Request, res: Response) => {\n${roleGuard} const { id } = req.params;\n // TODO: delete admin\n res.json({ message: \\`Admin \\${id} deleted\\` });\n};\n`\n : `${RA}${rr3}${mwAdmin3}\nexport const GET = async (req, res) => {\n${roleGuard} const { id } = req.params;\n // TODO: fetch admin by id\n res.json({ admin: { id } });\n};\n\nexport const PUT = async (req, res) => {\n${roleGuard} const { id } = req.params;\n // TODO: update admin record\n res.json({ message: 'Admin updated', admin: { id, ...req.body } });\n};\n\nexport const DELETE = async (req, res) => {\n${roleGuard} const { id } = req.params;\n // TODO: delete admin\n res.json({ message: \\`Admin \\${id} deleted\\` });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'admins', `[id].${ext}`), adminByIdContent);\n\n // ── Roles (rbac only) ─────────────────────────────────────────────────\n\n if (opts.rbac) {\n const rolesListContent = ts\n ? `${RA}${rr3}import type { Request, Response } from 'express';\n${mwAdmin3}\nexport const GET = async (_req: Request, res: Response) => {\n // TODO: fetch all roles\n res.json({ roles: [] });\n};\n\nexport const POST = async (req: Request, res: Response) => {\n const { name, description, permissions } = req.body;\n if (!name) return res.status(400).json({ error: 'name is required' });\n // TODO: create role\n res.status(201).json({ message: 'Role created', role: { id: 'new-id', name, permissions: permissions ?? [] } });\n};\n`\n : `${RA}${rr3}${mwAdmin3}\nexport const GET = async (_req, res) => {\n // TODO: fetch all roles\n res.json({ roles: [] });\n};\n\nexport const POST = async (req, res) => {\n const { name, description, permissions } = req.body;\n if (!name) return res.status(400).json({ error: 'name is required' });\n // TODO: create role\n res.status(201).json({ message: 'Role created', role: { id: 'new-id', name, permissions: permissions ?? [] } });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'roles', `index.${ext}`), rolesListContent);\n\n const roleByIdContent = ts\n ? `${RA}${rr3}import type { Request, Response } from 'express';\n${mwAdmin3}\nexport const GET = async (req: Request, res: Response) => {\n const { id } = req.params;\n // TODO: fetch role by id\n res.json({ role: { id } });\n};\n\nexport const PUT = async (req: Request, res: Response) => {\n const { id } = req.params;\n // TODO: update role\n res.json({ message: 'Role updated', role: { id, ...req.body } });\n};\n\nexport const DELETE = async (req: Request, res: Response) => {\n const { id } = req.params;\n // TODO: delete role\n res.json({ message: \\`Role \\${id} deleted\\` });\n};\n`\n : `${RA}${rr3}${mwAdmin3}\nexport const GET = async (req, res) => {\n const { id } = req.params;\n // TODO: fetch role by id\n res.json({ role: { id } });\n};\n\nexport const PUT = async (req, res) => {\n const { id } = req.params;\n // TODO: update role\n res.json({ message: 'Role updated', role: { id, ...req.body } });\n};\n\nexport const DELETE = async (req, res) => {\n const { id } = req.params;\n // TODO: delete role\n res.json({ message: \\`Role \\${id} deleted\\` });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'roles', `[id].${ext}`), roleByIdContent);\n }\n\n // ── Notifications ─────────────────────────────────────────────────────\n\n // admin/notifications/index.ts\n const adminNotifContent = ts\n ? `${RA}${rr3}import type { Request, Response } from 'express';\n${mwAdmin3}\nexport const GET = async (_req: Request, res: Response) => {\n${roleGuard} // TODO: fetch sent notifications\n res.json({ notifications: [], total: 0 });\n};\n\nexport const POST = async (req: Request, res: Response) => {\n${roleGuard} const { userId, title, message, type } = req.body;\n if (!userId || !title || !message) return res.status(400).json({ error: 'userId, title and message are required' });\n // TODO: create and send notification to user\n res.status(201).json({ message: 'Notification sent' });\n};\n`\n : `${RA}${rr3}${mwAdmin3}\nexport const GET = async (_req, res) => {\n${roleGuard} // TODO: fetch sent notifications\n res.json({ notifications: [], total: 0 });\n};\n\nexport const POST = async (req, res) => {\n${roleGuard} const { userId, title, message, type } = req.body;\n if (!userId || !title || !message) return res.status(400).json({ error: 'userId, title and message are required' });\n // TODO: create and send notification to user\n res.status(201).json({ message: 'Notification sent' });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'notifications', `index.${ext}`), adminNotifContent);\n\n // admin/notifications/broadcast.ts\n const broadcastMeta = mkMeta(opts, 'Broadcast a notification to all users.', `{ message: 'Broadcast sent', count: 0 }`, `{ title: 'Announcement', message: 'Hello everyone!', type: 'info' }`);\n const broadcastContent = ts\n ? `${RA}${rr3}import type { Request, Response } from 'express';\n${broadcastMeta}${mwAdmin3}\nexport const POST = async (req: Request, res: Response) => {\n${roleGuard} const { title, message, type } = req.body;\n if (!title || !message) return res.status(400).json({ error: 'title and message are required' });\n // TODO: send notification to all users\n res.json({ message: 'Broadcast sent', count: 0 });\n};\n`\n : `${RA}${rr3}${broadcastMeta}${mwAdmin3}\nexport const POST = async (req, res) => {\n${roleGuard} const { title, message, type } = req.body;\n if (!title || !message) return res.status(400).json({ error: 'title and message are required' });\n // TODO: send notification to all users\n res.json({ message: 'Broadcast sent', count: 0 });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'notifications', `broadcast.${ext}`), broadcastContent);\n\n // ── Logs ──────────────────────────────────────────────────────────────\n\n const mkLogContent = (label: string) => {\n const meta = mkMeta(opts, `Paginated ${label} log entries.`, `{ logs: [], total: 0, page: 1, limit: 50 }`);\n return ts\n ? `${RA}${rr3}import type { Request, Response } from 'express';\n${meta}${mwAdmin3}\nexport const GET = async (req: Request, res: Response) => {\n${roleGuard} const { page = 1, limit = 50 } = req.query;\n // TODO: fetch ${label} logs with pagination\n res.json({ logs: [], total: 0, page: Number(page), limit: Number(limit) });\n};\n`\n : `${RA}${rr3}${meta}${mwAdmin3}\nexport const GET = async (req, res) => {\n${roleGuard} const { page = 1, limit = 50 } = req.query;\n // TODO: fetch ${label} logs with pagination\n res.json({ logs: [], total: 0, page: Number(page), limit: Number(limit) });\n};\n`;\n };\n\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'logs', `audit.${ext}`), mkLogContent('audit'));\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'logs', `activity.${ext}`), mkLogContent('activity'));\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'logs', `security.${ext}`), mkLogContent('security'));\n\n // ── Settings & System ─────────────────────────────────────────────────\n\n // admin/settings/index.ts\n const settingsMeta = mkMeta(opts, 'Get or update system-wide settings.', `{ settings: {} }`);\n const settingsContent = ts\n ? `${RA}${rr3}import type { Request, Response } from 'express';\n${settingsMeta}${mwAdmin3}\nexport const GET = async (_req: Request, res: Response) => {\n${roleGuard} // TODO: fetch system settings from DB\n res.json({ settings: {} });\n};\n\nexport const PUT = async (req: Request, res: Response) => {\n${roleGuard} // TODO: update system settings\n res.json({ message: 'Settings updated', settings: req.body });\n};\n`\n : `${RA}${rr3}${settingsMeta}${mwAdmin3}\nexport const GET = async (_req, res) => {\n${roleGuard} // TODO: fetch system settings from DB\n res.json({ settings: {} });\n};\n\nexport const PUT = async (req, res) => {\n${roleGuard} // TODO: update system settings\n res.json({ message: 'Settings updated', settings: req.body });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'settings', `index.${ext}`), settingsContent);\n\n // admin/system/health.ts\n const healthMeta = mkMeta(opts, 'System health check: DB, queue, cache status.', `{ status: 'ok', db: 'ok', queue: 'ok' }`);\n const healthContent = ts\n ? `${RA}${rr3}import type { Request, Response } from 'express';\n${healthMeta}${mwAdmin3}\nexport const GET = async (_req: Request, res: Response) => {\n${roleGuard} // TODO: check DB connection, queue, cache health\n res.json({ status: 'ok', db: 'ok', queue: 'ok', uptime: process.uptime() });\n};\n`\n : `${RA}${rr3}${healthMeta}${mwAdmin3}\nexport const GET = async (_req, res) => {\n${roleGuard} // TODO: check DB connection, queue, cache health\n res.json({ status: 'ok', db: 'ok', queue: 'ok', uptime: process.uptime() });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'system', `health.${ext}`), healthContent);\n\n // admin/system/cache.ts\n const cacheMeta = mkMeta(opts, 'Flush the application cache.', `{ message: 'Cache cleared' }`);\n const cacheContent = ts\n ? `${RA}${rr3}import type { Request, Response } from 'express';\n${cacheMeta}${mwAdmin3}\nexport const DELETE = async (_req: Request, res: Response) => {\n${roleGuard} // TODO: flush Redis or in-memory cache\n res.json({ message: 'Cache cleared' });\n};\n`\n : `${RA}${rr3}${cacheMeta}${mwAdmin3}\nexport const DELETE = async (_req, res) => {\n${roleGuard} // TODO: flush Redis or in-memory cache\n res.json({ message: 'Cache cleared' });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'system', `cache.${ext}`), cacheContent);\n\n // ── Support Tickets (admin view) ──────────────────────────────────────\n\n // admin/tickets/index.ts\n const adminTicketsListMeta = mkMeta(opts, 'List all support tickets with filters.', `{ tickets: [], total: 0 }`);\n const adminTicketsListContent = ts\n ? `${RA}${rr3}import type { Request, Response } from 'express';\n${adminTicketsListMeta}${mwAdmin3}\nexport const GET = async (req: Request, res: Response) => {\n${roleGuard} const { status, priority, page = 1, limit = 20 } = req.query;\n // TODO: fetch all tickets with filters\n res.json({ tickets: [], total: 0, page: Number(page), limit: Number(limit) });\n};\n`\n : `${RA}${rr3}${adminTicketsListMeta}${mwAdmin3}\nexport const GET = async (req, res) => {\n${roleGuard} const { status, priority, page = 1, limit = 20 } = req.query;\n // TODO: fetch all tickets with filters\n res.json({ tickets: [], total: 0, page: Number(page), limit: Number(limit) });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'tickets', `index.${ext}`), adminTicketsListContent);\n\n // admin/tickets/[id].ts\n const adminTicketByIdContent = ts\n ? `${RA}${rr3}import type { Request, Response } from 'express';\n${mwAdmin3}\nexport const GET = async (req: Request, res: Response) => {\n${roleGuard} const { id } = req.params;\n // TODO: fetch ticket by id\n res.json({ ticket: { id } });\n};\n\nexport const PUT = async (req: Request, res: Response) => {\n${roleGuard} const { id } = req.params;\n const { reply, status, assignedTo } = req.body;\n // TODO: update ticket (assign, change status, add reply)\n res.json({ message: 'Ticket updated', ticket: { id, status, assignedTo } });\n};\n`\n : `${RA}${rr3}${mwAdmin3}\nexport const GET = async (req, res) => {\n${roleGuard} const { id } = req.params;\n // TODO: fetch ticket by id\n res.json({ ticket: { id } });\n};\n\nexport const PUT = async (req, res) => {\n${roleGuard} const { id } = req.params;\n const { reply, status, assignedTo } = req.body;\n // TODO: update ticket (assign, change status, add reply)\n res.json({ message: 'Ticket updated', ticket: { id, status, assignedTo } });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'tickets', `[id].${ext}`), adminTicketByIdContent);\n\n // ── Content ───────────────────────────────────────────────────────────\n\n const mkContentCrud = (\n name: string,\n namePlural: string,\n dir: string[],\n createFields: string,\n ) => {\n const listMeta = mkMeta(opts, `List ${namePlural} (GET) or create a new ${name} (POST).`, `{ ${namePlural}: [], total: 0 }`);\n const listContent = ts\n ? `${RA}${rr4}import type { Request, Response } from 'express';\n${listMeta}${mwAdmin4}\nexport const GET = async (_req: Request, res: Response) => {\n${roleGuard} // TODO: fetch ${namePlural}\n res.json({ ${namePlural}: [], total: 0 });\n};\n\nexport const POST = async (req: Request, res: Response) => {\n${roleGuard} const { ${createFields} } = req.body;\n // TODO: create ${name}\n res.status(201).json({ message: '${name} created', ${name.toLowerCase()}: { id: 'new-id', ${createFields.split(', ')[0]} } });\n};\n`\n : `${RA}${rr4}${listMeta}${mwAdmin4}\nexport const GET = async (_req, res) => {\n${roleGuard} // TODO: fetch ${namePlural}\n res.json({ ${namePlural}: [], total: 0 });\n};\n\nexport const POST = async (req, res) => {\n${roleGuard} const { ${createFields} } = req.body;\n // TODO: create ${name}\n res.status(201).json({ message: '${name} created', ${name.toLowerCase()}: { id: 'new-id' } });\n};\n`;\n const byIdContent = ts\n ? `${RA}${rr4}import type { Request, Response } from 'express';\n${mwAdmin4}\nexport const GET = async (req: Request, res: Response) => {\n${roleGuard} const { id } = req.params;\n // TODO: fetch ${name} by id\n res.json({ ${name.toLowerCase()}: { id } });\n};\n\nexport const PUT = async (req: Request, res: Response) => {\n${roleGuard} const { id } = req.params;\n // TODO: update ${name}\n res.json({ message: '${name} updated', ${name.toLowerCase()}: { id, ...req.body } });\n};\n\nexport const DELETE = async (req: Request, res: Response) => {\n${roleGuard} const { id } = req.params;\n // TODO: delete ${name}\n res.json({ message: \\`${name} \\${id} deleted\\` });\n};\n`\n : `${RA}${rr4}${mwAdmin4}\nexport const GET = async (req, res) => {\n${roleGuard} const { id } = req.params;\n // TODO: fetch ${name} by id\n res.json({ ${name.toLowerCase()}: { id } });\n};\n\nexport const PUT = async (req, res) => {\n${roleGuard} const { id } = req.params;\n // TODO: update ${name}\n res.json({ message: '${name} updated', ${name.toLowerCase()}: { id, ...req.body } });\n};\n\nexport const DELETE = async (req, res) => {\n${roleGuard} const { id } = req.params;\n // TODO: delete ${name}\n res.json({ message: \\`${name} \\${id} deleted\\` });\n};\n`;\n return { listContent, byIdContent };\n };\n\n const { listContent: faqList, byIdContent: faqById } = mkContentCrud('FAQ', 'faqs', [], 'question, answer, category');\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'content', 'faqs', `index.${ext}`), faqList);\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'content', 'faqs', `[id].${ext}`), faqById);\n\n const { listContent: blogList, byIdContent: blogById } = mkContentCrud('Blog', 'blogs', [], 'title, slug, content');\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'content', 'blogs', `index.${ext}`), blogList);\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'content', 'blogs', `[id].${ext}`), blogById);\n\n const { listContent: catList, byIdContent: catById } = mkContentCrud('Category', 'categories', [], 'name, slug');\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'content', 'categories', `index.${ext}`), catList);\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'content', 'categories', `[id].${ext}`), catById);\n\n // ── Billing (admin) ───────────────────────────────────────────────────\n\n const { listContent: planList, byIdContent: planById } = mkContentCrud('Plan', 'plans', [], 'name, price, interval');\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'billing', 'plans', `index.${ext}`), planList);\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'billing', 'plans', `[id].${ext}`), planById);\n\n const { listContent: couponList, byIdContent: couponById } = mkContentCrud('Coupon', 'coupons', [], 'code, type, value');\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'billing', 'coupons', `index.${ext}`), couponList);\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'billing', 'coupons', `[id].${ext}`), couponById);\n\n // admin/billing/subscriptions/index.ts\n const adminSubsMeta = mkMeta(opts, 'List all subscriptions with filters.', `{ subscriptions: [], total: 0 }`);\n const adminSubsContent = ts\n ? `${RA}${rr4}import type { Request, Response } from 'express';\n${adminSubsMeta}${mwAdmin4}\nexport const GET = async (req: Request, res: Response) => {\n${roleGuard} const { status, page = 1, limit = 20 } = req.query;\n // TODO: fetch all subscriptions with filters\n res.json({ subscriptions: [], total: 0, page: Number(page), limit: Number(limit) });\n};\n`\n : `${RA}${rr4}${adminSubsMeta}${mwAdmin4}\nexport const GET = async (req, res) => {\n${roleGuard} const { status, page = 1, limit = 20 } = req.query;\n // TODO: fetch all subscriptions with filters\n res.json({ subscriptions: [], total: 0, page: Number(page), limit: Number(limit) });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'billing', 'subscriptions', `index.${ext}`), adminSubsContent);\n}\n"],"mappings":"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","names":["cancel","spinner"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/scaffold.ts"],"sourcesContent":["import * as p from '@clack/prompts';\nimport pc from 'picocolors';\nimport { spawn } from 'node:child_process';\nimport { scaffold, type ScaffoldOptions } from './scaffold.js';\n\nfunction cancel(msg = 'Cancelled'): never {\n p.cancel(msg);\n process.exit(0);\n}\n\nasync function main(): Promise<void> {\n console.log();\n p.intro(pc.bgCyan(pc.black(' create-efc-app ')));\n\n const projectName = await p.text({\n message: 'Project name:',\n placeholder: 'my-api',\n defaultValue: 'my-api',\n validate: (v) => (!v.trim() ? 'Project name is required' : undefined),\n });\n if (p.isCancel(projectName)) cancel();\n\n const language = await p.select({\n message: 'Language:',\n options: [\n { value: 'typescript', label: 'TypeScript', hint: 'recommended' },\n { value: 'javascript', label: 'JavaScript' },\n ],\n });\n if (p.isCancel(language)) cancel();\n\n const database = await p.select({\n message: 'Database:',\n options: [\n { value: 'mongodb', label: 'MongoDB', hint: 'Mongoose' },\n { value: 'postgresql', label: 'PostgreSQL', hint: 'Drizzle ORM' },\n ],\n });\n if (p.isCancel(database)) cancel();\n\n const authStrategy = await p.select({\n message: 'Authentication strategy:',\n options: [\n { value: 'http-only', label: 'http-only', hint: 'secure cookie — recommended for SSR' },\n { value: 'localStorage', label: 'localStorage', hint: 'bearer token — for SPAs' },\n ],\n });\n if (p.isCancel(authStrategy)) cancel();\n\n const features = await p.multiselect({\n message: 'Features: (space to toggle, enter to confirm)',\n options: [\n { value: 'cluster', label: 'Multi-core clustering', hint: 'Node cluster module' },\n { value: 'tasks', label: 'Background tasks', hint: 'BullMQ / pg-boss' },\n { value: 'routeDocs', label: 'API route documentation', hint: 'meta exports + dashboard' },\n { value: 'userPortal', label: 'User portal', hint: 'auth, profile, billing routes' },\n { value: 'adminPortal',label: 'Admin portal', hint: 'dashboard, user mgmt, analytics' },\n { value: 'rbac', label: 'Role-based access control', hint: \"requireAuth('role') middleware\" },\n { value: 'mailer', label: 'Mailer', hint: 'nodemailer + SMTP' },\n ],\n initialValues: ['cluster', 'tasks', 'routeDocs', 'userPortal', 'adminPortal', 'rbac'],\n required: false,\n });\n if (p.isCancel(features)) cancel();\n\n const selected = new Set(features as string[]);\n\n let taskBackend: ScaffoldOptions['taskBackend'];\n if (selected.has('tasks')) {\n const backend = await p.select({\n message: 'Task queue backend:',\n options: [\n { value: 'bullmq', label: 'BullMQ', hint: 'Redis' },\n { value: 'pg-boss', label: 'pg-boss', hint: 'PostgreSQL' },\n ],\n });\n if (p.isCancel(backend)) cancel();\n taskBackend = backend as ScaffoldOptions['taskBackend'];\n }\n\n let smtpProvider: ScaffoldOptions['smtpProvider'];\n let smtpHost: string | undefined;\n let smtpPort: string | undefined;\n let smtpUser: string | undefined;\n let smtpPass: string | undefined;\n if (selected.has('mailer')) {\n const provider = await p.select({\n message: 'Email provider:',\n options: [\n { value: 'gmail', label: 'Gmail', hint: 'smtp.gmail.com, preconfigured' },\n { value: 'custom', label: 'Other (custom SMTP)', hint: \"you'll provide host + port\" },\n ],\n });\n if (p.isCancel(provider)) cancel();\n smtpProvider = provider as ScaffoldOptions['smtpProvider'];\n\n if (smtpProvider === 'custom') {\n const host = await p.text({\n message: 'SMTP host:',\n placeholder: 'smtp.mailtrap.io',\n validate: (v) => (!v.trim() ? 'SMTP host is required' : undefined),\n });\n if (p.isCancel(host)) cancel();\n smtpHost = host as string;\n\n const port = await p.text({\n message: 'SMTP port:',\n placeholder: '587',\n defaultValue: '587',\n });\n if (p.isCancel(port)) cancel();\n smtpPort = port as string;\n }\n\n const user = await p.text({\n message: smtpProvider === 'gmail' ? 'Gmail address:' : 'SMTP username / email:',\n placeholder: 'you@example.com',\n validate: (v) => (!v.trim() ? 'Email is required' : undefined),\n });\n if (p.isCancel(user)) cancel();\n smtpUser = user as string;\n\n if (smtpProvider === 'gmail') {\n p.note(\n 'Google no longer accepts your regular account password for SMTP.\\n' +\n \"Generate a 16-character App Password: Google Account -> Security -> 2-Step Verification -> App passwords.\\n\" +\n \"Enter it below without spaces (not your Gmail login password).\",\n 'Gmail app password required',\n );\n }\n\n const pass = await p.password({\n message: smtpProvider === 'gmail' ? 'Gmail app password (16 characters):' : 'SMTP password:',\n validate: (v) => {\n if (!v.trim()) return 'Password is required';\n if (smtpProvider === 'gmail' && v.replace(/\\s/g, '').length !== 16) {\n return 'Gmail app passwords are 16 characters — this looks like a regular password, not an app password';\n }\n return undefined;\n },\n });\n if (p.isCancel(pass)) cancel();\n smtpPass = (pass as string).replace(/\\s/g, '');\n }\n\n const opts: ScaffoldOptions = {\n projectName: projectName as string,\n language: language as ScaffoldOptions['language'],\n database: database as ScaffoldOptions['database'],\n authStrategy: authStrategy as ScaffoldOptions['authStrategy'],\n cluster: selected.has('cluster'),\n tasks: selected.has('tasks'),\n routeDocs: selected.has('routeDocs'),\n userPortal: selected.has('userPortal'),\n adminPortal: selected.has('adminPortal'),\n rbac: selected.has('rbac'),\n mailer: selected.has('mailer'),\n ...(taskBackend !== undefined && { taskBackend }),\n ...(smtpProvider !== undefined && { smtpProvider }),\n ...(smtpHost !== undefined && { smtpHost }),\n ...(smtpPort !== undefined && { smtpPort }),\n ...(smtpUser !== undefined && { smtpUser }),\n ...(smtpPass !== undefined && { smtpPass }),\n };\n\n const spinner = p.spinner();\n spinner.start('Scaffolding project…');\n\n try {\n await scaffold(opts);\n spinner.stop('Project created');\n } catch (err) {\n spinner.stop('Failed to scaffold project');\n console.error(err);\n process.exit(1);\n }\n\n spinner.start('Installing dependencies…');\n await npmInstall(projectName as string);\n spinner.stop('Dependencies installed');\n\n spinner.start('Installing efc CLI globally…');\n await npmInstallGlobal().catch(() => { /* non-fatal */ });\n spinner.stop('efc CLI ready');\n\n if (opts.mailer) {\n p.note(\n `SMTP_USER and SMTP_PASS were written to ${projectName as string}/.env — that file is gitignored, never commit it.\\n` +\n (opts.smtpProvider === 'gmail'\n ? 'If this Gmail app password ever leaks, revoke it and generate a new one.'\n : 'Rotate SMTP_PASS immediately if it is ever exposed.'),\n 'Mailer credentials',\n );\n }\n\n p.outro(\n pc.green(`\\nYour project is ready!\\n\\n`) +\n pc.dim(` cd ${projectName as string}\\n`) +\n pc.dim(` efc start dev\\n`) +\n pc.dim(`\\n (or: npm run dev)\\n`),\n );\n}\n\nfunction npmInstall(projectDir: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const child = spawn('npm', ['install'], { cwd: projectDir, stdio: 'ignore' });\n child.on('exit', (code) => (code === 0 ? resolve() : reject(new Error('npm install failed'))));\n });\n}\n\nfunction npmInstallGlobal(): Promise<void> {\n return new Promise((resolve, reject) => {\n const child = spawn('npm', ['install', '-g', 'express-file-cluster'], { stdio: 'ignore' });\n child.on('exit', (code) => (code === 0 ? resolve() : reject(new Error('global install failed'))));\n });\n}\n\nmain().catch((err) => {\n console.error(err);\n process.exit(1);\n});\n","import fs from 'fs-extra';\nimport path from 'node:path';\nimport crypto from 'node:crypto';\n\nexport interface ScaffoldOptions {\n projectName: string;\n language: 'typescript' | 'javascript';\n database: 'mongodb' | 'postgresql';\n authStrategy: 'http-only' | 'localStorage';\n cluster: boolean;\n tasks: boolean;\n taskBackend?: 'bullmq' | 'pg-boss';\n routeDocs: boolean;\n userPortal: boolean;\n adminPortal: boolean;\n rbac: boolean;\n mailer: boolean;\n smtpProvider?: 'gmail' | 'custom';\n smtpHost?: string;\n smtpPort?: string;\n smtpUser?: string;\n smtpPass?: string;\n}\n\nexport async function scaffold(opts: ScaffoldOptions): Promise<void> {\n const dest = path.resolve(process.cwd(), opts.projectName);\n await fs.ensureDir(dest);\n\n await writePackageJson(dest, opts);\n await writeTsConfig(dest, opts);\n await writeEfcConfig(dest, opts);\n await writeEntryPoint(dest, opts);\n await writeGitignore(dest);\n await writeEnvFiles(dest, opts);\n await writeExampleRoute(dest, opts);\n if (opts.userPortal) await writeUserModel(dest, opts);\n if (opts.adminPortal) await writeAdminModel(dest, opts);\n await writeAuthRoutes(dest, opts);\n if (opts.adminPortal) await writeAdminRoutes(dest, opts);\n if (opts.userPortal) await writeUserRoutes(dest, opts);\n if (opts.tasks) await writeExampleTask(dest, opts);\n // Extended models\n if (opts.userPortal) await writeSessionModel(dest, opts);\n if (opts.userPortal) await writeNotificationModel(dest, opts);\n if (opts.userPortal) await writeFileModel(dest, opts);\n if (opts.userPortal || opts.adminPortal) await writeSupportTicketModel(dest, opts);\n if (opts.adminPortal) await writeAuditLogModel(dest, opts);\n if (opts.userPortal) await writeSubscriptionModel(dest, opts);\n if (opts.adminPortal) await writePlanModel(dest, opts);\n if (opts.userPortal) await writeInvoiceModel(dest, opts);\n if (opts.userPortal) await writeApiKeyModel(dest, opts);\n if (opts.rbac) await writeRoleModel(dest, opts);\n if (opts.adminPortal) await writeFAQModel(dest, opts);\n if (opts.adminPortal) await writeBlogModel(dest, opts);\n if (opts.adminPortal) await writeCategoryModel(dest, opts);\n if (opts.adminPortal) await writeCouponModel(dest, opts);\n // Extended routes\n if (opts.userPortal) await writeAuthExtendedRoutes(dest, opts);\n if (opts.userPortal) await writeUserExtendedRoutes(dest, opts);\n if (opts.userPortal) await writeUserBillingRoutes(dest, opts);\n if (opts.userPortal) await writeSupportRoutes(dest, opts);\n if (opts.adminPortal) await writeAdminExtendedRoutes(dest, opts);\n}\n\nasync function writePackageJson(dest: string, opts: ScaffoldOptions): Promise<void> {\n const deps: Record<string, string> = {\n 'express-file-cluster': '^0.2.1',\n };\n if (opts.database === 'mongodb') deps['mongoose'] = '^8.0.0';\n if (opts.database === 'postgresql') {\n deps['pg'] = '^8.0.0';\n deps['drizzle-orm'] = '^0.33.0';\n }\n if (opts.tasks && opts.taskBackend === 'bullmq') deps['bullmq'] = '^5.0.0';\n if (opts.tasks && opts.taskBackend === 'pg-boss') deps['pg-boss'] = '^10.0.0';\n if (opts.mailer) deps['nodemailer'] = '^6.9.0';\n if (opts.database === 'mongodb') deps['bcrypt'] = '^5.1.0';\n\n const devDeps: Record<string, string> = {\n vitest: '^4.1.9',\n };\n if (opts.language === 'typescript') {\n devDeps['typescript'] = '^5.5.0';\n devDeps['@types/node'] = '^22.0.0';\n devDeps['@types/express'] = '^4.17.21';\n devDeps['tsup'] = '^8.2.0';\n devDeps['tsx'] = '^4.0.0';\n if (opts.mailer) devDeps['@types/nodemailer'] = '^6.4.0';\n if (opts.database === 'mongodb') devDeps['@types/bcrypt'] = '^5.0.0';\n }\n\n const pkg = {\n name: opts.projectName,\n version: '0.1.0',\n type: 'module',\n scripts: {\n dev: 'efc start dev',\n build: 'efc build prod',\n start: 'efc start prod',\n test: 'efc run tests',\n },\n dependencies: deps,\n devDependencies: devDeps,\n };\n\n await fs.writeJson(path.join(dest, 'package.json'), pkg, { spaces: 2 });\n}\n\nasync function writeTsConfig(dest: string, opts: ScaffoldOptions): Promise<void> {\n if (opts.language !== 'typescript') return;\n const config = {\n compilerOptions: {\n target: 'ES2022',\n module: 'NodeNext',\n moduleResolution: 'NodeNext',\n strict: true,\n esModuleInterop: true,\n skipLibCheck: true,\n outDir: './dist',\n rootDir: './src',\n },\n include: ['src/**/*'],\n exclude: ['node_modules', 'dist'],\n };\n await fs.writeJson(path.join(dest, 'tsconfig.json'), config, { spaces: 2 });\n}\n\nasync function writeEfcConfig(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const tasks = opts.tasks\n ? `{ backend: '${opts.taskBackend ?? 'bullmq'}', concurrency: 5 }`\n : 'false';\n\n const content = `import type { EFCConfig } from 'express-file-cluster';\n\n// Structural config only — runtime values (PORT, DATABASE_URL, JWT_SECRET, etc.) are read from .env\nconst config: EFCConfig = {\n authStrategy: '${opts.authStrategy}',\n tasks: ${tasks},\n globalMiddlewares: [],\n};\n\nexport default config;\n`;\n await fs.outputFile(path.join(dest, `efc.config.${ext}`), content);\n}\n\nasync function writeEntryPoint(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const taskLine = opts.tasks ? ` tasks: { backend: '${opts.taskBackend ?? 'bullmq'}' },\\n` : '';\n const content = `import { ignite, gracefulShutdown } from 'express-file-cluster';\n\n// PORT, DATABASE_URL, JWT_SECRET, CORS_ORIGINS are read from .env automatically\nignite({\n cluster: ${opts.cluster},\n${taskLine}}).then(gracefulShutdown).catch(console.error);\n`;\n await fs.outputFile(path.join(dest, 'src', `index.${ext}`), content);\n}\n\nasync function writeGitignore(dest: string): Promise<void> {\n await fs.outputFile(\n path.join(dest, '.gitignore'),\n 'node_modules/\\ndist/\\n.env\\n.env.local\\n*.log\\n',\n );\n}\n\nasync function writeEnvFiles(dest: string, opts: ScaffoldOptions): Promise<void> {\n const secret = crypto.randomBytes(64).toString('hex');\n const projectName = path.basename(dest);\n const dbUrl =\n opts.database === 'mongodb'\n ? `mongodb://localhost:27017/${projectName}`\n : `postgresql://localhost:5432/${projectName}`;\n const dbExampleUrl =\n opts.database === 'mongodb'\n ? `mongodb://localhost:27017/${projectName}`\n : `postgresql://user:password@localhost:5432/${projectName}`;\n\n const isGmail = opts.mailer && opts.smtpProvider !== 'custom';\n const resolvedHost = isGmail ? 'smtp.gmail.com' : opts.smtpHost ?? 'smtp.gmail.com';\n const resolvedPort = isGmail ? '465' : opts.smtpPort ?? '587';\n const passComment = isGmail\n ? ' # Gmail App Password (16 chars) — NOT your regular Gmail password. Generate at: Google Account > Security > 2-Step Verification > App passwords'\n : '';\n\n const smtpVars = opts.mailer\n ? `\\nAPP_URL=http://localhost:3000\\nSMTP_HOST=${resolvedHost}\\nSMTP_PORT=${resolvedPort}\\nSMTP_USER=${opts.smtpUser ?? ''}\\nSMTP_PASS=${opts.smtpPass ?? ''}${passComment}\\nSMTP_FROM=${opts.smtpUser ?? 'noreply@example.com'}\\n`\n : '';\n const smtpExample = opts.mailer\n ? `\\nAPP_URL=http://localhost:3000\\nSMTP_HOST=${resolvedHost}\\nSMTP_PORT=${resolvedPort}\\nSMTP_USER=your@email.com\\nSMTP_PASS=${isGmail ? 'your_16_char_app_password' : 'your_smtp_password'}${passComment}\\nSMTP_FROM=noreply@yourapp.com\\n`\n : '';\n const dotenv = `PORT=3000\\nNODE_ENV=development\\nDATABASE_URL=${dbUrl}\\nJWT_SECRET=${secret}\\nREDIS_URL=redis://localhost:6379\\nCORS_ORIGINS=http://localhost:3000${smtpVars}`;\n const example = `PORT=3000\\nNODE_ENV=development\\nDATABASE_URL=${dbExampleUrl}\\nJWT_SECRET=<generate with: openssl rand -hex 64>\\nREDIS_URL=redis://localhost:6379\\nCORS_ORIGINS=http://localhost:3000,https://yourapp.com${smtpExample}`;\n await fs.outputFile(path.join(dest, '.env'), dotenv);\n await fs.outputFile(path.join(dest, '.env.example'), example);\n}\n\nasync function writeExampleRoute(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const metaTs = opts.routeDocs\n ? `import type { RouteMeta } from 'express-file-cluster';\\n\\nexport const meta: RouteMeta = {\\n description: 'Health check — returns server status and current timestamp.',\\n response: { status: 200, body: { status: 'OK', timestamp: '2024-01-01T00:00:00.000Z' } },\\n};\\n\\n`\n : '';\n const metaJs = opts.routeDocs\n ? `export const meta = {\\n description: 'Health check — returns server status and current timestamp.',\\n response: { status: 200, body: { status: 'OK', timestamp: '2024-01-01T00:00:00.000Z' } },\\n};\\n\\n`\n : '';\n const content =\n opts.language === 'typescript'\n ? `import type { Request, Response } from 'express';\\n${metaTs}export const GET = async (_req: Request, res: Response) => {\\n res.json({ status: 'OK', timestamp: new Date().toISOString() });\\n};\\n`\n : `${metaJs}export const GET = async (_req, res) => {\\n res.json({ status: 'OK', timestamp: new Date().toISOString() });\\n};\\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', `health.${ext}`), content);\n}\n\nasync function writeExampleTask(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n\n const tsMailer = `import { defineTask } from 'express-file-cluster/tasks';\nimport nodemailer from 'nodemailer';\n\ninterface SendEmailPayload {\n to: string;\n subject: string;\n body: string;\n}\n\nconst transporter = nodemailer.createTransport({\n host: process.env.SMTP_HOST,\n port: Number(process.env.SMTP_PORT ?? 587),\n secure: Number(process.env.SMTP_PORT) === 465,\n auth: {\n user: process.env.SMTP_USER,\n pass: process.env.SMTP_PASS,\n },\n});\n\nexport default defineTask<SendEmailPayload>(async (payload) => {\n await transporter.sendMail({\n from: process.env.SMTP_FROM ?? process.env.SMTP_USER,\n to: payload.to,\n subject: payload.subject,\n html: payload.body,\n });\n});\n`;\n\n const jsMailer = `import { defineTask } from 'express-file-cluster/tasks';\nimport nodemailer from 'nodemailer';\n\nconst transporter = nodemailer.createTransport({\n host: process.env.SMTP_HOST,\n port: Number(process.env.SMTP_PORT ?? 587),\n secure: Number(process.env.SMTP_PORT) === 465,\n auth: {\n user: process.env.SMTP_USER,\n pass: process.env.SMTP_PASS,\n },\n});\n\nexport default defineTask(async (payload) => {\n await transporter.sendMail({\n from: process.env.SMTP_FROM ?? process.env.SMTP_USER,\n to: payload.to,\n subject: payload.subject,\n html: payload.body,\n });\n});\n`;\n\n const tsStub = `import { defineTask } from 'express-file-cluster/tasks';\n\ninterface SendEmailPayload {\n to: string;\n subject: string;\n body: string;\n}\n\nexport default defineTask<SendEmailPayload>(async (payload) => {\n // TODO: wire up your mailer\n console.log('[SendEmail] Sending to', payload.to);\n});\n`;\n\n const jsStub = `import { defineTask } from 'express-file-cluster/tasks';\n\nexport default defineTask(async (payload) => {\n // TODO: wire up your mailer\n console.log('[SendEmail] Sending to', payload.to);\n});\n`;\n\n const content = opts.mailer\n ? opts.language === 'typescript' ? tsMailer : jsMailer\n : opts.language === 'typescript' ? tsStub : jsStub;\n\n await fs.outputFile(path.join(dest, 'src', 'tasks', `SendEmail.${ext}`), content);\n}\n\nasync function writeUserModel(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const ts = opts.language === 'typescript';\n\n const content = opts.database === 'mongodb'\n ? ts\n ? `import { defineModel } from 'express-file-cluster';\n\nexport interface UserDocument {\n name: string;\n email: string;\n password: string;\n role: string;\n avatar?: string;\n isVerified: boolean;\n isActive: boolean;\n verifyToken?: string;\n resetToken?: string;\n resetTokenExpiry?: Date;\n refreshToken?: string;\n refreshTokenExpiry?: Date;\n}\n\nexport const User = defineModel<UserDocument>('User', {\n name: { type: 'string', required: true },\n email: { type: 'string', required: true, unique: true },\n password: { type: 'string', required: true },\n role: { type: 'string', required: true, default: 'user' },\n avatar: { type: 'string' },\n isVerified: { type: 'boolean', default: false },\n isActive: { type: 'boolean', default: true },\n verifyToken: { type: 'string' },\n resetToken: { type: 'string' },\n resetTokenExpiry: { type: 'date' },\n refreshToken: { type: 'string' },\n refreshTokenExpiry: { type: 'date' },\n});\n`\n : `import { defineModel } from 'express-file-cluster';\n\nexport const User = defineModel('User', {\n name: { type: 'string', required: true },\n email: { type: 'string', required: true, unique: true },\n password: { type: 'string', required: true },\n role: { type: 'string', required: true, default: 'user' },\n avatar: { type: 'string' },\n isVerified: { type: 'boolean', default: false },\n isActive: { type: 'boolean', default: true },\n verifyToken: { type: 'string' },\n resetToken: { type: 'string' },\n resetTokenExpiry: { type: 'date' },\n refreshToken: { type: 'string' },\n refreshTokenExpiry: { type: 'date' },\n});\n`\n : ts\n ? `// TODO: define your Drizzle schema for User\n// import { pgTable, serial, text, boolean, timestamp } from 'drizzle-orm/pg-core';\n//\n// export const users = pgTable('users', {\n// id: serial('id').primaryKey(),\n// name: text('name').notNull(),\n// email: text('email').notNull().unique(),\n// password: text('password').notNull(),\n// role: text('role').notNull().default('user'),\n// avatar: text('avatar'),\n// isVerified: boolean('is_verified').notNull().default(false),\n// isActive: boolean('is_active').notNull().default(true),\n// createdAt: timestamp('created_at').defaultNow(),\n// updatedAt: timestamp('updated_at').defaultNow(),\n// });\nexport {};\n`\n : `// TODO: define your Drizzle schema for User\nexport {};\n`;\n\n await fs.outputFile(path.join(dest, 'src', 'model', `User.${ext}`), content);\n}\n\nasync function writeAdminModel(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const ts = opts.language === 'typescript';\n\n const content = opts.database === 'mongodb'\n ? ts\n ? `import { defineModel } from 'express-file-cluster';\n\nexport interface AdminDocument {\n name: string;\n email: string;\n password: string;\n role: string;\n permissions: string[];\n isActive: boolean;\n resetToken?: string;\n resetTokenExpiry?: Date;\n refreshToken?: string;\n refreshTokenExpiry?: Date;\n}\n\nexport const Admin = defineModel<AdminDocument>('Admin', {\n name: { type: 'string', required: true },\n email: { type: 'string', required: true, unique: true },\n password: { type: 'string', required: true },\n role: { type: 'string', required: true, default: 'admin' },\n permissions: { type: 'array', default: [] },\n isActive: { type: 'boolean', default: true },\n resetToken: { type: 'string' },\n resetTokenExpiry: { type: 'date' },\n refreshToken: { type: 'string' },\n refreshTokenExpiry: { type: 'date' },\n});\n`\n : `import { defineModel } from 'express-file-cluster';\n\nexport const Admin = defineModel('Admin', {\n name: { type: 'string', required: true },\n email: { type: 'string', required: true, unique: true },\n password: { type: 'string', required: true },\n role: { type: 'string', required: true, default: 'admin' },\n permissions: { type: 'array', default: [] },\n isActive: { type: 'boolean', default: true },\n resetToken: { type: 'string' },\n resetTokenExpiry: { type: 'date' },\n refreshToken: { type: 'string' },\n refreshTokenExpiry: { type: 'date' },\n});\n`\n : ts\n ? `// TODO: define your Drizzle schema for Admin\n// import { pgTable, serial, text, boolean, timestamp } from 'drizzle-orm/pg-core';\n//\n// export const admins = pgTable('admins', {\n// id: serial('id').primaryKey(),\n// name: text('name').notNull(),\n// email: text('email').notNull().unique(),\n// password: text('password').notNull(),\n// role: text('role').notNull().default('admin'),\n// permissions: text('permissions').array().notNull().default([]),\n// isActive: boolean('is_active').notNull().default(true),\n// createdAt: timestamp('created_at').defaultNow(),\n// updatedAt: timestamp('updated_at').defaultNow(),\n// });\nexport {};\n`\n : `// TODO: define your Drizzle schema for Admin\nexport {};\n`;\n\n await fs.outputFile(path.join(dest, 'src', 'model', `Admin.${ext}`), content);\n}\n\nasync function writeAuthRoutes(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const ts = opts.language === 'typescript';\n\n const loginMeta = opts.routeDocs\n ? ts\n ? `import type { RouteMeta } from 'express-file-cluster';\\n\\nexport const meta: RouteMeta = {\\n description: 'Authenticate a user and issue a JWT.',\\n request: { body: { email: 'user@example.com', password: 'user' } },\\n response: { status: 200, body: { message: 'Logged in as user' } },\\n};\\n\\n`\n : `export const meta = {\\n description: 'Authenticate a user and issue a JWT.',\\n request: { body: { email: 'user@example.com', password: 'user' } },\\n response: { status: 200, body: { message: 'Logged in as user' } },\\n};\\n\\n`\n : '';\n\n const loginDbImports = opts.database === 'mongodb'\n ? ts\n ? `import bcrypt from 'bcrypt';\\nimport crypto from 'node:crypto';\\nimport { User } from '../../model/User.js';\\nimport { Admin } from '../../model/Admin.js';\\n`\n : `import bcrypt from 'bcrypt';\\nimport crypto from 'node:crypto';\\nimport { User } from '../../model/User.js';\\nimport { Admin } from '../../model/Admin.js';\\n`\n : '';\n\n const loginContent = opts.database === 'mongodb'\n ? ts\n ? `import { issueToken } from 'express-file-cluster/auth';\nimport type { Request, Response } from 'express';\n${loginDbImports}${loginMeta}const REFRESH_TOKEN_TTL_MS = 1000 * 60 * 60 * 24 * 30; // 30 days\n\nasync function issueRefreshToken(\n res: Response,\n model: { update: (id: string, data: Record<string, unknown>) => Promise<unknown> },\n id: string,\n): Promise<void> {\n const refreshToken = crypto.randomBytes(40).toString('hex');\n await model.update(id, { refreshToken, refreshTokenExpiry: new Date(Date.now() + REFRESH_TOKEN_TTL_MS) });\n res.cookie('efc_refresh_token', refreshToken, {\n httpOnly: true,\n secure: process.env.NODE_ENV === 'production',\n sameSite: 'strict',\n maxAge: REFRESH_TOKEN_TTL_MS,\n });\n}\n\nexport const POST = async (req: Request, res: Response) => {\n const { email, password } = req.body;\n if (!email || !password) return res.status(400).json({ error: 'email and password are required' });\n\n const admin = await Admin.findOne({ email });\n if (admin) {\n const match = await bcrypt.compare(password, admin.password);\n if (!match) return res.status(401).json({ error: 'Invalid credentials' });\n if (!admin.isActive) return res.status(403).json({ error: 'Account suspended' });\n await issueToken(res, { id: admin.id, role: admin.role, email: admin.email });\n await issueRefreshToken(res, Admin, admin.id);\n return res.json({ message: 'Logged in as admin' });\n }\n\n const user = await User.findOne({ email });\n if (!user) return res.status(401).json({ error: 'Invalid credentials' });\n const match = await bcrypt.compare(password, user.password);\n if (!match) return res.status(401).json({ error: 'Invalid credentials' });\n if (!user.isActive) return res.status(403).json({ error: 'Account suspended' });\n await issueToken(res, { id: user.id, role: user.role, email: user.email });\n await issueRefreshToken(res, User, user.id);\n res.json({ message: 'Logged in' });\n};\n`\n : `import { issueToken } from 'express-file-cluster/auth';\n${loginDbImports}${loginMeta}const REFRESH_TOKEN_TTL_MS = 1000 * 60 * 60 * 24 * 30; // 30 days\n\nasync function issueRefreshToken(res, model, id) {\n const refreshToken = crypto.randomBytes(40).toString('hex');\n await model.update(id, { refreshToken, refreshTokenExpiry: new Date(Date.now() + REFRESH_TOKEN_TTL_MS) });\n res.cookie('efc_refresh_token', refreshToken, {\n httpOnly: true,\n secure: process.env.NODE_ENV === 'production',\n sameSite: 'strict',\n maxAge: REFRESH_TOKEN_TTL_MS,\n });\n}\n\nexport const POST = async (req, res) => {\n const { email, password } = req.body;\n if (!email || !password) return res.status(400).json({ error: 'email and password are required' });\n\n const admin = await Admin.findOne({ email });\n if (admin) {\n const match = await bcrypt.compare(password, admin.password);\n if (!match) return res.status(401).json({ error: 'Invalid credentials' });\n if (!admin.isActive) return res.status(403).json({ error: 'Account suspended' });\n await issueToken(res, { id: admin.id, role: admin.role, email: admin.email });\n await issueRefreshToken(res, Admin, admin.id);\n return res.json({ message: 'Logged in as admin' });\n }\n\n const user = await User.findOne({ email });\n if (!user) return res.status(401).json({ error: 'Invalid credentials' });\n const match = await bcrypt.compare(password, user.password);\n if (!match) return res.status(401).json({ error: 'Invalid credentials' });\n if (!user.isActive) return res.status(403).json({ error: 'Account suspended' });\n await issueToken(res, { id: user.id, role: user.role, email: user.email });\n await issueRefreshToken(res, User, user.id);\n res.json({ message: 'Logged in' });\n};\n`\n : ts\n ? `import { issueToken } from 'express-file-cluster/auth';\nimport type { Request, Response } from 'express';\n${loginMeta}export const POST = async (req: Request, res: Response) => {\n const { email, password } = req.body;\n // TODO: look up user in DB and compare password\n res.status(401).json({ error: 'Invalid credentials' });\n};\n`\n : `import { issueToken } from 'express-file-cluster/auth';\n${loginMeta}export const POST = async (req, res) => {\n const { email, password } = req.body;\n // TODO: look up user in DB and compare password\n res.status(401).json({ error: 'Invalid credentials' });\n};\n`;\n\n const logoutMeta = opts.routeDocs\n ? ts\n ? `import type { RouteMeta } from 'express-file-cluster';\\n\\nexport const meta: RouteMeta = {\\n description: 'Clear the auth cookie and log the user out.',\\n response: { status: 200, body: { message: 'Logged out successfully' } },\\n};\\n\\n`\n : `export const meta = {\\n description: 'Clear the auth cookie and log the user out.',\\n response: { status: 200, body: { message: 'Logged out successfully' } },\\n};\\n\\n`\n : '';\n\n const logoutContent = ts\n ? `import { revokeToken } from 'express-file-cluster/auth';\nimport type { Request, Response } from 'express';\n${logoutMeta}export const POST = async (_req: Request, res: Response) => {\n revokeToken(res);\n res.clearCookie('efc_refresh_token');\n res.json({ message: 'Logged out successfully' });\n};\n`\n : `import { revokeToken } from 'express-file-cluster/auth';\n${logoutMeta}export const POST = async (_req, res) => {\n revokeToken(res);\n res.clearCookie('efc_refresh_token');\n res.json({ message: 'Logged out successfully' });\n};\n`;\n\n await fs.outputFile(path.join(dest, 'src', 'api', 'auth', `login.${ext}`), loginContent);\n await fs.outputFile(path.join(dest, 'src', 'api', 'auth', `logout.${ext}`), logoutContent);\n\n if (!opts.userPortal) return;\n\n const registerMeta = opts.routeDocs\n ? ts\n ? `import type { RouteMeta } from 'express-file-cluster';\\n\\nexport const meta: RouteMeta = {\\n description: 'Register a new user account.',\\n request: { body: { name: 'Jane Doe', email: 'jane@example.com', password: 'secret' } },\\n response: { status: 201, body: { message: 'Account created successfully' } },\\n};\\n\\n`\n : `export const meta = {\\n description: 'Register a new user account.',\\n request: { body: { name: 'Jane Doe', email: 'jane@example.com', password: 'secret' } },\\n response: { status: 201, body: { message: 'Account created successfully' } },\\n};\\n\\n`\n : '';\n\n const registerDbImports = opts.database === 'mongodb'\n ? `import bcrypt from 'bcrypt';\\nimport crypto from 'node:crypto';\\n${opts.mailer ? \"import { enqueue } from 'express-file-cluster/tasks';\\n\" : ''}import { User } from '../../model/User.js';\\n`\n : '';\n\n const sendVerifyEmail = opts.mailer\n ? `\n var appUrl = process.env.APP_URL || 'http://localhost:3000';\n await enqueue('SendEmail', {\n to: email,\n subject: 'Verify your email address',\n body: 'Welcome, ' + name + '! Verify your email: ' + appUrl + '/auth/verify-email?token=' + verifyToken,\n });\n`\n : `\n // TODO: email this token to the user — enable the Mailer feature to auto-wire SendEmail\n`;\n\n const registerContent = opts.database === 'mongodb'\n ? ts\n ? `import type { Request, Response } from 'express';\n${registerDbImports}${registerMeta}export const POST = async (req: Request, res: Response) => {\n const { name, email, password } = req.body;\n if (!name || !email || !password) {\n return res.status(400).json({ error: 'name, email and password are required' });\n }\n const existing = await User.findOne({ email });\n if (existing) return res.status(409).json({ error: 'Email already in use' });\n const hashed = await bcrypt.hash(password, 10);\n const verifyToken = crypto.randomBytes(32).toString('hex');\n const user = await User.create({ name, email, password: hashed, verifyToken });\n${sendVerifyEmail}\n const { password: _, verifyToken: __, ...safe } = user;\n res.status(201).json({ message: 'Account created successfully', user: safe });\n};\n`\n : `${registerDbImports}${registerMeta}export const POST = async (req, res) => {\n const { name, email, password } = req.body;\n if (!name || !email || !password) {\n return res.status(400).json({ error: 'name, email and password are required' });\n }\n const existing = await User.findOne({ email });\n if (existing) return res.status(409).json({ error: 'Email already in use' });\n const hashed = await bcrypt.hash(password, 10);\n const verifyToken = crypto.randomBytes(32).toString('hex');\n const user = await User.create({ name, email, password: hashed, verifyToken });\n${sendVerifyEmail}\n const { password: _, verifyToken: __, ...safe } = user;\n res.status(201).json({ message: 'Account created successfully', user: safe });\n};\n`\n : ts\n ? `import type { Request, Response } from 'express';\n${registerMeta}export const POST = async (req: Request, res: Response) => {\n const { name, email, password } = req.body;\n if (!name || !email || !password) {\n return res.status(400).json({ error: 'name, email and password are required' });\n }\n // TODO: hash password and persist to DB\n res.status(201).json({ message: 'Account created successfully' });\n};\n`\n : `${registerMeta}export const POST = async (req, res) => {\n const { name, email, password } = req.body;\n if (!name || !email || !password) {\n return res.status(400).json({ error: 'name, email and password are required' });\n }\n // TODO: hash password and persist to DB\n res.status(201).json({ message: 'Account created successfully' });\n};\n`;\n\n const meMeta = opts.routeDocs\n ? ts\n ? `import type { RouteMeta } from 'express-file-cluster';\\n\\nexport const meta: RouteMeta = {\\n description: 'Return the currently authenticated user.',\\n response: { status: 200, body: { user: { id: '1', role: 'user', email: 'user@example.com' } } },\\n};\\n\\n`\n : `export const meta = {\\n description: 'Return the currently authenticated user.',\\n response: { status: 200, body: { user: { id: '1', role: 'user', email: 'user@example.com' } } },\\n};\\n\\n`\n : '';\n const meMiddlewares = opts.rbac\n ? `export const middlewares = [requireAuth('user', 'admin')];\\n\\n`\n : `export const middlewares = [requireAuth];\\n\\n`;\n\n const meContent = ts\n ? `import { requireAuth } from 'express-file-cluster/auth';\nimport type { Request, Response } from 'express';\n${meMeta}${meMiddlewares}export const GET = async (req: Request, res: Response) => {\n res.json({ user: (req as any).user });\n};\n`\n : `import { requireAuth } from 'express-file-cluster/auth';\n${meMeta}${meMiddlewares}export const GET = async (req, res) => {\n res.json({ user: req.user });\n};\n`;\n\n await fs.outputFile(path.join(dest, 'src', 'api', 'auth', `register.${ext}`), registerContent);\n await fs.outputFile(path.join(dest, 'src', 'api', 'auth', `me.${ext}`), meContent);\n}\n\nasync function writeAdminRoutes(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const ts = opts.language === 'typescript';\n const middlewares = opts.rbac\n ? `export const middlewares = [requireAuth('admin')];\\n`\n : `export const middlewares = [requireAuth];\\n`;\n const roleGuard = opts.rbac\n ? ''\n : ts\n ? ` const user = (req as any).user;\\n if (user?.role !== 'admin') {\\n return res.status(403).json({ error: 'Forbidden: Admin access required' });\\n }\\n\\n`\n : ` const user = req.user;\\n if (user?.role !== 'admin') {\\n return res.status(403).json({ error: 'Forbidden: Admin access required' });\\n }\\n\\n`;\n\n const dashboardMeta = opts.routeDocs\n ? ts\n ? `import type { RouteMeta } from 'express-file-cluster';\\n\\nexport const meta: RouteMeta = {\\n description: 'Admin dashboard stats. Requires admin role.',\\n response: { status: 200, body: { stats: { users: 120, revenue: 5000 } } },\\n};\\n\\n`\n : `export const meta = {\\n description: 'Admin dashboard stats. Requires admin role.',\\n response: { status: 200, body: { stats: { users: 120, revenue: 5000 } } },\\n};\\n\\n`\n : '';\n\n const dashboardDbImport = opts.database === 'mongodb'\n ? `import { User } from '../../model/User.js';\\n`\n : '';\n\n const dashboardContent = opts.database === 'mongodb'\n ? ts\n ? `import { requireAuth } from 'express-file-cluster/auth';\nimport type { Request, Response } from 'express';\n${dashboardDbImport}${dashboardMeta}${middlewares}\nexport const GET = async (_req: Request, res: Response) => {\n${roleGuard} const [totalUsers, activeUsers, verifiedUsers] = await Promise.all([\n User.count({}),\n User.count({ isActive: true }),\n User.count({ isVerified: true }),\n ]);\n res.json({ stats: { totalUsers, activeUsers, verifiedUsers } });\n};\n`\n : `import { requireAuth } from 'express-file-cluster/auth';\n${dashboardDbImport}${dashboardMeta}${middlewares}\nexport const GET = async (_req, res) => {\n${roleGuard} const [totalUsers, activeUsers, verifiedUsers] = await Promise.all([\n User.count({}),\n User.count({ isActive: true }),\n User.count({ isVerified: true }),\n ]);\n res.json({ stats: { totalUsers, activeUsers, verifiedUsers } });\n};\n`\n : ts\n ? `import { requireAuth } from 'express-file-cluster/auth';\nimport type { Request, Response } from 'express';\n${dashboardMeta}${middlewares}\nexport const GET = async (_req: Request, res: Response) => {\n${roleGuard} // TODO: aggregate stats from DB\n res.json({ stats: { users: 0 } });\n};\n`\n : `import { requireAuth } from 'express-file-cluster/auth';\n${dashboardMeta}${middlewares}\nexport const GET = async (_req, res) => {\n${roleGuard} // TODO: aggregate stats from DB\n res.json({ stats: { users: 0 } });\n};\n`;\n\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', `dashboard.${ext}`), dashboardContent);\n\n // Admin user management routes\n const usersListMeta = opts.routeDocs\n ? ts\n ? `import type { RouteMeta } from 'express-file-cluster';\\n\\nexport const meta: RouteMeta = {\\n description: 'List all users (admin only).',\\n response: { status: 200, body: { users: [], total: 0 } },\\n};\\n\\n`\n : `export const meta = {\\n description: 'List all users (admin only).',\\n response: { status: 200, body: { users: [], total: 0 } },\\n};\\n\\n`\n : '';\n\n const adminUsersDbImport = opts.database === 'mongodb'\n ? ts\n ? `import bcrypt from 'bcrypt';\\nimport { User } from '../../../model/User.js';\\n`\n : `import bcrypt from 'bcrypt';\\nimport { User } from '../../../model/User.js';\\n`\n : '';\n\n const usersListContent = opts.database === 'mongodb'\n ? ts\n ? `import { requireAuth } from 'express-file-cluster/auth';\nimport type { Request, Response } from 'express';\n${adminUsersDbImport}${usersListMeta}${middlewares}\nexport const GET = async (req: Request, res: Response) => {\n${roleGuard} const page = Math.max(1, Number(req.query.page) || 1);\n const limit = Math.min(100, Number(req.query.limit) || 20);\n const [all, total] = await Promise.all([User.find({}), User.count({})]);\n const users = all.slice((page - 1) * limit, page * limit).map(({ password: _, ...u }) => u);\n res.json({ users, total, page, limit });\n};\n\nexport const POST = async (req: Request, res: Response) => {\n${roleGuard} const { name, email, password, role } = req.body;\n if (!name || !email || !password) return res.status(400).json({ error: 'name, email and password are required' });\n const existing = await User.findOne({ email });\n if (existing) return res.status(409).json({ error: 'Email already in use' });\n const hashed = await bcrypt.hash(password, 10);\n const user = await User.create({ name, email, password: hashed, role: role ?? 'user' });\n const { password: _, ...safe } = user;\n res.status(201).json({ message: 'User created', user: safe });\n};\n`\n : `import { requireAuth } from 'express-file-cluster/auth';\n${adminUsersDbImport}${usersListMeta}${middlewares}\nexport const GET = async (req, res) => {\n${roleGuard} const page = Math.max(1, Number(req.query.page) || 1);\n const limit = Math.min(100, Number(req.query.limit) || 20);\n const [all, total] = await Promise.all([User.find({}), User.count({})]);\n const users = all.slice((page - 1) * limit, page * limit).map(({ password: _, ...u }) => u);\n res.json({ users, total, page, limit });\n};\n\nexport const POST = async (req, res) => {\n${roleGuard} const { name, email, password, role } = req.body;\n if (!name || !email || !password) return res.status(400).json({ error: 'name, email and password are required' });\n const existing = await User.findOne({ email });\n if (existing) return res.status(409).json({ error: 'Email already in use' });\n const hashed = await bcrypt.hash(password, 10);\n const user = await User.create({ name, email, password: hashed, role: role ?? 'user' });\n const { password: _, ...safe } = user;\n res.status(201).json({ message: 'User created', user: safe });\n};\n`\n : ts\n ? `import { requireAuth } from 'express-file-cluster/auth';\nimport type { Request, Response } from 'express';\n${usersListMeta}${middlewares}\nexport const GET = async (_req: Request, res: Response) => {\n${roleGuard} // TODO: fetch users from DB with pagination\n res.json({ users: [], total: 0 });\n};\n\nexport const POST = async (req: Request, res: Response) => {\n${roleGuard} const { name, email, role } = req.body;\n if (!name || !email) return res.status(400).json({ error: 'name and email are required' });\n // TODO: create user in DB\n res.status(201).json({ message: 'User created', user: { id: 'new-id', name, email, role: role ?? 'user' } });\n};\n`\n : `import { requireAuth } from 'express-file-cluster/auth';\n${usersListMeta}${middlewares}\nexport const GET = async (_req, res) => {\n${roleGuard} // TODO: fetch users from DB with pagination\n res.json({ users: [], total: 0 });\n};\n\nexport const POST = async (req, res) => {\n${roleGuard} const { name, email, role } = req.body;\n if (!name || !email) return res.status(400).json({ error: 'name and email are required' });\n // TODO: create user in DB\n res.status(201).json({ message: 'User created', user: { id: 'new-id', name, email, role: role ?? 'user' } });\n};\n`;\n\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'users', `index.${ext}`), usersListContent);\n\n const userByIdMeta = opts.routeDocs\n ? ts\n ? `import type { RouteMeta } from 'express-file-cluster';\\n\\nexport const meta: RouteMeta = {\\n description: 'Get, update, or delete a single user by ID (admin only).',\\n};\\n\\n`\n : `export const meta = {\\n description: 'Get, update, or delete a single user by ID (admin only).',\\n};\\n\\n`\n : '';\n\n const adminUserByIdDbImport = opts.database === 'mongodb'\n ? `import { User } from '../../../model/User.js';\\n`\n : '';\n\n const userByIdContent = opts.database === 'mongodb'\n ? ts\n ? `import { requireAuth } from 'express-file-cluster/auth';\nimport type { Request, Response } from 'express';\n${adminUserByIdDbImport}${userByIdMeta}${middlewares}\nexport const GET = async (req: Request, res: Response) => {\n${roleGuard} const { id } = req.params;\n const user = await User.findById(id);\n if (!user) return res.status(404).json({ error: 'User not found' });\n const { password: _, ...safe } = user;\n res.json({ user: safe });\n};\n\nexport const PUT = async (req: Request, res: Response) => {\n${roleGuard} const { id } = req.params;\n const { name, email, role, isActive } = req.body;\n const updated = await User.update(id, { name, email, role, isActive });\n if (!updated) return res.status(404).json({ error: 'User not found' });\n const { password: _, ...safe } = updated;\n res.json({ message: 'User updated', user: safe });\n};\n\nexport const DELETE = async (req: Request, res: Response) => {\n${roleGuard} const { id } = req.params;\n const user = await User.findById(id);\n if (!user) return res.status(404).json({ error: 'User not found' });\n await User.delete(id);\n res.json({ message: \\`User \\${id} deleted\\` });\n};\n`\n : `import { requireAuth } from 'express-file-cluster/auth';\n${adminUserByIdDbImport}${userByIdMeta}${middlewares}\nexport const GET = async (req, res) => {\n${roleGuard} const { id } = req.params;\n const user = await User.findById(id);\n if (!user) return res.status(404).json({ error: 'User not found' });\n const { password: _, ...safe } = user;\n res.json({ user: safe });\n};\n\nexport const PUT = async (req, res) => {\n${roleGuard} const { id } = req.params;\n const { name, email, role, isActive } = req.body;\n const updated = await User.update(id, { name, email, role, isActive });\n if (!updated) return res.status(404).json({ error: 'User not found' });\n const { password: _, ...safe } = updated;\n res.json({ message: 'User updated', user: safe });\n};\n\nexport const DELETE = async (req, res) => {\n${roleGuard} const { id } = req.params;\n const user = await User.findById(id);\n if (!user) return res.status(404).json({ error: 'User not found' });\n await User.delete(id);\n res.json({ message: \\`User \\${id} deleted\\` });\n};\n`\n : ts\n ? `import { requireAuth } from 'express-file-cluster/auth';\nimport type { Request, Response } from 'express';\n${userByIdMeta}${middlewares}\nexport const GET = async (req: Request, res: Response) => {\n${roleGuard} const { id } = req.params;\n // TODO: fetch user from DB\n res.json({ user: { id } });\n};\n\nexport const PUT = async (req: Request, res: Response) => {\n${roleGuard} const { id } = req.params;\n // TODO: update user in DB\n res.json({ message: 'User updated', user: { id, ...req.body } });\n};\n\nexport const DELETE = async (req: Request, res: Response) => {\n${roleGuard} const { id } = req.params;\n // TODO: delete user from DB\n res.json({ message: \\`User \\${id} deleted\\` });\n};\n`\n : `import { requireAuth } from 'express-file-cluster/auth';\n${userByIdMeta}${middlewares}\nexport const GET = async (req, res) => {\n${roleGuard} const { id } = req.params;\n // TODO: fetch user from DB\n res.json({ user: { id } });\n};\n\nexport const PUT = async (req, res) => {\n${roleGuard} const { id } = req.params;\n // TODO: update user in DB\n res.json({ message: 'User updated', user: { id, ...req.body } });\n};\n\nexport const DELETE = async (req, res) => {\n${roleGuard} const { id } = req.params;\n // TODO: delete user from DB\n res.json({ message: \\`User \\${id} deleted\\` });\n};\n`;\n\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'users', `[id].${ext}`), userByIdContent);\n}\n\nasync function writeUserRoutes(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const ts = opts.language === 'typescript';\n const middlewares = opts.rbac\n ? `export const middlewares = [requireAuth('user', 'admin')];\\n`\n : `export const middlewares = [requireAuth];\\n`;\n\n const profileMeta = opts.routeDocs\n ? ts\n ? `import type { RouteMeta } from 'express-file-cluster';\\n\\nexport const meta: RouteMeta = {\\n description: \"View or update the authenticated user's profile.\",\\n response: { status: 200, body: { user: { id: '1', role: 'user', email: 'user@example.com' } } },\\n};\\n\\n`\n : `export const meta = {\\n description: \"View or update the authenticated user's profile.\",\\n response: { status: 200, body: { user: { id: '1', role: 'user', email: 'user@example.com' } } },\\n};\\n\\n`\n : '';\n\n const profileDbImport = opts.database === 'mongodb'\n ? `import { User } from '../../model/User.js';\\n`\n : '';\n\n const profileContent = opts.database === 'mongodb'\n ? ts\n ? `import { requireAuth } from 'express-file-cluster/auth';\nimport type { Request, Response } from 'express';\n${profileDbImport}${profileMeta}${middlewares}\nexport const GET = async (req: Request, res: Response) => {\n const { id } = (req as any).user;\n const user = await User.findById(id);\n if (!user) return res.status(404).json({ error: 'User not found' });\n const { password: _, ...safe } = user;\n res.json({ user: safe });\n};\n\nexport const PUT = async (req: Request, res: Response) => {\n const { id } = (req as any).user;\n const { name, email } = req.body;\n const updated = await User.update(id, { name, email });\n if (!updated) return res.status(404).json({ error: 'User not found' });\n const { password: _, ...safe } = updated;\n res.json({ message: 'Profile updated', user: safe });\n};\n`\n : `import { requireAuth } from 'express-file-cluster/auth';\n${profileDbImport}${profileMeta}${middlewares}\nexport const GET = async (req, res) => {\n const { id } = req.user;\n const user = await User.findById(id);\n if (!user) return res.status(404).json({ error: 'User not found' });\n const { password: _, ...safe } = user;\n res.json({ user: safe });\n};\n\nexport const PUT = async (req, res) => {\n const { id } = req.user;\n const { name, email } = req.body;\n const updated = await User.update(id, { name, email });\n if (!updated) return res.status(404).json({ error: 'User not found' });\n const { password: _, ...safe } = updated;\n res.json({ message: 'Profile updated', user: safe });\n};\n`\n : ts\n ? `import { requireAuth } from 'express-file-cluster/auth';\nimport type { Request, Response } from 'express';\n${profileMeta}${middlewares}\nexport const GET = async (req: Request, res: Response) => {\n res.json({ user: (req as any).user });\n};\n\nexport const PUT = async (req: Request, res: Response) => {\n const { name, email } = req.body;\n // TODO: update user in DB\n res.json({ message: 'Profile updated', user: { ...(req as any).user, name, email } });\n};\n`\n : `import { requireAuth } from 'express-file-cluster/auth';\n${profileMeta}${middlewares}\nexport const GET = async (req, res) => {\n res.json({ user: req.user });\n};\n\nexport const PUT = async (req, res) => {\n const { name, email } = req.body;\n // TODO: update user in DB\n res.json({ message: 'Profile updated', user: { ...req.user, name, email } });\n};\n`;\n\n await fs.outputFile(path.join(dest, 'src', 'api', 'user', `profile.${ext}`), profileContent);\n}\n\n// ─── META HELPER ─────────────────────────────────────────────────────────\n\nfunction mkMeta(opts: ScaffoldOptions, description: string, body: string, req?: string): string {\n if (!opts.routeDocs) return '';\n const reqLine = req ? ` request: { body: ${req} },\\n` : '';\n return opts.language === 'typescript'\n ? `import type { RouteMeta } from 'express-file-cluster';\\n\\nexport const meta: RouteMeta = {\\n description: '${description}',\\n${reqLine} response: { status: 200, body: ${body} },\\n};\\n\\n`\n : `export const meta = {\\n description: '${description}',\\n${reqLine} response: { status: 200, body: ${body} },\\n};\\n\\n`;\n}\n\n// ─── EXTENDED MODEL WRITERS ───────────────────────────────────────────────\n\nasync function writeSessionModel(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const ts = opts.language === 'typescript';\n const content = opts.database === 'mongodb'\n ? ts\n ? `import { defineModel } from 'express-file-cluster';\n\nexport interface SessionDocument {\n userId: string;\n token: string;\n ip: string;\n userAgent: string;\n expiresAt: Date;\n isActive: boolean;\n}\n\nexport const Session = defineModel<SessionDocument>('Session', {\n userId: { type: 'string', required: true },\n token: { type: 'string', required: true, unique: true },\n ip: { type: 'string', required: true },\n userAgent: { type: 'string', required: true },\n expiresAt: { type: 'date', required: true },\n isActive: { type: 'boolean', default: true },\n});\n`\n : `import { defineModel } from 'express-file-cluster';\n\nexport const Session = defineModel('Session', {\n userId: { type: 'string', required: true },\n token: { type: 'string', required: true, unique: true },\n ip: { type: 'string', required: true },\n userAgent: { type: 'string', required: true },\n expiresAt: { type: 'date', required: true },\n isActive: { type: 'boolean', default: true },\n});\n`\n : ts\n ? `// TODO: define your Drizzle schema for Session\n// import { pgTable, serial, text, boolean, timestamp } from 'drizzle-orm/pg-core';\n//\n// export const sessions = pgTable('sessions', {\n// id: serial('id').primaryKey(),\n// userId: text('user_id').notNull(),\n// token: text('token').notNull().unique(),\n// ip: text('ip').notNull(),\n// userAgent: text('user_agent').notNull(),\n// expiresAt: timestamp('expires_at').notNull(),\n// isActive: boolean('is_active').notNull().default(true),\n// });\nexport {};\n`\n : `// TODO: define your Drizzle schema for Session\nexport {};\n`;\n await fs.outputFile(path.join(dest, 'src', 'model', `Session.${ext}`), content);\n}\n\nasync function writeNotificationModel(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const ts = opts.language === 'typescript';\n const content = opts.database === 'mongodb'\n ? ts\n ? `import { defineModel } from 'express-file-cluster';\n\nexport interface NotificationDocument {\n userId: string;\n title: string;\n message: string;\n type: string;\n isRead: boolean;\n link?: string;\n}\n\nexport const Notification = defineModel<NotificationDocument>('Notification', {\n userId: { type: 'string', required: true },\n title: { type: 'string', required: true },\n message: { type: 'string', required: true },\n type: { type: 'string', required: true, default: 'info' },\n isRead: { type: 'boolean', default: false },\n link: { type: 'string' },\n});\n`\n : `import { defineModel } from 'express-file-cluster';\n\nexport const Notification = defineModel('Notification', {\n userId: { type: 'string', required: true },\n title: { type: 'string', required: true },\n message: { type: 'string', required: true },\n type: { type: 'string', required: true, default: 'info' },\n isRead: { type: 'boolean', default: false },\n link: { type: 'string' },\n});\n`\n : ts\n ? `// TODO: define your Drizzle schema for Notification\n// import { pgTable, serial, text, boolean, timestamp } from 'drizzle-orm/pg-core';\n//\n// export const notifications = pgTable('notifications', {\n// id: serial('id').primaryKey(),\n// userId: text('user_id').notNull(),\n// title: text('title').notNull(),\n// message: text('message').notNull(),\n// type: text('type').notNull().default('info'),\n// isRead: boolean('is_read').notNull().default(false),\n// link: text('link'),\n// createdAt: timestamp('created_at').defaultNow(),\n// });\nexport {};\n`\n : `// TODO: define your Drizzle schema for Notification\nexport {};\n`;\n await fs.outputFile(path.join(dest, 'src', 'model', `Notification.${ext}`), content);\n}\n\nasync function writeFileModel(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const ts = opts.language === 'typescript';\n const content = opts.database === 'mongodb'\n ? ts\n ? `import { defineModel } from 'express-file-cluster';\n\nexport interface FileDocument {\n userId: string;\n filename: string;\n originalName: string;\n mimeType: string;\n size: number;\n url: string;\n isPublic: boolean;\n}\n\nexport const File = defineModel<FileDocument>('File', {\n userId: { type: 'string', required: true },\n filename: { type: 'string', required: true },\n originalName: { type: 'string', required: true },\n mimeType: { type: 'string', required: true },\n size: { type: 'number', required: true },\n url: { type: 'string', required: true },\n isPublic: { type: 'boolean', default: false },\n});\n`\n : `import { defineModel } from 'express-file-cluster';\n\nexport const File = defineModel('File', {\n userId: { type: 'string', required: true },\n filename: { type: 'string', required: true },\n originalName: { type: 'string', required: true },\n mimeType: { type: 'string', required: true },\n size: { type: 'number', required: true },\n url: { type: 'string', required: true },\n isPublic: { type: 'boolean', default: false },\n});\n`\n : ts\n ? `// TODO: define your Drizzle schema for File\n// import { pgTable, serial, text, boolean, integer, timestamp } from 'drizzle-orm/pg-core';\n//\n// export const files = pgTable('files', {\n// id: serial('id').primaryKey(),\n// userId: text('user_id').notNull(),\n// filename: text('filename').notNull(),\n// originalName: text('original_name').notNull(),\n// mimeType: text('mime_type').notNull(),\n// size: integer('size').notNull(),\n// url: text('url').notNull(),\n// isPublic: boolean('is_public').notNull().default(false),\n// createdAt: timestamp('created_at').defaultNow(),\n// });\nexport {};\n`\n : `// TODO: define your Drizzle schema for File\nexport {};\n`;\n await fs.outputFile(path.join(dest, 'src', 'model', `File.${ext}`), content);\n}\n\nasync function writeSupportTicketModel(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const ts = opts.language === 'typescript';\n const content = opts.database === 'mongodb'\n ? ts\n ? `import { defineModel } from 'express-file-cluster';\n\nexport interface SupportTicketDocument {\n userId: string;\n subject: string;\n message: string;\n status: string;\n priority: string;\n assignedTo?: string;\n}\n\nexport const SupportTicket = defineModel<SupportTicketDocument>('SupportTicket', {\n userId: { type: 'string', required: true },\n subject: { type: 'string', required: true },\n message: { type: 'string', required: true },\n status: { type: 'string', required: true, default: 'open' },\n priority: { type: 'string', required: true, default: 'normal' },\n assignedTo: { type: 'string' },\n});\n`\n : `import { defineModel } from 'express-file-cluster';\n\nexport const SupportTicket = defineModel('SupportTicket', {\n userId: { type: 'string', required: true },\n subject: { type: 'string', required: true },\n message: { type: 'string', required: true },\n status: { type: 'string', required: true, default: 'open' },\n priority: { type: 'string', required: true, default: 'normal' },\n assignedTo: { type: 'string' },\n});\n`\n : ts\n ? `// TODO: define your Drizzle schema for SupportTicket\n// import { pgTable, serial, text, timestamp } from 'drizzle-orm/pg-core';\n//\n// export const supportTickets = pgTable('support_tickets', {\n// id: serial('id').primaryKey(),\n// userId: text('user_id').notNull(),\n// subject: text('subject').notNull(),\n// message: text('message').notNull(),\n// status: text('status').notNull().default('open'),\n// priority: text('priority').notNull().default('normal'),\n// assignedTo: text('assigned_to'),\n// createdAt: timestamp('created_at').defaultNow(),\n// updatedAt: timestamp('updated_at').defaultNow(),\n// });\nexport {};\n`\n : `// TODO: define your Drizzle schema for SupportTicket\nexport {};\n`;\n await fs.outputFile(path.join(dest, 'src', 'model', `SupportTicket.${ext}`), content);\n}\n\nasync function writeAuditLogModel(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const ts = opts.language === 'typescript';\n const content = opts.database === 'mongodb'\n ? ts\n ? `import { defineModel } from 'express-file-cluster';\n\nexport interface AuditLogDocument {\n adminId: string;\n action: string;\n entity: string;\n entityId: string;\n metadata?: Record<string, unknown>;\n ip: string;\n}\n\nexport const AuditLog = defineModel<AuditLogDocument>('AuditLog', {\n adminId: { type: 'string', required: true },\n action: { type: 'string', required: true },\n entity: { type: 'string', required: true },\n entityId: { type: 'string', required: true },\n metadata: { type: 'object' },\n ip: { type: 'string', required: true },\n});\n`\n : `import { defineModel } from 'express-file-cluster';\n\nexport const AuditLog = defineModel('AuditLog', {\n adminId: { type: 'string', required: true },\n action: { type: 'string', required: true },\n entity: { type: 'string', required: true },\n entityId: { type: 'string', required: true },\n metadata: { type: 'object' },\n ip: { type: 'string', required: true },\n});\n`\n : ts\n ? `// TODO: define your Drizzle schema for AuditLog\n// import { pgTable, serial, text, jsonb, timestamp } from 'drizzle-orm/pg-core';\n//\n// export const auditLogs = pgTable('audit_logs', {\n// id: serial('id').primaryKey(),\n// adminId: text('admin_id').notNull(),\n// action: text('action').notNull(),\n// entity: text('entity').notNull(),\n// entityId: text('entity_id').notNull(),\n// metadata: jsonb('metadata'),\n// ip: text('ip').notNull(),\n// createdAt: timestamp('created_at').defaultNow(),\n// });\nexport {};\n`\n : `// TODO: define your Drizzle schema for AuditLog\nexport {};\n`;\n await fs.outputFile(path.join(dest, 'src', 'model', `AuditLog.${ext}`), content);\n}\n\nasync function writeSubscriptionModel(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const ts = opts.language === 'typescript';\n const content = opts.database === 'mongodb'\n ? ts\n ? `import { defineModel } from 'express-file-cluster';\n\nexport interface SubscriptionDocument {\n userId: string;\n planId: string;\n status: string;\n startDate: Date;\n endDate: Date;\n cancelledAt?: Date;\n}\n\nexport const Subscription = defineModel<SubscriptionDocument>('Subscription', {\n userId: { type: 'string', required: true },\n planId: { type: 'string', required: true },\n status: { type: 'string', required: true, default: 'active' },\n startDate: { type: 'date', required: true },\n endDate: { type: 'date', required: true },\n cancelledAt: { type: 'date' },\n});\n`\n : `import { defineModel } from 'express-file-cluster';\n\nexport const Subscription = defineModel('Subscription', {\n userId: { type: 'string', required: true },\n planId: { type: 'string', required: true },\n status: { type: 'string', required: true, default: 'active' },\n startDate: { type: 'date', required: true },\n endDate: { type: 'date', required: true },\n cancelledAt: { type: 'date' },\n});\n`\n : ts\n ? `// TODO: define your Drizzle schema for Subscription\n// import { pgTable, serial, text, timestamp } from 'drizzle-orm/pg-core';\n//\n// export const subscriptions = pgTable('subscriptions', {\n// id: serial('id').primaryKey(),\n// userId: text('user_id').notNull(),\n// planId: text('plan_id').notNull(),\n// status: text('status').notNull().default('active'),\n// startDate: timestamp('start_date').notNull(),\n// endDate: timestamp('end_date').notNull(),\n// cancelledAt: timestamp('cancelled_at'),\n// createdAt: timestamp('created_at').defaultNow(),\n// });\nexport {};\n`\n : `// TODO: define your Drizzle schema for Subscription\nexport {};\n`;\n await fs.outputFile(path.join(dest, 'src', 'model', `Subscription.${ext}`), content);\n}\n\nasync function writePlanModel(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const ts = opts.language === 'typescript';\n const content = opts.database === 'mongodb'\n ? ts\n ? `import { defineModel } from 'express-file-cluster';\n\nexport interface PlanDocument {\n name: string;\n description: string;\n price: number;\n interval: string;\n features: string[];\n isActive: boolean;\n}\n\nexport const Plan = defineModel<PlanDocument>('Plan', {\n name: { type: 'string', required: true },\n description: { type: 'string', required: true },\n price: { type: 'number', required: true },\n interval: { type: 'string', required: true, default: 'monthly' },\n features: { type: 'array', default: [] },\n isActive: { type: 'boolean', default: true },\n});\n`\n : `import { defineModel } from 'express-file-cluster';\n\nexport const Plan = defineModel('Plan', {\n name: { type: 'string', required: true },\n description: { type: 'string', required: true },\n price: { type: 'number', required: true },\n interval: { type: 'string', required: true, default: 'monthly' },\n features: { type: 'array', default: [] },\n isActive: { type: 'boolean', default: true },\n});\n`\n : ts\n ? `// TODO: define your Drizzle schema for Plan\n// import { pgTable, serial, text, numeric, boolean, timestamp } from 'drizzle-orm/pg-core';\n//\n// export const plans = pgTable('plans', {\n// id: serial('id').primaryKey(),\n// name: text('name').notNull(),\n// description: text('description').notNull(),\n// price: numeric('price').notNull(),\n// interval: text('interval').notNull().default('monthly'),\n// features: text('features').array().notNull().default([]),\n// isActive: boolean('is_active').notNull().default(true),\n// createdAt: timestamp('created_at').defaultNow(),\n// });\nexport {};\n`\n : `// TODO: define your Drizzle schema for Plan\nexport {};\n`;\n await fs.outputFile(path.join(dest, 'src', 'model', `Plan.${ext}`), content);\n}\n\nasync function writeInvoiceModel(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const ts = opts.language === 'typescript';\n const content = opts.database === 'mongodb'\n ? ts\n ? `import { defineModel } from 'express-file-cluster';\n\nexport interface InvoiceDocument {\n userId: string;\n subscriptionId: string;\n amount: number;\n currency: string;\n status: string;\n paidAt?: Date;\n}\n\nexport const Invoice = defineModel<InvoiceDocument>('Invoice', {\n userId: { type: 'string', required: true },\n subscriptionId: { type: 'string', required: true },\n amount: { type: 'number', required: true },\n currency: { type: 'string', required: true, default: 'USD' },\n status: { type: 'string', required: true, default: 'pending' },\n paidAt: { type: 'date' },\n});\n`\n : `import { defineModel } from 'express-file-cluster';\n\nexport const Invoice = defineModel('Invoice', {\n userId: { type: 'string', required: true },\n subscriptionId: { type: 'string', required: true },\n amount: { type: 'number', required: true },\n currency: { type: 'string', required: true, default: 'USD' },\n status: { type: 'string', required: true, default: 'pending' },\n paidAt: { type: 'date' },\n});\n`\n : ts\n ? `// TODO: define your Drizzle schema for Invoice\n// import { pgTable, serial, text, numeric, timestamp } from 'drizzle-orm/pg-core';\n//\n// export const invoices = pgTable('invoices', {\n// id: serial('id').primaryKey(),\n// userId: text('user_id').notNull(),\n// subscriptionId: text('subscription_id').notNull(),\n// amount: numeric('amount').notNull(),\n// currency: text('currency').notNull().default('USD'),\n// status: text('status').notNull().default('pending'),\n// paidAt: timestamp('paid_at'),\n// createdAt: timestamp('created_at').defaultNow(),\n// });\nexport {};\n`\n : `// TODO: define your Drizzle schema for Invoice\nexport {};\n`;\n await fs.outputFile(path.join(dest, 'src', 'model', `Invoice.${ext}`), content);\n}\n\nasync function writeApiKeyModel(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const ts = opts.language === 'typescript';\n const content = opts.database === 'mongodb'\n ? ts\n ? `import { defineModel } from 'express-file-cluster';\n\nexport interface ApiKeyDocument {\n userId: string;\n name: string;\n key: string;\n lastUsed?: Date;\n expiresAt?: Date;\n isActive: boolean;\n}\n\nexport const ApiKey = defineModel<ApiKeyDocument>('ApiKey', {\n userId: { type: 'string', required: true },\n name: { type: 'string', required: true },\n key: { type: 'string', required: true, unique: true },\n lastUsed: { type: 'date' },\n expiresAt:{ type: 'date' },\n isActive: { type: 'boolean', default: true },\n});\n`\n : `import { defineModel } from 'express-file-cluster';\n\nexport const ApiKey = defineModel('ApiKey', {\n userId: { type: 'string', required: true },\n name: { type: 'string', required: true },\n key: { type: 'string', required: true, unique: true },\n lastUsed: { type: 'date' },\n expiresAt: { type: 'date' },\n isActive: { type: 'boolean', default: true },\n});\n`\n : ts\n ? `// TODO: define your Drizzle schema for ApiKey\n// import { pgTable, serial, text, boolean, timestamp } from 'drizzle-orm/pg-core';\n//\n// export const apiKeys = pgTable('api_keys', {\n// id: serial('id').primaryKey(),\n// userId: text('user_id').notNull(),\n// name: text('name').notNull(),\n// key: text('key').notNull().unique(),\n// lastUsed: timestamp('last_used'),\n// expiresAt: timestamp('expires_at'),\n// isActive: boolean('is_active').notNull().default(true),\n// createdAt: timestamp('created_at').defaultNow(),\n// });\nexport {};\n`\n : `// TODO: define your Drizzle schema for ApiKey\nexport {};\n`;\n await fs.outputFile(path.join(dest, 'src', 'model', `ApiKey.${ext}`), content);\n}\n\nasync function writeRoleModel(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const ts = opts.language === 'typescript';\n const content = opts.database === 'mongodb'\n ? ts\n ? `import { defineModel } from 'express-file-cluster';\n\nexport interface RoleDocument {\n name: string;\n description: string;\n permissions: string[];\n}\n\nexport const Role = defineModel<RoleDocument>('Role', {\n name: { type: 'string', required: true, unique: true },\n description: { type: 'string', required: true },\n permissions: { type: 'array', default: [] },\n});\n`\n : `import { defineModel } from 'express-file-cluster';\n\nexport const Role = defineModel('Role', {\n name: { type: 'string', required: true, unique: true },\n description: { type: 'string', required: true },\n permissions: { type: 'array', default: [] },\n});\n`\n : ts\n ? `// TODO: define your Drizzle schema for Role\n// import { pgTable, serial, text, timestamp } from 'drizzle-orm/pg-core';\n//\n// export const roles = pgTable('roles', {\n// id: serial('id').primaryKey(),\n// name: text('name').notNull().unique(),\n// description: text('description').notNull(),\n// permissions: text('permissions').array().notNull().default([]),\n// createdAt: timestamp('created_at').defaultNow(),\n// });\nexport {};\n`\n : `// TODO: define your Drizzle schema for Role\nexport {};\n`;\n await fs.outputFile(path.join(dest, 'src', 'model', `Role.${ext}`), content);\n}\n\nasync function writeFAQModel(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const ts = opts.language === 'typescript';\n const content = opts.database === 'mongodb'\n ? ts\n ? `import { defineModel } from 'express-file-cluster';\n\nexport interface FAQDocument {\n question: string;\n answer: string;\n category: string;\n order: number;\n isPublished: boolean;\n}\n\nexport const FAQ = defineModel<FAQDocument>('FAQ', {\n question: { type: 'string', required: true },\n answer: { type: 'string', required: true },\n category: { type: 'string', required: true, default: 'general' },\n order: { type: 'number', default: 0 },\n isPublished: { type: 'boolean', default: false },\n});\n`\n : `import { defineModel } from 'express-file-cluster';\n\nexport const FAQ = defineModel('FAQ', {\n question: { type: 'string', required: true },\n answer: { type: 'string', required: true },\n category: { type: 'string', required: true, default: 'general' },\n order: { type: 'number', default: 0 },\n isPublished: { type: 'boolean', default: false },\n});\n`\n : ts\n ? `// TODO: define your Drizzle schema for FAQ\n// import { pgTable, serial, text, boolean, integer, timestamp } from 'drizzle-orm/pg-core';\n//\n// export const faqs = pgTable('faqs', {\n// id: serial('id').primaryKey(),\n// question: text('question').notNull(),\n// answer: text('answer').notNull(),\n// category: text('category').notNull().default('general'),\n// order: integer('order').notNull().default(0),\n// isPublished: boolean('is_published').notNull().default(false),\n// createdAt: timestamp('created_at').defaultNow(),\n// });\nexport {};\n`\n : `// TODO: define your Drizzle schema for FAQ\nexport {};\n`;\n await fs.outputFile(path.join(dest, 'src', 'model', `FAQ.${ext}`), content);\n}\n\nasync function writeBlogModel(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const ts = opts.language === 'typescript';\n const content = opts.database === 'mongodb'\n ? ts\n ? `import { defineModel } from 'express-file-cluster';\n\nexport interface BlogDocument {\n title: string;\n slug: string;\n content: string;\n authorId: string;\n category: string;\n tags: string[];\n status: string;\n publishedAt?: Date;\n}\n\nexport const Blog = defineModel<BlogDocument>('Blog', {\n title: { type: 'string', required: true },\n slug: { type: 'string', required: true, unique: true },\n content: { type: 'string', required: true },\n authorId: { type: 'string', required: true },\n category: { type: 'string', required: true, default: 'general' },\n tags: { type: 'array', default: [] },\n status: { type: 'string', required: true, default: 'draft' },\n publishedAt: { type: 'date' },\n});\n`\n : `import { defineModel } from 'express-file-cluster';\n\nexport const Blog = defineModel('Blog', {\n title: { type: 'string', required: true },\n slug: { type: 'string', required: true, unique: true },\n content: { type: 'string', required: true },\n authorId: { type: 'string', required: true },\n category: { type: 'string', required: true, default: 'general' },\n tags: { type: 'array', default: [] },\n status: { type: 'string', required: true, default: 'draft' },\n publishedAt: { type: 'date' },\n});\n`\n : ts\n ? `// TODO: define your Drizzle schema for Blog\n// import { pgTable, serial, text, timestamp } from 'drizzle-orm/pg-core';\n//\n// export const blogs = pgTable('blogs', {\n// id: serial('id').primaryKey(),\n// title: text('title').notNull(),\n// slug: text('slug').notNull().unique(),\n// content: text('content').notNull(),\n// authorId: text('author_id').notNull(),\n// category: text('category').notNull().default('general'),\n// tags: text('tags').array().notNull().default([]),\n// status: text('status').notNull().default('draft'),\n// publishedAt: timestamp('published_at'),\n// createdAt: timestamp('created_at').defaultNow(),\n// updatedAt: timestamp('updated_at').defaultNow(),\n// });\nexport {};\n`\n : `// TODO: define your Drizzle schema for Blog\nexport {};\n`;\n await fs.outputFile(path.join(dest, 'src', 'model', `Blog.${ext}`), content);\n}\n\nasync function writeCategoryModel(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const ts = opts.language === 'typescript';\n const content = opts.database === 'mongodb'\n ? ts\n ? `import { defineModel } from 'express-file-cluster';\n\nexport interface CategoryDocument {\n name: string;\n slug: string;\n description?: string;\n parentId?: string;\n}\n\nexport const Category = defineModel<CategoryDocument>('Category', {\n name: { type: 'string', required: true },\n slug: { type: 'string', required: true, unique: true },\n description: { type: 'string' },\n parentId: { type: 'string' },\n});\n`\n : `import { defineModel } from 'express-file-cluster';\n\nexport const Category = defineModel('Category', {\n name: { type: 'string', required: true },\n slug: { type: 'string', required: true, unique: true },\n description: { type: 'string' },\n parentId: { type: 'string' },\n});\n`\n : ts\n ? `// TODO: define your Drizzle schema for Category\n// import { pgTable, serial, text, timestamp } from 'drizzle-orm/pg-core';\n//\n// export const categories = pgTable('categories', {\n// id: serial('id').primaryKey(),\n// name: text('name').notNull(),\n// slug: text('slug').notNull().unique(),\n// description: text('description'),\n// parentId: text('parent_id'),\n// createdAt: timestamp('created_at').defaultNow(),\n// });\nexport {};\n`\n : `// TODO: define your Drizzle schema for Category\nexport {};\n`;\n await fs.outputFile(path.join(dest, 'src', 'model', `Category.${ext}`), content);\n}\n\nasync function writeCouponModel(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const ts = opts.language === 'typescript';\n const content = opts.database === 'mongodb'\n ? ts\n ? `import { defineModel } from 'express-file-cluster';\n\nexport interface CouponDocument {\n code: string;\n type: string;\n value: number;\n maxUses: number;\n usedCount: number;\n expiresAt?: Date;\n isActive: boolean;\n}\n\nexport const Coupon = defineModel<CouponDocument>('Coupon', {\n code: { type: 'string', required: true, unique: true },\n type: { type: 'string', required: true, default: 'percent' },\n value: { type: 'number', required: true },\n maxUses: { type: 'number', default: 0 },\n usedCount: { type: 'number', default: 0 },\n expiresAt: { type: 'date' },\n isActive: { type: 'boolean', default: true },\n});\n`\n : `import { defineModel } from 'express-file-cluster';\n\nexport const Coupon = defineModel('Coupon', {\n code: { type: 'string', required: true, unique: true },\n type: { type: 'string', required: true, default: 'percent' },\n value: { type: 'number', required: true },\n maxUses: { type: 'number', default: 0 },\n usedCount: { type: 'number', default: 0 },\n expiresAt: { type: 'date' },\n isActive: { type: 'boolean', default: true },\n});\n`\n : ts\n ? `// TODO: define your Drizzle schema for Coupon\n// import { pgTable, serial, text, numeric, integer, boolean, timestamp } from 'drizzle-orm/pg-core';\n//\n// export const coupons = pgTable('coupons', {\n// id: serial('id').primaryKey(),\n// code: text('code').notNull().unique(),\n// type: text('type').notNull().default('percent'),\n// value: numeric('value').notNull(),\n// maxUses: integer('max_uses').notNull().default(0),\n// usedCount: integer('used_count').notNull().default(0),\n// expiresAt: timestamp('expires_at'),\n// isActive: boolean('is_active').notNull().default(true),\n// createdAt: timestamp('created_at').defaultNow(),\n// });\nexport {};\n`\n : `// TODO: define your Drizzle schema for Coupon\nexport {};\n`;\n await fs.outputFile(path.join(dest, 'src', 'model', `Coupon.${ext}`), content);\n}\n\n// ─── EXTENDED ROUTE WRITERS ───────────────────────────────────────────────\n\nasync function writeAuthExtendedRoutes(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const ts = opts.language === 'typescript';\n const mwUser2 = opts.rbac\n ? `export const middlewares = [requireAuth('user', 'admin')];\\n`\n : `export const middlewares = [requireAuth];\\n`;\n const mwUser3 = mwUser2;\n const reqT = ts ? `import type { Request, Response } from 'express';\\n` : '';\n const RA = `import { requireAuth } from 'express-file-cluster/auth';\\n`;\n\n const mongo = opts.database === 'mongodb';\n const sendResetEmail = opts.mailer\n ? ` var appUrl = process.env.APP_URL || 'http://localhost:3000';\n await enqueue('SendEmail', {\n to: email,\n subject: 'Reset your password',\n body: 'Reset your password: ' + appUrl + '/auth/reset-password?token=' + resetToken,\n });\n`\n : ` // TODO: email this token to the user — enable the Mailer feature to auto-wire SendEmail\n`;\n const sendVerifyEmailResend = opts.mailer\n ? ` var appUrl = process.env.APP_URL || 'http://localhost:3000';\n await enqueue('SendEmail', {\n to: email,\n subject: 'Verify your email address',\n body: 'Verify your email: ' + appUrl + '/auth/verify-email?token=' + verifyToken,\n });\n`\n : ` // TODO: email this token to the user — enable the Mailer feature to auto-wire SendEmail\n`;\n const mailerTaskImport = opts.mailer ? `import { enqueue } from 'express-file-cluster/tasks';\\n` : '';\n\n // refresh.ts\n const refreshMeta = mkMeta(opts, 'Refresh the JWT and issue a new token.', `{ message: 'Token refreshed' }`);\n const refreshContent = mongo\n ? ts\n ? `import { issueToken } from 'express-file-cluster/auth';\nimport type { Request, Response } from 'express';\nimport crypto from 'node:crypto';\nimport { User } from '../../model/User.js';\nimport { Admin } from '../../model/Admin.js';\n${refreshMeta}const REFRESH_TOKEN_TTL_MS = 1000 * 60 * 60 * 24 * 30; // 30 days\n\nexport const POST = async (req: Request, res: Response) => {\n const token = req.cookies?.['efc_refresh_token'] || req.body?.refreshToken;\n if (!token) return res.status(401).json({ error: 'Refresh token required' });\n\n const user = await User.findOne({ refreshToken: token });\n const admin = user ? null : await Admin.findOne({ refreshToken: token });\n const account = user || admin;\n\n if (!account || !account.refreshTokenExpiry || new Date(account.refreshTokenExpiry) < new Date()) {\n return res.status(401).json({ error: 'Invalid or expired refresh token' });\n }\n\n const newRefreshToken = crypto.randomBytes(40).toString('hex');\n const refreshTokenExpiry = new Date(Date.now() + REFRESH_TOKEN_TTL_MS);\n if (user) await User.update(user.id, { refreshToken: newRefreshToken, refreshTokenExpiry });\n else if (admin) await Admin.update(admin.id, { refreshToken: newRefreshToken, refreshTokenExpiry });\n\n res.cookie('efc_refresh_token', newRefreshToken, {\n httpOnly: true,\n secure: process.env.NODE_ENV === 'production',\n sameSite: 'strict',\n maxAge: REFRESH_TOKEN_TTL_MS,\n });\n\n await issueToken(res, { id: account.id, role: account.role, email: account.email });\n res.json({ message: 'Token refreshed' });\n};\n`\n : `import { issueToken } from 'express-file-cluster/auth';\nimport crypto from 'node:crypto';\nimport { User } from '../../model/User.js';\nimport { Admin } from '../../model/Admin.js';\n${refreshMeta}const REFRESH_TOKEN_TTL_MS = 1000 * 60 * 60 * 24 * 30; // 30 days\n\nexport const POST = async (req, res) => {\n const token = req.cookies?.efc_refresh_token || req.body?.refreshToken;\n if (!token) return res.status(401).json({ error: 'Refresh token required' });\n\n const user = await User.findOne({ refreshToken: token });\n const admin = user ? null : await Admin.findOne({ refreshToken: token });\n const account = user || admin;\n\n if (!account || !account.refreshTokenExpiry || new Date(account.refreshTokenExpiry) < new Date()) {\n return res.status(401).json({ error: 'Invalid or expired refresh token' });\n }\n\n const newRefreshToken = crypto.randomBytes(40).toString('hex');\n const refreshTokenExpiry = new Date(Date.now() + REFRESH_TOKEN_TTL_MS);\n if (user) await User.update(user.id, { refreshToken: newRefreshToken, refreshTokenExpiry });\n else if (admin) await Admin.update(admin.id, { refreshToken: newRefreshToken, refreshTokenExpiry });\n\n res.cookie('efc_refresh_token', newRefreshToken, {\n httpOnly: true,\n secure: process.env.NODE_ENV === 'production',\n sameSite: 'strict',\n maxAge: REFRESH_TOKEN_TTL_MS,\n });\n\n await issueToken(res, { id: account.id, role: account.role, email: account.email });\n res.json({ message: 'Token refreshed' });\n};\n`\n : ts\n ? `${RA}import type { Request, Response } from 'express';\n${refreshMeta}export const POST = async (_req: Request, res: Response) => {\n // TODO: validate refresh token, issue new JWT\n res.json({ message: 'Token refreshed' });\n};\n`\n : `${RA}${refreshMeta}export const POST = async (_req, res) => {\n // TODO: validate refresh token, issue new JWT\n res.json({ message: 'Token refreshed' });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'auth', `refresh.${ext}`), refreshContent);\n\n // verify-email.ts\n const veMeta = mkMeta(opts, 'Verify email address via token or resend verification email.', `{ message: 'Email verified' }`);\n const veContent = mongo\n ? ts\n ? `import type { Request, Response } from 'express';\nimport crypto from 'node:crypto';\n${mailerTaskImport}import { User } from '../../model/User.js';\n${veMeta}export const GET = async (req: Request, res: Response) => {\n const { token } = req.query;\n if (!token || typeof token !== 'string') return res.status(400).json({ error: 'token is required' });\n\n const user = await User.findOne({ verifyToken: token });\n if (!user) return res.status(400).json({ error: 'Invalid or expired verification token' });\n\n await User.update(user.id, { isVerified: true, verifyToken: '' });\n res.json({ message: 'Email verified' });\n};\n\nexport const POST = async (req: Request, res: Response) => {\n const { email } = req.body;\n if (!email) return res.status(400).json({ error: 'email is required' });\n\n const user = await User.findOne({ email });\n if (user && !user.isVerified) {\n const verifyToken = crypto.randomBytes(32).toString('hex');\n await User.update(user.id, { verifyToken });\n${sendVerifyEmailResend} }\n\n res.json({ message: 'Verification email sent' });\n};\n`\n : `import crypto from 'node:crypto';\n${mailerTaskImport}import { User } from '../../model/User.js';\n${veMeta}export const GET = async (req, res) => {\n const { token } = req.query;\n if (!token || typeof token !== 'string') return res.status(400).json({ error: 'token is required' });\n\n const user = await User.findOne({ verifyToken: token });\n if (!user) return res.status(400).json({ error: 'Invalid or expired verification token' });\n\n await User.update(user.id, { isVerified: true, verifyToken: '' });\n res.json({ message: 'Email verified' });\n};\n\nexport const POST = async (req, res) => {\n const { email } = req.body;\n if (!email) return res.status(400).json({ error: 'email is required' });\n\n const user = await User.findOne({ email });\n if (user && !user.isVerified) {\n const verifyToken = crypto.randomBytes(32).toString('hex');\n await User.update(user.id, { verifyToken });\n${sendVerifyEmailResend} }\n\n res.json({ message: 'Verification email sent' });\n};\n`\n : ts\n ? `${RA}import type { Request, Response } from 'express';\n${veMeta}export const GET = async (req: Request, res: Response) => {\n const { token } = req.query;\n // TODO: verify token and mark user as verified\n res.json({ message: 'Email verified' });\n};\n\nexport const POST = async (_req: Request, res: Response) => {\n // TODO: resend verification email\n res.json({ message: 'Verification email sent' });\n};\n`\n : `${RA}${veMeta}export const GET = async (req, res) => {\n const { token } = req.query;\n // TODO: verify token and mark user as verified\n res.json({ message: 'Email verified' });\n};\n\nexport const POST = async (_req, res) => {\n // TODO: resend verification email\n res.json({ message: 'Verification email sent' });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'auth', `verify-email.${ext}`), veContent);\n\n // forgot-password.ts\n const fpMeta = mkMeta(opts, 'Send a password reset email to the given address.', `{ message: 'Reset email sent' }`, `{ email: 'user@example.com' }`);\n const fpContent = mongo\n ? ts\n ? `import type { Request, Response } from 'express';\nimport crypto from 'node:crypto';\n${mailerTaskImport}import { User } from '../../model/User.js';\nimport { Admin } from '../../model/Admin.js';\n${fpMeta}const RESET_TOKEN_TTL_MS = 1000 * 60 * 60; // 1 hour\n\nexport const POST = async (req: Request, res: Response) => {\n const { email } = req.body;\n if (!email) return res.status(400).json({ error: 'email is required' });\n\n const user = await User.findOne({ email });\n const admin = user ? null : await Admin.findOne({ email });\n\n // Always respond the same way whether or not the account exists, so this\n // endpoint can't be used to enumerate registered emails.\n if (user || admin) {\n const resetToken = crypto.randomBytes(32).toString('hex');\n const resetTokenExpiry = new Date(Date.now() + RESET_TOKEN_TTL_MS);\n if (user) await User.update(user.id, { resetToken, resetTokenExpiry });\n else if (admin) await Admin.update(admin.id, { resetToken, resetTokenExpiry });\n${sendResetEmail} }\n\n res.json({ message: 'Reset email sent' });\n};\n`\n : `import crypto from 'node:crypto';\n${mailerTaskImport}import { User } from '../../model/User.js';\nimport { Admin } from '../../model/Admin.js';\n${fpMeta}const RESET_TOKEN_TTL_MS = 1000 * 60 * 60; // 1 hour\n\nexport const POST = async (req, res) => {\n const { email } = req.body;\n if (!email) return res.status(400).json({ error: 'email is required' });\n\n const user = await User.findOne({ email });\n const admin = user ? null : await Admin.findOne({ email });\n\n // Always respond the same way whether or not the account exists, so this\n // endpoint can't be used to enumerate registered emails.\n if (user || admin) {\n const resetToken = crypto.randomBytes(32).toString('hex');\n const resetTokenExpiry = new Date(Date.now() + RESET_TOKEN_TTL_MS);\n if (user) await User.update(user.id, { resetToken, resetTokenExpiry });\n else if (admin) await Admin.update(admin.id, { resetToken, resetTokenExpiry });\n${sendResetEmail} }\n\n res.json({ message: 'Reset email sent' });\n};\n`\n : ts\n ? `${RA}import type { Request, Response } from 'express';\n${fpMeta}export const POST = async (req: Request, res: Response) => {\n const { email } = req.body;\n if (!email) return res.status(400).json({ error: 'email is required' });\n // TODO: generate reset token and send email\n res.json({ message: 'Reset email sent' });\n};\n`\n : `${RA}${fpMeta}export const POST = async (req, res) => {\n const { email } = req.body;\n if (!email) return res.status(400).json({ error: 'email is required' });\n // TODO: generate reset token and send email\n res.json({ message: 'Reset email sent' });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'auth', `forgot-password.${ext}`), fpContent);\n\n // reset-password.ts\n const rpMeta = mkMeta(opts, 'Reset password using a valid reset token.', `{ message: 'Password reset successfully' }`, `{ token: 'reset-token', password: 'newpassword' }`);\n const rpContent = mongo\n ? ts\n ? `import type { Request, Response } from 'express';\nimport bcrypt from 'bcrypt';\nimport { User } from '../../model/User.js';\nimport { Admin } from '../../model/Admin.js';\n${rpMeta}export const POST = async (req: Request, res: Response) => {\n const { token, password } = req.body;\n if (!token || !password) return res.status(400).json({ error: 'token and password are required' });\n\n const user = await User.findOne({ resetToken: token });\n const admin = user ? null : await Admin.findOne({ resetToken: token });\n const account = user || admin;\n\n if (!account || !account.resetTokenExpiry || new Date(account.resetTokenExpiry) < new Date()) {\n return res.status(400).json({ error: 'Invalid or expired reset token' });\n }\n\n const hashed = await bcrypt.hash(password, 10);\n if (user) await User.update(user.id, { password: hashed, resetToken: '' });\n else if (admin) await Admin.update(admin.id, { password: hashed, resetToken: '' });\n\n res.json({ message: 'Password reset successfully' });\n};\n`\n : `import bcrypt from 'bcrypt';\nimport { User } from '../../model/User.js';\nimport { Admin } from '../../model/Admin.js';\n${rpMeta}export const POST = async (req, res) => {\n const { token, password } = req.body;\n if (!token || !password) return res.status(400).json({ error: 'token and password are required' });\n\n const user = await User.findOne({ resetToken: token });\n const admin = user ? null : await Admin.findOne({ resetToken: token });\n const account = user || admin;\n\n if (!account || !account.resetTokenExpiry || new Date(account.resetTokenExpiry) < new Date()) {\n return res.status(400).json({ error: 'Invalid or expired reset token' });\n }\n\n const hashed = await bcrypt.hash(password, 10);\n if (user) await User.update(user.id, { password: hashed, resetToken: '' });\n else if (admin) await Admin.update(admin.id, { password: hashed, resetToken: '' });\n\n res.json({ message: 'Password reset successfully' });\n};\n`\n : ts\n ? `${RA}import type { Request, Response } from 'express';\n${rpMeta}export const POST = async (req: Request, res: Response) => {\n const { token, password } = req.body;\n if (!token || !password) return res.status(400).json({ error: 'token and password are required' });\n // TODO: validate token, hash and update password\n res.json({ message: 'Password reset successfully' });\n};\n`\n : `${RA}${rpMeta}export const POST = async (req, res) => {\n const { token, password } = req.body;\n if (!token || !password) return res.status(400).json({ error: 'token and password are required' });\n // TODO: validate token, hash and update password\n res.json({ message: 'Password reset successfully' });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'auth', `reset-password.${ext}`), rpContent);\n\n // change-password.ts (protected)\n const cpMeta = mkMeta(opts, 'Change password for the authenticated user.', `{ message: 'Password changed successfully' }`, `{ oldPassword: 'current', newPassword: 'newpassword' }`);\n const cpContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${cpMeta}${mwUser2}\nexport const POST = async (req: Request, res: Response) => {\n const { oldPassword, newPassword } = req.body;\n if (!oldPassword || !newPassword) return res.status(400).json({ error: 'oldPassword and newPassword are required' });\n // TODO: verify old password, hash and update new password\n res.json({ message: 'Password changed successfully' });\n};\n`\n : `${RA}${cpMeta}${mwUser2}\nexport const POST = async (req, res) => {\n const { oldPassword, newPassword } = req.body;\n if (!oldPassword || !newPassword) return res.status(400).json({ error: 'oldPassword and newPassword are required' });\n // TODO: verify old password, hash and update new password\n res.json({ message: 'Password changed successfully' });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'auth', `change-password.${ext}`), cpContent);\n\n // 2fa/setup.ts\n const tfaSetupMeta = mkMeta(opts, 'Get 2FA QR code (GET) or enable 2FA with a verified TOTP code (POST).', `{ message: '2FA enabled' }`);\n const tfaSetupContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${tfaSetupMeta}${mwUser3}\nexport const GET = async (req: Request, res: Response) => {\n // TODO: generate TOTP secret and return QR code URL\n res.json({ qrCode: 'otpauth://totp/...', secret: 'BASE32SECRET' });\n};\n\nexport const POST = async (req: Request, res: Response) => {\n const { code } = req.body;\n if (!code) return res.status(400).json({ error: 'code is required' });\n // TODO: verify TOTP code and enable 2FA\n res.json({ message: '2FA enabled' });\n};\n`\n : `${RA}${tfaSetupMeta}${mwUser3}\nexport const GET = async (req, res) => {\n // TODO: generate TOTP secret and return QR code URL\n res.json({ qrCode: 'otpauth://totp/...', secret: 'BASE32SECRET' });\n};\n\nexport const POST = async (req, res) => {\n const { code } = req.body;\n if (!code) return res.status(400).json({ error: 'code is required' });\n // TODO: verify TOTP code and enable 2FA\n res.json({ message: '2FA enabled' });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'auth', '2fa', `setup.${ext}`), tfaSetupContent);\n\n // 2fa/verify.ts\n const tfaVerifyMeta = mkMeta(opts, 'Verify a TOTP code during login.', `{ message: '2FA verified' }`);\n const tfaVerifyContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${tfaVerifyMeta}export const POST = async (req: Request, res: Response) => {\n const { code } = req.body;\n if (!code) return res.status(400).json({ error: 'code is required' });\n // TODO: verify TOTP code\n res.json({ message: '2FA verified' });\n};\n`\n : `${RA}${tfaVerifyMeta}export const POST = async (req, res) => {\n const { code } = req.body;\n if (!code) return res.status(400).json({ error: 'code is required' });\n // TODO: verify TOTP code\n res.json({ message: '2FA verified' });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'auth', '2fa', `verify.${ext}`), tfaVerifyContent);\n\n // 2fa/disable.ts\n const tfaDisableMeta = mkMeta(opts, 'Disable 2FA for the authenticated user.', `{ message: '2FA disabled' }`);\n const tfaDisableContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${tfaDisableMeta}${mwUser3}\nexport const POST = async (req: Request, res: Response) => {\n const { code } = req.body;\n if (!code) return res.status(400).json({ error: 'code is required' });\n // TODO: verify code and disable 2FA\n res.json({ message: '2FA disabled' });\n};\n`\n : `${RA}${tfaDisableMeta}${mwUser3}\nexport const POST = async (req, res) => {\n const { code } = req.body;\n if (!code) return res.status(400).json({ error: 'code is required' });\n // TODO: verify code and disable 2FA\n res.json({ message: '2FA disabled' });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'auth', '2fa', `disable.${ext}`), tfaDisableContent);\n\n // sessions/index.ts\n const sessListMeta = mkMeta(opts, 'List all active sessions for the authenticated user.', `{ sessions: [] }`);\n const sessListContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${sessListMeta}${mwUser3}\nexport const GET = async (req: Request, res: Response) => {\n // TODO: fetch sessions for req.user.id\n res.json({ sessions: [] });\n};\n`\n : `${RA}${sessListMeta}${mwUser3}\nexport const GET = async (req, res) => {\n // TODO: fetch sessions for req.user.id\n res.json({ sessions: [] });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'auth', 'sessions', `index.${ext}`), sessListContent);\n\n // sessions/[id].ts\n const sessRevokeContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${mwUser3}\nexport const DELETE = async (req: Request, res: Response) => {\n const { id } = req.params;\n // TODO: revoke session by id\n res.json({ message: \\`Session \\${id} revoked\\` });\n};\n`\n : `${RA}${mwUser3}\nexport const DELETE = async (req, res) => {\n const { id } = req.params;\n // TODO: revoke session by id\n res.json({ message: \\`Session \\${id} revoked\\` });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'auth', 'sessions', `[id].${ext}`), sessRevokeContent);\n}\n\nasync function writeUserExtendedRoutes(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const ts = opts.language === 'typescript';\n // user/* = 2 levels up to src/, user/subdir/* = 3 levels\n const mw2 = opts.rbac\n ? `export const middlewares = [requireAuth('user', 'admin')];\\n`\n : `export const middlewares = [requireAuth];\\n`;\n const mw3 = mw2;\n const RA = `import { requireAuth } from 'express-file-cluster/auth';\\n`;\n const user = ts ? `(req as any).user` : `req.user`;\n\n // avatar.ts\n const avatarMeta = mkMeta(opts, 'Upload (POST) or remove (DELETE) the authenticated user avatar.', `{ message: 'Avatar updated', url: 'https://...' }`);\n const avatarContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${avatarMeta}${mw2}\nexport const POST = async (req: Request, res: Response) => {\n // TODO: handle multipart upload, store file, update user.avatar\n res.json({ message: 'Avatar updated', url: 'https://example.com/avatar.jpg' });\n};\n\nexport const DELETE = async (req: Request, res: Response) => {\n // TODO: remove avatar and clear user.avatar\n res.json({ message: 'Avatar removed' });\n};\n`\n : `${RA}${avatarMeta}${mw2}\nexport const POST = async (req, res) => {\n // TODO: handle multipart upload, store file, update user.avatar\n res.json({ message: 'Avatar updated', url: 'https://example.com/avatar.jpg' });\n};\n\nexport const DELETE = async (req, res) => {\n // TODO: remove avatar and clear user.avatar\n res.json({ message: 'Avatar removed' });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'user', `avatar.${ext}`), avatarContent);\n\n // settings.ts\n const settingsMeta = mkMeta(opts, 'Get or update account settings (notifications, language, theme, privacy).', `{ settings: { notifications: true, language: 'en', theme: 'system' } }`);\n const settingsContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${settingsMeta}${mw2}\nexport const GET = async (req: Request, res: Response) => {\n // TODO: fetch user settings from DB\n res.json({ settings: { notifications: true, language: 'en', theme: 'system', privacy: 'public' } });\n};\n\nexport const PUT = async (req: Request, res: Response) => {\n const { notifications, language, theme, privacy } = req.body;\n // TODO: update user settings in DB\n res.json({ message: 'Settings updated', settings: { notifications, language, theme, privacy } });\n};\n`\n : `${RA}${settingsMeta}${mw2}\nexport const GET = async (req, res) => {\n // TODO: fetch user settings from DB\n res.json({ settings: { notifications: true, language: 'en', theme: 'system', privacy: 'public' } });\n};\n\nexport const PUT = async (req, res) => {\n const { notifications, language, theme, privacy } = req.body;\n // TODO: update user settings in DB\n res.json({ message: 'Settings updated', settings: { notifications, language, theme, privacy } });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'user', `settings.${ext}`), settingsContent);\n\n // account.ts\n const accountMeta = mkMeta(opts, 'Delete account (DELETE) or download personal data (GET).', `{ message: 'Account deleted' }`);\n const accountContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${accountMeta}${mw2}\nexport const GET = async (req: Request, res: Response) => {\n // TODO: compile and return personal data export\n res.json({ data: { user: ${user}, exportedAt: new Date().toISOString() } });\n};\n\nexport const DELETE = async (req: Request, res: Response) => {\n const { password } = req.body;\n if (!password) return res.status(400).json({ error: 'password confirmation required' });\n // TODO: verify password, schedule account deletion\n res.json({ message: 'Account scheduled for deletion' });\n};\n`\n : `${RA}${accountMeta}${mw2}\nexport const GET = async (req, res) => {\n // TODO: compile and return personal data export\n res.json({ data: { user: ${user}, exportedAt: new Date().toISOString() } });\n};\n\nexport const DELETE = async (req, res) => {\n const { password } = req.body;\n if (!password) return res.status(400).json({ error: 'password confirmation required' });\n // TODO: verify password, schedule account deletion\n res.json({ message: 'Account scheduled for deletion' });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'user', `account.${ext}`), accountContent);\n\n // dashboard.ts\n const dashMeta = mkMeta(opts, 'Personal dashboard: stats, recent activity, and quick actions.', `{ stats: {}, recentActivity: [], quickActions: [] }`);\n const dashContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${dashMeta}${mw2}\nexport const GET = async (req: Request, res: Response) => {\n // TODO: aggregate personal stats and activity\n res.json({ stats: {}, recentActivity: [], quickActions: [] });\n};\n`\n : `${RA}${dashMeta}${mw2}\nexport const GET = async (req, res) => {\n // TODO: aggregate personal stats and activity\n res.json({ stats: {}, recentActivity: [], quickActions: [] });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'user', `dashboard.${ext}`), dashContent);\n\n // activity.ts\n const actMeta = mkMeta(opts, 'Paginated activity history for the authenticated user.', `{ activities: [], total: 0, page: 1, limit: 20 }`);\n const actContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${actMeta}${mw2}\nexport const GET = async (req: Request, res: Response) => {\n const { page = 1, limit = 20 } = req.query;\n // TODO: fetch paginated activity log\n res.json({ activities: [], total: 0, page: Number(page), limit: Number(limit) });\n};\n`\n : `${RA}${actMeta}${mw2}\nexport const GET = async (req, res) => {\n const { page = 1, limit = 20 } = req.query;\n // TODO: fetch paginated activity log\n res.json({ activities: [], total: 0, page: Number(page), limit: Number(limit) });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'user', `activity.${ext}`), actContent);\n\n // notifications/index.ts\n const notifListMeta = mkMeta(opts, 'List notifications (GET) or mark all as read (POST).', `{ notifications: [], total: 0, unread: 0 }`);\n const notifListContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${notifListMeta}${mw3}\nexport const GET = async (req: Request, res: Response) => {\n // TODO: fetch notifications for user\n res.json({ notifications: [], total: 0, unread: 0 });\n};\n\nexport const POST = async (req: Request, res: Response) => {\n // TODO: mark all notifications as read\n res.json({ message: 'All notifications marked as read' });\n};\n`\n : `${RA}${notifListMeta}${mw3}\nexport const GET = async (req, res) => {\n // TODO: fetch notifications for user\n res.json({ notifications: [], total: 0, unread: 0 });\n};\n\nexport const POST = async (req, res) => {\n // TODO: mark all notifications as read\n res.json({ message: 'All notifications marked as read' });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'user', 'notifications', `index.${ext}`), notifListContent);\n\n // notifications/[id].ts\n const notifByIdContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${mw3}\nexport const GET = async (req: Request, res: Response) => {\n const { id } = req.params;\n // TODO: fetch notification by id\n res.json({ notification: { id } });\n};\n\nexport const PATCH = async (req: Request, res: Response) => {\n const { id } = req.params;\n // TODO: mark notification as read\n res.json({ message: 'Notification marked as read', id });\n};\n\nexport const DELETE = async (req: Request, res: Response) => {\n const { id } = req.params;\n // TODO: delete notification\n res.json({ message: \\`Notification \\${id} deleted\\` });\n};\n`\n : `${RA}${mw3}\nexport const GET = async (req, res) => {\n const { id } = req.params;\n // TODO: fetch notification by id\n res.json({ notification: { id } });\n};\n\nexport const PATCH = async (req, res) => {\n const { id } = req.params;\n // TODO: mark notification as read\n res.json({ message: 'Notification marked as read', id });\n};\n\nexport const DELETE = async (req, res) => {\n const { id } = req.params;\n // TODO: delete notification\n res.json({ message: \\`Notification \\${id} deleted\\` });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'user', 'notifications', `[id].${ext}`), notifByIdContent);\n\n // files/index.ts\n const filesListMeta = mkMeta(opts, 'List uploaded files with storage usage (GET) or upload a new file (POST).', `{ files: [], total: 0, storageUsed: 0 }`);\n const filesListContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${filesListMeta}${mw3}\nexport const GET = async (req: Request, res: Response) => {\n // TODO: fetch user files and compute storage usage\n res.json({ files: [], total: 0, storageUsed: 0 });\n};\n\nexport const POST = async (req: Request, res: Response) => {\n // TODO: handle multipart upload, persist file record\n res.status(201).json({ message: 'File uploaded', file: { id: 'new-id' } });\n};\n`\n : `${RA}${filesListMeta}${mw3}\nexport const GET = async (req, res) => {\n // TODO: fetch user files and compute storage usage\n res.json({ files: [], total: 0, storageUsed: 0 });\n};\n\nexport const POST = async (req, res) => {\n // TODO: handle multipart upload, persist file record\n res.status(201).json({ message: 'File uploaded', file: { id: 'new-id' } });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'user', 'files', `index.${ext}`), filesListContent);\n\n // files/[id].ts\n const fileByIdContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${mw3}\nexport const GET = async (req: Request, res: Response) => {\n const { id } = req.params;\n // TODO: stream or redirect to file download/preview URL\n res.json({ file: { id, url: 'https://...' } });\n};\n\nexport const DELETE = async (req: Request, res: Response) => {\n const { id } = req.params;\n // TODO: delete file from storage and DB\n res.json({ message: \\`File \\${id} deleted\\` });\n};\n`\n : `${RA}${mw3}\nexport const GET = async (req, res) => {\n const { id } = req.params;\n // TODO: stream or redirect to file download/preview URL\n res.json({ file: { id, url: 'https://...' } });\n};\n\nexport const DELETE = async (req, res) => {\n const { id } = req.params;\n // TODO: delete file from storage and DB\n res.json({ message: \\`File \\${id} deleted\\` });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'user', 'files', `[id].${ext}`), fileByIdContent);\n\n // favorites/index.ts\n const favListContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${mw3}\nexport const GET = async (req: Request, res: Response) => {\n // TODO: fetch user favorites\n res.json({ favorites: [] });\n};\n\nexport const POST = async (req: Request, res: Response) => {\n const { entityId, entityType } = req.body;\n if (!entityId || !entityType) return res.status(400).json({ error: 'entityId and entityType are required' });\n // TODO: add to favorites\n res.status(201).json({ message: 'Added to favorites' });\n};\n`\n : `${RA}${mw3}\nexport const GET = async (req, res) => {\n // TODO: fetch user favorites\n res.json({ favorites: [] });\n};\n\nexport const POST = async (req, res) => {\n const { entityId, entityType } = req.body;\n if (!entityId || !entityType) return res.status(400).json({ error: 'entityId and entityType are required' });\n // TODO: add to favorites\n res.status(201).json({ message: 'Added to favorites' });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'user', 'favorites', `index.${ext}`), favListContent);\n\n // favorites/[id].ts\n const favByIdContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${mw3}\nexport const DELETE = async (req: Request, res: Response) => {\n const { id } = req.params;\n // TODO: remove from favorites\n res.json({ message: \\`Removed favorite \\${id}\\` });\n};\n`\n : `${RA}${mw3}\nexport const DELETE = async (req, res) => {\n const { id } = req.params;\n // TODO: remove from favorites\n res.json({ message: \\`Removed favorite \\${id}\\` });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'user', 'favorites', `[id].${ext}`), favByIdContent);\n\n // bookmarks/index.ts\n const bkListContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${mw3}\nexport const GET = async (req: Request, res: Response) => {\n // TODO: fetch user bookmarks\n res.json({ bookmarks: [] });\n};\n\nexport const POST = async (req: Request, res: Response) => {\n const { url, title } = req.body;\n if (!url) return res.status(400).json({ error: 'url is required' });\n // TODO: save bookmark\n res.status(201).json({ message: 'Bookmark saved' });\n};\n`\n : `${RA}${mw3}\nexport const GET = async (req, res) => {\n // TODO: fetch user bookmarks\n res.json({ bookmarks: [] });\n};\n\nexport const POST = async (req, res) => {\n const { url, title } = req.body;\n if (!url) return res.status(400).json({ error: 'url is required' });\n // TODO: save bookmark\n res.status(201).json({ message: 'Bookmark saved' });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'user', 'bookmarks', `index.${ext}`), bkListContent);\n\n // bookmarks/[id].ts\n const bkByIdContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${mw3}\nexport const DELETE = async (req: Request, res: Response) => {\n const { id } = req.params;\n // TODO: delete bookmark\n res.json({ message: \\`Bookmark \\${id} removed\\` });\n};\n`\n : `${RA}${mw3}\nexport const DELETE = async (req, res) => {\n const { id } = req.params;\n // TODO: delete bookmark\n res.json({ message: \\`Bookmark \\${id} removed\\` });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'user', 'bookmarks', `[id].${ext}`), bkByIdContent);\n\n // search.ts\n const searchMeta = mkMeta(opts, 'Search with filters, sort, and pagination.', `{ results: [], total: 0, page: 1, limit: 20 }`);\n const searchContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${searchMeta}${mw2}\nexport const GET = async (req: Request, res: Response) => {\n const { q, filter, sort, page = 1, limit = 20 } = req.query;\n // TODO: implement search\n res.json({ results: [], total: 0, page: Number(page), limit: Number(limit) });\n};\n`\n : `${RA}${searchMeta}${mw2}\nexport const GET = async (req, res) => {\n const { q, filter, sort, page = 1, limit = 20 } = req.query;\n // TODO: implement search\n res.json({ results: [], total: 0, page: Number(page), limit: Number(limit) });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'user', `search.${ext}`), searchContent);\n\n // api-keys/index.ts\n const akListMeta = mkMeta(opts, 'List API keys (GET) or create a new one (POST).', `{ apiKeys: [] }`);\n const akListContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${akListMeta}${mw3}\nexport const GET = async (req: Request, res: Response) => {\n // TODO: fetch api keys for user\n res.json({ apiKeys: [] });\n};\n\nexport const POST = async (req: Request, res: Response) => {\n const { name } = req.body;\n if (!name) return res.status(400).json({ error: 'name is required' });\n // TODO: generate and store API key\n res.status(201).json({ message: 'API key created', key: 'efc_...' });\n};\n`\n : `${RA}${akListMeta}${mw3}\nexport const GET = async (req, res) => {\n // TODO: fetch api keys for user\n res.json({ apiKeys: [] });\n};\n\nexport const POST = async (req, res) => {\n const { name } = req.body;\n if (!name) return res.status(400).json({ error: 'name is required' });\n // TODO: generate and store API key\n res.status(201).json({ message: 'API key created', key: 'efc_...' });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'user', 'api-keys', `index.${ext}`), akListContent);\n\n // api-keys/[id].ts\n const akByIdContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${mw3}\nexport const DELETE = async (req: Request, res: Response) => {\n const { id } = req.params;\n // TODO: revoke and delete API key\n res.json({ message: \\`API key \\${id} revoked\\` });\n};\n`\n : `${RA}${mw3}\nexport const DELETE = async (req, res) => {\n const { id } = req.params;\n // TODO: revoke and delete API key\n res.json({ message: \\`API key \\${id} revoked\\` });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'user', 'api-keys', `[id].${ext}`), akByIdContent);\n}\n\nasync function writeUserBillingRoutes(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const ts = opts.language === 'typescript';\n // user/billing/* = 3 levels, user/billing/subdir/* = 4 levels\n const mw3 = opts.rbac\n ? `export const middlewares = [requireAuth('user', 'admin')];\\n`\n : `export const middlewares = [requireAuth];\\n`;\n const mw4 = mw3;\n const RA = `import { requireAuth } from 'express-file-cluster/auth';\\n`;\n\n // billing/plans.ts\n const plansMeta = mkMeta(opts, 'List all available subscription plans.', `{ plans: [] }`);\n const plansContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${plansMeta}${mw3}\nexport const GET = async (_req: Request, res: Response) => {\n // TODO: fetch active plans from DB\n res.json({ plans: [] });\n};\n`\n : `${RA}${plansMeta}${mw3}\nexport const GET = async (_req, res) => {\n // TODO: fetch active plans from DB\n res.json({ plans: [] });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'user', 'billing', `plans.${ext}`), plansContent);\n\n // billing/subscription.ts\n const subMeta = mkMeta(opts, 'Get current subscription (GET), subscribe to a plan (POST), or cancel (DELETE).', `{ subscription: null }`);\n const subContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${subMeta}${mw3}\nexport const GET = async (req: Request, res: Response) => {\n // TODO: fetch current subscription for user\n res.json({ subscription: null });\n};\n\nexport const POST = async (req: Request, res: Response) => {\n const { planId } = req.body;\n if (!planId) return res.status(400).json({ error: 'planId is required' });\n // TODO: create subscription via payment gateway\n res.status(201).json({ message: 'Subscribed', subscription: { planId } });\n};\n\nexport const DELETE = async (req: Request, res: Response) => {\n // TODO: cancel subscription at period end\n res.json({ message: 'Subscription cancelled' });\n};\n`\n : `${RA}${subMeta}${mw3}\nexport const GET = async (req, res) => {\n // TODO: fetch current subscription for user\n res.json({ subscription: null });\n};\n\nexport const POST = async (req, res) => {\n const { planId } = req.body;\n if (!planId) return res.status(400).json({ error: 'planId is required' });\n // TODO: create subscription via payment gateway\n res.status(201).json({ message: 'Subscribed', subscription: { planId } });\n};\n\nexport const DELETE = async (req, res) => {\n // TODO: cancel subscription at period end\n res.json({ message: 'Subscription cancelled' });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'user', 'billing', `subscription.${ext}`), subContent);\n\n // billing/payment-methods/index.ts\n const pmListContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${mw4}\nexport const GET = async (req: Request, res: Response) => {\n // TODO: fetch payment methods for user\n res.json({ paymentMethods: [] });\n};\n\nexport const POST = async (req: Request, res: Response) => {\n const { token } = req.body;\n if (!token) return res.status(400).json({ error: 'payment token is required' });\n // TODO: attach payment method via payment gateway\n res.status(201).json({ message: 'Payment method added' });\n};\n`\n : `${RA}${mw4}\nexport const GET = async (req, res) => {\n // TODO: fetch payment methods for user\n res.json({ paymentMethods: [] });\n};\n\nexport const POST = async (req, res) => {\n const { token } = req.body;\n if (!token) return res.status(400).json({ error: 'payment token is required' });\n // TODO: attach payment method via payment gateway\n res.status(201).json({ message: 'Payment method added' });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'user', 'billing', 'payment-methods', `index.${ext}`), pmListContent);\n\n // billing/payment-methods/[id].ts\n const pmByIdContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${mw4}\nexport const DELETE = async (req: Request, res: Response) => {\n const { id } = req.params;\n // TODO: detach payment method from payment gateway\n res.json({ message: \\`Payment method \\${id} removed\\` });\n};\n`\n : `${RA}${mw4}\nexport const DELETE = async (req, res) => {\n const { id } = req.params;\n // TODO: detach payment method from payment gateway\n res.json({ message: \\`Payment method \\${id} removed\\` });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'user', 'billing', 'payment-methods', `[id].${ext}`), pmByIdContent);\n\n // billing/invoices/index.ts\n const invListMeta = mkMeta(opts, 'List all invoices for the authenticated user.', `{ invoices: [], total: 0 }`);\n const invListContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${invListMeta}${mw4}\nexport const GET = async (req: Request, res: Response) => {\n // TODO: fetch invoices for user\n res.json({ invoices: [], total: 0 });\n};\n`\n : `${RA}${invListMeta}${mw4}\nexport const GET = async (req, res) => {\n // TODO: fetch invoices for user\n res.json({ invoices: [], total: 0 });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'user', 'billing', 'invoices', `index.${ext}`), invListContent);\n\n // billing/invoices/[id].ts\n const invByIdContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${mw4}\nexport const GET = async (req: Request, res: Response) => {\n const { id } = req.params;\n // TODO: return invoice PDF URL or inline data\n res.json({ invoice: { id, downloadUrl: 'https://...' } });\n};\n`\n : `${RA}${mw4}\nexport const GET = async (req, res) => {\n const { id } = req.params;\n // TODO: return invoice PDF URL or inline data\n res.json({ invoice: { id, downloadUrl: 'https://...' } });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'user', 'billing', 'invoices', `[id].${ext}`), invByIdContent);\n}\n\nasync function writeSupportRoutes(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const ts = opts.language === 'typescript';\n // support/tickets/* = 3 levels\n const mw3 = opts.rbac\n ? `export const middlewares = [requireAuth('user', 'admin')];\\n`\n : `export const middlewares = [requireAuth];\\n`;\n const RA = `import { requireAuth } from 'express-file-cluster/auth';\\n`;\n\n // support/tickets/index.ts\n const ticketListMeta = mkMeta(opts, 'List own support tickets (GET) or create a new one (POST).', `{ tickets: [], total: 0 }`, `{ subject: 'Issue with login', message: 'I cannot log in', priority: 'normal' }`);\n const ticketListContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${ticketListMeta}${mw3}\nexport const GET = async (req: Request, res: Response) => {\n // TODO: fetch tickets for current user\n res.json({ tickets: [], total: 0 });\n};\n\nexport const POST = async (req: Request, res: Response) => {\n const { subject, message, priority } = req.body;\n if (!subject || !message) return res.status(400).json({ error: 'subject and message are required' });\n // TODO: create support ticket in DB\n res.status(201).json({ message: 'Ticket created', ticket: { id: 'new-id', subject, status: 'open' } });\n};\n`\n : `${RA}${ticketListMeta}${mw3}\nexport const GET = async (req, res) => {\n // TODO: fetch tickets for current user\n res.json({ tickets: [], total: 0 });\n};\n\nexport const POST = async (req, res) => {\n const { subject, message, priority } = req.body;\n if (!subject || !message) return res.status(400).json({ error: 'subject and message are required' });\n // TODO: create support ticket in DB\n res.status(201).json({ message: 'Ticket created', ticket: { id: 'new-id', subject, status: 'open' } });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'support', 'tickets', `index.${ext}`), ticketListContent);\n\n // support/tickets/[id].ts\n const ticketByIdMeta = mkMeta(opts, 'View a support ticket (GET) or add a reply / close it (PUT).', `{ ticket: { id: '1', subject: 'Issue', status: 'open', replies: [] } }`);\n const ticketByIdContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${ticketByIdMeta}${mw3}\nexport const GET = async (req: Request, res: Response) => {\n const { id } = req.params;\n // TODO: fetch ticket by id, verify ownership\n res.json({ ticket: { id, subject: '', status: 'open', replies: [] } });\n};\n\nexport const PUT = async (req: Request, res: Response) => {\n const { id } = req.params;\n const { reply, status } = req.body;\n // TODO: add reply or update status\n res.json({ message: 'Ticket updated', ticket: { id, status: status ?? 'open' } });\n};\n`\n : `${RA}${ticketByIdMeta}${mw3}\nexport const GET = async (req, res) => {\n const { id } = req.params;\n // TODO: fetch ticket by id, verify ownership\n res.json({ ticket: { id, subject: '', status: 'open', replies: [] } });\n};\n\nexport const PUT = async (req, res) => {\n const { id } = req.params;\n const { reply, status } = req.body;\n // TODO: add reply or update status\n res.json({ message: 'Ticket updated', ticket: { id, status: status ?? 'open' } });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'support', 'tickets', `[id].${ext}`), ticketByIdContent);\n}\n\nasync function writeAdminExtendedRoutes(dest: string, opts: ScaffoldOptions): Promise<void> {\n const ext = opts.language === 'typescript' ? 'ts' : 'js';\n const ts = opts.language === 'typescript';\n // depth: admin/subdir/* = 3, admin/subdir/subdir/* = 4, admin/users/[id]/* = 4\n const mwAdmin3 = opts.rbac\n ? `export const middlewares = [requireAuth('admin')];\\n`\n : `export const middlewares = [requireAuth];\\n`;\n const mwAdmin4 = mwAdmin3;\n const roleGuard = opts.rbac\n ? ''\n : ts\n ? ` const user = (req as any).user;\\n if (user?.role !== 'admin') return res.status(403).json({ error: 'Forbidden' });\\n`\n : ` const user = req.user;\\n if (user?.role !== 'admin') return res.status(403).json({ error: 'Forbidden' });\\n`;\n const RA = `import { requireAuth } from 'express-file-cluster/auth';\\n`;\n\n // ── Analytics ──────────────────────────────────────────────────────────\n\n // admin/analytics/index.ts\n const analyticsOverviewMeta = mkMeta(opts, 'Analytics overview: users, revenue, traffic.', `{ users: {}, revenue: {}, traffic: {} }`);\n const analyticsOverviewContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${analyticsOverviewMeta}${mwAdmin3}\nexport const GET = async (req: Request, res: Response) => {\n${roleGuard} // TODO: aggregate analytics overview\n res.json({ users: {}, revenue: {}, traffic: {} });\n};\n`\n : `${RA}${analyticsOverviewMeta}${mwAdmin3}\nexport const GET = async (req, res) => {\n${roleGuard} // TODO: aggregate analytics overview\n res.json({ users: {}, revenue: {}, traffic: {} });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'analytics', `index.${ext}`), analyticsOverviewContent);\n\n const analyticsUsersMeta = mkMeta(opts, 'User analytics: registrations, active users, churn.', `{ registrations: [], activeUsers: 0, churn: 0 }`);\n const analyticsUsersContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${analyticsUsersMeta}${mwAdmin3}\nexport const GET = async (req: Request, res: Response) => {\n${roleGuard} const { period = '30d' } = req.query;\n // TODO: fetch user analytics for period\n res.json({ registrations: [], activeUsers: 0, churn: 0, period });\n};\n`\n : `${RA}${analyticsUsersMeta}${mwAdmin3}\nexport const GET = async (req, res) => {\n${roleGuard} const { period = '30d' } = req.query;\n // TODO: fetch user analytics for period\n res.json({ registrations: [], activeUsers: 0, churn: 0, period });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'analytics', `users.${ext}`), analyticsUsersContent);\n\n const analyticsRevenueMeta = mkMeta(opts, 'Revenue analytics: MRR, ARR, payment history.', `{ mrr: 0, arr: 0, history: [] }`);\n const analyticsRevenueContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${analyticsRevenueMeta}${mwAdmin3}\nexport const GET = async (req: Request, res: Response) => {\n${roleGuard} const { period = '30d' } = req.query;\n // TODO: fetch revenue analytics for period\n res.json({ mrr: 0, arr: 0, history: [], period });\n};\n`\n : `${RA}${analyticsRevenueMeta}${mwAdmin3}\nexport const GET = async (req, res) => {\n${roleGuard} const { period = '30d' } = req.query;\n // TODO: fetch revenue analytics for period\n res.json({ mrr: 0, arr: 0, history: [], period });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'analytics', `revenue.${ext}`), analyticsRevenueContent);\n\n const analyticsTrafficMeta = mkMeta(opts, 'Traffic analytics: page views, devices, countries.', `{ pageViews: 0, devices: {}, countries: {} }`);\n const analyticsTrafficContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${analyticsTrafficMeta}${mwAdmin3}\nexport const GET = async (req: Request, res: Response) => {\n${roleGuard} const { period = '30d' } = req.query;\n // TODO: fetch traffic analytics for period\n res.json({ pageViews: 0, devices: {}, countries: {}, period });\n};\n`\n : `${RA}${analyticsTrafficMeta}${mwAdmin3}\nexport const GET = async (req, res) => {\n${roleGuard} const { period = '30d' } = req.query;\n // TODO: fetch traffic analytics for period\n res.json({ pageViews: 0, devices: {}, countries: {}, period });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'analytics', `traffic.${ext}`), analyticsTrafficContent);\n\n // ── User Actions ──────────────────────────────────────────────────────\n\n // admin/users/[id]/suspend.ts\n const suspendContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${mwAdmin4}\nexport const POST = async (req: Request, res: Response) => {\n${roleGuard} const { id } = req.params;\n const { reason } = req.body;\n // TODO: set user.isActive = false, log audit event\n res.json({ message: \\`User \\${id} suspended\\`, reason });\n};\n`\n : `${RA}${mwAdmin4}\nexport const POST = async (req, res) => {\n${roleGuard} const { id } = req.params;\n const { reason } = req.body;\n // TODO: set user.isActive = false, log audit event\n res.json({ message: \\`User \\${id} suspended\\`, reason });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'users', '[id]', `suspend.${ext}`), suspendContent);\n\n // admin/users/[id]/activate.ts\n const activateContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${mwAdmin4}\nexport const POST = async (req: Request, res: Response) => {\n${roleGuard} const { id } = req.params;\n // TODO: set user.isActive = true, log audit event\n res.json({ message: \\`User \\${id} activated\\` });\n};\n`\n : `${RA}${mwAdmin4}\nexport const POST = async (req, res) => {\n${roleGuard} const { id } = req.params;\n // TODO: set user.isActive = true, log audit event\n res.json({ message: \\`User \\${id} activated\\` });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'users', '[id]', `activate.${ext}`), activateContent);\n\n // admin/users/[id]/verify.ts\n const verifyUserContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${mwAdmin4}\nexport const POST = async (req: Request, res: Response) => {\n${roleGuard} const { id } = req.params;\n // TODO: set user.isVerified = true\n res.json({ message: \\`User \\${id} verified\\` });\n};\n`\n : `${RA}${mwAdmin4}\nexport const POST = async (req, res) => {\n${roleGuard} const { id } = req.params;\n // TODO: set user.isVerified = true\n res.json({ message: \\`User \\${id} verified\\` });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'users', '[id]', `verify.${ext}`), verifyUserContent);\n\n // admin/users/export.ts\n const exportMeta = mkMeta(opts, 'Export all users as CSV.', `{ csv: '...' }`);\n const exportContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${exportMeta}${mwAdmin3}\nexport const GET = async (_req: Request, res: Response) => {\n${roleGuard} // TODO: generate CSV of all users and stream response\n res.setHeader('Content-Type', 'text/csv');\n res.setHeader('Content-Disposition', 'attachment; filename=\"users.csv\"');\n res.send('id,name,email,role,createdAt\\\\n');\n};\n`\n : `${RA}${exportMeta}${mwAdmin3}\nexport const GET = async (_req, res) => {\n${roleGuard} // TODO: generate CSV of all users and stream response\n res.setHeader('Content-Type', 'text/csv');\n res.setHeader('Content-Disposition', 'attachment; filename=\"users.csv\"');\n res.send('id,name,email,role,createdAt\\\\n');\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'users', `export.${ext}`), exportContent);\n\n // ── Admins ────────────────────────────────────────────────────────────\n\n // admin/admins/index.ts\n const adminsListMeta = mkMeta(opts, 'List all admins (GET) or create a new admin (POST).', `{ admins: [], total: 0 }`);\n const adminsListContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${adminsListMeta}${mwAdmin3}\nexport const GET = async (_req: Request, res: Response) => {\n${roleGuard} // TODO: fetch admins from DB\n res.json({ admins: [], total: 0 });\n};\n\nexport const POST = async (req: Request, res: Response) => {\n${roleGuard} const { name, email, role } = req.body;\n if (!name || !email) return res.status(400).json({ error: 'name and email are required' });\n // TODO: create admin account\n res.status(201).json({ message: 'Admin created', admin: { id: 'new-id', name, email, role: role ?? 'admin' } });\n};\n`\n : `${RA}${adminsListMeta}${mwAdmin3}\nexport const GET = async (_req, res) => {\n${roleGuard} // TODO: fetch admins from DB\n res.json({ admins: [], total: 0 });\n};\n\nexport const POST = async (req, res) => {\n${roleGuard} const { name, email, role } = req.body;\n if (!name || !email) return res.status(400).json({ error: 'name and email are required' });\n // TODO: create admin account\n res.status(201).json({ message: 'Admin created', admin: { id: 'new-id', name, email, role: role ?? 'admin' } });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'admins', `index.${ext}`), adminsListContent);\n\n // admin/admins/[id].ts\n const adminByIdContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${mwAdmin3}\nexport const GET = async (req: Request, res: Response) => {\n${roleGuard} const { id } = req.params;\n // TODO: fetch admin by id\n res.json({ admin: { id } });\n};\n\nexport const PUT = async (req: Request, res: Response) => {\n${roleGuard} const { id } = req.params;\n // TODO: update admin record\n res.json({ message: 'Admin updated', admin: { id, ...req.body } });\n};\n\nexport const DELETE = async (req: Request, res: Response) => {\n${roleGuard} const { id } = req.params;\n // TODO: delete admin\n res.json({ message: \\`Admin \\${id} deleted\\` });\n};\n`\n : `${RA}${mwAdmin3}\nexport const GET = async (req, res) => {\n${roleGuard} const { id } = req.params;\n // TODO: fetch admin by id\n res.json({ admin: { id } });\n};\n\nexport const PUT = async (req, res) => {\n${roleGuard} const { id } = req.params;\n // TODO: update admin record\n res.json({ message: 'Admin updated', admin: { id, ...req.body } });\n};\n\nexport const DELETE = async (req, res) => {\n${roleGuard} const { id } = req.params;\n // TODO: delete admin\n res.json({ message: \\`Admin \\${id} deleted\\` });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'admins', `[id].${ext}`), adminByIdContent);\n\n // ── Roles (rbac only) ─────────────────────────────────────────────────\n\n if (opts.rbac) {\n const rolesListContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${mwAdmin3}\nexport const GET = async (_req: Request, res: Response) => {\n // TODO: fetch all roles\n res.json({ roles: [] });\n};\n\nexport const POST = async (req: Request, res: Response) => {\n const { name, description, permissions } = req.body;\n if (!name) return res.status(400).json({ error: 'name is required' });\n // TODO: create role\n res.status(201).json({ message: 'Role created', role: { id: 'new-id', name, permissions: permissions ?? [] } });\n};\n`\n : `${RA}${mwAdmin3}\nexport const GET = async (_req, res) => {\n // TODO: fetch all roles\n res.json({ roles: [] });\n};\n\nexport const POST = async (req, res) => {\n const { name, description, permissions } = req.body;\n if (!name) return res.status(400).json({ error: 'name is required' });\n // TODO: create role\n res.status(201).json({ message: 'Role created', role: { id: 'new-id', name, permissions: permissions ?? [] } });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'roles', `index.${ext}`), rolesListContent);\n\n const roleByIdContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${mwAdmin3}\nexport const GET = async (req: Request, res: Response) => {\n const { id } = req.params;\n // TODO: fetch role by id\n res.json({ role: { id } });\n};\n\nexport const PUT = async (req: Request, res: Response) => {\n const { id } = req.params;\n // TODO: update role\n res.json({ message: 'Role updated', role: { id, ...req.body } });\n};\n\nexport const DELETE = async (req: Request, res: Response) => {\n const { id } = req.params;\n // TODO: delete role\n res.json({ message: \\`Role \\${id} deleted\\` });\n};\n`\n : `${RA}${mwAdmin3}\nexport const GET = async (req, res) => {\n const { id } = req.params;\n // TODO: fetch role by id\n res.json({ role: { id } });\n};\n\nexport const PUT = async (req, res) => {\n const { id } = req.params;\n // TODO: update role\n res.json({ message: 'Role updated', role: { id, ...req.body } });\n};\n\nexport const DELETE = async (req, res) => {\n const { id } = req.params;\n // TODO: delete role\n res.json({ message: \\`Role \\${id} deleted\\` });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'roles', `[id].${ext}`), roleByIdContent);\n }\n\n // ── Notifications ─────────────────────────────────────────────────────\n\n // admin/notifications/index.ts\n const adminNotifContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${mwAdmin3}\nexport const GET = async (_req: Request, res: Response) => {\n${roleGuard} // TODO: fetch sent notifications\n res.json({ notifications: [], total: 0 });\n};\n\nexport const POST = async (req: Request, res: Response) => {\n${roleGuard} const { userId, title, message, type } = req.body;\n if (!userId || !title || !message) return res.status(400).json({ error: 'userId, title and message are required' });\n // TODO: create and send notification to user\n res.status(201).json({ message: 'Notification sent' });\n};\n`\n : `${RA}${mwAdmin3}\nexport const GET = async (_req, res) => {\n${roleGuard} // TODO: fetch sent notifications\n res.json({ notifications: [], total: 0 });\n};\n\nexport const POST = async (req, res) => {\n${roleGuard} const { userId, title, message, type } = req.body;\n if (!userId || !title || !message) return res.status(400).json({ error: 'userId, title and message are required' });\n // TODO: create and send notification to user\n res.status(201).json({ message: 'Notification sent' });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'notifications', `index.${ext}`), adminNotifContent);\n\n // admin/notifications/broadcast.ts\n const broadcastMeta = mkMeta(opts, 'Broadcast a notification to all users.', `{ message: 'Broadcast sent', count: 0 }`, `{ title: 'Announcement', message: 'Hello everyone!', type: 'info' }`);\n const broadcastContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${broadcastMeta}${mwAdmin3}\nexport const POST = async (req: Request, res: Response) => {\n${roleGuard} const { title, message, type } = req.body;\n if (!title || !message) return res.status(400).json({ error: 'title and message are required' });\n // TODO: send notification to all users\n res.json({ message: 'Broadcast sent', count: 0 });\n};\n`\n : `${RA}${broadcastMeta}${mwAdmin3}\nexport const POST = async (req, res) => {\n${roleGuard} const { title, message, type } = req.body;\n if (!title || !message) return res.status(400).json({ error: 'title and message are required' });\n // TODO: send notification to all users\n res.json({ message: 'Broadcast sent', count: 0 });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'notifications', `broadcast.${ext}`), broadcastContent);\n\n // ── Logs ──────────────────────────────────────────────────────────────\n\n const mkLogContent = (label: string) => {\n const meta = mkMeta(opts, `Paginated ${label} log entries.`, `{ logs: [], total: 0, page: 1, limit: 50 }`);\n return ts\n ? `${RA}import type { Request, Response } from 'express';\n${meta}${mwAdmin3}\nexport const GET = async (req: Request, res: Response) => {\n${roleGuard} const { page = 1, limit = 50 } = req.query;\n // TODO: fetch ${label} logs with pagination\n res.json({ logs: [], total: 0, page: Number(page), limit: Number(limit) });\n};\n`\n : `${RA}${meta}${mwAdmin3}\nexport const GET = async (req, res) => {\n${roleGuard} const { page = 1, limit = 50 } = req.query;\n // TODO: fetch ${label} logs with pagination\n res.json({ logs: [], total: 0, page: Number(page), limit: Number(limit) });\n};\n`;\n };\n\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'logs', `audit.${ext}`), mkLogContent('audit'));\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'logs', `activity.${ext}`), mkLogContent('activity'));\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'logs', `security.${ext}`), mkLogContent('security'));\n\n // ── Settings & System ─────────────────────────────────────────────────\n\n // admin/settings/index.ts\n const settingsMeta = mkMeta(opts, 'Get or update system-wide settings.', `{ settings: {} }`);\n const settingsContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${settingsMeta}${mwAdmin3}\nexport const GET = async (_req: Request, res: Response) => {\n${roleGuard} // TODO: fetch system settings from DB\n res.json({ settings: {} });\n};\n\nexport const PUT = async (req: Request, res: Response) => {\n${roleGuard} // TODO: update system settings\n res.json({ message: 'Settings updated', settings: req.body });\n};\n`\n : `${RA}${settingsMeta}${mwAdmin3}\nexport const GET = async (_req, res) => {\n${roleGuard} // TODO: fetch system settings from DB\n res.json({ settings: {} });\n};\n\nexport const PUT = async (req, res) => {\n${roleGuard} // TODO: update system settings\n res.json({ message: 'Settings updated', settings: req.body });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'settings', `index.${ext}`), settingsContent);\n\n // admin/system/health.ts\n const healthMeta = mkMeta(opts, 'System health check: DB, queue, cache status.', `{ status: 'ok', db: 'ok', queue: 'ok' }`);\n const healthContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${healthMeta}${mwAdmin3}\nexport const GET = async (_req: Request, res: Response) => {\n${roleGuard} // TODO: check DB connection, queue, cache health\n res.json({ status: 'ok', db: 'ok', queue: 'ok', uptime: process.uptime() });\n};\n`\n : `${RA}${healthMeta}${mwAdmin3}\nexport const GET = async (_req, res) => {\n${roleGuard} // TODO: check DB connection, queue, cache health\n res.json({ status: 'ok', db: 'ok', queue: 'ok', uptime: process.uptime() });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'system', `health.${ext}`), healthContent);\n\n // admin/system/cache.ts\n const cacheMeta = mkMeta(opts, 'Flush the application cache.', `{ message: 'Cache cleared' }`);\n const cacheContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${cacheMeta}${mwAdmin3}\nexport const DELETE = async (_req: Request, res: Response) => {\n${roleGuard} // TODO: flush Redis or in-memory cache\n res.json({ message: 'Cache cleared' });\n};\n`\n : `${RA}${cacheMeta}${mwAdmin3}\nexport const DELETE = async (_req, res) => {\n${roleGuard} // TODO: flush Redis or in-memory cache\n res.json({ message: 'Cache cleared' });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'system', `cache.${ext}`), cacheContent);\n\n // ── Support Tickets (admin view) ──────────────────────────────────────\n\n // admin/tickets/index.ts\n const adminTicketsListMeta = mkMeta(opts, 'List all support tickets with filters.', `{ tickets: [], total: 0 }`);\n const adminTicketsListContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${adminTicketsListMeta}${mwAdmin3}\nexport const GET = async (req: Request, res: Response) => {\n${roleGuard} const { status, priority, page = 1, limit = 20 } = req.query;\n // TODO: fetch all tickets with filters\n res.json({ tickets: [], total: 0, page: Number(page), limit: Number(limit) });\n};\n`\n : `${RA}${adminTicketsListMeta}${mwAdmin3}\nexport const GET = async (req, res) => {\n${roleGuard} const { status, priority, page = 1, limit = 20 } = req.query;\n // TODO: fetch all tickets with filters\n res.json({ tickets: [], total: 0, page: Number(page), limit: Number(limit) });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'tickets', `index.${ext}`), adminTicketsListContent);\n\n // admin/tickets/[id].ts\n const adminTicketByIdContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${mwAdmin3}\nexport const GET = async (req: Request, res: Response) => {\n${roleGuard} const { id } = req.params;\n // TODO: fetch ticket by id\n res.json({ ticket: { id } });\n};\n\nexport const PUT = async (req: Request, res: Response) => {\n${roleGuard} const { id } = req.params;\n const { reply, status, assignedTo } = req.body;\n // TODO: update ticket (assign, change status, add reply)\n res.json({ message: 'Ticket updated', ticket: { id, status, assignedTo } });\n};\n`\n : `${RA}${mwAdmin3}\nexport const GET = async (req, res) => {\n${roleGuard} const { id } = req.params;\n // TODO: fetch ticket by id\n res.json({ ticket: { id } });\n};\n\nexport const PUT = async (req, res) => {\n${roleGuard} const { id } = req.params;\n const { reply, status, assignedTo } = req.body;\n // TODO: update ticket (assign, change status, add reply)\n res.json({ message: 'Ticket updated', ticket: { id, status, assignedTo } });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'tickets', `[id].${ext}`), adminTicketByIdContent);\n\n // ── Content ───────────────────────────────────────────────────────────\n\n const mkContentCrud = (\n name: string,\n namePlural: string,\n dir: string[],\n createFields: string,\n ) => {\n const listMeta = mkMeta(opts, `List ${namePlural} (GET) or create a new ${name} (POST).`, `{ ${namePlural}: [], total: 0 }`);\n const listContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${listMeta}${mwAdmin4}\nexport const GET = async (_req: Request, res: Response) => {\n${roleGuard} // TODO: fetch ${namePlural}\n res.json({ ${namePlural}: [], total: 0 });\n};\n\nexport const POST = async (req: Request, res: Response) => {\n${roleGuard} const { ${createFields} } = req.body;\n // TODO: create ${name}\n res.status(201).json({ message: '${name} created', ${name.toLowerCase()}: { id: 'new-id', ${createFields.split(', ')[0]} } });\n};\n`\n : `${RA}${listMeta}${mwAdmin4}\nexport const GET = async (_req, res) => {\n${roleGuard} // TODO: fetch ${namePlural}\n res.json({ ${namePlural}: [], total: 0 });\n};\n\nexport const POST = async (req, res) => {\n${roleGuard} const { ${createFields} } = req.body;\n // TODO: create ${name}\n res.status(201).json({ message: '${name} created', ${name.toLowerCase()}: { id: 'new-id' } });\n};\n`;\n const byIdContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${mwAdmin4}\nexport const GET = async (req: Request, res: Response) => {\n${roleGuard} const { id } = req.params;\n // TODO: fetch ${name} by id\n res.json({ ${name.toLowerCase()}: { id } });\n};\n\nexport const PUT = async (req: Request, res: Response) => {\n${roleGuard} const { id } = req.params;\n // TODO: update ${name}\n res.json({ message: '${name} updated', ${name.toLowerCase()}: { id, ...req.body } });\n};\n\nexport const DELETE = async (req: Request, res: Response) => {\n${roleGuard} const { id } = req.params;\n // TODO: delete ${name}\n res.json({ message: \\`${name} \\${id} deleted\\` });\n};\n`\n : `${RA}${mwAdmin4}\nexport const GET = async (req, res) => {\n${roleGuard} const { id } = req.params;\n // TODO: fetch ${name} by id\n res.json({ ${name.toLowerCase()}: { id } });\n};\n\nexport const PUT = async (req, res) => {\n${roleGuard} const { id } = req.params;\n // TODO: update ${name}\n res.json({ message: '${name} updated', ${name.toLowerCase()}: { id, ...req.body } });\n};\n\nexport const DELETE = async (req, res) => {\n${roleGuard} const { id } = req.params;\n // TODO: delete ${name}\n res.json({ message: \\`${name} \\${id} deleted\\` });\n};\n`;\n return { listContent, byIdContent };\n };\n\n const { listContent: faqList, byIdContent: faqById } = mkContentCrud('FAQ', 'faqs', [], 'question, answer, category');\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'content', 'faqs', `index.${ext}`), faqList);\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'content', 'faqs', `[id].${ext}`), faqById);\n\n const { listContent: blogList, byIdContent: blogById } = mkContentCrud('Blog', 'blogs', [], 'title, slug, content');\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'content', 'blogs', `index.${ext}`), blogList);\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'content', 'blogs', `[id].${ext}`), blogById);\n\n const { listContent: catList, byIdContent: catById } = mkContentCrud('Category', 'categories', [], 'name, slug');\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'content', 'categories', `index.${ext}`), catList);\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'content', 'categories', `[id].${ext}`), catById);\n\n // ── Billing (admin) ───────────────────────────────────────────────────\n\n const { listContent: planList, byIdContent: planById } = mkContentCrud('Plan', 'plans', [], 'name, price, interval');\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'billing', 'plans', `index.${ext}`), planList);\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'billing', 'plans', `[id].${ext}`), planById);\n\n const { listContent: couponList, byIdContent: couponById } = mkContentCrud('Coupon', 'coupons', [], 'code, type, value');\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'billing', 'coupons', `index.${ext}`), couponList);\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'billing', 'coupons', `[id].${ext}`), couponById);\n\n // admin/billing/subscriptions/index.ts\n const adminSubsMeta = mkMeta(opts, 'List all subscriptions with filters.', `{ subscriptions: [], total: 0 }`);\n const adminSubsContent = ts\n ? `${RA}import type { Request, Response } from 'express';\n${adminSubsMeta}${mwAdmin4}\nexport const GET = async (req: Request, res: Response) => {\n${roleGuard} const { status, page = 1, limit = 20 } = req.query;\n // TODO: fetch all subscriptions with filters\n res.json({ subscriptions: [], total: 0, page: Number(page), limit: Number(limit) });\n};\n`\n : `${RA}${adminSubsMeta}${mwAdmin4}\nexport const GET = async (req, res) => {\n${roleGuard} const { status, page = 1, limit = 20 } = req.query;\n // TODO: fetch all subscriptions with filters\n res.json({ subscriptions: [], total: 0, page: Number(page), limit: Number(limit) });\n};\n`;\n await fs.outputFile(path.join(dest, 'src', 'api', 'admin', 'billing', 'subscriptions', `index.${ext}`), adminSubsContent);\n}\n"],"mappings":"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","names":["cancel","spinner"]}
|