Pipeline/backend/.learnings/neo/LEARNINGS.md

42 lines
1.7 KiB
Markdown

# Learnings Log - Neo (Forgejo Integration)
## Key Decisions
### 1. Relationship Strategy
- **Decision**: Use explicit eager loading in API layer instead of SQLModel relationships
- **Pattern**: Fetch connection separately in API endpoints and attach to repository object
- **Rationale**: Simpler than dealing with SQLModel relationship type annotations and lazy loading complexity
### 2. Token Security
- **Pattern**: Store `token_last_eight` in DB, full token only in memory (client session)
- **API Response**: Only return `has_token` and `token_last_eight`, never the actual token
- **Rationale**: Follows security best practices for sensitive credentials
### 3. Base URL Normalization
- **Pattern**: Strip trailing slash and `/api/v1` path from Forgejo base URL
- **API**: Input validation in schemas and service factory
- **Rationale**: Forgejo API typically uses base URL without `/api/v1` suffix
### 4. Migration Management
- **Pattern**: Manual migration creation instead of autogenerate
- **Rationale**: Autogenerate failed due to environment setup issues; manual migration is more reliable
## Code Patterns Established
### ForgejoAPIClient
- Async context manager pattern: `async with ForgejoAPIClient(...) as client:`
- Token-based auth: `Authorization: token <token>` header
- User-Agent: `Pipeline/ForgejoClient/1.0` for identification
- Short timeouts: connect=5s, read=30s
### CRUD API Pattern
- All endpoints enforce org-scoped admin access
- Duplicate checks before create/update
- Connection validation ensures connection belongs to caller's org
- Safe response schema excludes sensitive data (token)
### Model Pattern
- All models inherit from `QueryModel`
- Timestamps use `app.core.time.utcnow()`
- UUID primary keys with `default_factory=uuid4`