Init Repo

This commit is contained in:
2026-02-28 03:22:04 +08:00
commit de59b57ee7
883 changed files with 156857 additions and 0 deletions
@@ -0,0 +1,197 @@
# Design Document
## Overview
This design implements a database schema enhancement to add a `project_id` column to the shots table, establishing a direct relationship between shots and projects. This change improves data integrity, enables project-scoped shot name uniqueness, and provides better query performance for project-based shot operations.
## Architecture
The enhancement follows a layered approach:
1. **Database Layer**: Add project_id column with foreign key constraint and index
2. **Model Layer**: Update SQLAlchemy Shot model with project relationship
3. **Schema Layer**: Update Pydantic schemas to include project_id
4. **API Layer**: Modify endpoints to handle project_id in requests/responses
5. **Service Layer**: Update business logic for project-scoped validation
6. **Frontend Layer**: Update TypeScript interfaces and components
## Components and Interfaces
### Database Schema Changes
```sql
-- Add project_id column to shots table
ALTER TABLE shots ADD COLUMN project_id INTEGER;
-- Create foreign key constraint
ALTER TABLE shots ADD CONSTRAINT fk_shots_project_id
FOREIGN KEY (project_id) REFERENCES projects(id);
-- Create index for performance
CREATE INDEX idx_shots_project_id ON shots(project_id);
-- Create composite index for project-scoped name uniqueness
CREATE UNIQUE INDEX idx_shots_project_name_unique
ON shots(project_id, name) WHERE deleted_at IS NULL;
```
### Model Updates
**Shot Model (backend/models/shot.py)**:
- Add `project_id` column as non-nullable foreign key
- Add `project` relationship to Project model
- Update uniqueness constraints to be project-scoped
- Maintain backward compatibility with episode relationship
**Project Model (backend/models/project.py)**:
- Add `shots` relationship back-reference
### Schema Updates
**ShotBase Schema**:
- Add optional `project_id` field for API flexibility
- Maintain episode_id as primary relationship identifier
**ShotResponse Schema**:
- Include `project_id` in all response payloads
- Add computed `project_name` field for frontend convenience
### API Endpoint Changes
**Shot Creation Endpoints**:
- Automatically derive `project_id` from `episode_id`
- Validate project consistency between episode and provided project_id
- Update uniqueness validation to be project-scoped
**Shot Query Endpoints**:
- Add optional `project_id` filter parameter
- Include project information in response payloads
- Maintain existing episode-based filtering
## Data Models
### Updated Shot Model Structure
```python
class Shot(Base):
__tablename__ = "shots"
id = Column(Integer, primary_key=True, index=True)
project_id = Column(Integer, ForeignKey("projects.id"), nullable=False, index=True)
episode_id = Column(Integer, ForeignKey("episodes.id"), nullable=False)
name = Column(String, nullable=False, index=True)
# ... other existing fields
# Relationships
project = relationship("Project", back_populates="shots")
episode = relationship("Episode", back_populates="shots")
# ... other existing relationships
# Constraints
__table_args__ = (
UniqueConstraint('project_id', 'name', name='uq_shot_project_name'),
)
```
### Frontend Interface Updates
```typescript
interface Shot {
id: number
project_id: number
episode_id: number
name: string
// ... other existing fields
// Optional computed fields
project_name?: string
}
interface ShotCreate {
name: string
project_id?: number // Optional, derived from episode if not provided
// ... other existing fields
}
```
## Correctness Properties
*A property is a characteristic or behavior that should hold true across all valid executions of a system-essentially, a formal statement about what the system should do. Properties serve as the bridge between human-readable specifications and machine-verifiable correctness guarantees.*
### Property 1: Project-Episode Consistency
*For any* shot in the system, the project_id must match the project_id of its associated episode
**Validates: Requirements 1.2, 3.3, 4.2**
### Property 2: Project-Scoped Name Uniqueness
*For any* project, shot names must be unique within that project scope (excluding soft-deleted shots)
**Validates: Requirements 1.1, 1.4**
### Property 3: API Response Completeness
*For any* shot API response, the response must include both the project_id field and all previously existing fields
**Validates: Requirements 1.3, 3.1, 4.1**
### Property 4: Migration Data Preservation
*For any* existing shot before migration, the shot data after migration should be identical except for the addition of the correct project_id derived from the episode relationship
**Validates: Requirements 2.4, 2.5**
### Property 5: Project Filtering Accuracy
*For any* project_id filter parameter, the API should return only shots that belong to that specific project
**Validates: Requirements 3.4**
### Property 6: Bulk Operation Consistency
*For any* bulk shot creation operation, all created shots must have the same project_id as their target episode
**Validates: Requirements 3.5**
### Property 7: Soft Deletion Project Preservation
*For any* shot that undergoes soft deletion, the project_id must be preserved for recovery operations
**Validates: Requirements 4.5**
### Property 8: Permission System Continuity
*For any* shot operation that was previously authorized, the same operation should remain authorized after the schema change
**Validates: Requirements 4.4**
## Error Handling
### Migration Errors
- **Orphaned Episodes**: Handle episodes without valid project references
- **Data Inconsistency**: Detect and report shots with mismatched episode-project relationships
- **Constraint Violations**: Handle existing duplicate shot names within projects
### Runtime Errors
- **Invalid Project ID**: Return 400 Bad Request for non-existent project references
- **Project-Episode Mismatch**: Return 400 Bad Request when provided project_id doesn't match episode's project
- **Duplicate Shot Names**: Return 409 Conflict for project-scoped name collisions
### Frontend Error Handling
- **Migration Status**: Display migration progress and handle temporary unavailability
- **Validation Errors**: Show clear messages for project-scoped naming conflicts
- **Fallback Behavior**: Gracefully handle missing project information during transition
## Testing Strategy
### Unit Tests
- Test Shot model creation with project_id
- Test project-scoped uniqueness validation
- Test API endpoint parameter handling
- Test schema serialization/deserialization
### Property-Based Tests
- **Property 1 Test**: Generate random shots and verify project-episode consistency
- **Property 2 Test**: Generate random shot names within projects and verify uniqueness enforcement
- **Property 3 Test**: Create test data, run migration simulation, verify data preservation
- **Property 4 Test**: Generate shots with various project_id values and verify foreign key constraints
- **Property 5 Test**: Generate API requests in old format and verify response compatibility
### Integration Tests
- Test complete shot creation workflow with project validation
- Test shot querying with project filtering
- Test bulk shot creation with project consistency
- Test soft deletion with project_id preservation
### Migration Tests
- Test migration script with various data scenarios
- Test rollback procedures
- Test performance with large datasets
- Test constraint creation and validation
The testing approach uses **Pytest** for the Python backend with **Hypothesis** for property-based testing. Each property-based test will run a minimum of 100 iterations to ensure comprehensive coverage of the input space.
@@ -0,0 +1,63 @@
# Requirements Document
## Introduction
This feature enhances the shot table schema by adding a direct `project_id` column to prevent shots with the same name from being created across different projects. Currently, shots are only linked to episodes, which can lead to naming conflicts when the same shot name exists in different projects.
## Glossary
- **Shot**: A sequence or scene in a VFX project that represents a specific portion of work
- **Project**: A top-level container for organizing episodes, shots, and assets
- **Episode**: A subdivision of a project containing multiple shots
- **VFX_System**: The VFX Project Management System backend and frontend
- **Database_Schema**: The SQLAlchemy model definitions and database structure
## Requirements
### Requirement 1
**User Story:** As a project coordinator, I want shot names to be unique within each project, so that I can avoid naming conflicts when managing multiple projects with similar shot naming conventions.
#### Acceptance Criteria
1. WHEN a shot is created, THE VFX_System SHALL enforce uniqueness of shot names within the project scope
2. WHEN a shot is created, THE VFX_System SHALL automatically populate the project_id from the associated episode
3. WHEN querying shots, THE VFX_System SHALL include project_id in all shot responses
4. WHEN validating shot names, THE VFX_System SHALL check for duplicates within the same project only
5. WHEN migrating existing data, THE VFX_System SHALL populate project_id for all existing shots based on their episode relationships
### Requirement 2
**User Story:** As a database administrator, I want the shot table to have proper foreign key constraints to the project table, so that data integrity is maintained across the system.
#### Acceptance Criteria
1. WHEN the database schema is updated, THE VFX_System SHALL add a non-nullable project_id column to the shots table
2. WHEN the database schema is updated, THE VFX_System SHALL create a foreign key constraint from shots.project_id to projects.id
3. WHEN the database schema is updated, THE VFX_System SHALL create an index on the project_id column for query performance
4. WHEN the migration runs, THE VFX_System SHALL preserve all existing shot data without loss
5. WHEN the migration completes, THE VFX_System SHALL validate that all shots have valid project_id values
### Requirement 3
**User Story:** As a frontend developer, I want the shot API responses to include project information, so that I can display project context in shot management interfaces.
#### Acceptance Criteria
1. WHEN retrieving shots via API, THE VFX_System SHALL include project_id in the response payload
2. WHEN creating shots via API, THE VFX_System SHALL accept project_id as an optional parameter for validation
3. WHEN updating shots via API, THE VFX_System SHALL maintain project_id consistency with the episode relationship
4. WHEN filtering shots, THE VFX_System SHALL support filtering by project_id parameter
5. WHEN bulk creating shots, THE VFX_System SHALL validate that all shots belong to the same project as the episode
### Requirement 4
**User Story:** As a system user, I want existing shot functionality to continue working seamlessly after the schema change, so that my workflow is not disrupted.
#### Acceptance Criteria
1. WHEN accessing existing shot endpoints, THE VFX_System SHALL maintain backward compatibility for all current API operations
2. WHEN creating shots through existing workflows, THE VFX_System SHALL automatically derive project_id from episode_id
3. WHEN displaying shots in the frontend, THE VFX_System SHALL show project context where appropriate
4. WHEN performing shot operations, THE VFX_System SHALL maintain all existing access control and permission checks
5. WHEN soft deleting shots, THE VFX_System SHALL preserve project_id information for recovery operations
@@ -0,0 +1,174 @@
# Implementation Plan
- [x] 1. Create database migration script
- Create migration script to add project_id column to shots table
- Add foreign key constraint to projects table
- Create indexes for performance optimization
- Populate project_id for existing shots based on episode relationships
- Add unique constraint for project-scoped shot names
- _Requirements: 2.1, 2.2, 2.3, 2.4, 2.5_
- [ ]* 1.1 Write property test for migration data preservation
- **Property 4: Migration Data Preservation**
- **Validates: Requirements 2.4, 2.5**
- [x] 2. Update Shot model and relationships
- Add project_id column to Shot SQLAlchemy model
- Add project relationship to Shot model
- Update Project model to include shots back-reference
- Add project-scoped uniqueness constraint
- _Requirements: 1.1, 1.2, 2.1, 2.2_
- [ ]* 2.1 Write property test for project-episode consistency
- **Property 1: Project-Episode Consistency**
- **Validates: Requirements 1.2, 3.3, 4.2**
- [ ]* 2.2 Write property test for project-scoped name uniqueness
- **Property 2: Project-Scoped Name Uniqueness**
- **Validates: Requirements 1.1, 1.4**
- [x] 3. Update Pydantic schemas
- Add project_id field to ShotBase schema
- Update ShotResponse to include project_id
- Add optional project_name computed field
- Maintain backward compatibility for existing schemas
- _Requirements: 1.3, 3.1, 4.1_
- [ ]* 3.1 Write property test for API response completeness
- **Property 3: API Response Completeness**
- **Validates: Requirements 1.3, 3.1, 4.1**
- [x] 4. Update shot router endpoints
- Modify shot creation to auto-populate project_id from episode
- Add project_id validation in shot creation and updates
- Update shot querying to include project_id filtering
- Ensure project-scoped name uniqueness validation
- _Requirements: 1.1, 1.2, 1.4, 3.2, 3.4_
- [ ]* 4.1 Write property test for project filtering accuracy
- **Property 5: Project Filtering Accuracy**
- **Validates: Requirements 3.4**
- [x] 5. Update bulk shot creation
- Modify bulk shot creation to validate project consistency
- Ensure all shots in bulk operation belong to same project as episode
- Update bulk validation logic for project-scoped uniqueness
- _Requirements: 3.5_
- [ ]* 5.1 Write property test for bulk operation consistency
- **Property 6: Bulk Operation Consistency**
- **Validates: Requirements 3.5**
- [x] 6. Update soft deletion service
- Ensure project_id is preserved during soft deletion
- Update recovery operations to maintain project relationships
- Verify project_id consistency in deletion info endpoints
- _Requirements: 4.5_
- [ ]* 6.1 Write property test for soft deletion project preservation
- **Property 7: Soft Deletion Project Preservation**
- **Validates: Requirements 4.5**
- [x] 7. Update frontend TypeScript interfaces
- Add project_id to Shot interface
- Update ShotCreate and ShotUpdate interfaces
- Add optional project_name field for display
- Maintain backward compatibility
- _Requirements: 3.1, 4.1_
- [x] 8. Update frontend shot service
- Modify shot service to handle project_id in responses
- Add project filtering support to shot queries
- Update error handling for project-related validation errors
- _Requirements: 3.1, 3.4, 4.1_
- [x] 9. Update shot form components
- Display project context in shot forms where appropriate
- Handle project-scoped validation errors
- Maintain existing form functionality
- _Requirements: 4.1, 4.3_
- [x] 10. Checkpoint - Ensure all tests pass
- Ensure all tests pass, ask the user if questions arise.
- [ ]* 10.1 Write property test for permission system continuity
- **Property 8: Permission System Continuity**
- **Validates: Requirements 4.4**
- [-] 11. Run database migration
- Execute migration script on development database
- Verify data integrity after migration
- Test all shot operations with new schema
- _Requirements: 2.1, 2.2, 2.3, 2.4, 2.5_
- [ ]* 11.1 Write unit tests for migration script
- Test migration with various data scenarios
- Test constraint creation and validation
- Test rollback procedures
- [ ] 12. Integration testing
- Test complete shot workflows with project_id
- Verify API backward compatibility
- Test frontend integration with new schema
- Test performance with project-scoped queries
- _Requirements: 4.1, 4.2, 4.4_
- [ ]* 12.1 Write integration tests for shot workflows
- Test shot creation, update, and deletion workflows
- Test bulk operations with project validation
- Test API filtering and querying
- [ ] 13. Final checkpoint - Ensure all tests pass
- Ensure all tests pass, ask the user if questions arise.