step 5 (partial): strip dropped packages from production code

Removed all references to dropped packages in non-test code.
Zero dropped imports, store refs, or model types remaining.

Major removals:
  - scheduler/ package (entire dir) — tasks moved to extension track
  - taskutil/ package (entire dir)
  - health/ package (entire dir) — provider/tool health
  - sandbox/provider_module.go — provider.complete module
  - handlers: workflow_entry, workflow_instances, workflow_forms,
    workflow_assignments, workflow_monitor, health_admin (6 files)
  - auth/session.go, middleware/session_auth.go
  - store/{postgres,sqlite}/sessions.go, tasks.go

Rewrites:
  - store/{postgres,sqlite}/health.go — kernel-only Prune
    (ws_tickets, rate_limit_counters, stale presence)
  - handlers/admin.go: 847→467 lines (stripped provider CRUD)
  - handlers/teams.go: 520→411 lines (stripped model listing)
  - sandbox/runner.go: removed ProviderResolver
  - sandbox/workflow_module.go: 216→83 lines (definition-only)
  - main.go: 1579→1325 lines (stripped dropped package init)
  - pages/pages.go: stripped channel/session lookups
  - events/types.go: stripped chat/channel/workspace event routes
  - models: stripped stale types, constants, notification types

Store interface cleanup:
  - Removed SessionStore, TaskStore from Stores struct
  - Stripped workflow assignment methods from WorkflowStore iface
  - Stripped assignment methods from PG+SQLite workflow stores
  - Updated testhelper.go table list to kernel-only

Migrations: removed 008_tasks.sql (both dialects)

-9665/+69 lines across 51 files.
This commit is contained in:
2026-03-25 21:13:01 -04:00
parent ebea16344c
commit e4b7ee98a5
55 changed files with 95 additions and 9981 deletions

View File

@@ -14,43 +14,23 @@ const EveryoneGroupID = "00000000-0000-0000-0000-000000000001"
// Permission constants — domain.action convention.
const (
PermModelUse = "model.use" // use models for completion
PermModelSelectAny = "model.select_any" // use any enabled model (vs. group allowlist)
PermKBRead = "kb.read" // search KBs through personas
PermKBWrite = "kb.write" // upload/delete KB documents
PermKBCreate = "kb.create" // create new knowledge bases
PermChannelCreate = "channel.create" // create group/channel conversations
PermChannelInvite = "channel.invite" // invite users to channels
PermPersonaCreate = "persona.create" // create new personas
PermPersonaManage = "persona.manage" // edit/delete team personas
PermWorkflowCreate = "workflow.create" // create workflow definitions (v0.25.0)
PermAdminView = "admin.view" // read-only admin panel access
PermTokenUnlimited = "token.unlimited" // bypass token budgets
PermTaskCreate = "task.create" // create scheduled tasks (v0.27.2)
PermTaskAdmin = "task.admin" // manage all tasks, set global task config (v0.27.2)
PermTaskAction = "task.action" // create non-LLM action tasks (v0.28.0)
PermTaskStarlark = "task.starlark" // create Starlark tasks (pre-positioned for v0.29.0)
PermExtensionUse = "extension.use" // use installed extensions
PermExtensionInstall = "extension.install" // install/manage extension packages
PermWorkflowCreate = "workflow.create" // create workflow definitions
PermWorkflowSubmit = "workflow.submit" // submit to public workflows
PermAdminView = "admin.view" // read-only admin panel access
PermTokenUnlimited = "token.unlimited" // bypass token budgets
)
// AllPermissions is the complete set of valid permission strings.
// Used for validation in handlers and rendering checkboxes in admin UI.
var AllPermissions = []string{
PermModelUse,
PermModelSelectAny,
PermKBRead,
PermKBWrite,
PermKBCreate,
PermChannelCreate,
PermChannelInvite,
PermPersonaCreate,
PermPersonaManage,
PermExtensionUse,
PermExtensionInstall,
PermWorkflowCreate,
PermWorkflowSubmit,
PermAdminView,
PermTokenUnlimited,
PermTaskCreate,
PermTaskAdmin,
PermTaskAction,
PermTaskStarlark,
}
// ── Resolution ──────────────────────────────

View File

@@ -1,96 +0,0 @@
package auth
import (
"context"
"database/sql"
"fmt"
"log"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
"switchboard-core/config"
"switchboard-core/models"
"switchboard-core/store"
)
const sessionCookieName = "sb_session"
// CreateOrResumeSession looks up or creates a session participant for
// an anonymous visitor to a workflow channel.
//
// Two entry paths:
// - Cookie-based (default): random token stored in sb_session cookie
// - mTLS-based: cert fingerprint used as stable session identity
func CreateOrResumeSession(c *gin.Context, stores store.Stores, channelID string, cfg *config.Config) (*models.SessionParticipant, error) {
// Check for existing session cookie
token, _ := c.Cookie(sessionCookieName)
// mTLS mode: use cert fingerprint as stable token
if cfg.AuthMode == "mtls" {
fp := c.GetHeader("X-SSL-Client-Fingerprint")
if fp != "" {
token = "mtls:" + fp
}
}
// Resume existing session if token matches this channel
if token != "" {
session, err := stores.Sessions.GetByToken(c.Request.Context(), token)
if err == nil && session.ChannelID == channelID {
return session, nil
}
// Token exists but for different channel — fall through to create
if err != nil && err != sql.ErrNoRows {
log.Printf("[auth/session] warn: GetByToken error: %v", err)
}
}
// Create new session
token = "sess:" + uuid.New().String()
displayName, err := generateVisitorName(c.Request.Context(), stores, channelID)
if err != nil {
displayName = "Visitor"
}
session := &models.SessionParticipant{
SessionToken: token,
ChannelID: channelID,
DisplayName: displayName,
}
// mTLS mode: store fingerprint for team member visibility
if cfg.AuthMode == "mtls" {
fp := c.GetHeader("X-SSL-Client-Fingerprint")
if fp != "" {
session.Fingerprint = fp
}
}
if err := stores.Sessions.Create(c.Request.Context(), session); err != nil {
return nil, fmt.Errorf("create session: %w", err)
}
// Add as channel participant
_ = stores.Channels.AddParticipant(c.Request.Context(), &models.ChannelParticipant{
ChannelID: channelID,
ParticipantType: "session",
ParticipantID: session.ID,
Role: "visitor",
})
// Set cookie (httponly, secure, 30 day expiry)
c.SetCookie(sessionCookieName, token, 60*60*24*30, "/", "", true, true)
log.Printf("[auth/session] created session %s for channel %s (%s)", session.ID, channelID, displayName)
return session, nil
}
// generateVisitorName produces "Visitor #N" based on existing session count.
func generateVisitorName(ctx context.Context, stores store.Stores, channelID string) (string, error) {
count, err := stores.Sessions.CountForChannel(ctx, channelID)
if err != nil {
return "", err
}
return fmt.Sprintf("Visitor #%d", count+1), nil
}