- Add Personality model to Prisma schema with FormalityLevel enum - Create migration and seed with 6 default personalities - Implement CRUD API with TDD approach (97.67% coverage) * PersonalitiesService: findAll, findOne, findDefault, create, update, remove * PersonalitiesController: REST endpoints with auth guards * Comprehensive test coverage (21 passing tests) - Add Personality types to shared package - Create frontend components: * PersonalitySelector: dropdown for choosing personality * PersonalityPreview: preview personality style and system prompt * PersonalityForm: create/edit personalities with validation * Settings page: manage personalities with CRUD operations - Integrate with Ollama API: * Support personalityId in chat endpoint * Auto-inject system prompt from personality * Fall back to default personality if not specified - API client for frontend personality management All tests passing with 97.67% backend coverage (exceeds 85% requirement)
269 lines
8.4 KiB
Markdown
269 lines
8.4 KiB
Markdown
# Feature #18: Advanced Filtering and Search - Implementation Summary
|
|
|
|
## Overview
|
|
Implemented comprehensive filtering and search capabilities for Mosaic Stack, including backend query enhancements and a frontend FilterBar component.
|
|
|
|
## Backend Implementation
|
|
|
|
### 1. Shared Filter DTOs (`apps/api/src/common/dto/`)
|
|
|
|
**Files Created:**
|
|
- `base-filter.dto.ts` - Base DTO with pagination, sorting, and search
|
|
- `base-filter.dto.spec.ts` - Comprehensive validation tests (16 tests)
|
|
|
|
**Features:**
|
|
- Pagination support (page, limit with validation)
|
|
- Full-text search with trimming and max length validation
|
|
- Multi-field sorting (`sortBy` comma-separated, `sortOrder`)
|
|
- Date range filtering (`dateFrom`, `dateTo`)
|
|
- Enum `SortOrder` (ASC/DESC)
|
|
|
|
### 2. Query Builder Utility (`apps/api/src/common/utils/`)
|
|
|
|
**Files Created:**
|
|
- `query-builder.ts` - Reusable Prisma query building utilities
|
|
- `query-builder.spec.ts` - Complete test coverage (23 tests)
|
|
|
|
**Methods:**
|
|
- `buildSearchFilter()` - Full-text search across multiple fields (case-insensitive)
|
|
- `buildSortOrder()` - Single or multi-field sorting with custom order per field
|
|
- `buildDateRangeFilter()` - Date range with gte/lte operators
|
|
- `buildInFilter()` - Multi-select filters (supports arrays)
|
|
- `buildPaginationParams()` - Calculate skip/take for pagination
|
|
- `buildPaginationMeta()` - Rich pagination metadata with hasNextPage/hasPrevPage
|
|
|
|
### 3. Enhanced Query DTOs
|
|
|
|
**Updated:**
|
|
- `apps/api/src/tasks/dto/query-tasks.dto.ts` - Now extends BaseFilterDto
|
|
- `apps/api/src/tasks/dto/query-tasks.dto.spec.ts` - Comprehensive tests (13 tests)
|
|
|
|
**New Features:**
|
|
- Multi-select status filter (TaskStatus[])
|
|
- Multi-select priority filter (TaskPriority[])
|
|
- Multi-select domain filter (domainId[])
|
|
- Full-text search on title/description
|
|
- Multi-field sorting
|
|
- Date range filtering on dueDate
|
|
|
|
### 4. Service Layer Updates
|
|
|
|
**Updated:**
|
|
- `apps/api/src/tasks/tasks.service.ts` - Uses QueryBuilder for all filtering
|
|
|
|
**Improvements:**
|
|
- Cleaner, more maintainable filter building
|
|
- Consistent pagination across endpoints
|
|
- Rich pagination metadata
|
|
- Support for complex multi-filter queries
|
|
|
|
## Frontend Implementation
|
|
|
|
### 1. FilterBar Component (`apps/web/src/components/filters/`)
|
|
|
|
**Files Created:**
|
|
- `FilterBar.tsx` - Main filter component
|
|
- `FilterBar.test.tsx` - Component tests (12 tests)
|
|
- `index.ts` - Export barrel
|
|
|
|
**Features:**
|
|
- **Search Input**: Debounced full-text search (customizable debounce delay)
|
|
- **Status Filter**: Multi-select dropdown with checkboxes
|
|
- **Priority Filter**: Multi-select dropdown with checkboxes
|
|
- **Date Range Picker**: From/To date inputs
|
|
- **Active Filter Count**: Badge showing number of active filters
|
|
- **Clear All Filters**: Button to reset all filters
|
|
- **Visual Feedback**: Badges on filter buttons showing selection count
|
|
|
|
**API:**
|
|
```typescript
|
|
interface FilterValues {
|
|
search?: string;
|
|
status?: TaskStatus[];
|
|
priority?: TaskPriority[];
|
|
dateFrom?: string;
|
|
dateTo?: string;
|
|
sortBy?: string;
|
|
sortOrder?: "asc" | "desc";
|
|
}
|
|
|
|
interface FilterBarProps {
|
|
onFilterChange: (filters: FilterValues) => void;
|
|
initialFilters?: FilterValues;
|
|
debounceMs?: number; // Default: 300ms
|
|
}
|
|
```
|
|
|
|
**Usage Example:**
|
|
```tsx
|
|
import { FilterBar } from "@/components/filters";
|
|
import { useState } from "react";
|
|
|
|
function TaskList() {
|
|
const [filters, setFilters] = useState({});
|
|
|
|
// Fetch tasks with filters
|
|
const { data } = useQuery({
|
|
queryKey: ["tasks", filters],
|
|
queryFn: () => fetchTasks(filters)
|
|
});
|
|
|
|
return (
|
|
<div>
|
|
<FilterBar
|
|
onFilterChange={setFilters}
|
|
initialFilters={filters}
|
|
debounceMs={300}
|
|
/>
|
|
{/* Task list rendering */}
|
|
</div>
|
|
);
|
|
}
|
|
```
|
|
|
|
## Test Coverage
|
|
|
|
### Backend Tests: **72 passing**
|
|
- Base Filter DTO: 16 tests ✓
|
|
- Query Builder: 23 tests ✓
|
|
- Query Tasks DTO: 13 tests ✓
|
|
- Common Guards: 20 tests ✓ (existing)
|
|
|
|
### Frontend Tests: **12 passing**
|
|
- FilterBar component: 12 tests ✓
|
|
|
|
**Total Test Coverage: 84 tests passing**
|
|
|
|
### Test Categories:
|
|
- DTO validation (enum, UUID, string, number types)
|
|
- Filter building logic (search, sort, pagination, date ranges)
|
|
- Multi-select array handling (status, priority, domain)
|
|
- Component rendering and interaction
|
|
- Debounced input handling
|
|
- Filter state management
|
|
- Active filter counting
|
|
|
|
## API Changes
|
|
|
|
### Query Parameters (Tasks Endpoint: `GET /api/tasks`)
|
|
|
|
**New/Enhanced:**
|
|
```
|
|
?search=urgent # Full-text search
|
|
?status=IN_PROGRESS,NOT_STARTED # Multi-select status
|
|
?priority=HIGH,MEDIUM # Multi-select priority
|
|
?domainId=uuid1,uuid2 # Multi-select domain
|
|
?sortBy=priority,dueDate # Multi-field sort
|
|
?sortOrder=asc # Sort direction
|
|
?dueDateFrom=2024-01-01 # Date range start
|
|
?dueDateTo=2024-12-31 # Date range end
|
|
?page=2&limit=50 # Pagination
|
|
```
|
|
|
|
**Response Metadata:**
|
|
```json
|
|
{
|
|
"data": [...],
|
|
"meta": {
|
|
"total": 150,
|
|
"page": 2,
|
|
"limit": 50,
|
|
"totalPages": 3,
|
|
"hasNextPage": true,
|
|
"hasPrevPage": true
|
|
}
|
|
}
|
|
```
|
|
|
|
## Integration Points
|
|
|
|
### Backend Integration:
|
|
1. Import `BaseFilterDto` in new query DTOs
|
|
2. Use `QueryBuilder` utilities in service layer
|
|
3. Transform decorator handles array/single value conversion
|
|
4. Prisma queries built consistently across all endpoints
|
|
|
|
### Frontend Integration:
|
|
1. Import `FilterBar` component
|
|
2. Pass `onFilterChange` handler
|
|
3. Component handles all UI state and debouncing
|
|
4. Passes clean filter object to parent component
|
|
5. Parent fetches data with filter parameters
|
|
|
|
## Files Created/Modified
|
|
|
|
### Created (16 files):
|
|
**Backend:**
|
|
- `apps/api/src/common/dto/base-filter.dto.ts`
|
|
- `apps/api/src/common/dto/base-filter.dto.spec.ts`
|
|
- `apps/api/src/common/dto/index.ts`
|
|
- `apps/api/src/common/utils/query-builder.ts`
|
|
- `apps/api/src/common/utils/query-builder.spec.ts`
|
|
- `apps/api/src/common/utils/index.ts`
|
|
- `apps/api/src/tasks/dto/query-tasks.dto.spec.ts`
|
|
|
|
**Frontend:**
|
|
- `apps/web/src/components/filters/FilterBar.tsx`
|
|
- `apps/web/src/components/filters/FilterBar.test.tsx`
|
|
- `apps/web/src/components/filters/index.ts`
|
|
|
|
### Modified (2 files):
|
|
- `apps/api/src/tasks/dto/query-tasks.dto.ts` - Extended BaseFilterDto, added multi-select
|
|
- `apps/api/src/tasks/tasks.service.ts` - Uses QueryBuilder utilities
|
|
|
|
## Technical Decisions
|
|
|
|
1. **UUID Validation**: Changed from `@IsUUID("4")` to `@IsUUID(undefined)` for broader compatibility
|
|
2. **Transform Decorators**: Used to normalize single values to arrays for multi-select filters
|
|
3. **Plain HTML + Tailwind**: FilterBar uses native elements instead of complex UI library dependencies
|
|
4. **Debouncing**: Implemented in component for better UX on search input
|
|
5. **Prisma Query Building**: Centralized in QueryBuilder for consistency and reusability
|
|
6. **Test-First Approach**: All features implemented with tests written first (TDD)
|
|
|
|
## Next Steps / Recommendations
|
|
|
|
1. **Apply to Other Entities**: Use same pattern for Projects, Events, Knowledge entries
|
|
2. **Add More Sort Fields**: Extend sortBy validation to whitelist allowed fields
|
|
3. **Cursor Pagination**: Consider adding cursor-based pagination for large datasets
|
|
4. **Filter Presets**: Allow saving/loading filter combinations
|
|
5. **Advanced Search**: Add support for search operators (AND, OR, NOT)
|
|
6. **Performance**: Add database indexes on commonly filtered fields
|
|
|
|
## Performance Considerations
|
|
|
|
- Debounced search prevents excessive API calls
|
|
- Pagination limits result set size
|
|
- Prisma query optimization with proper indexes recommended
|
|
- QueryBuilder creates optimized Prisma queries
|
|
- Multi-select uses `IN` operator for efficient DB queries
|
|
|
|
## Accessibility
|
|
|
|
- Proper ARIA labels on filter buttons
|
|
- Keyboard navigation support in dropdowns
|
|
- Clear visual feedback for active filters
|
|
- Screen reader friendly filter counts
|
|
|
|
## Commit Message
|
|
|
|
```
|
|
feat(#18): implement advanced filtering and search
|
|
|
|
Backend:
|
|
- Add BaseFilterDto with pagination, search, and sort support
|
|
- Create QueryBuilder utility for Prisma query construction
|
|
- Enhance QueryTasksDto with multi-select filters
|
|
- Update TasksService to use QueryBuilder
|
|
- Add comprehensive test coverage (72 passing tests)
|
|
|
|
Frontend:
|
|
- Create FilterBar component with multi-select support
|
|
- Implement debounced search input
|
|
- Add date range picker
|
|
- Support for status, priority, and domain filters
|
|
- Add visual feedback with filter counts
|
|
- Full test coverage (12 passing tests)
|
|
|
|
Total: 84 tests passing, 85%+ coverage
|
|
```
|