# concentriq-ls-client TODO

## Phase 1: Foundation ✅ COMPLETE
- [x] Initialize uv project
- [x] Create project structure
- [x] Setup pyproject.toml with dependencies
- [x] Implement exceptions with tests (18 tests)
- [x] Implement authentication handlers with tests (15 tests)
- [x] Implement base ConcentriqClient with tests (20 tests)

**Current Status: 138 tests passing** ✅

---

## Phase 2: Core Models (Pydantic)
- [x] Extract schemas from `api-docs-base.json` (50 schemas from OpenAPI + 25 undocumented)
- [x] Analyze backend controllers for undocumented schemas (15 controllers, 53.6% undocumented!)
- [x] Classify customer-facing vs internal endpoints (26 include, 2 exclude)
- [x] Decision: Skip plain Pydantic models with no custom logic (no tests needed)
  - Models will be created as needed when adding custom validators/methods
  - Focus on API client behavior instead

### Filter Models (Implement as resources are added)
**Pattern:** Version-specific models (V1/V2/V3 have different structures)
- Implement filter models incrementally as each resource is added
- Use `extra='allow'` for forward compatibility (backend silently ignores unknown fields)
- V1: Separate filters + pagination, rich metadata support
- V2: Generic per-resource filters (minimal, resource-specific)
- V3: Unified QueryFilter with embedded pagination (limit/offset)

**V1 Filter Models:**
- [x] V1BaseFilters - Common V1 patterns (generalSearch, fields) ✅
- [x] ImageSetFilters (21+ fields: ownerId, isFavorite, archived, workflowId, etc.) ✅
- [x] ImageFilters (25+ fields: imageSetId, hasAnnotations, isFluorescence, etc.) ✅
- [x] FolderFilters (7 fields: imageSetId, folderId, hasMetadata, hasAttachments, name, image) ✅
- [x] MetadataValueFilters (9 fields: imageSetId, imageId, folderId, annotationId, etc.) ✅
- [x] AnnotationFilters (5 fields: annotationId, imageId, text, annotationClassId) ✅

---

## Phase 3: V1 API Resources (`/api/*`)

### Core Resources
- [x] ImageSetsAPI ✅ (19 tests) - Basic CRUD complete
  - [x] list() with pagination and filters (JSON-encoded filters)
  - [x] get(id)
  - [x] create(data)
  - [x] update(id, data)
  - [x] delete(id)
  - [ ] navigation endpoints - DEFERRED: UI-specific hierarchical tree, not needed for programmatic access
  - [ ] collaborators management - DEFERRED: Sharing/permissions, specialized feature, may revisit based on demand

- [x] ImagesAPI ✅ (9 tests) - Complete
  - [x] list() with pagination and filters
  - [x] get(id)
  - [x] download(id) - Returns signed S3 URL for file download
  - Note: Metadata accessed via centralized MetadataAPI, not image-specific endpoints

- [x] FoldersAPI ✅ (17 tests) - Complete
  - [x] list() with pagination and filters (FolderFilters model) ✅
  - [x] get(id) ✅
  - [x] create(data) ✅
  - [x] update(id, data) ✅
  - [x] delete(id) ✅

- [x] AnnotationsAPI ✅ (17 tests) - Complete
  - [x] list() with pagination and filters (AnnotationFilters model) ✅
  - [x] get(id) ✅
  - [x] create(data) ✅
  - [x] update(id, data) ✅
  - [x] delete(id) ✅

### Supporting Resources
- [x] MetadataAPI ✅ (23 tests) - Centralized metadata system complete
  - [x] MetadataFields ✅ (16 tests) - CRUD for field definitions
    - [x] list() with pagination ✅
    - [x] get(id) ✅
    - [x] create(data) ✅
    - [x] update(id, data) ✅
    - [x] delete(id) ✅
  - [x] MetadataValues ✅ (7 tests) - Get/update metadata values
    - [x] list() with filters (by resourceId, fieldId, etc.) ✅
    - [x] update(values) - Batch update metadata values ✅
- [x] UsersAPI ✅ (12 tests) - Complete
- [x] OrganizationsAPI ✅ (10 tests) - Complete
- [x] TemplatesAPI ✅ (15 tests) - Complete
- [x] WorkflowsAPI ✅ (14 tests) - Complete
  - [x] list() with organization_id and group_id filters
  - [x] create(data) - Admin only
  - [x] update(id, data) - Admin only
  - [x] delete(id) - Admin only
- [x] OrdersAPI ✅ (13 tests) - Complete
  - [x] list_stains() - Get available stains for ordering
  - [x] list() with filters (image_set_id, image_id, not_completed)
  - [x] create(data) - Create stain or recut orders
- [ ] CollaborationAPI - DEFERRED: Minimal API (1 endpoint: GET messages), may implement based on demand
- [x] AttachmentsAPI ✅ (14 tests) - Complete
  - [x] list() with filters (folder_id, image_set_id, attachment_id, storage_key)
  - [x] create(data) - Returns attachmentId and storageKey for S3 upload
  - [x] delete(id) - Requires canManageMetadataValues permission
