feat: complete Git Repo Manager MVP implementation

Backend (Phase 1-6):
- Pydantic schemas for request/response validation
- Service layer (SSH Key, Server, Repo, Sync)
- API routes with authentication
- FastAPI main application with lifespan management
- ORM models (SshKey, Server, Repo, SyncLog)

Frontend (Phase 7):
- Vue 3 + Element Plus + Pinia + Vue Router
- API client with Axios and interceptors
- State management stores
- All page components (Dashboard, Servers, Repos, SyncLogs, SshKeys, Settings)

Deployment (Phase 8):
- README with quick start guide
- Startup script (start.sh)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
panw
2026-03-30 16:30:13 +08:00
parent 960056c88c
commit 44921c5646
46 changed files with 6533 additions and 2 deletions

View File

@@ -1,12 +1,13 @@
import sys
import pytest
from pathlib import Path
from typing import Generator
# Add backend to path
sys.path.insert(0, str(Path(__file__).parent.parent))
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.orm import sessionmaker, Session
# NOTE: This import will fail until models are created in Task 2.1
# This is expected behavior - the models module doesn't exist yet
@@ -58,3 +59,71 @@ def test_env_vars(db_path, test_encrypt_key, monkeypatch):
"GM_ENCRYPT_KEY": test_encrypt_key,
"GM_API_TOKEN": "test-token",
}
@pytest.fixture(scope="function")
def client(db_session: Session, test_env_vars: dict, monkeypatch):
"""
FastAPI test client fixture.
Provides a test client for the FastAPI application with:
- In-memory database session
- Test environment variables
- Disabled lifespan (for faster tests)
Args:
db_session: Database session fixture
test_env_vars: Test environment variables fixture
monkeypatch: Pytest monkeypatch fixture
Yields:
FastAPI test client
Example:
def test_create_ssh_key(client):
response = client.post(
"/api/ssh-keys",
json={"name": "test-key", "private_key": "..."},
headers={"Authorization": "Bearer test-token"}
)
assert response.status_code == 201
"""
from fastapi.testclient import TestClient
from unittest.mock import AsyncMock, patch
# Mock the lifespan context manager
async def mock_lifespan(app): # noqa: ARG001 - Unused app parameter
# Database is already initialized by db_session fixture
yield
# Import after setting env vars
import app.database
import app.config
# Initialize database with test session
app.database._engine = db_session.bind
app.database._session_factory = sessionmaker(bind=db_session.bind, autocommit=False, autoflush=False)
# Create app with mocked lifespan
from app.main import create_app
test_app = create_app(lifespan_handler=mock_lifespan)
# Override get_db_session dependency to use test session
from app.api import deps
def override_get_db_session():
try:
yield db_session
finally:
pass
test_app.dependency_overrides[deps.get_db_session] = override_get_db_session
with TestClient(test_app) as test_client:
yield test_client
# Clean up
test_app.dependency_overrides = {}
app.database._engine = None
app.database._session_factory = None
app.config._settings = None