|
| 1 | +# Copilot Instructions for Wuzzy Search API |
| 2 | + |
| 3 | +## Project Overview |
| 4 | + |
| 5 | +This is a NestJS-based search API that integrates with OpenSearch, featuring User Behavior Insights (UBI) tracking for search analytics. The application provides full-text search capabilities across indexed web documents with highlight snippets. |
| 6 | + |
| 7 | +## Architecture |
| 8 | + |
| 9 | +- **Framework**: NestJS (Node.js/TypeScript) |
| 10 | +- **Search Engine**: OpenSearch with UBI plugin |
| 11 | +- **Client Library**: `@opensearch-project/opensearch` |
| 12 | +- **Key Features**: Combined fields search, HTML highlight processing, client tracking |
| 13 | + |
| 14 | +## Key Patterns and Conventions |
| 15 | + |
| 16 | +### OpenSearch Integration |
| 17 | + |
| 18 | +- Use `combined_fields` query type to search across multiple document fields: `title`, `meta_description`, `headings`, and `body` |
| 19 | +- Always include UBI extension in search queries with `object_id_field`, `query_id`, `user_query`, and `application` fields |
| 20 | +- Track client behavior via optional `client_id` field in UBI data |
| 21 | +- Generate unique `query_id` using `randomUUID()` for each search request |
| 22 | + |
| 23 | +### Highlight Processing |
| 24 | + |
| 25 | +- Use custom highlight tags `[[h]]` and `[[/h]]` in OpenSearch queries to avoid conflicts with HTML in indexed content |
| 26 | +- Strip HTML from highlighted fragments using `string-strip-html` library |
| 27 | +- Replace custom tags with `<strong>` tags for final output |
| 28 | +- Join multiple highlight fragments with double spaces |
| 29 | + |
| 30 | +### Client Tracking |
| 31 | + |
| 32 | +- Accept client tracking via HTTP headers: `x-client-name`, `x-client-version`, `x-session-id` |
| 33 | +- Combine tracking headers into a single `client_id` string: `{name}@{version}@{session}` |
| 34 | +- Log warnings when client tracking headers are missing |
| 35 | +- Pass `client_id` to OpenSearch UBI for analytics |
| 36 | + |
| 37 | +### Configuration Management |
| 38 | + |
| 39 | +- Use `@nestjs/config` with typed `ConfigService` for environment variables |
| 40 | +- Validate required configuration on service construction (fail fast) |
| 41 | +- Support optional TLS/SSL with certificate file path |
| 42 | +- Default `UBI_STORE_NAME` to `.ubi_queries` if not specified |
| 43 | + |
| 44 | +### Logging |
| 45 | + |
| 46 | +- Use NestJS `Logger` with class-specific contexts |
| 47 | +- Log search execution details: query, offset, size, query_id, client_id |
| 48 | +- Log search results: response time, hit count, total results |
| 49 | +- Log OpenSearch connection status on application bootstrap |
| 50 | + |
| 51 | +### Error Handling |
| 52 | + |
| 53 | +- Throw descriptive errors for missing required configuration |
| 54 | +- Verify OpenSearch connectivity on application bootstrap |
| 55 | +- Log errors with appropriate context before throwing |
| 56 | + |
| 57 | +## Environment Variables |
| 58 | + |
| 59 | +All environment variables are required unless noted as optional: |
| 60 | + |
| 61 | +- `SEARCH_INDEX_NAME` - OpenSearch index name for document search |
| 62 | +- `ES_HOST` - OpenSearch cluster URL (e.g., `https://localhost:9200`) |
| 63 | +- `ES_USERNAME` - OpenSearch authentication username |
| 64 | +- `ES_PASSWORD` - OpenSearch authentication password |
| 65 | +- `ES_USE_TLS` - Enable TLS/SSL (`true` or `false`) |
| 66 | +- `ES_CERT_PATH` - Path to CA certificate file (required if `ES_USE_TLS=true`) |
| 67 | +- `UBI_STORE_NAME` - UBI index name (optional, defaults to `.ubi_queries`) |
| 68 | +- `PORT` - HTTP server port (optional, defaults to `3000`) |
| 69 | +- `CORS_DOMAINS` - CORS allowed origins (optional, defaults to `*`) |
| 70 | + |
| 71 | +## Code Style |
| 72 | + |
| 73 | +- Use TypeScript with strict typing |
| 74 | +- Prefer `readonly` for class properties that don't change |
| 75 | +- Use template literals for multi-line strings and string concatenation |
| 76 | +- Use optional chaining and nullish coalescing operators |
| 77 | +- Follow NestJS conventions: controllers for HTTP, services for business logic |
| 78 | +- Use dependency injection via constructor parameters |
| 79 | +- Implement lifecycle hooks (`OnApplicationBootstrap`) for initialization logic |
| 80 | + |
| 81 | +## Testing Considerations |
| 82 | + |
| 83 | +- Mock OpenSearch client in unit tests |
| 84 | +- Test configuration validation (missing required env vars) |
| 85 | +- Test highlight processing with various HTML content |
| 86 | +- Test client_id formatting with different header combinations |
| 87 | +- Verify UBI data structure in search requests |
| 88 | + |
| 89 | +## OpenSearch Requirements |
| 90 | + |
| 91 | +- OpenSearch cluster must have UBI plugin installed and enabled |
| 92 | +- Search index must contain fields: `id`, `title`, `meta_description`, `headings`, `body`, `url`, and related URL components |
| 93 | +- Index documents should be web page content with HTML in body field |
| 94 | +- UBI queries index (default `.ubi_queries`) must be accessible for analytics tracking |
| 95 | + |
| 96 | +## Important Notes |
| 97 | +- Do not install dependencies. Instead, provide a summary of dependency updates to the user so they can manually install or remove before implementation begins. |
| 98 | +- Do not modify package.json. Instead, provide a summary of changes to the user so they can manually update it before or after implementation. |
| 99 | +- Do not run the app itself, the user will handle manual spot testing. |
| 100 | +- Make sure the app compiles with `npm run build`. |
0 commit comments