feat: add repository workspace as default project view
- Create git file utilities (list_tree, get_file_content, list_branches, commit_file) - Add file browsing API endpoints (list, content, branches, update) - Create RepoWorkspace page with sidebar + main content layout - Add FileTree component with directory navigation - Add FileViewer component for viewing file contents - Update project list to link to workspace - Add workspace CSS styles - Update router with workspace route Quality gates: ruff ✓, mypy ✓, typecheck ✓, build ✓
This commit is contained in:
@@ -0,0 +1,213 @@
|
||||
# Git History Visualization Specification
|
||||
|
||||
## Requirements
|
||||
|
||||
### Functional Requirements
|
||||
|
||||
1. **View Commit History**: Display all commits in a repository
|
||||
2. **Graph Visualization**: Show commits as nodes with branch/merge lines
|
||||
3. **List View**: Alternative linear view of commits
|
||||
4. **Commit Details**: Click to view full commit info and diff
|
||||
5. **Branch Display**: Show branch names on commits
|
||||
6. **Tag Display**: Show tags on commits
|
||||
7. **View Toggle**: Switch between graph and list views
|
||||
|
||||
### Non-Functional Requirements
|
||||
|
||||
1. **Performance**: Load first 100 commits in < 2 seconds
|
||||
2. **Responsiveness**: Graph should render smoothly up to 500 commits
|
||||
3. **Compatibility**: Work with bare repositories and mirror clones
|
||||
4. **Read-only**: No write operations to repository
|
||||
|
||||
## API Specification
|
||||
|
||||
### GET /projects/{project_id}/repositories/{repo_id}/history
|
||||
|
||||
Retrieve commit history for a repository.
|
||||
|
||||
**Query Parameters:**
|
||||
| Parameter | Type | Default | Description |
|
||||
|-----------|------|---------|-------------|
|
||||
| view | string | "graph" | "graph" or "list" |
|
||||
| branch | string | null | Filter by branch name |
|
||||
| limit | integer | 100 | Max commits to return |
|
||||
| offset | integer | 0 | Skip first N commits |
|
||||
|
||||
**Response 200:**
|
||||
```json
|
||||
{
|
||||
"commits": [
|
||||
{
|
||||
"hash": "full-sha-hash",
|
||||
"short_hash": "abc1234",
|
||||
"parents": ["parent-hash-1", "parent-hash-2"],
|
||||
"author": "John Doe",
|
||||
"email": "john@example.com",
|
||||
"date": "2026-05-19",
|
||||
"timestamp": 1716123456,
|
||||
"message": "feat: add new feature",
|
||||
"branches": ["main"],
|
||||
"tags": []
|
||||
}
|
||||
],
|
||||
"branches": ["main", "develop", "feature/x"],
|
||||
"total_commits": 250,
|
||||
"graph_data": {
|
||||
"nodes": [
|
||||
{
|
||||
"hash": "abc1234",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"column": 0
|
||||
}
|
||||
],
|
||||
"edges": [
|
||||
{
|
||||
"from_hash": "abc1234",
|
||||
"to_hash": "def5678",
|
||||
"type": "parent"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### GET /projects/{project_id}/repositories/{repo_id}/commits/{commit_hash}
|
||||
|
||||
Get detailed information about a specific commit.
|
||||
|
||||
**Response 200:**
|
||||
```json
|
||||
{
|
||||
"hash": "full-sha-hash",
|
||||
"short_hash": "abc1234",
|
||||
"parents": ["parent-hash"],
|
||||
"author": "John Doe",
|
||||
"email": "john@example.com",
|
||||
"date": "2026-05-19",
|
||||
"timestamp": 1716123456,
|
||||
"message": "feat: add new feature",
|
||||
"body": "Detailed description here",
|
||||
"stats": {
|
||||
"files_changed": 3,
|
||||
"insertions": 45,
|
||||
"deletions": 12
|
||||
},
|
||||
"files": [
|
||||
{
|
||||
"path": "src/main.py",
|
||||
"change_type": "modified",
|
||||
"insertions": 20,
|
||||
"deletions": 5,
|
||||
"diff": "diff content here"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Frontend Components
|
||||
|
||||
### GitHistoryPage
|
||||
Main page component that orchestrates the view.
|
||||
|
||||
### GraphView
|
||||
SVG-based commit graph visualization.
|
||||
|
||||
**Props:**
|
||||
- `commits`: Commit[]
|
||||
- `graphData`: GraphData
|
||||
- `selectedCommit`: string | null
|
||||
- `onCommitSelect`: (hash: string) => void
|
||||
|
||||
### ListView
|
||||
Linear commit list.
|
||||
|
||||
**Props:**
|
||||
- `commits`: Commit[]
|
||||
- `selectedCommit`: string | null
|
||||
- `onCommitSelect`: (hash: string) => void
|
||||
|
||||
### CommitDetails
|
||||
Panel showing commit details and diff.
|
||||
|
||||
**Props:**
|
||||
- `commit`: CommitDetail | null
|
||||
|
||||
### DiffViewer
|
||||
Component to display git diff with syntax highlighting.
|
||||
|
||||
**Props:**
|
||||
- `files`: FileChange[]
|
||||
|
||||
## Data Models
|
||||
|
||||
### Commit
|
||||
```typescript
|
||||
interface Commit {
|
||||
hash: string;
|
||||
short_hash: string;
|
||||
parents: string[];
|
||||
author: string;
|
||||
email: string;
|
||||
date: string;
|
||||
timestamp: number;
|
||||
message: string;
|
||||
branches: string[];
|
||||
tags: string[];
|
||||
}
|
||||
```
|
||||
|
||||
### CommitDetail
|
||||
```typescript
|
||||
interface CommitDetail extends Commit {
|
||||
body: string;
|
||||
stats: {
|
||||
files_changed: number;
|
||||
insertions: number;
|
||||
deletions: number;
|
||||
};
|
||||
files: FileChange[];
|
||||
}
|
||||
```
|
||||
|
||||
### FileChange
|
||||
```typescript
|
||||
interface FileChange {
|
||||
path: string;
|
||||
change_type: "added" | "modified" | "deleted" | "renamed";
|
||||
insertions: number;
|
||||
deletions: number;
|
||||
diff: string;
|
||||
}
|
||||
```
|
||||
|
||||
## URL Structure
|
||||
|
||||
```
|
||||
/projects/:projectId/repositories/:repoId/history
|
||||
```
|
||||
|
||||
## Error Codes
|
||||
|
||||
| Error Code | Description | User Message |
|
||||
|------------|-------------|--------------|
|
||||
| REPO_EMPTY | Repository has no commits | "This repository has no commits yet" |
|
||||
| GIT_ERROR | Git command failed | "Failed to load repository history" |
|
||||
| COMMIT_NOT_FOUND | Commit hash not found | "Commit not found" |
|
||||
| INVALID_BRANCH | Branch doesn't exist | "Branch not found" |
|
||||
|
||||
## Testing Strategy
|
||||
|
||||
### Backend Tests
|
||||
- Test git log parsing with various repo structures
|
||||
- Test commit detail extraction
|
||||
- Test error handling for empty repos
|
||||
|
||||
### Frontend Tests
|
||||
- Test graph rendering with sample data
|
||||
- Test list view rendering
|
||||
- Test commit selection and details display
|
||||
- Test view toggle
|
||||
|
||||
### Integration Tests
|
||||
- End-to-end flow: load history → select commit → view details
|
||||
Reference in New Issue
Block a user