Skip to content

Conversation

@muneebhashone
Copy link
Owner

No description provided.

… configuration and add openapi.yml to .gitignore
muneebhashone and others added 27 commits October 20, 2025 23:44
…rating plugins, middleware, modules, and seeders
… introduce introspection utility for model metadata
- 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.
@muneebhashone muneebhashone merged commit fdf93cc into main Oct 30, 2025
@gemini-code-assist
Copy link

Summary of Changes

Hello @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

  • Project Scaffolding: This PR introduces a new CLI tool, create-tbk-app, for scaffolding TypeScript Backend Toolkit projects with customizable features and presets.
  • Monorepo Structure: The project is converted to a pnpm workspace monorepo, with create-tbk-app as a separate npm package.
  • Template Engine: Handlebars is used for templating, enabling conditional file inclusion and customization based on user selections.
  • Feature-Based Dependencies: Dependencies are resolved based on selected features, ensuring only necessary packages are installed.
  • Admin Panel: Adds a Django-style admin panel for managing data and operations, protected by a separate authentication system.
  • Realtime Support: Adds Socket.IO integration for real-time communication capabilities.
  • Email Support: Adds support for multiple email providers (Resend, Mailgun, SMTP) with React Email templates.
  • Storage Support: Adds support for multiple storage providers (S3, R2, Local) for file uploads.
  • Queue Support: Adds support for background jobs using BullMQ with a monitoring dashboard.
  • Code Quality: Adds linting and formatting configurations to maintain code consistency.
Using Gemini Code Assist

The 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 /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

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 .gemini/ folder in the base of the repository. Detailed instructions can be found here.

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

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a 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\")",

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

This configuration contains a hardcoded absolute Windows path. This will break the functionality for any other user on a different machine or operating system. Paths in configuration should be relative or derived from environment variables to ensure portability.

Comment on lines +47 to +56
// 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
```

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

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 });

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The command pnpm run seeder is incorrect. Based on the package.json changes, the script has been renamed to seed. This documentation should be updated to reflect the correct script name.

pnpm run seed

@@ -0,0 +1,221 @@
---
globs: .env*,config.service.ts

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The glob pattern in the frontmatter is incorrect. The file config.service.ts has been replaced by src/config/env.ts in the new project structure. The glob should be updated to point to the correct file to ensure this rule is applied correctly.

globs: .env*,src/config/env.ts

const multipleFiles = req.body.multipleFiles; // Multiple files (optional)

if (!avatar) {
return errorResponse(res, 'File not uploaded');

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

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);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The example code uses UserModel without defining or importing it. This makes the example incomplete. Please add an example import for it, like import UserModel from '@/modules/user/user.model';.

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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The command pnpm tbk generate:factory <name> is incorrect. According to bin/tbk.ts, the correct command is make:factory and it expects a <module>/<name> argument.

Suggested change
pnpm tbk seed # Run database seeders
pnpm tbk make:factory <module>/<Name> # Generate factory for model

Comment on lines +86 to +88
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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

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.

Comment on lines +252 to +278
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
};

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

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,
  };

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants