diff --git a/.agents/workflows/comprehensive-search.md b/.agents/workflows/comprehensive-search.md new file mode 100644 index 0000000000..bdac1e6b54 --- /dev/null +++ b/.agents/workflows/comprehensive-search.md @@ -0,0 +1,35 @@ +--- +description: how to do comprehensive file search on Windows +--- + +# Comprehensive File Search on Windows + +The built-in `grep_search` tool can **silently miss files** on Windows, returning no results even for files that clearly contain the search term. This may be related to workspace paths with spaces, long paths, or other Windows-specific issues. + +## Steps + +// turbo-all + +1. Use `findstr /S /N` for comprehensive recursive search across all directories: + +```powershell +findstr /S /N "searchTerm" packages\*.ts +``` + +2. For case-insensitive search, add `/I`: + +```powershell +findstr /S /N /I "searchterm" packages\*.ts +``` + +3. To search multiple file types or directories: + +```powershell +findstr /S /N "searchTerm" packages\*.ts apps\*.ts +``` + +## When to Use + +- **Always** use `findstr /S /N` when searching for function/class usage references, because plugins and other gitignored code may reference them +- **Always** use `findstr /S /N` when auditing for security-related patterns across the entire codebase +- Use `grep_search` only for quick searches where completeness is not critical diff --git a/AGENTS.md b/AGENTS.md index a90fe272e0..37d11f0838 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -3,12 +3,39 @@ # General Guidelines for working with Nx -- When running tasks (for example build, lint, test, e2e, etc.), always prefer running the task through `nx` (i.e. `nx run`, `nx run-many`, `nx affected`) instead of using the underlying tooling directly -- You have access to the Nx MCP server and its tools, use them to help the user -- When answering questions about the repository, use the `nx_workspace` tool first to gain an understanding of the workspace architecture where applicable. -- When working in individual projects, use the `nx_project_details` mcp tool to analyze and understand the specific project structure and dependencies -- For questions around nx configuration, best practices or if you're unsure, use the `nx_docs` tool to get relevant, up-to-date docs. Always use this instead of assuming things about nx configuration -- If the user needs help with an Nx configuration or project graph error, use the `nx_workspace` tool to get any errors -- For Nx plugin best practices, check `node_modules/@nx//PLUGIN.md`. Not all plugins have this file - proceed without it if unavailable. +- When running tasks (for example build, lint, test, e2e, etc.), always prefer running the task through `nx` (i.e. `nx run`, `nx run-many`, `nx affected`) instead of using the underlying tooling directly +- You have access to the Nx MCP server and its tools, use them to help the user +- When answering questions about the repository, use the `nx_workspace` tool first to gain an understanding of the workspace architecture where applicable. +- When working in individual projects, use the `nx_project_details` mcp tool to analyze and understand the specific project structure and dependencies +- For questions around nx configuration, best practices or if you're unsure, use the `nx_docs` tool to get relevant, up-to-date docs. Always use this instead of assuming things about nx configuration +- If the user needs help with an Nx configuration or project graph error, use the `nx_workspace` tool to get any errors +- For Nx plugin best practices, check `node_modules/@nx//PLUGIN.md`. Not all plugins have this file - proceed without it if unavailable. + +# File Search on Windows + +> **IMPORTANT**: The built-in `grep_search` tool (ripgrep) can **silently miss files** on Windows, returning no results even for files that clearly contain the search term. This may be related to workspace paths with spaces, long paths, or other Windows-specific issues. Always verify critical searches with `findstr /S`. + +## Recommended Approach + +Always use `findstr /S` for comprehensive code searches to ensure **all** files are covered: + +```powershell +# Search recursively in all .ts files under packages/ +findstr /S /N "searchTerm" packages\*.ts + +# Search with case-insensitivity +findstr /S /N /I "searchterm" packages\*.ts + +# Search across all source files +findstr /S /N "searchTerm" packages\*.ts apps\*.ts +``` + +## When to Use Each Tool + +| Tool | Use When | +| --------------- | ------------------------------------------------------------------ | +| `grep_search` | Quick searches — but always verify critical results with `findstr` | +| `findstr /S /N` | **Comprehensive searches** where completeness is essential | +| `find_by_name` | Finding files by name/pattern | diff --git a/packages/core/src/lib/estimate-email/dto/find-estimate-email-query.dto.ts b/packages/core/src/lib/estimate-email/dto/find-estimate-email-query.dto.ts index edc8eb54f1..e403cc3603 100644 --- a/packages/core/src/lib/estimate-email/dto/find-estimate-email-query.dto.ts +++ b/packages/core/src/lib/estimate-email/dto/find-estimate-email-query.dto.ts @@ -1,17 +1,37 @@ -import { IEstimateEmailFindInput } from "@gauzy/contracts"; -import { ApiProperty } from "@nestjs/swagger"; -import { IsEmail, IsNotEmpty, IsString } from "class-validator"; -import { RelationsQueryDTO } from "./../../shared/dto"; +import { IEstimateEmailFindInput } from '@gauzy/contracts'; +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; +import { Transform, TransformFnParams } from 'class-transformer'; +import { IsEmail, IsEnum, IsNotEmpty, IsOptional, IsString } from 'class-validator'; -export class FindEstimateEmailQueryDTO extends RelationsQueryDTO implements IEstimateEmailFindInput { +/** + * Allowed relations for the estimate-email validation endpoint. + * + * Only relations whose columns are explicitly constrained by the service's + * `select` clause are permitted. Any relation not in this enum will be + * rejected by class-validator. + */ +export enum EstimateEmailRelationEnum { + 'tenant' = 'tenant', + 'organization' = 'organization' +} - @ApiProperty({ type: () => String, readOnly: true }) +/** + * Find estimate email request DTO validation + */ +export class FindEstimateEmailQueryDTO implements IEstimateEmailFindInput { + @ApiProperty({ type: () => String, readOnly: true }) @IsNotEmpty() @IsEmail() readonly email: string; - @ApiProperty({ type: () => String, readOnly: true }) + @ApiProperty({ type: () => String, readOnly: true }) @IsNotEmpty() @IsString() readonly token: string; + + @ApiPropertyOptional({ type: () => String, enum: EstimateEmailRelationEnum }) + @IsOptional() + @Transform(({ value }: TransformFnParams) => (value ? value.map((element: string) => element.trim()) : [])) + @IsEnum(EstimateEmailRelationEnum, { each: true }) + readonly relations: string[] = []; } \ No newline at end of file diff --git a/packages/core/src/lib/public-share/invoice/dto/public-invoice-query.dto.ts b/packages/core/src/lib/public-share/invoice/dto/public-invoice-query.dto.ts index c5181c6739..8dcf144466 100644 --- a/packages/core/src/lib/public-share/invoice/dto/public-invoice-query.dto.ts +++ b/packages/core/src/lib/public-share/invoice/dto/public-invoice-query.dto.ts @@ -1,3 +1,35 @@ -import { RelationsQueryDTO } from "./../../../shared/dto"; +import { ApiPropertyOptional } from '@nestjs/swagger'; +import { Transform, TransformFnParams } from 'class-transformer'; +import { IsEnum, IsOptional } from 'class-validator'; -export class PublicInvoiceQueryDTO extends RelationsQueryDTO {} \ No newline at end of file +/** + * Allowed relations for the public invoice endpoint. + * + * Only relations whose columns are explicitly constrained by the service's + * `select` clause are permitted. Any relation not in this enum will be + * rejected by class-validator. + */ +export enum PublicInvoiceRelationEnum { + 'tenant' = 'tenant', + 'organization' = 'organization', + 'fromOrganization' = 'fromOrganization', + 'toContact' = 'toContact', + 'invoiceItems' = 'invoiceItems', + 'invoiceItems.employee' = 'invoiceItems.employee', + 'invoiceItems.employee.user' = 'invoiceItems.employee.user', + 'invoiceItems.project' = 'invoiceItems.project', + 'invoiceItems.product' = 'invoiceItems.product', + 'invoiceItems.expense' = 'invoiceItems.expense', + 'invoiceItems.task' = 'invoiceItems.task' +} + +/** + * Get public invoice request DTO validation + */ +export class PublicInvoiceQueryDTO { + @ApiPropertyOptional({ type: () => String, enum: PublicInvoiceRelationEnum }) + @IsOptional() + @Transform(({ value }: TransformFnParams) => (value ? value.map((element: string) => element.trim()) : [])) + @IsEnum(PublicInvoiceRelationEnum, { each: true }) + readonly relations: string[] = []; +} \ No newline at end of file diff --git a/packages/core/src/lib/public-share/invoice/public-invoice.service.ts b/packages/core/src/lib/public-share/invoice/public-invoice.service.ts index 56e4548f3b..9c87d9a3c1 100644 --- a/packages/core/src/lib/public-share/invoice/public-invoice.service.ts +++ b/packages/core/src/lib/public-share/invoice/public-invoice.service.ts @@ -72,6 +72,11 @@ export class PublicInvoiceService { description: true }, productId: true, + product: { + id: true, + code: true, + imageUrl: true + }, expenseId: true, expense: { id: true,