feat: sidebar nav (default), group member management, per-customer ticketing identity mapping

- Navigation: new per-user setting (default "side") renders the page links as a
  left sidebar while keeping theme/bell/avatar/logout in the top-right; falls
  back to a top bar under 760px or when set to "top". Profile selector added.
- Group conversations: record a creatorId; the creator gets a "Manage members"
  button to add/remove participants (new GET/POST/DELETE members endpoints,
  creator-only). Existing groups backfilled.
- Customer ticketing: admin can map each assigned consultant to their username
  in that customer's ticketing system. Per-customer mapping takes precedence
  over the consultant's global ticketingIdentities during sync.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
etalon
2026-06-13 11:05:33 +02:00
parent 0d28f69320
commit e8beb7d4f3
16 changed files with 367 additions and 19 deletions
+8 -3
View File
@@ -28,9 +28,14 @@ type Ticketing struct {
CredentialsEnc string `bson:"credentialsEnc" json:"-"`
ProjectKey string `bson:"projectKey" json:"projectKey"`
PollIntervalSec int `bson:"pollIntervalSec" json:"pollIntervalSec"`
LastSyncAt time.Time `bson:"lastSyncAt" json:"lastSyncAt"`
LastSyncStatus string `bson:"lastSyncStatus" json:"lastSyncStatus"` // "", ok, error
LastSyncError string `bson:"lastSyncError" json:"lastSyncError"`
// ConsultantIdentities maps a bounty-board consultant id to that
// consultant's username in THIS customer's ticketing system. It takes
// precedence over the consultant's global extra.ticketingIdentities so an
// admin can map accounts per project (§5.3).
ConsultantIdentities map[string]string `bson:"consultantIdentities,omitempty" json:"consultantIdentities,omitempty"`
LastSyncAt time.Time `bson:"lastSyncAt" json:"lastSyncAt"`
LastSyncStatus string `bson:"lastSyncStatus" json:"lastSyncStatus"` // "", ok, error
LastSyncError string `bson:"lastSyncError" json:"lastSyncError"`
}
// Customer == "project" in the UI (§4.2).
+1
View File
@@ -54,6 +54,7 @@ type NotificationPrefs struct {
type UserSettings struct {
Theme string `bson:"theme" json:"theme"`
NavLayout string `bson:"navLayout" json:"navLayout"` // "side" (default) | "top"
Notifications NotificationPrefs `bson:"notifications" json:"notifications"`
LeaderboardOptOut bool `bson:"leaderboardOptOut" json:"leaderboardOptOut"`
}