Skip to content

Conversation

@codihuston
Copy link
Owner

@codihuston codihuston commented Jan 30, 2026

Summary

Implement Global Jump Navigation backend API - a cross-video artifact search service that enables navigation across the entire video library in chronological order. Supports searching by object labels, faces, transcript text, OCR text, scenes, places, and GPS locations.

Changes

  • Product changes
  • Security changes
  • Test changes
  • Dependency changes
  • UX changes
  • Architecture changes
  • Feature/code changes
  • CI/CD changes
  • Breaking changes

Testing

  • Tests pass locally (135 tests)
  • New tests added
  • Manual testing completed

Related Issues

N/A

Screenshots (if applicable)

N/A


Detailed Changes

API Endpoint

GET /api/v1/jump/global - Global Jump Navigation

Navigate across videos to find artifacts in chronological order using a unified API.

Parameters:

  • kind (required): Artifact type - object, face, transcript, ocr, scene, place, location
  • direction (required): Navigation direction - next, prev
  • from_video_id (optional): Starting video ID
  • from_ms (optional): Starting timestamp in milliseconds
  • label (optional): Filter by label (for object/place)
  • query (optional): Full-text search query (for transcript/ocr/location)
  • face_cluster_id (optional): Filter by face cluster ID
  • min_confidence (optional): Minimum confidence threshold (0-1)
  • limit (optional): Max results (1-50, default 1)

Response:

{
  "results": [{
    "video_id": "abc-123",
    "video_filename": "beach_trip.mp4",
    "file_created_at": "2025-05-19T02:22:21Z",
    "jump_to": {"start_ms": 15000, "end_ms": 15500},
    "artifact_id": "obj_xyz_001",
    "preview": {"label": "dog", "confidence": 0.95}
  }],
  "has_more": true
}

Global Timeline Ordering

Results are ordered using a deterministic three-level sort:

  1. file_created_at (EXIF/filesystem date) - primary sort
  2. video_id - secondary sort for deterministic ordering
  3. start_ms - tertiary sort for artifacts within same video

Domain Models

  • GlobalJumpResult - Result object with video metadata and temporal boundaries
  • JumpTo - Temporal boundaries (start_ms, end_ms) for seeking
  • VideoNotFoundError - Exception for non-existent video IDs
  • InvalidParameterError - Exception for invalid parameters

Service Layer

GlobalJumpService - Core service for cross-video navigation

Methods:

  • jump_next() - Navigate forward in global timeline
  • jump_prev() - Navigate backward in global timeline

Internal search methods:

  • _search_objects_global() - Object label search with confidence filter
  • _search_transcript_global() - Full-text transcript search (PostgreSQL + SQLite)
  • _search_ocr_global() - Full-text OCR search (PostgreSQL + SQLite)
  • _search_scenes_global() - Scene boundary navigation
  • _search_places_global() - Place label search (reuses object_labels projection)
  • _search_locations_global() - GPS location search with text matching

Database Queries

  • Uses existing projection tables: object_labels, face_clusters, transcript_fts, ocr_fts, scene_ranges, video_locations
  • Supports both PostgreSQL (tsvector/tsquery) and SQLite (FTS5) for full-text search
  • Handles NULL file_created_at values with NULLS LAST ordering
  • Added database indexes for global jump queries

Tests

135 comprehensive tests covering:

  • Object search (next/prev direction, label filter, confidence filter, ordering, limits)
  • Transcript search (next/prev, cross-video, ordering)
  • OCR search (next/prev, cross-video, ordering)
  • Scene search (next/prev, cross-video)
  • Place search (routes to object_labels)
  • Location search (text matching on country/state/city)
  • Boundary conditions (from_ms beyond duration)
  • Arbitrary position navigation
  • Error handling (video not found, invalid parameters)

…o navigation

- Add GlobalJumpResult and JumpTo dataclasses for navigation results
- Add GlobalJumpError, VideoNotFoundError, InvalidParameterError exceptions
- Add spec documents (requirements, design, tasks)
- Create JumpToSchema with start_ms and end_ms fields (with ge=0 validation)
- Create GlobalJumpResultSchema with video_id, video_filename, file_created_at,
  jump_to, artifact_id, and preview fields
- Create GlobalJumpResponseSchema with results array and has_more boolean
- Add comprehensive docstrings and field descriptions
- Export new schemas from global_jump module

Requirements: 5.3, 7.1, 7.2, 7.3, 7.4, 7.5, 13.1
- Add GlobalJumpResult and JumpTo domain models
- Add GlobalJumpError, VideoNotFoundError, InvalidParameterError exceptions
- Add GlobalJumpResultSchema and GlobalJumpResponseSchema for API responses
- Implement GlobalJumpService with _get_video() and _to_global_result() helpers

