refactor: split phase3.go + extract MCP tool registry (R4)
internal/httpapi/phase3.go (2627 lines, 12+ resource domains) split into 15 per-resource files: - actuator.go: SSH execution machinery (initSSH, sshExec, resolveRunTarget, executeApprovedAction, jsonErr, gatewayPreflightPassed, resolveTemplate) - checks.go, classifications.go, executions.go, approvals.go, patterns.go, skills.go, approval_rules.go, autonomy.go, risk_classes.go, relationships.go, entity_types.go, metrics.go, agent_activity.go, helpers.go — one file per resource domain, each with its own imports. internal/mcp/server.go: newServer (708 lines, 33 inline tool registrations) refactored to a registry pattern: - internal/mcp/tools.go (new): toolReg struct + allTools() returning all 33 tool definitions. Handler logic moved verbatim — no changes to tool names, descriptions, schemas, or behavior. - server.go: newServer is now 9 lines (iterate registry, AddTool each). -699 lines. No function logic, names, or signatures changed. go vet, build, and all tests pass (httpapi, mcp, db, policy).
This commit is contained in:
85
internal/httpapi/classifications.go
Normal file
85
internal/httpapi/classifications.go
Normal file
@@ -0,0 +1,85 @@
|
||||
package httpapi
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/dtoro/oikos/internal/httpapi/gen"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
// ─── Classifications ───────────────────────────────────────────────────
|
||||
|
||||
func (s *Server) ListClassifications(ctx context.Context, req gen.ListClassificationsRequestObject) (gen.ListClassificationsResponseObject, error) {
|
||||
limit := clampLimit(req.Params.Limit)
|
||||
var route *string
|
||||
if req.Params.Route != nil {
|
||||
r := string(*req.Params.Route)
|
||||
route = &r
|
||||
}
|
||||
rows, err := s.pool.Query(ctx, `
|
||||
SELECT c.entity_id, c.signal_entity_id, c.target_entity_id, c.action,
|
||||
c.recommended_action, c.risk_class, c.route, c.blast_radius,
|
||||
c.pattern_confidence, c.skill_id, c.autonomy_check, c.reasoning,
|
||||
c.correlation_id, c.created_at,
|
||||
e.slug, COALESCE(se.slug, '') AS signal_slug, COALESCE(te.slug, '') AS target_slug
|
||||
FROM classifications c
|
||||
LEFT JOIN entities e ON e.id = c.entity_id
|
||||
LEFT JOIN entities se ON se.id = c.signal_entity_id
|
||||
LEFT JOIN entities te ON te.id = c.target_entity_id
|
||||
WHERE ($1::text IS NULL OR c.route = $1)
|
||||
AND ($2::text IS NULL OR e.slug > $2)
|
||||
ORDER BY e.slug
|
||||
LIMIT $3`,
|
||||
route, req.Params.Cursor, limit+1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
items := []gen.Classification{}
|
||||
for rows.Next() {
|
||||
var cls gen.Classification
|
||||
var recActionJSON []byte
|
||||
var reasoningJSON []byte
|
||||
var blastRadius []uuid.UUID
|
||||
var signalSlug, targetSlug string
|
||||
if err := rows.Scan(&cls.Id, &cls.SignalId, &targetSlug, &cls.Action,
|
||||
&recActionJSON, &cls.RiskClass, &cls.Route, &blastRadius,
|
||||
&cls.PatternConfidence, &cls.SkillId, &cls.AutonomyCheck, &reasoningJSON,
|
||||
&cls.CorrelationId, &cls.CreatedAt,
|
||||
&cls.Target, &signalSlug, &targetSlug); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if targetSlug != "" {
|
||||
cls.Target = &targetSlug
|
||||
}
|
||||
var reasoning map[string]any
|
||||
if json.Unmarshal(reasoningJSON, &reasoning) == nil {
|
||||
cls.Reasoning = reasoning
|
||||
}
|
||||
if len(blastRadius) > 0 {
|
||||
br := make([]string, len(blastRadius))
|
||||
for i, id := range blastRadius {
|
||||
br[i] = id.String()
|
||||
}
|
||||
cls.BlastRadius = &br
|
||||
}
|
||||
items = append(items, cls)
|
||||
}
|
||||
if rows.Err() != nil {
|
||||
return nil, rows.Err()
|
||||
}
|
||||
|
||||
var next *string
|
||||
if len(items) > limit {
|
||||
items = items[:limit]
|
||||
if items[len(items)-1].Target != nil {
|
||||
next = items[len(items)-1].Target
|
||||
}
|
||||
}
|
||||
if items == nil {
|
||||
items = []gen.Classification{}
|
||||
}
|
||||
return gen.ListClassifications200JSONResponse{Items: items, NextCursor: next}, nil
|
||||
}
|
||||
Reference in New Issue
Block a user