MindSift CI & Docker Release / Build, Test in Container & Push (push) Failing after 16s
237 lines
7.8 KiB
Go
237 lines
7.8 KiB
Go
package domain
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"regexp"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
// NewID generates a readable prefixed ID as specified in BRAIN.md (e.g. th_4x8z19a0b1)
|
|
func NewID(prefix string) string {
|
|
b := make([]byte, 5)
|
|
_, _ = rand.Read(b)
|
|
return fmt.Sprintf("%s_%s", prefix, hex.EncodeToString(b))
|
|
}
|
|
|
|
// NowISO returns the current UTC timestamp in ISO-8601 format
|
|
func NowISO() string {
|
|
return time.Now().UTC().Format(time.RFC3339)
|
|
}
|
|
|
|
var hashtagRegex = regexp.MustCompile(`#([a-zA-Z0-9äöüÄÖÜß_-]+)`)
|
|
|
|
// ExtractTags extracts #hashtags from content
|
|
func ExtractTags(content string) []string {
|
|
matches := hashtagRegex.FindAllStringSubmatch(content, -1)
|
|
seen := make(map[string]bool)
|
|
tags := make([]string, 0, len(matches))
|
|
for _, m := range matches {
|
|
if len(m) > 1 {
|
|
tag := strings.ToLower(m[1])
|
|
if !seen[tag] {
|
|
seen[tag] = true
|
|
tags = append(tags, tag)
|
|
}
|
|
}
|
|
}
|
|
return tags
|
|
}
|
|
|
|
type User struct {
|
|
ID string `json:"id"`
|
|
Email string `json:"email"`
|
|
PasswordHash string `json:"-"`
|
|
DisplayName string `json:"displayName"`
|
|
Role string `json:"role"` // admin | member
|
|
IsActive bool `json:"isActive"`
|
|
DiscordWebhookURL string `json:"discordWebhookUrl"`
|
|
NotifyBeforeMinutes int `json:"notifyBeforeMinutes"`
|
|
CreatedAt string `json:"createdAt"`
|
|
}
|
|
|
|
type ThoughtStatus string
|
|
|
|
const (
|
|
StatusInbox ThoughtStatus = "inbox"
|
|
StatusKept ThoughtStatus = "kept"
|
|
StatusDiscarded ThoughtStatus = "discarded"
|
|
StatusConverted ThoughtStatus = "converted"
|
|
)
|
|
|
|
type Thought struct {
|
|
ID string `json:"id"`
|
|
UserID string `json:"userId"`
|
|
Content string `json:"content"`
|
|
Tags []string `json:"tags"`
|
|
Priority string `json:"priority"` // low | normal | high | urgent
|
|
Source string `json:"source"` // manual | voice | webhook
|
|
Status ThoughtStatus `json:"status"`
|
|
IsCompleted bool `json:"isCompleted"`
|
|
ConvertedType string `json:"convertedType,omitempty"` // task | document | list_item
|
|
ConvertedRefID string `json:"convertedRefId,omitempty"` // referenced entity ID
|
|
DueDate string `json:"dueDate,omitempty"`
|
|
TaskListID string `json:"taskListId,omitempty"`
|
|
KanbanStatus string `json:"kanbanStatus,omitempty"` // todo | in_progress | done
|
|
Notes string `json:"notes,omitempty"`
|
|
AlarmSent bool `json:"alarmSent,omitempty"`
|
|
CreatedAt string `json:"createdAt"`
|
|
TriagedAt string `json:"triagedAt,omitempty"`
|
|
}
|
|
|
|
type TaskList struct {
|
|
ID string `json:"id"`
|
|
UserID string `json:"userId"`
|
|
SpaceID string `json:"spaceId,omitempty"`
|
|
Title string `json:"title"`
|
|
Icon string `json:"icon"`
|
|
Color string `json:"color"`
|
|
TasksCount int `json:"tasksCount,omitempty"`
|
|
CreatedAt string `json:"createdAt"`
|
|
UpdatedAt string `json:"updatedAt"`
|
|
}
|
|
|
|
type Organization struct {
|
|
ID string `json:"id"`
|
|
Name string `json:"name"`
|
|
OwnerID string `json:"ownerId"`
|
|
CreatedAt string `json:"createdAt"`
|
|
}
|
|
|
|
type Team struct {
|
|
ID string `json:"id"`
|
|
OrgID string `json:"orgId"`
|
|
Name string `json:"name"`
|
|
Description string `json:"description"`
|
|
Members []TeamMember `json:"members,omitempty"`
|
|
CreatedAt string `json:"createdAt"`
|
|
}
|
|
|
|
type TeamMember struct {
|
|
TeamID string `json:"teamId"`
|
|
UserID string `json:"userId"`
|
|
DisplayName string `json:"displayName"`
|
|
Email string `json:"email"`
|
|
Role string `json:"role"` // owner | editor | viewer
|
|
JoinedAt string `json:"joinedAt"`
|
|
}
|
|
|
|
type SystemSettings struct {
|
|
SharingMode string `json:"sharingMode"` // open | teams_only | strict_private
|
|
AllowRegistration bool `json:"allowRegistration"`
|
|
InstanceName string `json:"instanceName"`
|
|
}
|
|
|
|
type DocumentBlock struct {
|
|
ID string `json:"id"`
|
|
Type string `json:"type"` // h1 | h2 | h3 | paragraph | todo | bullet | code | callout | divider | table | progress
|
|
Content string `json:"content"`
|
|
Checked bool `json:"checked,omitempty"`
|
|
Lang string `json:"lang,omitempty"`
|
|
}
|
|
|
|
type Document struct {
|
|
ID string `json:"id"`
|
|
UserID string `json:"userId"`
|
|
SpaceID string `json:"spaceId,omitempty"`
|
|
Title string `json:"title"`
|
|
Icon string `json:"icon"`
|
|
Content string `json:"content"`
|
|
Blocks []DocumentBlock `json:"blocks"`
|
|
Tags []string `json:"tags"`
|
|
FolderPath string `json:"folderPath,omitempty"`
|
|
IsPinned bool `json:"isPinned"`
|
|
IsArchived bool `json:"isArchived"`
|
|
CreatedAt string `json:"createdAt"`
|
|
UpdatedAt string `json:"updatedAt"`
|
|
}
|
|
|
|
type SpaceMember struct {
|
|
SpaceID string `json:"spaceId"`
|
|
UserID string `json:"userId"`
|
|
DisplayName string `json:"displayName"`
|
|
Email string `json:"email"`
|
|
Role string `json:"role"` // owner | editor | viewer
|
|
JoinedAt string `json:"joinedAt"`
|
|
}
|
|
|
|
type Space struct {
|
|
ID string `json:"id"`
|
|
Name string `json:"name"`
|
|
Icon string `json:"icon"`
|
|
Description string `json:"description"`
|
|
InviteCode string `json:"inviteCode"`
|
|
IsPersonal bool `json:"isPersonal"`
|
|
OwnerID string `json:"ownerId"`
|
|
Members []SpaceMember `json:"members,omitempty"`
|
|
ListsCount int `json:"listsCount"`
|
|
CreatedAt string `json:"createdAt"`
|
|
}
|
|
|
|
type ListItem struct {
|
|
ID string `json:"id"`
|
|
ListID string `json:"listId"`
|
|
Content string `json:"content"`
|
|
Category string `json:"category,omitempty"`
|
|
Quantity string `json:"quantity,omitempty"`
|
|
IsCompleted bool `json:"isCompleted"`
|
|
CompletedBy string `json:"completedBy,omitempty"`
|
|
CompletedByName string `json:"completedByName,omitempty"`
|
|
SortOrder int `json:"sortOrder"`
|
|
CreatedAt string `json:"createdAt"`
|
|
CompletedAt string `json:"completedAt,omitempty"`
|
|
}
|
|
|
|
type SharedList struct {
|
|
ID string `json:"id"`
|
|
SpaceID string `json:"spaceId"`
|
|
Title string `json:"title"`
|
|
Icon string `json:"icon"`
|
|
ListType string `json:"listType"` // shopping | checklist | vacation
|
|
Items []ListItem `json:"items"`
|
|
UpdatedAt string `json:"updatedAt"`
|
|
CreatedAt string `json:"createdAt"`
|
|
}
|
|
|
|
type APIKey struct {
|
|
ID string `json:"id"`
|
|
UserID string `json:"userId"`
|
|
Name string `json:"name"`
|
|
KeyPrefix string `json:"keyPrefix"`
|
|
KeyHash string `json:"-"`
|
|
RawKey string `json:"rawKey,omitempty"` // Only returned once on creation
|
|
Scopes string `json:"scopes"`
|
|
LastUsedAt string `json:"lastUsedAt,omitempty"`
|
|
CreatedAt string `json:"createdAt"`
|
|
}
|
|
|
|
type WSMessage struct {
|
|
Event string `json:"event"` // ITEM_CREATED | ITEM_UPDATED | ITEM_TOGGLED | ITEM_DELETED | LIST_CLEARED | USER_PRESENCE
|
|
SpaceID string `json:"space_id"`
|
|
ListID string `json:"list_id,omitempty"`
|
|
Payload interface{} `json:"payload"`
|
|
Timestamp string `json:"timestamp"`
|
|
}
|
|
|
|
type DashboardStats struct {
|
|
InboxCount int `json:"inboxCount"`
|
|
TasksOpenCount int `json:"tasksOpenCount"`
|
|
TasksDoneCount int `json:"tasksDoneCount"`
|
|
DocsCount int `json:"docsCount"`
|
|
ListsCount int `json:"listsCount"`
|
|
DiscardedCount int `json:"discardedCount"`
|
|
}
|
|
|
|
type FullExport struct {
|
|
ExportedAt string `json:"exportedAt"`
|
|
Version string `json:"version"`
|
|
User User `json:"user"`
|
|
Thoughts []Thought `json:"thoughts"`
|
|
Documents []Document `json:"documents"`
|
|
Spaces []Space `json:"spaces"`
|
|
Lists []SharedList `json:"lists"`
|
|
TaskLists []TaskList `json:"taskLists,omitempty"`
|
|
}
|