# 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 ` 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`