- Remove duplicate WorkspaceHeader render (was showing twice)
- Update empty state 'Add Repository' link to point to
/projects/{id}/settings/repositories instead of old route
- Quality gates: typecheck ✓ lint ✓ build ✓
Frontend workspace was calling GET /projects/{id} which didn't exist,
causing 405 errors and preventing WorkspaceHeader from rendering.
Add get_project endpoint that returns a single project by ID with
ownership verification.
- Create SettingsTabLayout component with sidebar navigation
- Create ProjectSettingsPage with General settings tab
- Create RepositoriesSettingsTab for repo management
- Add Members placeholder tab
- Update router with settings routes
- Add CSS styles for settings layout
- Navigate to /projects/:id/settings from workspace header
- Add CommitPanel component for viewing changed files and committing
- Show file status indicators (M/A/D/?) in file tree
- Integrate git status with workspace for real-time updates
- Add CSS styles for commit panel and status badges
Part of git-control change implementation.
The workspace was using /api/projects/... but the API routes are mounted
at /projects without the /api prefix. Switched from raw fetch() to the
apiClient which already has the correct baseURL configured.
Also fixed TypeScript types and removed unused variables.
Using 'git log --all <branch>' creates ambiguous behavior. Now:
- Without branch: uses --all to show all commits from all refs
- With branch: shows only commits from that specific branch
This ensures consistent commit counts between git CLI and API.
The backend defaults to returning only 100 commits. Update frontend
to explicitly request up to 10000 commits to show full history for
most repositories.
Backend was sending Unix timestamps as strings (e.g. '1716112800')
which JavaScript Date couldn't parse. Now sends proper ISO 8601
format dates that work with new Date() in the browser.
Backend was returning fields like 'author', 'email', 'date' but frontend
expected 'author_name', 'author_email', 'author_date'. Also 'branches' and
'tags' were separate but frontend expects unified 'refs' array.
- Update _commit_to_dict to return frontend-compatible field names
- Add graph_symbol and graph_depth for commit graph display
- Update get_commit_detail to return matching field names
- Include diff as top-level field for detail view
The git log --graph output uses | characters in the ASCII art,
which conflicts with using | as a format separator. Switch to
NULL bytes (\x00) which won't appear in commit data.
Also removed --graph flag since we build graph data from
parent relationships instead.
- Add git_history.py utility for extracting commit history and details
- Add API endpoints for repository history and commit details
- Integrate with existing git_repositories router
This completes the backend for git history visualization.
- Add API client functions for commit history and detail endpoints
- Create GitHistoryPage with commit list, graph visualization, and detail panel
- Add branch selector for viewing different branches
- Integrate history view into repository list with History button
- Add comprehensive CSS styles for history page layout
Quality gates: typecheck ✓, lint ✓, build ✓
Tool types and git repositories response models declared created_at/
updated_at as str but ORM returns datetime objects. Change to datetime
type so Pydantic serializes correctly to ISO format strings.
- Create missing /dashboard/summary endpoint that frontend expects
- Fix SSH key Fernet key generation to use proper base64 encoding
(was using raw session secret slice which failed validation)
FastAPI uses parameter name as cookie name by default.
get_current_user_id was looking for 'session_cookie' but we set
the cookie as 'session'. Add alias='session' to match.
In production, the session cookie needs to be shared across
subdomains (e.g., api.example.com and app.example.com).
- Add cookie_domain property to config (extracts parent domain)
- Set SameSite=None for cross-origin requests in production
- Update auth callback and logout to use cookie domain
- This fixes the login loop where session cookie wasn't sent
Add CORSMiddleware configured to:
- Allow the frontend origin (web_base_url)
- Allow credentials (cookies)
- Allow all methods and headers
This fixes cross-origin requests between frontend and API
when they're on different subdomains.
- /auth/callback now redirects to frontend URL with session cookie
- /auth/login stores 'next' path in cookie for post-login redirect
- User is redirected to their original destination after authentication
Add if_not_exists=True to CREATE TABLE operations in migrations
0003 and 0004. This prevents DuplicateTableError when migrations
are re-run on databases where tables were partially created.
SQLAlchemy 2.0 async engines conflict with alembic's sync context manager.
Instead of trying to bridge async/sync, use subprocess to run
'alembic upgrade head' directly. This is simpler and more reliable.
- Remove psycopg2-binary dependency (no longer needed)
- Simplify init_database to use subprocess.run()
- Remove all sync engine code
SQLAlchemy 2.0 async engines don't support the sync context manager
protocol needed by alembic. Create a separate sync engine (using
psycopg2) for migration operations while keeping async engine for
application queries.
- Add psycopg2-binary dependency
- Rename async connection variable to avoid mypy confusion
- Use sync engine for MigrationContext and alembic commands
- Exit with error code 1 if init_database() returns False
- Update health check to verify database connectivity
- Prevents confusing 'table does not exist' errors later
Add migration version check before running alembic upgrade to prevent
multiple uvicorn workers from running migrations simultaneously.
- Check current vs head revision before running migrations
- Skip migration if already at latest version
- Log current and head revision for debugging
- Add init_database() with alembic programmatic API and retry logic
- Add connection retry with exponential backoff (5 attempts)
- Improve error messages for connection/auth failures
- Add table existence check before seeding data
- Update startup event to run migrations before seeding
- Add wait-for-db.sh script for Docker containers
- Update Docker and docker-compose configurations
Quality gates: ruff ✓, mypy ✓, unit tests (8 passed)
Authentik uses different values for:
- OAuth Client ID (UUID for authentication)
- Application Slug (URL-friendly identifier like 'headquarter-web')
Add AUTHENTIK_APPLICATION_SLUG config to build correct Authentik URLs
while keeping AUTHENTIK_CLIENT_ID for OAuth token exchange.
Add explicit traefik.http.routers.*.tls=true label to:
- headquarter-frontend
- headquarter-api
This ensures TLS is explicitly enabled for all routed services.