feedbackapi

package
v1.118.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 1, 2026 License: Apache-2.0 Imports: 20 Imported by: 0

Documentation

Overview

Package feedbackapi holds the portal's feedback surface: threads and their events, the activity feed, the practitioner and SME worklists, asset and collection sign-off, validation responses, and capturing a thread as an insight.

These routes are one family. They share a target model (a thread hangs off an asset, a collection, a prompt, a knowledge page, or nothing), one set of visibility rules over those targets, and one target-gathering policy that the worklist and the activity feed both read. Splitting them apart would fork that policy; leaving them in pkg/portal kept that package at its size ceiling.

The seam owns no policy of its own: every permission decision goes through the shared authorization core in internal/portal/access, which pkg/portal builds once and hands over, so a check cannot mean one thing here and another in the parent.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func KeepAnyShare

func KeepAnyShare(portaldomain.SharePermission) bool

KeepAnyShare keeps shares at any permission.

func KeepEditorShares

func KeepEditorShares(p portaldomain.SharePermission) bool

KeepEditorShares keeps only editor-permission shares.

Types

type ChangesetReader

type ChangesetReader interface {
	ListChangesets(ctx context.Context, filter knowledge.ChangesetFilter) ([]knowledge.Changeset, int, error)
}

ChangesetReader provides read access to knowledge changesets, used to surface the thread -> insight -> changeset chain on a feedback thread.

type Config

type Config struct {
	Threads        threads.ThreadStore
	Assets         portaldomain.AssetStore
	Collections    portaldomain.CollectionStore
	Shares         portaldomain.ShareStore
	Prompts        prompt.Store
	KnowledgePages knowledgepage.Store
	Changesets     ChangesetReader
	MemoryWriter   MemoryWriter
	Mentions       MentionResolver
	Notifier       ThreadNotifier
	// Access is the portal's authorization core, built by the parent so this
	// surface and the routes that stayed behind answer permission questions
	// the same way.
	Access *access.Checker
	// PersonaName resolves a caller's roles to their persona name, the value
	// stamped on a captured insight. nil yields no persona.
	PersonaName func(roles []string) string
}

Config carries everything the feedback routes need. A nil store disables the routes that require it rather than failing them at request time, except where the handler reports the capability as unconfigured (503).

type Handler

type Handler struct {
	// contains filtered or unexported fields
}

Handler serves the portal's feedback routes.

func New

func New(cfg Config) *Handler

New returns a Handler over cfg.

func (*Handler) Register

func (h *Handler) Register(mux *http.ServeMux)

Register wires the feedback routes onto mux. Threads require a thread store; with none configured the surface registers nothing, which is what a portal running without a database expects.

func (*Handler) RegisterInsightCapture

func (h *Handler) RegisterInsightCapture(mux *http.ServeMux)

RegisterInsightCapture wires the "capture feedback as an insight" route. It is separate from Register because it needs a memory writer as well as a thread store, the same pair the route required before the split.

type MemoryWriter

type MemoryWriter interface {
	Insert(ctx context.Context, record memory.Record) error
}

MemoryWriter inserts memory records. It backs the "capture feedback as an insight" path: a reviewer turns a feedback thread into a pending, knowledge-dimension memory record that enters the apply_knowledge review queue.

type MentionResolver

type MentionResolver interface {
	ResolveMentions(ctx context.Context, targetType, targetID, body, author string) []string
}

MentionResolver returns the addresses a comment body delivers an @-mention to on a thread target: the names written in the body, minus the author's own address, filtered to the people who can open that target. A nil resolver disables mentions (no database), leaving every token ordinary text.

type ShareKeep

type ShareKeep func(portaldomain.SharePermission) bool

ShareKeep decides whether a share grant counts toward a gathered target set. KeepEditorShares is the "I can act on it" scope (worklist, MCP agent); KeepAnyShare is the "I can view it" scope (activity feed).

type TargetGatherer

type TargetGatherer struct {
	Assets      portaldomain.AssetStore
	Collections portaldomain.CollectionStore
	Shares      portaldomain.ShareStore
	UserID      string
	Email       string
}

TargetGatherer gathers the asset/collection ids a single user can reach, bundling the stores and identity so callers (REST worklist/activity feed, the manage_feedback MCP tool) build it once and ask for asset or collection ids with the desired share scope.

func (TargetGatherer) AssetIDs

func (g TargetGatherer) AssetIDs(ctx context.Context, keep ShareKeep) ([]string, error)

AssetIDs returns the ids of assets the user owns plus shared assets whose permission satisfies keep.

func (TargetGatherer) CollectionIDs

func (g TargetGatherer) CollectionIDs(ctx context.Context, keep ShareKeep) ([]string, error)

CollectionIDs returns the ids of collections the user owns plus shared collections whose permission satisfies keep.

type ThreadNotifier

type ThreadNotifier interface {
	// NotifyThreadEvent fires after a successful thread create or event
	// append. thread carries the target reference; body is the comment text;
	// mentioned carries the @-mentions the body delivers, already filtered to
	// people who can open the target.
	NotifyThreadEvent(ctx context.Context, thread *threads.Thread, actorEmail, body string, mentioned []string)
}

ThreadNotifier receives the thread half of the portal's notification triggers. It is the narrow view of the platform notifier this surface needs; the share half stays with the routes that create shares. A nil notifier disables thread notifications.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL