Changeset 0.23.2 (#155)
This commit is contained in:
@@ -333,6 +333,14 @@ func (h *AdminHandler) PublicSettings(c *gin.Context) {
|
||||
hasAdminPrompt = true
|
||||
}
|
||||
|
||||
// Channel retention mode (v0.23.2 — flexible or retain)
|
||||
retentionMode := "flexible"
|
||||
if retCfg, err := h.stores.GlobalConfig.Get(c.Request.Context(), "channel_retention"); err == nil {
|
||||
if mode, ok := retCfg["mode"].(string); ok && mode != "" {
|
||||
retentionMode = mode
|
||||
}
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"banner": banner,
|
||||
"branding": branding,
|
||||
@@ -340,9 +348,10 @@ func (h *AdminHandler) PublicSettings(c *gin.Context) {
|
||||
"storage_configured": storageConfigured,
|
||||
"paste_to_file_chars": pasteChars,
|
||||
"policies": gin.H{
|
||||
"allow_registration": policies["allow_registration"],
|
||||
"allow_user_byok": policies["allow_user_byok"],
|
||||
"allow_user_personas": policies["allow_user_personas"],
|
||||
"allow_registration": policies["allow_registration"],
|
||||
"allow_user_byok": policies["allow_user_byok"],
|
||||
"allow_user_personas": policies["allow_user_personas"],
|
||||
"channel_retention_mode": retentionMode,
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -724,3 +733,88 @@ func (h *AdminHandler) auditLog(c *gin.Context, action, resourceType, resourceID
|
||||
log.Printf("audit log error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// ── Archived Channels (v0.23.2) ──────────────
|
||||
|
||||
func (h *AdminHandler) ListArchivedChannels(c *gin.Context) {
|
||||
rows, err := database.DB.QueryContext(c.Request.Context(), database.Q(`
|
||||
SELECT c.id, c.title, c.type, c.user_id,
|
||||
COALESCE(u.username, '') AS owner_name,
|
||||
c.updated_at,
|
||||
(SELECT COUNT(*) FROM messages WHERE channel_id = c.id) AS message_count
|
||||
FROM channels c
|
||||
LEFT JOIN users u ON u.id = c.user_id
|
||||
WHERE c.is_archived = true
|
||||
ORDER BY c.updated_at DESC
|
||||
LIMIT 100
|
||||
`))
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "query failed"})
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
type archivedChannel struct {
|
||||
ID string `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Type string `json:"type"`
|
||||
OwnerName string `json:"owner_name"`
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
MessageCount int `json:"message_count"`
|
||||
}
|
||||
|
||||
channels := []archivedChannel{}
|
||||
for rows.Next() {
|
||||
var ch archivedChannel
|
||||
var userID string
|
||||
if rows.Scan(&ch.ID, &ch.Title, &ch.Type, &userID, &ch.OwnerName, &ch.UpdatedAt, &ch.MessageCount) == nil {
|
||||
channels = append(channels, ch)
|
||||
}
|
||||
}
|
||||
|
||||
// Retention config
|
||||
retentionMode := "flexible"
|
||||
if retCfg, err := h.stores.GlobalConfig.Get(c.Request.Context(), "channel_retention"); err == nil {
|
||||
if mode, ok := retCfg["mode"].(string); ok {
|
||||
retentionMode = mode
|
||||
}
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"channels": channels,
|
||||
"retention_mode": retentionMode,
|
||||
})
|
||||
}
|
||||
|
||||
func (h *AdminHandler) PurgeChannel(c *gin.Context) {
|
||||
channelID := c.Param("id")
|
||||
|
||||
// Verify the channel is actually archived
|
||||
var isArchived bool
|
||||
err := database.DB.QueryRowContext(c.Request.Context(), database.Q(`
|
||||
SELECT is_archived FROM channels WHERE id = $1
|
||||
`), channelID).Scan(&isArchived)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "channel not found"})
|
||||
return
|
||||
}
|
||||
if !isArchived {
|
||||
c.JSON(http.StatusConflict, gin.H{"error": "channel must be archived before purging"})
|
||||
return
|
||||
}
|
||||
|
||||
// Hard delete (CASCADE removes messages, participants, models)
|
||||
_, err = database.DB.ExecContext(c.Request.Context(), database.Q(`
|
||||
DELETE FROM channels WHERE id = $1
|
||||
`), channelID)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "purge failed"})
|
||||
return
|
||||
}
|
||||
|
||||
// Audit log
|
||||
uid := getUserID(c)
|
||||
h.auditLog(c, uid, "channel.purged", "channel", channelID)
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"ok": true})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user