refactor(store): replace project and skill models with generated models
Some checks failed
CI / build-and-test (push) Failing after -31m25s
Some checks failed
CI / build-and-test (push) Failing after -31m25s
* Update project creation and retrieval to use generated models * Modify skill addition and listing to utilize generated models * Refactor thought handling to incorporate generated models * Adjust tool annotations to align with new model structure * Update API calls in the UI to use new ResolveSpec-based endpoints * Enhance stats retrieval logic to aggregate thought metadata
This commit is contained in:
128
internal/app/resolvespec_admin.go
Normal file
128
internal/app/resolvespec_admin.go
Normal file
@@ -0,0 +1,128 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
|
||||
"github.com/bitechdev/ResolveSpec/pkg/resolvespec"
|
||||
"github.com/uptrace/bunrouter"
|
||||
|
||||
"git.warky.dev/wdevs/amcs/internal/generatedmodels"
|
||||
"git.warky.dev/wdevs/amcs/internal/store"
|
||||
)
|
||||
|
||||
func registerResolveSpecAdminRoutes(mux *http.ServeMux, db *store.DB, middleware func(http.Handler) http.Handler, logger *slog.Logger) error {
|
||||
rs := resolvespec.NewHandlerWithBun(db.Bun())
|
||||
registerResolveSpecGuards(rs)
|
||||
for _, model := range resolveSpecModels() {
|
||||
if err := rs.RegisterModel(model.schema, model.entity, model.model); err != nil {
|
||||
return fmt.Errorf("register resolvespec model %s.%s: %w", model.schema, model.entity, err)
|
||||
}
|
||||
}
|
||||
|
||||
rsRouter := bunrouter.New()
|
||||
resolvespec.SetupBunRouterRoutes(rsRouter, rs, nil)
|
||||
|
||||
rsMount := http.StripPrefix("/api/rs", rsRouter)
|
||||
protectedRSMount := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method == http.MethodOptions {
|
||||
rsMount.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
middleware(rsMount).ServeHTTP(w, r)
|
||||
})
|
||||
|
||||
mux.Handle("/api/rs/", protectedRSMount)
|
||||
mux.Handle("/api/rs", http.RedirectHandler("/api/rs/openapi", http.StatusTemporaryRedirect))
|
||||
|
||||
if logger != nil {
|
||||
logger.Info("resolvespec admin api enabled",
|
||||
slog.String("prefix", "/api/rs"),
|
||||
slog.Int("models", len(resolveSpecModels())),
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func registerResolveSpecGuards(rs *resolvespec.Handler) {
|
||||
mutableByEntity := map[string]map[string]struct{}{
|
||||
"projects": {
|
||||
"create": {},
|
||||
},
|
||||
"thoughts": {
|
||||
"update": {},
|
||||
"delete": {},
|
||||
},
|
||||
"agent_skills": {
|
||||
"delete": {},
|
||||
},
|
||||
"agent_guardrails": {
|
||||
"delete": {},
|
||||
},
|
||||
}
|
||||
|
||||
rs.Hooks().Register(resolvespec.BeforeHandle, func(hookCtx *resolvespec.HookContext) error {
|
||||
switch hookCtx.Operation {
|
||||
case "read", "meta":
|
||||
return nil
|
||||
case "create", "update", "delete":
|
||||
allowedOps, ok := mutableByEntity[hookCtx.Entity]
|
||||
if !ok {
|
||||
hookCtx.Abort = true
|
||||
hookCtx.AbortCode = http.StatusForbidden
|
||||
hookCtx.AbortMessage = fmt.Sprintf("operation %q is not allowed for %s.%s", hookCtx.Operation, hookCtx.Schema, hookCtx.Entity)
|
||||
return fmt.Errorf("forbidden operation")
|
||||
}
|
||||
if _, ok := allowedOps[hookCtx.Operation]; !ok {
|
||||
hookCtx.Abort = true
|
||||
hookCtx.AbortCode = http.StatusForbidden
|
||||
hookCtx.AbortMessage = fmt.Sprintf("operation %q is not allowed for %s.%s", hookCtx.Operation, hookCtx.Schema, hookCtx.Entity)
|
||||
return fmt.Errorf("forbidden operation")
|
||||
}
|
||||
return nil
|
||||
default:
|
||||
hookCtx.Abort = true
|
||||
hookCtx.AbortCode = http.StatusBadRequest
|
||||
hookCtx.AbortMessage = fmt.Sprintf("unsupported operation %q", hookCtx.Operation)
|
||||
return fmt.Errorf("unsupported operation")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
type resolveSpecModel struct {
|
||||
schema string
|
||||
entity string
|
||||
model any
|
||||
}
|
||||
|
||||
func resolveSpecModels() []resolveSpecModel {
|
||||
return []resolveSpecModel{
|
||||
{schema: "public", entity: "activities", model: generatedmodels.ModelPublicActivities{}},
|
||||
{schema: "public", entity: "agent_guardrails", model: generatedmodels.ModelPublicAgentGuardrails{}},
|
||||
{schema: "public", entity: "agent_skills", model: generatedmodels.ModelPublicAgentSkills{}},
|
||||
{schema: "public", entity: "chat_histories", model: generatedmodels.ModelPublicChatHistories{}},
|
||||
{schema: "public", entity: "contact_interactions", model: generatedmodels.ModelPublicContactInteractions{}},
|
||||
{schema: "public", entity: "embeddings", model: generatedmodels.ModelPublicEmbeddings{}},
|
||||
{schema: "public", entity: "family_members", model: generatedmodels.ModelPublicFamilyMembers{}},
|
||||
{schema: "public", entity: "household_items", model: generatedmodels.ModelPublicHouseholdItems{}},
|
||||
{schema: "public", entity: "household_vendors", model: generatedmodels.ModelPublicHouseholdVendors{}},
|
||||
{schema: "public", entity: "important_dates", model: generatedmodels.ModelPublicImportantDates{}},
|
||||
{schema: "public", entity: "learnings", model: generatedmodels.ModelPublicLearnings{}},
|
||||
{schema: "public", entity: "maintenance_logs", model: generatedmodels.ModelPublicMaintenanceLogs{}},
|
||||
{schema: "public", entity: "maintenance_tasks", model: generatedmodels.ModelPublicMaintenanceTasks{}},
|
||||
{schema: "public", entity: "meal_plans", model: generatedmodels.ModelPublicMealPlans{}},
|
||||
{schema: "public", entity: "opportunities", model: generatedmodels.ModelPublicOpportunities{}},
|
||||
{schema: "public", entity: "professional_contacts", model: generatedmodels.ModelPublicProfessionalContacts{}},
|
||||
{schema: "public", entity: "project_guardrails", model: generatedmodels.ModelPublicProjectGuardrails{}},
|
||||
{schema: "public", entity: "project_skills", model: generatedmodels.ModelPublicProjectSkills{}},
|
||||
{schema: "public", entity: "projects", model: generatedmodels.ModelPublicProjects{}},
|
||||
{schema: "public", entity: "recipes", model: generatedmodels.ModelPublicRecipes{}},
|
||||
{schema: "public", entity: "shopping_lists", model: generatedmodels.ModelPublicShoppingLists{}},
|
||||
{schema: "public", entity: "stored_files", model: generatedmodels.ModelPublicStoredFiles{}},
|
||||
{schema: "public", entity: "thought_links", model: generatedmodels.ModelPublicThoughtLinks{}},
|
||||
{schema: "public", entity: "thoughts", model: generatedmodels.ModelPublicThoughts{}},
|
||||
{schema: "public", entity: "tool_annotations", model: generatedmodels.ModelPublicToolAnnotations{}},
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user