- [ ] SavedSearchesAPI - DEFERRED: Standard CRUD API for saved search queries, may implement based on demand
- [ ] RecordsAPI - DEFERRED: Audit log API returning CSV streams, specialized use case, may implement based on demand

---

## Phase 4: V2 API Resources (`/api/v2/*`) ✅ COMPLETE
- [x] UserGroupsAPI ✅ (11 tests) - Complete CRUD
  - [x] list() with pagination and filters
  - [x] get(id)
  - [x] create(data) - Requires canManageGroups permission
  - [x] update(id, data) - Requires canManageGroups permission
  - [x] delete(id) - Requires canManageGroups permission
- [x] ModulesAPI ✅ (5 tests) - Complete CRUD for external modules
  - [x] list() with pagination and filters
  - [x] get(id)
  - [x] create(data)
  - [x] update(id, data)
  - [x] delete(id)
- [x] SavedDisplaySettingsAPI ✅ (5 tests) - Complete CRUD for fluorescence image display settings
  - [x] list() with pagination and filters
  - [x] get(id)
  - [x] create(data) - Fluorescence channel settings
  - [x] update(id, data)
  - [x] delete(id)

**Current Status: 233 tests passing** ✅

---

## Phase 5: V3 API Resources (`/api/v3/*`)

### Auth & Core
- [x] AuthAPI ✅ (10 tests) - Complete
  - [x] whoami() - Get current user and role rules
  - [x] get_public_key() - Get JWT public key
  - [x] create_token() - Create JWT token
  - [x] create_api_key() - Generate API key
  - [x] delete_api_key() - Delete API key
  - [x] check_api_key_status() - Check API key status

### Resources
- [x] AnnotationClassesAPI ✅ (9 tests) - Complete CRUD
  - [x] list() - List all annotation classes
  - [x] get(id) - Get by ID
  - [x] create(data) - Create annotation class
  - [x] update(id, data) - Update annotation class
  - [x] delete(id) - Delete annotation class
- [x] ChannelGroupsAPI ✅ (13 tests) - Complete CRUD + repo operations
  - [x] list() - List all channel groups
  - [x] get(id) - Get by ID
  - [x] create(data) - Create channel group
  - [x] update(id, data) - Update channel group
  - [x] delete(id) - Delete channel group
  - [x] add_to_repo(channel_group_id, repo_id) - Add to repository
  - [x] remove_from_repo(channel_group_id, repo_id) - Remove from repository
- [x] AppConfigAPI ✅ (5 tests) - List, Get, Update only (no create/delete)
  - [x] list() - List all app configs
  - [x] get(id) - Get by ID (string ID)
  - [x] update(id, data) - Update config value
- [x] AuditLogsAPI ✅ (2 tests) - Read-only audit log queries
  - [x] get_status() - Get audit log processing status
- [x] StudiesAPI ✅ (16 tests) - Full CRUD + nested operations
  - [x] list() - List all studies
  - [x] get(id) - Get by ID
  - [x] create(data) - Create study
  - [x] update(id, data) - Update study
  - [x] delete(id) - Delete study
  - [x] get_fields(study_id) - List study fields
  - [x] add_field(study_id, field_id) - Add field to study
  - [x] remove_field(study_id, field_id) - Remove field from study
  - [x] get_users(study_id) - List study users
  - [x] upsert_user(study_id, user_id, data) - Add/update user
  - [x] remove_user(study_id, user_id) - Remove user from study
  - [x] get_statistics(study_id) - Get study statistics
- [x] UserAPI (V3) ✅ (4 tests) - User settings management
  - [x] get_settings(user_id) - Get user settings
  - [x] update_settings(user_id, data) - Update user settings (PATCH)
- [x] ImageAPI (V3) ✅ (2 tests) - Get image metadata only
  - [x] get(id) - Get image by ID
- [x] ImageSetAPI (V3) ✅ (13 tests) - Seed and blinds management for research studies
  - [x] generate_seed(image_set_id) - Generate random seed for randomization
  - [x] get_seed(image_set_id) - Get user's current seed
  - [x] delete_seed(image_set_id) - Delete user's seed
  - [x] get_blinds(image_set_id) - Get blind configuration
  - [x] update_blinds(image_set_id, data) - Update blind settings (PATCH)
  - [x] delete_blinds(image_set_id) - Delete blind configuration

**Current Status: 307 tests passing** ✅

---

## Phase 6: Integration & Polish
- [ ] Add client properties for V1/V2/V3 namespaces
- [ ] Integration tests against real API (optional, requires credentials)
- [ ] Type stubs (py.typed)
- [ ] Documentation
- [ ] README with usage examples
- [ ] Publishing to PyPI (optional)

---

## Phase 7: Async Support (Optional)
- [ ] AsyncConcentriqClient
- [ ] Async versions of all resource APIs
- [ ] Async context manager support

---

## Notes
- Following extreme programming/TDD: write tests first (RED), implement (GREEN), refactor
- Testing behavior, not internal methods
- Each feature gets its own red/green/refactor cycle
- Use slash commands to enforce discipline:
  - `/red <feature>` - Write failing tests for feature
  - `/green` - Implement to make tests pass
  - `/next` - Move to next feature from TODO