Follows existing layer-based project structure rather than feature-module pattern.
- Add _search_objects_global() method to GlobalJumpService
- Query object_labels projection table joined with videos
- Support label and min_confidence filtering
- Order by global timeline (file_created_at, video_id, start_ms)
- Handle NULL file_created_at values (sorted after non-NULL)
- Add 11 unit tests covering cross-video navigation
- Fix unused imports in video_controller.py
- Extend _search_objects_global() to support direction="prev"
- Add WHERE clause for results chronologically before current position
- Order by file_created_at DESC, video_id DESC, start_ms DESC
- Handle NULL file_created_at values (non-NULL comes before NULLs)
- Add 10 unit tests for prev direction covering cross-video navigation,
  filtering, ordering, and edge cases
- Add _search_transcript_global() method for cross-video transcript search
- PostgreSQL: Use plainto_tsquery for FTS with ILIKE fallback
- SQLite: Use FTS5 MATCH with separate metadata table join
- Support both 'next' and 'prev' directions with global timeline ordering
- Handle NULL file_created_at values correctly
- Add 10 unit tests for transcript search covering single-video,
  cross-video, ordering, and edge cases
- Add _search_ocr_global() method for cross-video OCR text search
- PostgreSQL: Use plainto_tsquery for FTS with ILIKE fallback
- SQLite: Use FTS5 MATCH with separate metadata table join
- Support both 'next' and 'prev' directions with global timeline ordering
- Handle NULL file_created_at values correctly
- Add 10 unit tests for OCR search covering single-video,
  cross-video, ordering, and edge cases
- Add VALID_KINDS class attribute with valid artifact types
- Implement jump_next() method that routes to appropriate search method
- Handle object, transcript, ocr kinds with proper routing
- Add placeholder errors for face, scene, place, location (not yet implemented)
- Validate kind parameter and raise InvalidParameterError for invalid values
- Default from_ms to 0 for next direction
- Require query parameter for transcript and ocr searches
- Add 8 unit tests for jump_next() method

Requirements: 1.1, 2.1, 3.1, 4.1, 5.1, 6.1, 12.3
- Implement jump_prev() method that routes to appropriate search method
- Handle object, transcript, ocr kinds with direction='prev'
- Add placeholder errors for face, scene, place, location (not yet implemented)
- Validate kind parameter and raise InvalidParameterError for invalid values
- Default from_ms to max int value for prev direction (end of video)
- Require query parameter for transcript and ocr searches
- Add 8 unit tests for jump_prev() method

Requirements: 1.2, 2.1, 3.3, 4.2, 5.1, 6.5, 12.3
- Add SceneRange import from database models
- Implement _search_scenes_global() for scene boundary navigation
- Implement _search_places_global() using object_labels table
- Update jump_next() to route scene and place kinds
- Update jump_prev() to route scene and place kinds
- Add 16 unit tests for scene and place search functionality

Scene search queries scene_ranges projection table for scene boundaries.
Place search reuses object_labels table since place classifications
are stored as object labels from Places365 model.

Requirements: 5.1, 7.5
- Implement _search_locations_global() for GPS location navigation
- Query video_locations projection table for videos with GPS data
- Support optional geo_bounds filtering (min_lat, max_lat, min_lon, max_lon)
- Handle SQLite datetime comparison by converting to string format
- Update jump_next() and jump_prev() to route location kind
- Add 10 unit tests for location search functionality

Location search returns videos with GPS coordinates ordered by global
timeline. Unlike other artifact searches, location is per-video so
results point to start_ms=0.

Requirements: 5.1
- Follow existing project patterns for API controllers
- Delete orphaned test_face_detection.py (ML service moved)
- Add test_global_jump_router.py for error handling tests
- Update ErrorResponseSchema in schemas.py
- All 339 tests passing
- Add global_jump_controller with parameter validation and error handling
- Register global jump router in main_api.py at /v1/jump/global
- Add composite database indexes for query optimization
- Add comprehensive tests for:
  - Arbitrary position navigation (14 tests)
  - Filter change independence (9 tests)
  - Result chaining capability (7 tests)
  - Cross-video navigation correctness (8 tests)
  - Backward compatibility with single-video jump (9 tests)
- All 391 tests passing

Tasks completed: 13-25 (excluding optional property tests)
- Add detailed endpoint description with global timeline concept
- Add OpenAPI examples for all response types
- Document all query parameters with examples
- Add error response examples for all error codes
- Enhance schema docstrings with field descriptions
@codihuston codihuston merged commit cdfa13b into main Jan 30, 2026
0 of 2 checks passed
@codihuston codihuston deleted the global-jump branch January 31, 2026 06:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant