feat(search): Add complete Search UI with API and web interface
Implements full search functionality for StarPunk v1.1.0. Search API Endpoint (/api/search): - GET endpoint with query parameter (q) validation - Pagination via limit (default 20, max 100) and offset parameters - JSON response with results count and formatted search results - Authentication-aware: anonymous users see published notes only - Graceful handling of FTS5 unavailability (503 error) - Proper error responses for missing/empty queries Search Web Interface (/search): - HTML search results page with Bootstrap-inspired styling - Search form with HTML5 validation (minlength=2, maxlength=100) - Results display with title, excerpt, date, and links - Empty state for no results - Error state for FTS5 unavailability - Simple pagination (Next/Previous navigation) Navigation Integration: - Added search box to site navigation in base.html - Preserves query parameter on results page - Responsive design with emoji search icon - Accessible with proper ARIA labels FTS Index Population: - Added startup check in __init__.py for empty FTS index - Automatic rebuild from existing notes on first run - Graceful degradation if population fails - Logging for troubleshooting Security Features: - XSS prevention: HTML in search results properly escaped - Safe highlighting: FTS5 <mark> tags preserved, user content escaped - Query validation: empty queries rejected, length limits enforced - SQL injection prevention via FTS5 query parser - Authentication filtering: unpublished notes hidden from anonymous users Testing: - Added 41 comprehensive tests across 3 test files - test_search_api.py: 12 tests for API endpoint validation - test_search_integration.py: 17 tests for UI rendering and integration - test_search_security.py: 12 tests for XSS, SQL injection, auth filtering - All tests passing with no regressions Implementation follows architect specifications from: - docs/architecture/v1.1.0-validation-report.md - docs/architecture/v1.1.0-feature-architecture.md - docs/decisions/ADR-034-full-text-search.md Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -24,6 +24,20 @@
|
||||
{% if g.me %}
|
||||
<a href="{{ url_for('admin.dashboard') }}">Admin</a>
|
||||
{% endif %}
|
||||
<form action="/search" method="get" role="search" style="margin-left: auto; display: flex; gap: var(--spacing-sm);">
|
||||
<input
|
||||
type="search"
|
||||
name="q"
|
||||
placeholder="Search..."
|
||||
aria-label="Search"
|
||||
value="{{ request.args.get('q', '') }}"
|
||||
minlength="2"
|
||||
maxlength="100"
|
||||
required
|
||||
style="width: 200px; padding: var(--spacing-xs) var(--spacing-sm);"
|
||||
>
|
||||
<button type="submit" class="button button-small" style="padding: var(--spacing-xs) var(--spacing-sm);">🔍</button>
|
||||
</form>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user