Changeset 0.32.0 (#206)

This commit is contained in:
2026-03-19 18:50:27 +00:00
parent 6668e546fe
commit b1266b0d7c
283 changed files with 2187 additions and 1055 deletions

View File

@@ -12,14 +12,14 @@ import (
"github.com/gin-gonic/gin"
"golang.org/x/crypto/bcrypt"
"git.gobha.me/xcaliber/chat-switchboard/auth"
"git.gobha.me/xcaliber/chat-switchboard/crypto"
"git.gobha.me/xcaliber/chat-switchboard/database"
"git.gobha.me/xcaliber/chat-switchboard/models"
"git.gobha.me/xcaliber/chat-switchboard/providers"
"git.gobha.me/xcaliber/chat-switchboard/storage"
"git.gobha.me/xcaliber/chat-switchboard/store"
"git.gobha.me/xcaliber/chat-switchboard/tools/search"
"chat-switchboard/auth"
"chat-switchboard/crypto"
"chat-switchboard/database"
"chat-switchboard/models"
"chat-switchboard/providers"
"chat-switchboard/storage"
"chat-switchboard/store"
"chat-switchboard/tools/search"
)
type AdminHandler struct {

View File

@@ -6,8 +6,8 @@ import (
"github.com/gin-gonic/gin"
"git.gobha.me/xcaliber/chat-switchboard/notifications"
"git.gobha.me/xcaliber/chat-switchboard/store"
"chat-switchboard/notifications"
"chat-switchboard/store"
)
// AdminEmailHandler handles admin SMTP configuration and test endpoints.

View File

@@ -7,9 +7,9 @@ import (
"github.com/gin-gonic/gin"
"git.gobha.me/xcaliber/chat-switchboard/crypto"
"git.gobha.me/xcaliber/chat-switchboard/models"
"git.gobha.me/xcaliber/chat-switchboard/store"
"chat-switchboard/crypto"
"chat-switchboard/models"
"chat-switchboard/store"
)
// ProviderConfigHandler handles user-facing provider config endpoints.

View File

@@ -8,8 +8,8 @@ import (
"github.com/gin-gonic/gin"
"git.gobha.me/xcaliber/chat-switchboard/models"
"git.gobha.me/xcaliber/chat-switchboard/store"
"chat-switchboard/models"
"chat-switchboard/store"
)
// AuditLog writes an audit entry via the store interface.

View File

@@ -17,11 +17,11 @@ import (
"github.com/google/uuid"
"golang.org/x/crypto/bcrypt"
"git.gobha.me/xcaliber/chat-switchboard/auth"
"git.gobha.me/xcaliber/chat-switchboard/config"
"git.gobha.me/xcaliber/chat-switchboard/crypto"
"git.gobha.me/xcaliber/chat-switchboard/models"
"git.gobha.me/xcaliber/chat-switchboard/store"
"chat-switchboard/auth"
"chat-switchboard/config"
"chat-switchboard/crypto"
"chat-switchboard/models"
"chat-switchboard/store"
)
// Claims represents the JWT payload.

View File

@@ -14,9 +14,9 @@ import (
"github.com/golang-jwt/jwt/v5"
"golang.org/x/crypto/bcrypt"
"git.gobha.me/xcaliber/chat-switchboard/auth"
"git.gobha.me/xcaliber/chat-switchboard/config"
"git.gobha.me/xcaliber/chat-switchboard/store"
"chat-switchboard/auth"
"chat-switchboard/config"
"chat-switchboard/store"
)
func testConfig() *config.Config {

View File

@@ -15,8 +15,8 @@ import (
"github.com/gin-gonic/gin"
"git.gobha.me/xcaliber/chat-switchboard/models"
"git.gobha.me/xcaliber/chat-switchboard/store"
"chat-switchboard/models"
"chat-switchboard/store"
)
const avatarSize = 128

View File

@@ -8,11 +8,11 @@ import (
"github.com/gin-gonic/gin"
capspkg "git.gobha.me/xcaliber/chat-switchboard/capabilities"
"git.gobha.me/xcaliber/chat-switchboard/auth"
"git.gobha.me/xcaliber/chat-switchboard/health"
"git.gobha.me/xcaliber/chat-switchboard/models"
"git.gobha.me/xcaliber/chat-switchboard/store"
capspkg "chat-switchboard/capabilities"
"chat-switchboard/auth"
"chat-switchboard/health"
"chat-switchboard/models"
"chat-switchboard/store"
)
// ModelHandler provides the unified models endpoint.

View File

@@ -6,8 +6,8 @@ import (
"github.com/gin-gonic/gin"
"git.gobha.me/xcaliber/chat-switchboard/models"
"git.gobha.me/xcaliber/chat-switchboard/store"
"chat-switchboard/models"
"chat-switchboard/store"
)
// ── Channel Models Handler ──────────────────

View File

@@ -9,8 +9,8 @@ import (
"github.com/gin-gonic/gin"
"git.gobha.me/xcaliber/chat-switchboard/models"
"git.gobha.me/xcaliber/chat-switchboard/store"
"chat-switchboard/models"
"chat-switchboard/store"
)
// ── Request / Response types ────────────────

View File

@@ -13,22 +13,22 @@ import (
"github.com/gin-gonic/gin"
"git.gobha.me/xcaliber/chat-switchboard/auth"
capspkg "git.gobha.me/xcaliber/chat-switchboard/capabilities"
"git.gobha.me/xcaliber/chat-switchboard/crypto"
"git.gobha.me/xcaliber/chat-switchboard/database"
"git.gobha.me/xcaliber/chat-switchboard/events"
"git.gobha.me/xcaliber/chat-switchboard/filters"
"git.gobha.me/xcaliber/chat-switchboard/health"
"git.gobha.me/xcaliber/chat-switchboard/knowledge"
"git.gobha.me/xcaliber/chat-switchboard/models"
"git.gobha.me/xcaliber/chat-switchboard/notifications"
"git.gobha.me/xcaliber/chat-switchboard/providers"
"git.gobha.me/xcaliber/chat-switchboard/routing"
"git.gobha.me/xcaliber/chat-switchboard/sandbox"
"git.gobha.me/xcaliber/chat-switchboard/storage"
"git.gobha.me/xcaliber/chat-switchboard/store"
"git.gobha.me/xcaliber/chat-switchboard/tools"
"chat-switchboard/auth"
capspkg "chat-switchboard/capabilities"
"chat-switchboard/crypto"
"chat-switchboard/database"
"chat-switchboard/events"
"chat-switchboard/filters"
"chat-switchboard/health"
"chat-switchboard/knowledge"
"chat-switchboard/models"
"chat-switchboard/notifications"
"chat-switchboard/providers"
"chat-switchboard/routing"
"chat-switchboard/sandbox"
"chat-switchboard/storage"
"chat-switchboard/store"
"chat-switchboard/tools"
)
// ── Request Types ───────────────────────────
@@ -280,7 +280,7 @@ func (h *CompletionHandler) Complete(c *gin.Context) {
Ts: time.Now().UnixMilli(),
}
// Send to sender
h.hub.SendToUser(userID, evt)
h.hub.PublishToUser(userID, evt)
// Send to other user participants in the channel
pRows, pErr := database.DB.QueryContext(c.Request.Context(), database.Q(`
SELECT participant_id FROM channel_participants
@@ -291,7 +291,7 @@ func (h *CompletionHandler) Complete(c *gin.Context) {
for pRows.Next() {
var pid string
if pRows.Scan(&pid) == nil {
h.hub.SendToUser(pid, evt)
h.hub.PublishToUser(pid, evt)
}
}
}
@@ -598,7 +598,7 @@ func (h *CompletionHandler) Complete(c *gin.Context) {
"from_user": userID,
"content": truncateContent(req.Content, 120),
})
h.hub.SendToUser(mentionedUserID, events.Event{
h.hub.PublishToUser(mentionedUserID, events.Event{
Label: "user.mentioned",
Payload: payload,
Ts: time.Now().UnixMilli(),

View File

@@ -7,11 +7,11 @@ import (
"log"
"time"
"git.gobha.me/xcaliber/chat-switchboard/events"
"git.gobha.me/xcaliber/chat-switchboard/models"
"git.gobha.me/xcaliber/chat-switchboard/providers"
"chat-switchboard/events"
"chat-switchboard/models"
"chat-switchboard/providers"
capspkg "git.gobha.me/xcaliber/chat-switchboard/capabilities"
capspkg "chat-switchboard/capabilities"
)
// maxChainDepth limits AI-to-AI chaining to prevent runaway loops.
@@ -175,7 +175,7 @@ func (h *CompletionHandler) chainIfMentioned(
"tokens_used": resp.InputTokens + resp.OutputTokens,
"chain_depth": depth + 1,
})
h.hub.SendToUser(userID, events.Event{
h.hub.PublishToUser(userID, events.Event{
Label: "message.created",
Payload: payload,
Ts: time.Now().UnixMilli(),
@@ -314,7 +314,7 @@ func (h *CompletionHandler) chainToPersona(channelID, userID, personaID, trigger
"tokens_used": resp.InputTokens + resp.OutputTokens,
"chain_depth": depth,
})
h.hub.SendToUser(userID, events.Event{
h.hub.PublishToUser(userID, events.Event{
Label: "message.created",
Payload: payload,
Ts: time.Now().UnixMilli(),
@@ -350,7 +350,7 @@ func (h *CompletionHandler) emitTyping(userID, channelID, participantID, display
"participant_type": "persona",
"display_name": displayName,
})
h.hub.SendToUser(userID, events.Event{
h.hub.PublishToUser(userID, events.Event{
Label: eventType,
Payload: payload,
Ts: time.Now().UnixMilli(),

View File

@@ -42,9 +42,9 @@ import (
"github.com/gin-gonic/gin"
"go.starlark.net/starlark"
"git.gobha.me/xcaliber/chat-switchboard/models"
"git.gobha.me/xcaliber/chat-switchboard/sandbox"
"git.gobha.me/xcaliber/chat-switchboard/store"
"chat-switchboard/models"
"chat-switchboard/sandbox"
"chat-switchboard/store"
)
// ExtAPIHandler serves extension API routes via Starlark.

View File

@@ -15,7 +15,7 @@ import (
"regexp"
"strings"
"git.gobha.me/xcaliber/chat-switchboard/store"
"chat-switchboard/store"
)
// validSchemaIdentifier matches safe SQL identifiers for table and column names.

View File

@@ -8,7 +8,7 @@ import (
_ "modernc.org/sqlite"
"git.gobha.me/xcaliber/chat-switchboard/store"
"chat-switchboard/store"
)
// ── mock ExtDataStore ────────────────────────────────────────────────────────

View File

@@ -5,8 +5,8 @@ import (
"github.com/gin-gonic/gin"
"git.gobha.me/xcaliber/chat-switchboard/models"
"git.gobha.me/xcaliber/chat-switchboard/store"
"chat-switchboard/models"
"chat-switchboard/store"
)
// ExtPermHandler serves extension permission management endpoints.

View File

@@ -5,8 +5,8 @@ import (
"github.com/gin-gonic/gin"
"git.gobha.me/xcaliber/chat-switchboard/models"
"git.gobha.me/xcaliber/chat-switchboard/store"
"chat-switchboard/models"
"chat-switchboard/store"
)
// ExtSecretsHandler serves extension secret management endpoints.

View File

@@ -11,13 +11,13 @@ import (
"github.com/gin-gonic/gin"
authpkg "git.gobha.me/xcaliber/chat-switchboard/auth"
"git.gobha.me/xcaliber/chat-switchboard/config"
"git.gobha.me/xcaliber/chat-switchboard/database"
"git.gobha.me/xcaliber/chat-switchboard/middleware"
"git.gobha.me/xcaliber/chat-switchboard/store"
postgres "git.gobha.me/xcaliber/chat-switchboard/store/postgres"
sqlite "git.gobha.me/xcaliber/chat-switchboard/store/sqlite"
authpkg "chat-switchboard/auth"
"chat-switchboard/config"
"chat-switchboard/database"
"chat-switchboard/middleware"
"chat-switchboard/store"
postgres "chat-switchboard/store/postgres"
sqlite "chat-switchboard/store/sqlite"
)
// ── Extension Test Harness ──────────────────

View File

@@ -7,9 +7,9 @@ import (
"github.com/gin-gonic/gin"
"git.gobha.me/xcaliber/chat-switchboard/database"
"git.gobha.me/xcaliber/chat-switchboard/models"
"git.gobha.me/xcaliber/chat-switchboard/store"
"chat-switchboard/database"
"chat-switchboard/models"
"chat-switchboard/store"
)
// ExtensionHandler serves extension management endpoints.

View File

@@ -12,10 +12,10 @@ import (
"github.com/gin-gonic/gin"
"git.gobha.me/xcaliber/chat-switchboard/extraction"
"git.gobha.me/xcaliber/chat-switchboard/models"
"git.gobha.me/xcaliber/chat-switchboard/storage"
"git.gobha.me/xcaliber/chat-switchboard/store"
"chat-switchboard/extraction"
"chat-switchboard/models"
"chat-switchboard/storage"
"chat-switchboard/store"
)
// ── Default Limits ─────────────────────────

View File

@@ -10,8 +10,8 @@ import (
"github.com/gin-gonic/gin"
"git.gobha.me/xcaliber/chat-switchboard/models"
"git.gobha.me/xcaliber/chat-switchboard/store"
"chat-switchboard/models"
"chat-switchboard/store"
)
type FolderHandler struct {

View File

@@ -11,10 +11,10 @@ import (
"golang.org/x/crypto/ssh"
"git.gobha.me/xcaliber/chat-switchboard/crypto"
"git.gobha.me/xcaliber/chat-switchboard/models"
"git.gobha.me/xcaliber/chat-switchboard/store"
"git.gobha.me/xcaliber/chat-switchboard/workspace"
"chat-switchboard/crypto"
"chat-switchboard/models"
"chat-switchboard/store"
"chat-switchboard/workspace"
"github.com/gin-gonic/gin"
)

View File

@@ -7,13 +7,13 @@ import (
"github.com/gin-gonic/gin"
"git.gobha.me/xcaliber/chat-switchboard/config"
"git.gobha.me/xcaliber/chat-switchboard/crypto"
"git.gobha.me/xcaliber/chat-switchboard/database"
"git.gobha.me/xcaliber/chat-switchboard/middleware"
"git.gobha.me/xcaliber/chat-switchboard/store"
postgres "git.gobha.me/xcaliber/chat-switchboard/store/postgres"
sqlite "git.gobha.me/xcaliber/chat-switchboard/store/sqlite"
"chat-switchboard/config"
"chat-switchboard/crypto"
"chat-switchboard/database"
"chat-switchboard/middleware"
"chat-switchboard/store"
postgres "chat-switchboard/store/postgres"
sqlite "chat-switchboard/store/sqlite"
)
// ── Git Credentials Test Harness ──────────

View File

@@ -7,11 +7,11 @@ import (
"github.com/gin-gonic/gin"
"git.gobha.me/xcaliber/chat-switchboard/auth"
"git.gobha.me/xcaliber/chat-switchboard/database"
"git.gobha.me/xcaliber/chat-switchboard/models"
"git.gobha.me/xcaliber/chat-switchboard/notifications"
"git.gobha.me/xcaliber/chat-switchboard/store"
"chat-switchboard/auth"
"chat-switchboard/database"
"chat-switchboard/models"
"chat-switchboard/notifications"
"chat-switchboard/store"
)
// ── Request types ───────────────────────────

View File

@@ -6,11 +6,11 @@ import (
"github.com/gin-gonic/gin"
capspkg "git.gobha.me/xcaliber/chat-switchboard/capabilities"
"git.gobha.me/xcaliber/chat-switchboard/health"
"git.gobha.me/xcaliber/chat-switchboard/models"
"git.gobha.me/xcaliber/chat-switchboard/providers"
"git.gobha.me/xcaliber/chat-switchboard/store"
capspkg "chat-switchboard/capabilities"
"chat-switchboard/health"
"chat-switchboard/models"
"chat-switchboard/providers"
"chat-switchboard/store"
)
// ── Health Admin Handler ────────────────────

View File

@@ -15,16 +15,16 @@ import (
"github.com/golang-jwt/jwt/v5"
"github.com/google/uuid"
"git.gobha.me/xcaliber/chat-switchboard/config"
authpkg "git.gobha.me/xcaliber/chat-switchboard/auth"
"git.gobha.me/xcaliber/chat-switchboard/database"
"git.gobha.me/xcaliber/chat-switchboard/middleware"
"git.gobha.me/xcaliber/chat-switchboard/models"
"git.gobha.me/xcaliber/chat-switchboard/roles"
"git.gobha.me/xcaliber/chat-switchboard/store"
postgres "git.gobha.me/xcaliber/chat-switchboard/store/postgres"
sqlite "git.gobha.me/xcaliber/chat-switchboard/store/sqlite"
"git.gobha.me/xcaliber/chat-switchboard/treepath"
"chat-switchboard/config"
authpkg "chat-switchboard/auth"
"chat-switchboard/database"
"chat-switchboard/middleware"
"chat-switchboard/models"
"chat-switchboard/roles"
"chat-switchboard/store"
postgres "chat-switchboard/store/postgres"
sqlite "chat-switchboard/store/sqlite"
"chat-switchboard/treepath"
)
// ── Test Harness ────────────────────────────

View File

@@ -11,10 +11,10 @@ import (
"github.com/gin-gonic/gin"
"git.gobha.me/xcaliber/chat-switchboard/knowledge"
"git.gobha.me/xcaliber/chat-switchboard/models"
"git.gobha.me/xcaliber/chat-switchboard/storage"
"git.gobha.me/xcaliber/chat-switchboard/store"
"chat-switchboard/knowledge"
"chat-switchboard/models"
"chat-switchboard/storage"
"chat-switchboard/store"
)
// ── Limits ───────────────────────────────────

View File

@@ -7,14 +7,14 @@ import (
"strings"
"testing"
"git.gobha.me/xcaliber/chat-switchboard/compaction"
"git.gobha.me/xcaliber/chat-switchboard/database"
"git.gobha.me/xcaliber/chat-switchboard/models"
"git.gobha.me/xcaliber/chat-switchboard/roles"
"git.gobha.me/xcaliber/chat-switchboard/store"
postgres "git.gobha.me/xcaliber/chat-switchboard/store/postgres"
sqlite "git.gobha.me/xcaliber/chat-switchboard/store/sqlite"
"git.gobha.me/xcaliber/chat-switchboard/treepath"
"chat-switchboard/compaction"
"chat-switchboard/database"
"chat-switchboard/models"
"chat-switchboard/roles"
"chat-switchboard/store"
postgres "chat-switchboard/store/postgres"
sqlite "chat-switchboard/store/sqlite"
"chat-switchboard/treepath"
)
// ═══════════════════════════════════════════

View File

@@ -10,8 +10,8 @@ import (
"testing"
"time"
"git.gobha.me/xcaliber/chat-switchboard/database"
"git.gobha.me/xcaliber/chat-switchboard/providers"
"chat-switchboard/database"
"chat-switchboard/providers"
)
// ═══════════════════════════════════════════

View File

@@ -5,9 +5,9 @@ import (
"github.com/gin-gonic/gin"
"git.gobha.me/xcaliber/chat-switchboard/memory"
"git.gobha.me/xcaliber/chat-switchboard/models"
"git.gobha.me/xcaliber/chat-switchboard/store"
"chat-switchboard/memory"
"chat-switchboard/models"
"chat-switchboard/store"
)
// MemoryHandler provides REST endpoints for memory management.

View File

@@ -6,9 +6,9 @@ import (
"log"
"strings"
"git.gobha.me/xcaliber/chat-switchboard/knowledge"
"git.gobha.me/xcaliber/chat-switchboard/models"
"git.gobha.me/xcaliber/chat-switchboard/store"
"chat-switchboard/knowledge"
"chat-switchboard/models"
"chat-switchboard/store"
)
// maxMemoryChars is the approximate character budget for injected memories.

View File

@@ -4,8 +4,8 @@ import (
"net/http"
"testing"
"git.gobha.me/xcaliber/chat-switchboard/database"
"git.gobha.me/xcaliber/chat-switchboard/models"
"chat-switchboard/database"
"chat-switchboard/models"
)
// seedMemory inserts a memory directly into the DB for testing.

View File

@@ -10,15 +10,15 @@ import (
"github.com/gin-gonic/gin"
capspkg "git.gobha.me/xcaliber/chat-switchboard/capabilities"
"git.gobha.me/xcaliber/chat-switchboard/crypto"
"git.gobha.me/xcaliber/chat-switchboard/events"
"git.gobha.me/xcaliber/chat-switchboard/models"
"git.gobha.me/xcaliber/chat-switchboard/providers"
"git.gobha.me/xcaliber/chat-switchboard/storage"
"git.gobha.me/xcaliber/chat-switchboard/store"
"git.gobha.me/xcaliber/chat-switchboard/tools"
"git.gobha.me/xcaliber/chat-switchboard/treepath"
capspkg "chat-switchboard/capabilities"
"chat-switchboard/crypto"
"chat-switchboard/events"
"chat-switchboard/models"
"chat-switchboard/providers"
"chat-switchboard/storage"
"chat-switchboard/store"
"chat-switchboard/tools"
"chat-switchboard/treepath"
)
// ── Request / Response types ────────────────

View File

@@ -5,8 +5,8 @@ import (
"github.com/gin-gonic/gin"
"git.gobha.me/xcaliber/chat-switchboard/models"
"git.gobha.me/xcaliber/chat-switchboard/store"
"chat-switchboard/models"
"chat-switchboard/store"
)
// ModelPrefsHandler handles user model preference endpoints.

View File

@@ -8,12 +8,12 @@ import (
"github.com/gin-gonic/gin"
"github.com/google/uuid"
"git.gobha.me/xcaliber/chat-switchboard/config"
"git.gobha.me/xcaliber/chat-switchboard/database"
"git.gobha.me/xcaliber/chat-switchboard/middleware"
"git.gobha.me/xcaliber/chat-switchboard/store"
postgres "git.gobha.me/xcaliber/chat-switchboard/store/postgres"
sqlite "git.gobha.me/xcaliber/chat-switchboard/store/sqlite"
"chat-switchboard/config"
"chat-switchboard/database"
"chat-switchboard/middleware"
"chat-switchboard/store"
postgres "chat-switchboard/store/postgres"
sqlite "chat-switchboard/store/sqlite"
)
// ── Model Prefs Test Harness ──────────────

View File

@@ -10,9 +10,9 @@ import (
"strconv"
"time"
"git.gobha.me/xcaliber/chat-switchboard/models"
"git.gobha.me/xcaliber/chat-switchboard/providers"
"git.gobha.me/xcaliber/chat-switchboard/store"
"chat-switchboard/models"
"chat-switchboard/providers"
"chat-switchboard/store"
)
// providerSyncTimeout is the maximum time allowed for an outbound provider

View File

@@ -7,9 +7,9 @@ import (
"github.com/gin-gonic/gin"
"git.gobha.me/xcaliber/chat-switchboard/models"
"git.gobha.me/xcaliber/chat-switchboard/notelinks"
"git.gobha.me/xcaliber/chat-switchboard/store"
"chat-switchboard/models"
"chat-switchboard/notelinks"
"chat-switchboard/store"
)
// ── Request / Response Types ────────────────

View File

@@ -8,14 +8,14 @@ import (
"github.com/gin-gonic/gin"
"git.gobha.me/xcaliber/chat-switchboard/config"
"git.gobha.me/xcaliber/chat-switchboard/database"
"git.gobha.me/xcaliber/chat-switchboard/middleware"
"git.gobha.me/xcaliber/chat-switchboard/models"
"git.gobha.me/xcaliber/chat-switchboard/notifications"
"git.gobha.me/xcaliber/chat-switchboard/store"
postgres "git.gobha.me/xcaliber/chat-switchboard/store/postgres"
sqlite "git.gobha.me/xcaliber/chat-switchboard/store/sqlite"
"chat-switchboard/config"
"chat-switchboard/database"
"chat-switchboard/middleware"
"chat-switchboard/models"
"chat-switchboard/notifications"
"chat-switchboard/store"
postgres "chat-switchboard/store/postgres"
sqlite "chat-switchboard/store/sqlite"
)
// ── Notification Test Harness ──────────────

View File

@@ -10,10 +10,10 @@ import (
"github.com/gin-gonic/gin"
"git.gobha.me/xcaliber/chat-switchboard/events"
"git.gobha.me/xcaliber/chat-switchboard/models"
"git.gobha.me/xcaliber/chat-switchboard/notifications"
"git.gobha.me/xcaliber/chat-switchboard/store"
"chat-switchboard/events"
"chat-switchboard/models"
"chat-switchboard/notifications"
"chat-switchboard/store"
)
// ── Handler ─────────────────────────────────
@@ -111,7 +111,7 @@ func (h *NotificationHandler) MarkRead(c *gin.Context) {
// Sync badge across tabs
if h.hub != nil {
payload, _ := json.Marshal(map[string]string{"id": id})
h.hub.SendToUser(userID, events.Event{
h.hub.PublishToUser(userID, events.Event{
Label: "notification.read",
Payload: payload,
Ts: time.Now().UnixMilli(),
@@ -138,7 +138,7 @@ func (h *NotificationHandler) MarkAllRead(c *gin.Context) {
// Sync badge across tabs
if h.hub != nil {
payload, _ := json.Marshal(map[string]string{"action": "mark_all_read"})
h.hub.SendToUser(userID, events.Event{
h.hub.PublishToUser(userID, events.Event{
Label: "notification.read",
Payload: payload,
Ts: time.Now().UnixMilli(),
@@ -341,7 +341,7 @@ func (h *NotificationHandler) Broadcast(c *gin.Context) {
"level": level,
})
for _, uid := range userIDs {
h.hub.SendToUser(uid, events.Event{
h.hub.PublishToUser(uid, events.Event{
Label: "system.broadcast",
Payload: payload,
Ts: time.Now().UnixMilli(),

View File

@@ -18,7 +18,7 @@ import (
"github.com/gin-gonic/gin"
"git.gobha.me/xcaliber/chat-switchboard/store"
"chat-switchboard/store"
)
// PackageExportHandler handles package export operations.

View File

@@ -28,8 +28,8 @@ import (
"go.starlark.net/starlark"
"git.gobha.me/xcaliber/chat-switchboard/sandbox"
"git.gobha.me/xcaliber/chat-switchboard/store"
"chat-switchboard/sandbox"
"chat-switchboard/store"
)
// ParseSchemaVersion extracts the "schema_version" integer from a manifest.

View File

@@ -29,7 +29,7 @@ import (
"github.com/gin-gonic/gin"
"git.gobha.me/xcaliber/chat-switchboard/store"
"chat-switchboard/store"
)
// RegistryEntry represents a single package in the registry.

View File

@@ -14,9 +14,9 @@ import (
"github.com/gin-gonic/gin"
"git.gobha.me/xcaliber/chat-switchboard/database"
"git.gobha.me/xcaliber/chat-switchboard/sandbox"
"git.gobha.me/xcaliber/chat-switchboard/store"
"chat-switchboard/database"
"chat-switchboard/sandbox"
"chat-switchboard/store"
)
// validPackageID matches lowercase alphanumeric slugs with optional hyphens.

View File

@@ -6,8 +6,8 @@ import (
"github.com/gin-gonic/gin"
"git.gobha.me/xcaliber/chat-switchboard/models"
"git.gobha.me/xcaliber/chat-switchboard/store"
"chat-switchboard/models"
"chat-switchboard/store"
)
// ── Channel Participants Handler ──────────────

View File

@@ -10,8 +10,8 @@ import (
"github.com/gin-gonic/gin"
"git.gobha.me/xcaliber/chat-switchboard/models"
"git.gobha.me/xcaliber/chat-switchboard/store"
"chat-switchboard/models"
"chat-switchboard/store"
)
type PersonaGroupHandler struct {

View File

@@ -6,8 +6,8 @@ import (
"github.com/gin-gonic/gin"
"git.gobha.me/xcaliber/chat-switchboard/models"
"git.gobha.me/xcaliber/chat-switchboard/store"
"chat-switchboard/models"
"chat-switchboard/store"
)
// PersonaHandler handles persona endpoints.

View File

@@ -15,7 +15,7 @@ import (
"github.com/gin-gonic/gin"
"git.gobha.me/xcaliber/chat-switchboard/store"
"chat-switchboard/store"
)
const presenceOnlineThreshold = 90 * time.Second

View File

@@ -8,12 +8,12 @@ import (
"github.com/gin-gonic/gin"
"golang.org/x/crypto/bcrypt"
"git.gobha.me/xcaliber/chat-switchboard/config"
"git.gobha.me/xcaliber/chat-switchboard/database"
"git.gobha.me/xcaliber/chat-switchboard/middleware"
"git.gobha.me/xcaliber/chat-switchboard/store"
postgres "git.gobha.me/xcaliber/chat-switchboard/store/postgres"
sqlite "git.gobha.me/xcaliber/chat-switchboard/store/sqlite"
"chat-switchboard/config"
"chat-switchboard/database"
"chat-switchboard/middleware"
"chat-switchboard/store"
postgres "chat-switchboard/store/postgres"
sqlite "chat-switchboard/store/sqlite"
)
// ── Profile Test Harness ──────────────────

View File

@@ -6,8 +6,8 @@ import (
"github.com/gin-gonic/gin"
"git.gobha.me/xcaliber/chat-switchboard/models"
"git.gobha.me/xcaliber/chat-switchboard/store"
"chat-switchboard/models"
"chat-switchboard/store"
)
// ── Request / Response Types ────────────────

View File

@@ -8,13 +8,13 @@ import (
"github.com/gin-gonic/gin"
"git.gobha.me/xcaliber/chat-switchboard/config"
"git.gobha.me/xcaliber/chat-switchboard/database"
"git.gobha.me/xcaliber/chat-switchboard/middleware"
"git.gobha.me/xcaliber/chat-switchboard/models"
"git.gobha.me/xcaliber/chat-switchboard/store"
postgres "git.gobha.me/xcaliber/chat-switchboard/store/postgres"
sqlite "git.gobha.me/xcaliber/chat-switchboard/store/sqlite"
"chat-switchboard/config"
"chat-switchboard/database"
"chat-switchboard/middleware"
"chat-switchboard/models"
"chat-switchboard/store"
postgres "chat-switchboard/store/postgres"
sqlite "chat-switchboard/store/sqlite"
)
// ── Project Test Harness ──────────────────

View File

@@ -10,10 +10,10 @@ import (
"context"
"fmt"
"git.gobha.me/xcaliber/chat-switchboard/crypto"
"git.gobha.me/xcaliber/chat-switchboard/providers"
"git.gobha.me/xcaliber/chat-switchboard/sandbox"
"git.gobha.me/xcaliber/chat-switchboard/store"
"chat-switchboard/crypto"
"chat-switchboard/providers"
"chat-switchboard/sandbox"
"chat-switchboard/store"
)
// ProviderResolverAdapter implements sandbox.ProviderResolver using

View File

@@ -17,10 +17,10 @@ import (
"fmt"
"log"
"git.gobha.me/xcaliber/chat-switchboard/crypto"
"git.gobha.me/xcaliber/chat-switchboard/providers"
"git.gobha.me/xcaliber/chat-switchboard/store"
"git.gobha.me/xcaliber/chat-switchboard/tools"
"chat-switchboard/crypto"
"chat-switchboard/providers"
"chat-switchboard/store"
"chat-switchboard/tools"
)
// ── Provider Resolution ────────────────────────

View File

@@ -5,10 +5,10 @@ import (
"github.com/gin-gonic/gin"
"git.gobha.me/xcaliber/chat-switchboard/models"
"git.gobha.me/xcaliber/chat-switchboard/providers"
"git.gobha.me/xcaliber/chat-switchboard/roles"
"git.gobha.me/xcaliber/chat-switchboard/store"
"chat-switchboard/models"
"chat-switchboard/providers"
"chat-switchboard/roles"
"chat-switchboard/store"
)
// RolesHandler manages model role configuration.

View File

@@ -7,14 +7,14 @@ import (
"github.com/gin-gonic/gin"
"git.gobha.me/xcaliber/chat-switchboard/config"
authpkg "git.gobha.me/xcaliber/chat-switchboard/auth"
"git.gobha.me/xcaliber/chat-switchboard/database"
"git.gobha.me/xcaliber/chat-switchboard/middleware"
"git.gobha.me/xcaliber/chat-switchboard/pages"
"git.gobha.me/xcaliber/chat-switchboard/store"
postgres "git.gobha.me/xcaliber/chat-switchboard/store/postgres"
sqlite "git.gobha.me/xcaliber/chat-switchboard/store/sqlite"
"chat-switchboard/config"
authpkg "chat-switchboard/auth"
"chat-switchboard/database"
"chat-switchboard/middleware"
"chat-switchboard/pages"
"chat-switchboard/store"
postgres "chat-switchboard/store/postgres"
sqlite "chat-switchboard/store/sqlite"
)
// TestRouteRegistration verifies that ALL production routes can be

View File

@@ -6,10 +6,10 @@ import (
"github.com/gin-gonic/gin"
"git.gobha.me/xcaliber/chat-switchboard/health"
"git.gobha.me/xcaliber/chat-switchboard/models"
"git.gobha.me/xcaliber/chat-switchboard/routing"
"git.gobha.me/xcaliber/chat-switchboard/store"
"chat-switchboard/health"
"chat-switchboard/models"
"chat-switchboard/routing"
"chat-switchboard/store"
)
// ── Routing Admin Handler ───────────────────

View File

@@ -8,7 +8,7 @@ import (
"github.com/gin-gonic/gin"
"github.com/lib/pq"
"git.gobha.me/xcaliber/chat-switchboard/database"
"chat-switchboard/database"
)
// ── SafeJSON ────────────────────────────────

View File

@@ -7,7 +7,7 @@ import (
"os"
"path/filepath"
"git.gobha.me/xcaliber/chat-switchboard/store"
"chat-switchboard/store"
)
// builtinManifest is the on-disk manifest.json shape.

View File

@@ -5,10 +5,10 @@ import (
"log"
"strings"
"git.gobha.me/xcaliber/chat-switchboard/config"
"git.gobha.me/xcaliber/chat-switchboard/crypto"
"git.gobha.me/xcaliber/chat-switchboard/models"
"git.gobha.me/xcaliber/chat-switchboard/store"
"chat-switchboard/config"
"chat-switchboard/crypto"
"chat-switchboard/models"
"chat-switchboard/store"
)
// Known provider default endpoints for seeding.

View File

@@ -15,8 +15,8 @@ import (
"github.com/gin-gonic/gin"
"golang.org/x/crypto/bcrypt"
"git.gobha.me/xcaliber/chat-switchboard/crypto"
"git.gobha.me/xcaliber/chat-switchboard/store"
"chat-switchboard/crypto"
"chat-switchboard/store"
)
// ── Request Types ───────────────────────────

View File

@@ -5,7 +5,7 @@ import (
"github.com/gin-gonic/gin"
"git.gobha.me/xcaliber/chat-switchboard/storage"
"chat-switchboard/storage"
)
// storageConfigured is a package-level flag set during init.

View File

@@ -11,11 +11,11 @@ import (
"github.com/gin-gonic/gin"
"git.gobha.me/xcaliber/chat-switchboard/events"
"git.gobha.me/xcaliber/chat-switchboard/providers"
"git.gobha.me/xcaliber/chat-switchboard/sandbox"
"git.gobha.me/xcaliber/chat-switchboard/store"
"git.gobha.me/xcaliber/chat-switchboard/tools"
"chat-switchboard/events"
"chat-switchboard/providers"
"chat-switchboard/sandbox"
"chat-switchboard/store"
"chat-switchboard/tools"
)
// recordHealthFn records provider health from standalone streaming functions.
@@ -141,7 +141,7 @@ func executeBrowserTool(hub *events.Hub, userID string, call tools.ToolCall) too
"arguments": json.RawMessage(call.Arguments),
})
hub.SendToUser(userID, events.Event{
hub.PublishToUser(userID, events.Event{
Label: "tool.call." + callID,
Payload: payload,
Ts: time.Now().UnixMilli(),

View File

@@ -9,9 +9,9 @@ import (
"github.com/gin-gonic/gin"
"git.gobha.me/xcaliber/chat-switchboard/compaction"
"git.gobha.me/xcaliber/chat-switchboard/roles"
"git.gobha.me/xcaliber/chat-switchboard/store"
"chat-switchboard/compaction"
"chat-switchboard/roles"
"chat-switchboard/store"
)
// SummarizeHandler handles manual conversation summarization via HTTP.

View File

@@ -7,7 +7,7 @@ import (
"strings"
"testing"
"git.gobha.me/xcaliber/chat-switchboard/database"
"chat-switchboard/database"
)
// ═══════════════════════════════════════════════

View File

@@ -7,12 +7,12 @@ import (
"github.com/gin-gonic/gin"
"git.gobha.me/xcaliber/chat-switchboard/auth"
"git.gobha.me/xcaliber/chat-switchboard/middleware"
"git.gobha.me/xcaliber/chat-switchboard/models"
"git.gobha.me/xcaliber/chat-switchboard/store"
"git.gobha.me/xcaliber/chat-switchboard/taskutil"
"git.gobha.me/xcaliber/chat-switchboard/webhook"
"chat-switchboard/auth"
"chat-switchboard/middleware"
"chat-switchboard/models"
"chat-switchboard/store"
"chat-switchboard/taskutil"
"chat-switchboard/webhook"
)
// TaskHandler manages task CRUD and manual execution.

View File

@@ -8,10 +8,10 @@ import (
"github.com/gin-gonic/gin"
capspkg "git.gobha.me/xcaliber/chat-switchboard/capabilities"
"git.gobha.me/xcaliber/chat-switchboard/models"
"git.gobha.me/xcaliber/chat-switchboard/providers"
"git.gobha.me/xcaliber/chat-switchboard/store"
capspkg "chat-switchboard/capabilities"
"chat-switchboard/models"
"chat-switchboard/providers"
"chat-switchboard/store"
)
// ── Team Provider Handlers ──────────────────

View File

@@ -11,11 +11,11 @@ import (
"github.com/gin-gonic/gin"
"git.gobha.me/xcaliber/chat-switchboard/crypto"
"git.gobha.me/xcaliber/chat-switchboard/database"
"git.gobha.me/xcaliber/chat-switchboard/models"
"git.gobha.me/xcaliber/chat-switchboard/providers"
"git.gobha.me/xcaliber/chat-switchboard/store"
"chat-switchboard/crypto"
"chat-switchboard/database"
"chat-switchboard/models"
"chat-switchboard/providers"
"chat-switchboard/store"
)
// ── Request types ───────────────────────────
@@ -105,7 +105,6 @@ func (h *TeamHandler) CreateTeam(c *gin.Context) {
team := &models.Team{
Name: req.Name,
Slug: slugify(req.Name),
Description: req.Description,
CreatedBy: adminID,
IsActive: true,
@@ -119,7 +118,7 @@ func (h *TeamHandler) CreateTeam(c *gin.Context) {
return
}
c.JSON(http.StatusCreated, gin.H{"id": team.ID, "name": team.Name, "slug": team.Slug})
c.JSON(http.StatusCreated, gin.H{"id": team.ID, "name": team.Name})
AuditLog(h.stores.Audit, c, "team.create", "team", team.ID, map[string]interface{}{"name": team.Name})
}
@@ -156,7 +155,6 @@ func (h *TeamHandler) UpdateTeam(c *gin.Context) {
fields := map[string]interface{}{}
if req.Name != nil {
fields["name"] = *req.Name
fields["slug"] = slugify(*req.Name)
}
if req.Description != nil {
fields["description"] = *req.Description

View File

@@ -6,8 +6,8 @@ import (
"github.com/gin-gonic/gin"
"git.gobha.me/xcaliber/chat-switchboard/database"
"git.gobha.me/xcaliber/chat-switchboard/providers"
"chat-switchboard/database"
"chat-switchboard/providers"
_ "modernc.org/sqlite" // register sqlite driver for DB_DRIVER=sqlite
)

View File

@@ -9,9 +9,9 @@ import (
"github.com/gin-gonic/gin"
"git.gobha.me/xcaliber/chat-switchboard/providers"
"git.gobha.me/xcaliber/chat-switchboard/roles"
"git.gobha.me/xcaliber/chat-switchboard/store"
"chat-switchboard/providers"
"chat-switchboard/roles"
"chat-switchboard/store"
)
// TitleHandler generates chat titles using the utility role.

View File

@@ -27,11 +27,11 @@ import (
"github.com/gin-gonic/gin"
"go.starlark.net/starlark"
"git.gobha.me/xcaliber/chat-switchboard/events"
"git.gobha.me/xcaliber/chat-switchboard/providers"
"git.gobha.me/xcaliber/chat-switchboard/sandbox"
"git.gobha.me/xcaliber/chat-switchboard/store"
"git.gobha.me/xcaliber/chat-switchboard/tools"
"chat-switchboard/events"
"chat-switchboard/providers"
"chat-switchboard/sandbox"
"chat-switchboard/store"
"chat-switchboard/tools"
)
// ── Types ──────────────────────────────────────
@@ -564,7 +564,7 @@ func emitWorkspaceEvent(lcfg LoopConfig, call tools.ToolCall, result tools.ToolR
Path string `json:"path"`
}
if json.Unmarshal([]byte(call.Arguments), &toolArgs) == nil && toolArgs.Path != "" {
lcfg.Hub.SendToUser(lcfg.ExecCtx.UserID, events.Event{
lcfg.Hub.PublishToUser(lcfg.ExecCtx.UserID, events.Event{
Label: "workspace.file.changed",
Payload: events.MustJSON(map[string]string{
"workspace_id": lcfg.ExecCtx.WorkspaceID,

View File

@@ -8,7 +8,7 @@ package handlers
// New code should import treepath directly.
import (
"git.gobha.me/xcaliber/chat-switchboard/treepath"
"chat-switchboard/treepath"
)
// ── Type Aliases ────────────────────────────

View File

@@ -6,8 +6,8 @@ import (
"github.com/gin-gonic/gin"
"git.gobha.me/xcaliber/chat-switchboard/models"
"git.gobha.me/xcaliber/chat-switchboard/store"
"chat-switchboard/models"
"chat-switchboard/store"
)
// UsageHandler manages usage tracking and pricing endpoints.

View File

@@ -22,7 +22,7 @@ import (
"github.com/gin-gonic/gin"
"git.gobha.me/xcaliber/chat-switchboard/store"
"chat-switchboard/store"
)
// allowedNonGlobalPermissions is the set of permissions that non-admin

View File

@@ -11,9 +11,9 @@ import (
"github.com/gin-gonic/gin"
"git.gobha.me/xcaliber/chat-switchboard/events"
"git.gobha.me/xcaliber/chat-switchboard/notifications"
"git.gobha.me/xcaliber/chat-switchboard/store"
"chat-switchboard/events"
"chat-switchboard/notifications"
"chat-switchboard/store"
)
// ── Workflow Assignment Handler ─────────────
@@ -93,7 +93,7 @@ func (h *WorkflowAssignmentHandler) Claim(c *gin.Context) {
}
pids, _ := h.stores.Channels.ListUserParticipantIDs(c.Request.Context(), channelID, "")
for _, uid := range pids {
h.hub.SendToUser(uid, evt)
h.hub.PublishToUser(uid, evt)
}
}

View File

@@ -1,15 +1,14 @@
package handlers
import (
"context"
"fmt"
"log"
"net/http"
"github.com/gin-gonic/gin"
"git.gobha.me/xcaliber/chat-switchboard/models"
"git.gobha.me/xcaliber/chat-switchboard/store"
"chat-switchboard/models"
"chat-switchboard/store"
)
// ── Workflow Entry Handler ──────────────────
@@ -24,24 +23,6 @@ func NewWorkflowEntryHandler(stores store.Stores) *WorkflowEntryHandler {
return &WorkflowEntryHandler{stores: stores}
}
// resolveTeamScope converts a URL scope parameter to a team ID.
// Accepts "global" (returns nil), a UUID (passed through), or a team slug (looked up).
func resolveTeamScope(ctx context.Context, teams store.TeamStore, scope string) *string {
if scope == "global" {
return nil
}
// UUID format: 36 chars with dashes at 8,13,18,23
if len(scope) == 36 && scope[8] == '-' && scope[13] == '-' {
return &scope
}
// Try team slug lookup
t, err := teams.GetBySlug(ctx, scope)
if err == nil && t != nil {
return &t.ID
}
return &scope // fall through — will 404 downstream
}
// StartVisitor creates an anonymous session + workflow instance for a visitor.
// POST /api/v1/workflow-entry/:scope/:slug
func (h *WorkflowEntryHandler) StartVisitor(c *gin.Context) {
@@ -49,7 +30,10 @@ func (h *WorkflowEntryHandler) StartVisitor(c *gin.Context) {
scope := c.Param("scope")
slug := c.Param("slug")
teamID := resolveTeamScope(ctx, h.stores.Teams, scope)
var teamID *string
if scope != "global" {
teamID = &scope
}
wf, err := h.stores.Workflows.GetBySlug(ctx, teamID, slug)
if err != nil || wf == nil {

View File

@@ -8,11 +8,11 @@ import (
"github.com/gin-gonic/gin"
"git.gobha.me/xcaliber/chat-switchboard/events"
"git.gobha.me/xcaliber/chat-switchboard/models"
"git.gobha.me/xcaliber/chat-switchboard/sandbox"
"git.gobha.me/xcaliber/chat-switchboard/store"
"git.gobha.me/xcaliber/chat-switchboard/tools"
"chat-switchboard/events"
"chat-switchboard/models"
"chat-switchboard/sandbox"
"chat-switchboard/store"
"chat-switchboard/tools"
"go.starlark.net/starlark"
)
@@ -241,7 +241,7 @@ func (h *WorkflowFormHandler) emitFormEvent(channelID, label string, stage int)
}
evt := events.Event{Label: label, Payload: payload}
for _, uid := range pids {
h.hub.SendToUser(uid, evt)
h.hub.PublishToUser(uid, evt)
}
}

View File

@@ -8,13 +8,13 @@ import (
"github.com/gin-gonic/gin"
"git.gobha.me/xcaliber/chat-switchboard/config"
authpkg "git.gobha.me/xcaliber/chat-switchboard/auth"
"git.gobha.me/xcaliber/chat-switchboard/database"
"git.gobha.me/xcaliber/chat-switchboard/middleware"
"git.gobha.me/xcaliber/chat-switchboard/store"
postgres "git.gobha.me/xcaliber/chat-switchboard/store/postgres"
sqlite "git.gobha.me/xcaliber/chat-switchboard/store/sqlite"
"chat-switchboard/config"
authpkg "chat-switchboard/auth"
"chat-switchboard/database"
"chat-switchboard/middleware"
"chat-switchboard/store"
postgres "chat-switchboard/store/postgres"
sqlite "chat-switchboard/store/sqlite"
)
// ═══════════════════════════════════════════════════════════

View File

@@ -10,11 +10,11 @@ import (
"github.com/gin-gonic/gin"
"git.gobha.me/xcaliber/chat-switchboard/events"
"git.gobha.me/xcaliber/chat-switchboard/models"
"git.gobha.me/xcaliber/chat-switchboard/notifications"
"git.gobha.me/xcaliber/chat-switchboard/store"
"git.gobha.me/xcaliber/chat-switchboard/tools"
"chat-switchboard/events"
"chat-switchboard/models"
"chat-switchboard/notifications"
"chat-switchboard/store"
"chat-switchboard/tools"
)
// ── Workflow Instance Handler ───────────────
@@ -298,7 +298,7 @@ func (h *WorkflowInstanceHandler) readWorkflowState(ctx context.Context, channel
}
// emitWorkflowEvent pushes a workflow event to all user participants in the channel.
// Uses SendToUser (not room-scoped Bus.Publish) because room subscriptions are
// Uses PublishToUser (not room-scoped Bus.Publish) because room subscriptions are
// not yet wired on the client side. See websocket.md § Room Model.
func (h *WorkflowInstanceHandler) emitWorkflowEvent(label, channelID string, data map[string]any) {
if h.hub == nil {
@@ -318,7 +318,7 @@ func (h *WorkflowInstanceHandler) emitWorkflowEvent(label, channelID string, dat
return
}
for _, uid := range pids {
h.hub.SendToUser(uid, evt)
h.hub.PublishToUser(uid, evt)
}
}
@@ -398,7 +398,7 @@ func (h *WorkflowInstanceHandler) notifyAssignment(ctx context.Context, teamID,
"stage_name": stageName, "assigned_to": assignedTo,
})
for _, m := range members {
h.hub.SendToUser(m.UserID, events.Event{
h.hub.PublishToUser(m.UserID, events.Event{
Label: "workflow.assigned",
Payload: payload,
Ts: time.Now().UnixMilli(),

View File

@@ -15,8 +15,8 @@ import (
"github.com/gin-gonic/gin"
"git.gobha.me/xcaliber/chat-switchboard/models"
"git.gobha.me/xcaliber/chat-switchboard/store"
"chat-switchboard/models"
"chat-switchboard/store"
)
// WorkflowPackageHandler handles workflow package export and install.

View File

@@ -6,7 +6,7 @@ import (
"github.com/gin-gonic/gin"
"git.gobha.me/xcaliber/chat-switchboard/models"
"chat-switchboard/models"
)
// ── Team-Scoped Workflow Wrappers (v0.31.2) ────────────────

View File

@@ -7,13 +7,13 @@ import (
"github.com/gin-gonic/gin"
"git.gobha.me/xcaliber/chat-switchboard/config"
authpkg "git.gobha.me/xcaliber/chat-switchboard/auth"
"git.gobha.me/xcaliber/chat-switchboard/database"
"git.gobha.me/xcaliber/chat-switchboard/middleware"
"git.gobha.me/xcaliber/chat-switchboard/store"
postgres "git.gobha.me/xcaliber/chat-switchboard/store/postgres"
sqlite "git.gobha.me/xcaliber/chat-switchboard/store/sqlite"
"chat-switchboard/config"
authpkg "chat-switchboard/auth"
"chat-switchboard/database"
"chat-switchboard/middleware"
"chat-switchboard/store"
postgres "chat-switchboard/store/postgres"
sqlite "chat-switchboard/store/sqlite"
)
// TestWorkflowCRUD exercises the full workflow lifecycle:

View File

@@ -10,8 +10,8 @@ import (
"github.com/gin-gonic/gin"
"git.gobha.me/xcaliber/chat-switchboard/models"
"git.gobha.me/xcaliber/chat-switchboard/store"
"chat-switchboard/models"
"chat-switchboard/store"
)
// ── Workflow Handler ────────────────────────
@@ -106,10 +106,10 @@ func (h *WorkflowHandler) Create(c *gin.Context) {
w.CreatedBy = c.GetString("user_id")
// v0.31.2: Team-scoped workflow creation (set by CreateTeamWorkflow)
if forceTeam, ok := c.Get("force_team_id"); ok {
teamID := forceTeam.(string)
w.TeamID = &teamID
// v0.31.2: team-scoped route injects force_team_id via CreateTeamWorkflow
if ftid, ok := c.Get("force_team_id"); ok {
tid := ftid.(string)
w.TeamID = &tid
}
if err := h.stores.Workflows.Create(c.Request.Context(), &w); err != nil {

View File

@@ -8,13 +8,13 @@ import (
"github.com/gin-gonic/gin"
"git.gobha.me/xcaliber/chat-switchboard/config"
"git.gobha.me/xcaliber/chat-switchboard/database"
"git.gobha.me/xcaliber/chat-switchboard/middleware"
"git.gobha.me/xcaliber/chat-switchboard/models"
"git.gobha.me/xcaliber/chat-switchboard/store"
postgres "git.gobha.me/xcaliber/chat-switchboard/store/postgres"
sqlite "git.gobha.me/xcaliber/chat-switchboard/store/sqlite"
"chat-switchboard/config"
"chat-switchboard/database"
"chat-switchboard/middleware"
"chat-switchboard/models"
"chat-switchboard/store"
postgres "chat-switchboard/store/postgres"
sqlite "chat-switchboard/store/sqlite"
)
// ── Workspace Test Harness ────────────────

View File

@@ -12,9 +12,9 @@ import (
"github.com/gin-gonic/gin"
"git.gobha.me/xcaliber/chat-switchboard/models"
"git.gobha.me/xcaliber/chat-switchboard/store"
"git.gobha.me/xcaliber/chat-switchboard/workspace"
"chat-switchboard/models"
"chat-switchboard/store"
"chat-switchboard/workspace"
)
// ── Request Types ───────────────────────────