feature: move docs

This commit is contained in:
2026-07-27 11:52:13 -04:00
parent ae0939177c
commit 03c06c0dd9
20 changed files with 607 additions and 35 deletions

View File

@@ -53,6 +53,7 @@ type UserLookup interface {
}
type DocumentReadAuthorizer func(ctx context.Context, userID, documentID string) (bool, error)
type DocumentResolver func(ctx context.Context, documentID string) (path, title string, err error)
type NoOpEmailSender struct{}
@@ -68,6 +69,7 @@ type Service struct {
renderer EmailRenderer
users UserLookup
canReadDocument DocumentReadAuthorizer
resolveDocument DocumentResolver
hub *realtime.Hub
logger *slog.Logger
publicOrigin string
@@ -79,6 +81,7 @@ type Options struct {
EmailRenderer EmailRenderer
UserLookup UserLookup
CanReadDocument DocumentReadAuthorizer
ResolveDocument DocumentResolver
PublicOrigin string
}
@@ -101,6 +104,7 @@ func NewServiceWithOptions(repo *Repository, hub *realtime.Hub, logger *slog.Log
renderer: opts.EmailRenderer,
users: opts.UserLookup,
canReadDocument: opts.CanReadDocument,
resolveDocument: opts.ResolveDocument,
hub: hub,
logger: logger,
publicOrigin: opts.PublicOrigin,
@@ -345,7 +349,7 @@ func (s *Service) NotifyDocumentChanged(ctx context.Context, documentID string,
s.enqueueNotificationEmail(ctx, notification.ID, w.UserID, "file_changed", EmailData{
ActorName: actorName,
DocumentPath: documentPath,
ViewURL: s.documentURL(documentPath),
ViewURL: s.documentIDURL(documentID),
})
}
@@ -361,6 +365,18 @@ func (s *Service) notifyWatchersOfComment(ctx context.Context, comment Comment)
return err
}
documentPath := documentPathFromID(comment.DocumentID) + ".md"
documentTitle := ""
if s.resolveDocument != nil {
resolvedPath, resolvedTitle, err := s.resolveDocument(ctx, comment.DocumentID)
if err != nil {
s.logger.Warn("resolve comment document", "document_id", comment.DocumentID, "error", err)
} else {
documentPath = resolvedPath
documentTitle = resolvedTitle
}
}
seen := make(map[string]bool)
for _, w := range watchers {
if w.UserID == comment.AuthorID {
@@ -391,10 +407,11 @@ func (s *Service) notifyWatchersOfComment(ctx context.Context, comment Comment)
continue
}
s.enqueueNotificationEmail(ctx, notification.ID, w.UserID, "comment", EmailData{
ActorName: comment.AuthorName,
DocumentPath: documentPathFromID(comment.DocumentID) + ".md",
CommentBody: comment.Content,
ViewURL: s.documentURL(comment.DocumentID),
ActorName: comment.AuthorName,
DocumentPath: documentPath,
DocumentTitle: documentTitle,
CommentBody: comment.Content,
ViewURL: s.documentIDURL(comment.DocumentID),
})
}
return nil
@@ -428,17 +445,11 @@ func (s *Service) enqueueNotificationEmail(ctx context.Context, notificationID,
}
}
func (s *Service) documentURL(documentPath string) string {
func (s *Service) documentIDURL(documentID string) string {
if s.publicOrigin == "" {
return ""
}
clean := strings.TrimPrefix(documentPath, "doc:")
clean = strings.TrimSuffix(strings.TrimPrefix(clean, "/"), ".md")
parts := strings.Split(clean, "/")
for i, part := range parts {
parts[i] = url.PathEscape(part)
}
return strings.TrimRight(s.publicOrigin, "/") + "/docs/" + strings.Join(parts, "/")
return strings.TrimRight(s.publicOrigin, "/") + "/documents/" + url.PathEscape(documentID)
}
func (s *Service) watcherCanRead(ctx context.Context, userID, documentID string) bool {