.cursor/skills/hybrid-search-implementation/SKILL.md
--- name: hybrid-search-implementation description: Guides hybrid search implementation: vector embeddings, keyword search, fusion algorithms, caching strategies. Use when implementing search, recommendation systems, or discovery features. --- # Hybrid Search Implementation ## Core Principle **Community-first prioritization** - Local community knowledge comes first, external data fills gaps. ## Search Flow ``` 1. Search community data (highest priority) 2. Search external data (if needed) 3
npx skillsauth add avra-cadavra/avrai .cursor/skills/hybrid-search-implementationInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Community-first prioritization - Local community knowledge comes first, external data fills gaps.
1. Search community data (highest priority)
2. Search external data (if needed)
3. Combine and rank results
4. Apply filters
5. Return ranked results
/// Hybrid Search Repository
///
/// Community-first search with external data fallback
class HybridSearchRepository {
final SpotsLocalDataSource _localDataSource;
final GooglePlacesDataSource? _externalDataSource;
final SearchCacheService _cacheService;
/// Hybrid search with community-first prioritization
Future<HybridSearchResult> searchSpots({
required String query,
double? latitude,
double? longitude,
int maxResults = 50,
bool includeExternal = true,
}) async {
// Check cache first
final cacheKey = _generateCacheKey(query, latitude, longitude);
final cached = await _cacheService.getCachedResult(cacheKey);
if (cached != null) return cached;
// Step 1: Search community data (highest priority)
final communitySpots = await _localDataSource.searchSpots(query);
// Step 2: Search external data if needed
List<Spot> externalSpots = [];
if (includeExternal && communitySpots.length < maxResults) {
externalSpots = await _externalDataSource?.searchPlaces(
query: query,
location: (latitude != null && longitude != null)
? LatLng(latitude, longitude)
: null,
maxResults: maxResults - communitySpots.length,
) ?? [];
}
// Step 3: Combine and rank results
final rankedResults = _rankAndDeduplicateResults(
communitySpots: communitySpots,
externalSpots: externalSpots,
query: query,
userLatitude: latitude,
userLongitude: longitude,
);
// Step 4: Apply result limit
final finalResults = rankedResults.take(maxResults).toList();
// Step 5: Cache result
final result = HybridSearchResult(
spots: finalResults,
communityCount: communitySpots.length,
externalCount: externalSpots.length,
);
await _cacheService.cacheResult(cacheKey, result);
return result;
}
}
/// Rank and deduplicate results
List<Spot> rankAndDeduplicateResults({
required List<Spot> communitySpots,
required List<Spot> externalSpots,
required String query,
double? userLatitude,
double? userLongitude,
}) {
// Combine spots
final allSpots = <Spot>[...communitySpots, ...externalSpots];
// Deduplicate by place ID or coordinates
final deduplicated = _deduplicateSpots(allSpots);
// Calculate relevance scores
final scored = deduplicated.map((spot) {
final relevance = _calculateRelevanceScore(
spot: spot,
query: query,
userLatitude: userLatitude,
userLongitude: userLongitude,
isCommunity: communitySpots.contains(spot),
);
return (spot: spot, score: relevance);
}).toList();
// Sort by score (highest first)
scored.sort((a, b) => b.score.compareTo(a.score));
return scored.map((s) => s.spot).toList();
}
/// Calculate relevance score for spot
double calculateRelevanceScore({
required Spot spot,
required String query,
double? userLatitude,
double? userLongitude,
required bool isCommunity,
}) {
var score = 0.0;
// Community boost (higher priority)
if (isCommunity) {
score += 1.0; // Community spots ranked higher
}
// Text relevance
final textMatch = _calculateTextRelevance(spot, query);
score += textMatch * 0.5;
// Distance relevance (if location provided)
if (userLatitude != null && userLongitude != null) {
final distance = _calculateDistance(
userLatitude,
userLongitude,
spot.latitude,
spot.longitude,
);
final distanceScore = 1.0 / (1.0 + distance / 1000.0); // Decay with distance
score += distanceScore * 0.3;
}
// Popularity boost (if available)
if (spot.reviewCount != null && spot.rating != null) {
final popularityScore = (spot.rating! / 5.0) * (spot.reviewCount! / 100.0);
score += popularityScore * 0.2;
}
return score.clamp(0.0, 2.0);
}
/// Cache search results
Future<void> cacheResult(String cacheKey, HybridSearchResult result) async {
// Cache for 1 hour
await _cacheService.set(
key: cacheKey,
value: result.toJson(),
ttl: Duration(hours: 1),
);
}
/// Get cached result
Future<HybridSearchResult?> getCachedResult(String cacheKey) async {
final cached = await _cacheService.get(cacheKey);
if (cached == null) return null;
return HybridSearchResult.fromJson(cached);
}
lib/data/repositories/hybrid_search_repository.dartlib/core/services/search_cache_service.dartlib/presentation/blocs/search/hybrid_search_bloc.dartdevelopment
--- name: world-model-development description: Guides world model development patterns: state/action encoders, ONNX inference, feature extraction pipeline, latency budgets. Use when implementing world model components, state encoders, action encoders, feature extractors, or ONNX models. Core skill for Phases 3-6. --- # World Model Development Patterns ## Core Principle All world model components follow LeCun's autonomous machine intelligence framework. State observations flow through a percep
tools
Implements base workflow controller patterns for multi-step processes. Use when creating complex workflows that require orchestration of multiple steps with error handling and rollback.
testing
--- name: widget-test-patterns description: Guides widget test patterns: BLoC testing, user interactions, state changes, material app setup. Use when writing widget tests, testing UI components, or validating widget behavior. --- # Widget Test Patterns ## Core Pattern Widget tests verify UI behavior: user interactions, state changes, and visual display. ## Basic Widget Test Setup ```dart testWidgets('widget displays correctly', (WidgetTester tester) async { // Arrange: Create widget awa
testing
--- name: test-template-generation description: Generates test templates: unit, widget, integration, service tests following project patterns. Use when creating new tests or ensuring tests follow project standards. --- # Test Template Generation ## Available Templates Test templates are located in `test/templates/`: - `unit_test_template.dart` - `widget_test_template.dart` - `integration_test_template.dart` - `service_test_template.dart` ## Unit Test Template ```dart /// SPOTS Component Uni