-
Notifications
You must be signed in to change notification settings - Fork 57
V2 scaffolding #18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
V2 scaffolding #18
Conversation
…, and development workflows
…nfiguration files
… token generation
…d user session management
…improved readability
… configuration and add openapi.yml to .gitignore
…customization steps
… usage instructions
…n-access middleware and seed script
…port for fileFields
… JavaScript and HTML files
…routes and controller
…mport paths across the codebase
…te main application initialization
…and reposition logout button
…rating plugins, middleware, modules, and seeders
… introduce introspection utility for model metadata
…eScript SDK path in VSCode settings
…ckend-toolkit into v2-bullboard
- Replace successResponse() with typed ResponseExtended helpers - Add optional chaining for JWT payload (req.user?.sub) - Document two error handling approaches: typed responses vs thrown errors - Update examples to use res.ok?.(), res.created?.(), res.notFound?.() patterns - Remove legacy successResponse() documentation - Add response type annotations to controller signatures
- Replace multer middleware with formidable integration - Document multipart route configuration with multipart: true - Add comprehensive file upload workflow with zFile() and zFiles() helpers - Include schema validation patterns for file uploads - Update controller examples to access files via req.body (not req.file) - Document MIME_GROUPS and file validation options - Add mixed field (text + files) upload examples
- Add complete response schema workflow section - Document end-to-end type safety from schema to controller - Update naming conventions: camelCase for schemas, PascalCase for types - Add router configuration examples with response schemas - Include controller typing with ResponseExtended - Document available response builders (R.success, R.paginated, etc.) - Remove deprecated zod import patterns, enforce named imports
- Document that services ALWAYS throw errors, controllers decide handling - Add decision tree for error handling approaches - Include pattern examples for null returns vs thrown errors - Document permission errors, validation errors, and business logic failures - Add guidance on when to return null vs throw errors - Include unexpected error handling (let bubble up as 500)
- Highlight AI assistant compatibility (Cursor, Windsurf, Claude, ChatGPT) - Document comprehensive AI agent configuration with .cursor/rules/ - Add AI-optimized workflow examples with CLI commands - Restructure architecture section to emphasize plugin-based system - Update key features to include OpenAPI, auth, file upload, queues, realtime - Add comprehensive documentation links and development commands - Include production deployment instructions - Modernize formatting and add contribution guidelines
- Clarify intent (beginner→expert) and predictable structure for tools without guesswork - Highlight auto-generated admin dashboard, OpenAPI docs, plugin system - Add dedicated CLI section; switch examples to 'pnpm tbk' - Remove emojis; clean anchors for consistency - Replace webp logo with png and update references for consistent rendering Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
…dation - Add recommended command for generating modules using pnpm tbk - Specify the main app file path for router registration in module creation output - Introduce zMongoId for improved MongoDB ObjectId validation with customizable error messages - Update common schema to utilize zMongoId for ID validation
- Introduce CLAUDE.md to provide detailed instructions for using the TypeScript Backend Toolkit - Outline project overview, common commands, critical architecture patterns, and module structure - Include guidelines for response schemas, validation with Zod, and error handling - Document plugin system, session management, and environment configuration - Emphasize the importance of using the CLI for module creation and maintaining consistency
- Simplify the command for generating modules by removing the path specification - Ensure clarity in instructions for scaffolding project files following established patterns
…ding - Introduce create-module.md to guide users in generating a fully-typed module with necessary files and integration steps. - Add create-seeder.md to assist in creating seeders and factories for populating test data, including registration and execution instructions. - Update .gitignore to remove the .claude directory from tracking.
- Introduce NEXT_STEPS.md to outline upcoming tasks including documentation and beta testing. - Add SCAFFOLDING_SUMMARY.md to summarize the completion of Phase 1 and readiness for Phase 2. - Update pnpm-lock.yaml and pnpm-workspace.yaml for package management consistency. - Enhance README.md with installation instructions and environment configuration. - Introduce new files in create-tbk-app package for project scaffolding, including configuration, templates, and utility functions.
- Finalize Phase 1 and Phase 2 Week 1-3 tasks, ensuring all three presets (minimal, standard, full) are functional and generate successfully. - Extract and templatize approximately 4500 lines of code for improved maintainability. - Update NEXT_STEPS.md to reflect the completion of major milestones and outline future tasks. - Introduce new files and templates for admin and authentication modules, enhancing project structure and functionality. - Remove outdated test-minimal files to streamline the project.
- Set author information in package.json for better attribution. - Add repository, homepage, and bugs URLs to package.json for enhanced project visibility. - Update README.md with direct links to the main repository, documentation, and issue reporting for user convenience. - Modify prompts.ts to ensure type safety by casting to 'any'. - Update config.types.ts to make googleOAuth optional, improving flexibility in project configuration. - Adjust template.engine.ts to provide a default value for AUTH_GOOGLE_OAUTH, enhancing robustness.
Summary of ChangesHello @muneebhashone, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request introduces a scaffolding tool for the TypeScript Backend Toolkit, allowing users to generate projects with customizable features. It includes a CLI, template engine, dependency resolver, and configuration generators. The changes also add support for authentication, caching, queues, storage, email, real-time communication, and an admin panel, enhancing the toolkit's capabilities and developer experience. Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request introduces a significant amount of scaffolding and documentation for V2 of the project, including a CLI for generating modules and extensive rules for AI agents. The changes are comprehensive and set a strong foundation. My review focuses on ensuring the new documentation is accurate and consistent, fixing a critical issue with a hardcoded path, and improving the clarity and maintainability of some of the new generator scripts.
| "Bash(then rm -rf test-minimal)", | ||
| "Bash(fi)", | ||
| "Bash(node packages/create-tbk-app/dist/cli.js:*)", | ||
| "Bash(for file in \"c:\\Users\\themuneebh\\repos\\typescript-backend-toolkit\\packages\\create-tbk-app\\templates\\auth\\src\\modules\\auth\\auth.service.ts.hbs\" \"c:\\Users\\themuneebh\\repos\\typescript-backend-toolkit\\packages\\create-tbk-app\\templates\\auth\\src\\modules\\auth\\auth.controller.ts.hbs\" \"c:\\Users\\themuneebh\\repos\\typescript-backend-toolkit\\packages\\create-tbk-app\\templates\\auth\\src\\modules\\auth\\auth.router.ts.hbs\" \"c:\\Users\\themuneebh\\repos\\typescript-backend-toolkit\\packages\\create-tbk-app\\templates\\auth\\src\\plugins\\auth\\index.ts.hbs\" \"c:\\Users\\themuneebh\\repos\\typescript-backend-toolkit\\packages\\create-tbk-app\\templates\\auth\\src\\middlewares\\extract-jwt.ts.hbs\")", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| // In .env | ||
| JWT_EXPIRES_IN=7d | ||
| OTP_EXPIRES_IN=10m | ||
|
|
||
| // In env.ts - convert to milliseconds | ||
| import ms from "ms"; | ||
|
|
||
| JWT_EXPIRES_IN: z.string().transform((val) => ms(val)), | ||
| // Converts "7d" → 604800000ms | ||
| ``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The documentation regarding time duration format is inconsistent with the implementation. The documentation suggests using duration strings like 7d parsed with the ms package, but the implementation in env.ts.hbs expects a string of seconds and uses transform(Number). This will cause confusion and incorrect configuration. The documentation should be updated to match the actual implementation.
// In .env
JWT_EXPIRES_IN=86400 # in seconds
// In env.ts - convert to number
JWT_EXPIRES_IN: z.string().transform(Number),
// Converts "86400" → 86400
| // Pre-remove hook | ||
| schema.pre('remove', async function (next) { | ||
| // Example: Clean up related data | ||
| await RelatedModel.deleteMany({ modelId: this._id }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The example code uses RelatedModel without defining or importing it. This makes the example incomplete and potentially confusing. Please add a note that RelatedModel is a placeholder or add an example import for it.
// Example: Clean up related data from a hypothetical RelatedModel
// import { RelatedModel } from './related.model';
await RelatedModel.deleteMany({ modelId: this._id });
| nano .env | ||
|
|
||
| # 5. (Optional) Seed database | ||
| pnpm run seeder |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| @@ -0,0 +1,221 @@ | |||
| --- | |||
| globs: .env*,config.service.ts | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| const multipleFiles = req.body.multipleFiles; // Multiple files (optional) | ||
|
|
||
| if (!avatar) { | ||
| return errorResponse(res, 'File not uploaded'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The use of errorResponse from @/utils/response.utils in this example seems to contradict the recommended pattern described in controllers.mdc, which promotes using ResponseExtended helpers like res.notFound?.(). To maintain consistency across the documentation and encourage best practices, it would be better to use the ResponseExtended pattern here as well.
| data: any; | ||
| }) => { | ||
| // 1. Validate business rules | ||
| const user = await UserModel.findById(input.userId); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| pnpm tbk generate:plugin <name> # Generate plugin | ||
| pnpm tbk generate:middleware <name> # Generate middleware | ||
| pnpm tbk generate:factory <name> # Generate factory for model | ||
| pnpm tbk seed # Run database seeders |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| lines.push(`import ${info.modelExport === 'default' ? '' : `{ ${info.modelExport} as ` + info.modelName + `Model } from `} '../${baseName}.model';`); | ||
| // The above is messy; prefer default import as in repo styles | ||
| lines.length = 0; // reset |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This block of code is confusing. It adds a line to an array, then adds a comment, and then immediately clears the entire array with lines.length = 0. This makes the code hard to follow and maintain. Please refactor this to be more direct, for example by removing the initial lines.push and the lines.length = 0 line.
| const { skipGit } = await inquirer.prompt<{ skipGit: boolean }>([ | ||
| { | ||
| type: 'confirm', | ||
| name: 'skipGit', | ||
| message: 'Initialize git repository?', | ||
| default: true, | ||
| // Invert the response since we ask "Initialize" but store "skip" | ||
| transformer: (value: boolean) => !value, | ||
| }, | ||
| ]); | ||
|
|
||
| const { skipInstall } = await inquirer.prompt<{ skipInstall: boolean }>([ | ||
| { | ||
| type: 'confirm', | ||
| name: 'skipInstall', | ||
| message: 'Install dependencies now?', | ||
| default: true, | ||
| // Invert the response | ||
| transformer: (value: boolean) => !value, | ||
| }, | ||
| ]); | ||
|
|
||
| return { | ||
| packageManager, | ||
| skipGit: !skipGit, // Invert for storage | ||
| skipInstall: !skipInstall, // Invert for storage | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The logic for skipGit and skipInstall is inverted between the prompt and the stored config value, which is confusing. The prompt asks a positive question ('Initialize git repository?') but stores it in a negative variable (skipGit). This makes the code harder to reason about. Consider renaming the variables to reflect the positive action, for example, initGit and installDeps, to make the logic more straightforward.
const { initGit } = await inquirer.prompt<{ initGit: boolean }>([
{
type: 'confirm',
name: 'initGit',
message: 'Initialize git repository?',
default: true,
},
]);
const { installDeps } = await inquirer.prompt<{ installDeps: boolean }>([
{
type: 'confirm',
name: 'installDeps',
message: 'Install dependencies now?',
default: true,
},
]);
return {
packageManager,
skipGit: !initGit,
skipInstall: !installDeps,
};
No description provided.