handlers

package
v0.6.0 Latest Latest
Warning

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

Go to latest
Published: Jul 19, 2026 License: MIT Imports: 35 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type APIKeyHandler

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

APIKeyHandler handles browser-realm API key lifecycle endpoints.

func NewAPIKeyHandler

func NewAPIKeyHandler(
	apiKeyService APIKeyService,
	logger *util.Logger,
) *APIKeyHandler

NewAPIKeyHandler constructs a new APIKeyHandler.

func (*APIKeyHandler) CreateAPIKey

func (h *APIKeyHandler) CreateAPIKey(w http.ResponseWriter, r *http.Request)

CreateAPIKey handles POST /api/admin/api-keys.

func (*APIKeyHandler) ListAPIKeys

func (h *APIKeyHandler) ListAPIKeys(w http.ResponseWriter, r *http.Request)

ListAPIKeys handles GET /api/admin/api-keys. Returns the caller's keys as masked list entries (prefix + metadata only). The secret, key_hash, and last_used_ip are NEVER included in the response.

func (*APIKeyHandler) RevokeAPIKey

func (h *APIKeyHandler) RevokeAPIKey(w http.ResponseWriter, r *http.Request)

RevokeAPIKey handles DELETE /api/admin/api-keys/:id. Soft-deletes the key (sets revoked_at). Idempotent: revoking an already-revoked key returns 200. Cross-user or nonexistent ids return 404 NOT_FOUND (identical response — no cross-user disclosure).

type APIKeyListItem

type APIKeyListItem struct {
	ID         int        `json:"id"`
	Name       string     `json:"name"`
	Prefix     string     `json:"prefix"`
	CreatedAt  time.Time  `json:"createdAt"`
	LastUsedAt *time.Time `json:"lastUsedAt"`
	ExpiresAt  *time.Time `json:"expiresAt"`
	RevokedAt  *time.Time `json:"revokedAt"`
}

APIKeyListItem is a safe (masked) list entry. It MUST NOT contain keyHash, the secret, or lastUsedIp (privacy-sensitive). Prefix is the masked display form "lesstruct_<keyID>••••" produced via apikey.DisplayPrefix.

type APIKeyService

type APIKeyService interface {
	// Existing (Story 1.1):
	Create(ctx context.Context, userID int, name string) (string, *apikey.APIKey, error)
	// New (Story 1.2):
	List(ctx context.Context, userID int) ([]*apikey.APIKey, error)
	Revoke(ctx context.Context, id, userID int) (*apikey.APIKey, error)
}

APIKeyService is the narrow interface the handler depends on (avoids hard-coupling to *apikey.Service; mirrors the dashboard ServiceInterface pattern).

type ApproveUserResponse

type ApproveUserResponse struct {
	Message string      `json:"message"`
	User    *UserDetail `json:"user"`
}

ApproveUserResponse represents the response for approve user

type AuthHandler

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

AuthHandler handles authentication HTTP requests

func NewAuthHandler

func NewAuthHandler(
	authService *authdomain.AuthService,
	jwtManager *auth.JWTManager,
	logger *util.Logger,
	firstLoginService *authdomain.FirstLoginService,
	registrationService *authdomain.RegistrationService,
	verificationService *authdomain.VerificationService,
	loginService *authdomain.LoginService,
	passwordResetService *authdomain.PasswordResetService,
	userRepo repository.UserRepo,
	failedLoginRepo repository.FailedLoginAttemptRepo,
	notificationRepo repository.NotificationRepo,
	emailService email.EmailService,
	blockedEmailRepo repository.BlockedEmailRepo,
) *AuthHandler

NewAuthHandler creates a new auth handler

func (*AuthHandler) ForgotPassword

func (h *AuthHandler) ForgotPassword(w http.ResponseWriter, r *http.Request)

ForgotPassword handles POST /api/auth/forgot-password

func (*AuthHandler) Login

func (h *AuthHandler) Login(w http.ResponseWriter, r *http.Request)

Login handles POST /api/auth/login

func (*AuthHandler) RegisterUser

func (h *AuthHandler) RegisterUser(w http.ResponseWriter, r *http.Request)

RegisterUser handles POST /api/auth/register

func (*AuthHandler) ResendVerificationEmail

func (h *AuthHandler) ResendVerificationEmail(w http.ResponseWriter, r *http.Request)

ResendVerificationEmail handles POST /api/auth/resend-verification

func (*AuthHandler) ResetPassword

func (h *AuthHandler) ResetPassword(w http.ResponseWriter, r *http.Request)

ResetPassword handles POST /api/auth/reset-password

func (*AuthHandler) VerifyEmail

func (h *AuthHandler) VerifyEmail(w http.ResponseWriter, r *http.Request)

VerifyEmail handles GET /api/auth/verify-email

type CommentHandler

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

func NewCommentHandler

func NewCommentHandler(contentService contentdomain.ServiceInterface) *CommentHandler

func (*CommentHandler) CreateComment

func (h *CommentHandler) CreateComment(w http.ResponseWriter, r *http.Request)

func (*CommentHandler) DeleteComment

func (h *CommentHandler) DeleteComment(w http.ResponseWriter, r *http.Request)

func (*CommentHandler) DeleteOwnComment

func (h *CommentHandler) DeleteOwnComment(w http.ResponseWriter, r *http.Request)

func (*CommentHandler) GetComments

func (h *CommentHandler) GetComments(w http.ResponseWriter, r *http.Request)

func (*CommentHandler) GetCommentsForModeration

func (h *CommentHandler) GetCommentsForModeration(w http.ResponseWriter, r *http.Request)

func (*CommentHandler) GetMyComments

func (h *CommentHandler) GetMyComments(w http.ResponseWriter, r *http.Request)

func (*CommentHandler) GetPendingComments added in v0.3.0

func (h *CommentHandler) GetPendingComments(w http.ResponseWriter, r *http.Request)

func (*CommentHandler) UpdateCommentStatus

func (h *CommentHandler) UpdateCommentStatus(w http.ResponseWriter, r *http.Request)

type CommentResponse

type CommentResponse struct {
	ID        int       `json:"id"`
	Comment   string    `json:"comment"`
	Author    string    `json:"author,omitempty"`
	Username  string    `json:"username,omitempty"`
	Role      string    `json:"role,omitempty"`
	Status    string    `json:"status,omitempty"`
	CreatedAt time.Time `json:"createdAt"`
}

type CompleteSetupRequest

type CompleteSetupRequest struct {
	Password     string `json:"password"`
	Email        string `json:"email"`
	DatabaseType string `json:"databaseType"`
}

CompleteSetupRequest represents the request body for completing first-login setup

type CompleteSetupResponse

type CompleteSetupResponse struct {
	Message  string `json:"message"`
	Redirect string `json:"redirect"`
}

CompleteSetupResponse represents the response for completing first-login setup

type ContentHandler

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

func NewContentHandler

func NewContentHandler(
	contentService ContentServiceInterface,
	logger *util.Logger,
	baseURL string,
	profilePictureURLResolver func(string) string,
	featuredImageResolver func(string) string,
) *ContentHandler

func (*ContentHandler) CreateContent

func (h *ContentHandler) CreateContent(w http.ResponseWriter, r *http.Request)

func (*ContentHandler) DeleteContent

func (h *ContentHandler) DeleteContent(w http.ResponseWriter, r *http.Request)

func (*ContentHandler) GenerateSlug

func (h *ContentHandler) GenerateSlug(w http.ResponseWriter, r *http.Request)

func (*ContentHandler) GetContent

func (h *ContentHandler) GetContent(w http.ResponseWriter, r *http.Request)

func (*ContentHandler) GetPublishedContent

func (h *ContentHandler) GetPublishedContent(w http.ResponseWriter, r *http.Request)

func (*ContentHandler) GetPublishedContentByAuthor

func (h *ContentHandler) GetPublishedContentByAuthor(w http.ResponseWriter, r *http.Request)

func (*ContentHandler) GetSEO

func (h *ContentHandler) GetSEO(w http.ResponseWriter, r *http.Request)

func (*ContentHandler) ListContents

func (h *ContentHandler) ListContents(w http.ResponseWriter, r *http.Request)

func (*ContentHandler) ListPublishedArchive added in v0.6.0

func (h *ContentHandler) ListPublishedArchive(w http.ResponseWriter, r *http.Request)

ListPublishedArchive returns published-content counts grouped by year and month, newest first. Optional ?post_type filters to a single post type; optional ?language filters to a single language. Each entry includes a URL pointing to the matching listing page with ?year= and ?month= params.

func (*ContentHandler) ListPublishedAuthors added in v0.5.0

func (h *ContentHandler) ListPublishedAuthors(w http.ResponseWriter, r *http.Request)

ListPublishedAuthors returns the users who have published at least one content item, with only safe public fields (username, display name, avatar, profile URL, published-content count, and the distinct post types they publish under). No email, role, or custom fields are exposed. Ordered by published-content count (desc) then username (asc) — useful for "most active contributors" widgets and author directories.

func (*ContentHandler) ListPublishedContents

func (h *ContentHandler) ListPublishedContents(w http.ResponseWriter, r *http.Request)

func (*ContentHandler) SearchPublished

func (h *ContentHandler) SearchPublished(w http.ResponseWriter, r *http.Request)

func (*ContentHandler) SetSystemFields

func (h *ContentHandler) SetSystemFields(w http.ResponseWriter, r *http.Request)

func (*ContentHandler) UpdateContent

func (h *ContentHandler) UpdateContent(w http.ResponseWriter, r *http.Request)

type ContentServiceInterface

type ContentServiceInterface interface {
	Create(ctx context.Context, userID int, req contentdomain.CreateContentRequest) (*contentdomain.Content, error)
	GetByUser(ctx context.Context, userID int, limit int, offset int) ([]*contentdomain.Content, error)
	GetAll(ctx context.Context, limit int, offset int) ([]*contentdomain.Content, error)
	GetByID(ctx context.Context, id int) (*contentdomain.Content, error)
	GenerateSlugFromTitle(ctx context.Context, title string) (string, error)
	Update(ctx context.Context, id int, userID int, role string, req contentdomain.UpdateContentRequest) (*contentdomain.Content, error)
	DeleteContent(ctx context.Context, id int, userID int, role string) error
	GetPublished(ctx context.Context, limit int, offset int) ([]*contentdomain.Content, error)
	GetPublishedBySlug(ctx context.Context, slug string, language string) (*contentdomain.Content, error)
	GetTranslations(ctx context.Context, translationGroupID int, excludeID int) ([]*contentdomain.Content, error)
	GetPublishedByAuthorUsername(ctx context.Context, username string, language string, limit int, offset int) ([]*contentdomain.Content, error)
	AuthorExists(ctx context.Context, username string) (bool, error)
	ListByFilters(ctx context.Context, userID int, filters contentdomain.ContentFilters) ([]*contentdomain.Content, error)
	SetSystemFields(ctx context.Context, contentID int, systemFields map[string]any) (*contentdomain.Content, error)
	SearchPublished(ctx context.Context, query string, limit int) ([]*contentdomain.Content, error)
	GetPublishedAuthors(ctx context.Context, limit int, offset int) ([]*contentdomain.PublishedAuthor, error)
	GetPublishedArchive(ctx context.Context, postType string, language string) ([]*contentdomain.ArchiveMonth, error)
	GetPublishedByPostType(ctx context.Context, postType string, language string, year int, month int, limit int, offset int) ([]*contentdomain.Content, error)
}

type CreateAPIKeyRequest

type CreateAPIKeyRequest struct {
	Name  string `json:"name"`
	Scope string `json:"scope,omitempty"` // TODO(story-future): per-key scopes deferred — accepted but not persisted
}

CreateAPIKeyRequest is the payload for POST /api/admin/api-keys.

type CreateAPIKeyResponse

type CreateAPIKeyResponse struct {
	Key       string    `json:"key"`
	ID        int       `json:"id"`
	Name      string    `json:"name"`
	KeyPrefix string    `json:"keyPrefix"`
	CreatedAt time.Time `json:"createdAt"`
}

CreateAPIKeyResponse is returned on successful key creation. The full key string is included exactly once; the client must store it.

type CreateCommentRequest

type CreateCommentRequest struct {
	Comment string `json:"comment"`
}

type CreateContentData

type CreateContentData struct {
	Content *contentdomain.Content `json:"content"`
}

type CreateContentRequest

type CreateContentRequest struct {
	Title              string         `json:"title"`
	Content            string         `json:"content"`
	Format             string         `json:"format,omitempty"`
	Tags               []string       `json:"tags"`
	Status             string         `json:"status"`
	PostType           string         `json:"postType"`
	MetaDescription    string         `json:"metaDescription,omitempty"`
	OGTitle            string         `json:"ogTitle,omitempty"`
	OGDescription      string         `json:"ogDescription,omitempty"`
	AllowComments      *bool          `json:"allowComments,omitempty"`
	CustomFields       map[string]any `json:"customFields,omitempty"`
	Language           string         `json:"language,omitempty"`
	TranslationGroupID *int           `json:"translationGroupId,omitempty"`
}

type CreateContentResponse

type CreateContentResponse struct {
	Data *CreateContentData `json:"data"`
	Meta *ResponseMeta      `json:"meta"`
}

type CreateUserRequest

type CreateUserRequest struct {
	Username     string         `json:"username"`
	Name         string         `json:"name"`
	Email        string         `json:"email"`
	Role         string         `json:"role"`
	CustomFields map[string]any `json:"customFields,omitempty"`
}

CreateUserRequest represents the request body for creating a user

type CreateUserResponse

type CreateUserResponse struct {
	Message  string      `json:"message"`
	User     *UserDetail `json:"user"`
	Password string      `json:"password"`
}

CreateUserResponse represents the response for creating a user

type DashboardHandler

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

func NewDashboardHandler

func NewDashboardHandler(dashboardService DashboardServiceInterface, logger *util.Logger) *DashboardHandler

func (*DashboardHandler) GetStats

func (h *DashboardHandler) GetStats(w http.ResponseWriter, r *http.Request)

type DashboardServiceInterface

type DashboardServiceInterface interface {
	GetStats(ctx context.Context, userID int) (*dashboarddomain.Stats, error)
}

type DataExportMeta

type DataExportMeta struct {
	Timestamp string `json:"timestamp"`
}

DataExportMeta represents metadata in data export response

type DeleteAccountRequest

type DeleteAccountRequest struct {
	Confirmation string `json:"confirmation"`
}

DeleteAccountRequest represents a request to delete an account

type DeletedContentItem

type DeletedContentItem struct {
	ID          int    `json:"id"`
	ContentType string `json:"contentType"`
	ContentID   int    `json:"contentId"`
	DeletedAt   string `json:"deletedAt"`
	DeletedBy   string `json:"deletedBy"`
	Reason      string `json:"reason,omitempty"`
}

DeletedContentItem represents a soft deleted content item

type EmailUpdateData

type EmailUpdateData struct {
	Message  string `json:"message"`
	NewEmail string `json:"newEmail"`
}

EmailUpdateData represents email update data in the response

type EmailUpdateRequest

type EmailUpdateRequest struct {
	NewEmail        string `json:"newEmail"`
	CurrentPassword string `json:"currentPassword"`
}

EmailUpdateRequest represents a request to update email

type EmailUpdateResponse

type EmailUpdateResponse struct {
	Data *EmailUpdateData     `json:"data"`
	Meta *ProfileResponseMeta `json:"meta"`
}

EmailUpdateResponse represents the response for email update

type FirstLoginHandler

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

FirstLoginHandler handles first-login setup HTTP requests

func NewFirstLoginHandler

func NewFirstLoginHandler(
	firstLoginService *authdomain.FirstLoginService,
	userRepo repository.UserRepo,
	logger *util.Logger,
) *FirstLoginHandler

NewFirstLoginHandler creates a new first-login handler

func (*FirstLoginHandler) CompleteSetup

func (h *FirstLoginHandler) CompleteSetup(w http.ResponseWriter, r *http.Request)

CompleteSetup handles POST /api/auth/first-login

func (*FirstLoginHandler) GetStatus

func (h *FirstLoginHandler) GetStatus(w http.ResponseWriter, r *http.Request)

GetStatus handles GET /api/auth/first-login

type FirstLoginStatus

type FirstLoginStatus struct {
	FirstLoginComplete bool   `json:"firstLoginComplete"`
	Redirect           string `json:"redirect,omitempty"`
}

FirstLoginStatus represents the first-login status response

type ForgotPasswordRequest

type ForgotPasswordRequest struct {
	Email string `json:"email"`
}

ForgotPasswordRequest represents the forgot password request body

type GenerateSlugData

type GenerateSlugData struct {
	Slug string `json:"slug"`
}

type GenerateSlugRequest

type GenerateSlugRequest struct {
	Title string `json:"title"`
}

type GenerateSlugResponse

type GenerateSlugResponse struct {
	Data *GenerateSlugData `json:"data"`
	Meta *ResponseMeta     `json:"meta"`
}

type GetAllUsersResponse

type GetAllUsersResponse struct {
	Data []*UserInList `json:"data"`
	Meta *UsersMeta    `json:"meta"`
}

GetAllUsersResponse represents the response for get all users

type GetPendingUsersResponse

type GetPendingUsersResponse struct {
	Data []*PendingUser `json:"data"`
	Meta *ResponseMeta  `json:"meta"`
}

GetPendingUsersResponse represents the response for pending users

type GetSoftDeletedContentResponse

type GetSoftDeletedContentResponse struct {
	Data []*DeletedContentItem `json:"data"`
	Meta *ResponseMeta         `json:"meta"`
}

GetSoftDeletedContentResponse represents the response for get soft deleted content

type LoginRequest

type LoginRequest struct {
	Username string `json:"username"`
	Password string `json:"password"`
}

LoginRequest represents the login request body

type LoginResponse

type LoginResponse struct {
	Token string      `json:"token"`
	User  UserInfoRef `json:"user"`
}

LoginResponse represents the successful login response

type MarkUserAsSpamResponse

type MarkUserAsSpamResponse struct {
	Message string `json:"message"`
	Email   string `json:"email"`
}

MarkUserAsSpamResponse represents the response for mark as spam

type MediaHandler

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

func NewMediaHandler

func NewMediaHandler(
	mediaService MediaServiceInterface,
	imageGenService media.ImageGenerationService,
	logger *util.Logger,
) *MediaHandler

func (*MediaHandler) DeleteMedia

func (h *MediaHandler) DeleteMedia(w http.ResponseWriter, r *http.Request)

func (*MediaHandler) GenerateImage

func (h *MediaHandler) GenerateImage(w http.ResponseWriter, r *http.Request)

func (*MediaHandler) GetMedia

func (h *MediaHandler) GetMedia(w http.ResponseWriter, r *http.Request)

func (*MediaHandler) GetMediaByID

func (h *MediaHandler) GetMediaByID(w http.ResponseWriter, r *http.Request)

func (*MediaHandler) Upload

func (h *MediaHandler) Upload(w http.ResponseWriter, r *http.Request)

type MediaLister added in v0.6.0

type MediaLister interface {
	ListByCursor(ctx context.Context, userID int, limit int, beforeID int) ([]*mediadomain.Media, error)
}

MediaLister provides access to media items for AI context injection.

type MediaServiceInterface

type MediaServiceInterface interface {
	Upload(ctx context.Context, req media.UploadRequest) (*media.Media, error)
	ForceUpload(ctx context.Context, req media.UploadRequest) (*media.Media, error)
	GenerateFromBytes(ctx context.Context, imageBytes []byte, userID int, altText string, originalFilename string) (*media.Media, error)
	GetByID(ctx context.Context, id int) (*media.Media, error)
	GetAll(ctx context.Context, limit int, offset int) ([]*media.Media, error)
	Delete(ctx context.Context, id int, userID int, userRole string) error
	SearchMedia(ctx context.Context, search string, dateFilter string, limit int, offset int) ([]*media.Media, error)
}

type NotificationHandler

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

NotificationHandler handles notification HTTP requests

func NewNotificationHandler

func NewNotificationHandler(
	logger *util.Logger,
	notificationRepo repository.NotificationRepo,
) *NotificationHandler

NewNotificationHandler creates a new notification handler

func (*NotificationHandler) GetNotifications

func (h *NotificationHandler) GetNotifications(w http.ResponseWriter, r *http.Request)

GetNotifications handles GET /api/notifications

type NotificationRef

type NotificationRef struct {
	ID        int                         `json:"id"`
	Type      repository.NotificationType `json:"type"`
	Message   string                      `json:"message"`
	CreatedAt time.Time                   `json:"createdAt"`
}

NotificationRef represents a notification in the response

type NotificationsResponse

type NotificationsResponse struct {
	Notifications []NotificationRef `json:"notifications"`
}

NotificationsResponse represents the notifications response

type PasswordUpdateData

type PasswordUpdateData struct {
	Message string `json:"message"`
}

PasswordUpdateData represents password update data in the response

type PasswordUpdateRequest

type PasswordUpdateRequest struct {
	CurrentPassword string `json:"currentPassword"`
	NewPassword     string `json:"newPassword"`
}

PasswordUpdateRequest represents a request to update password

type PasswordUpdateResponse

type PasswordUpdateResponse struct {
	Data *PasswordUpdateData  `json:"data"`
	Meta *ProfileResponseMeta `json:"meta"`
}

PasswordUpdateResponse represents the response for password update

type PendingCommentResponse added in v0.3.0

type PendingCommentResponse struct {
	ID           int       `json:"id"`
	ContentID    int       `json:"contentId"`
	ContentTitle string    `json:"contentTitle,omitempty"`
	ContentSlug  string    `json:"contentSlug,omitempty"`
	Comment      string    `json:"comment"`
	Author       string    `json:"author,omitempty"`
	Username     string    `json:"username,omitempty"`
	Status       string    `json:"status,omitempty"`
	CreatedAt    time.Time `json:"createdAt"`
}

PendingCommentResponse is the admin-facing representation of a comment awaiting moderation, enriched with the content item it belongs to.

type PendingUser

type PendingUser struct {
	ID             int       `json:"id"`
	Username       string    `json:"username"`
	Email          string    `json:"email"`
	ProfilePicture string    `json:"profilePicture,omitempty"`
	CreatedAt      time.Time `json:"createdAt"`
}

PendingUser represents a pending user in the response

type PostTypeHandler

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

PostTypeHandler handles post type HTTP requests

func NewPostTypeHandler

func NewPostTypeHandler(postTypeService PostTypeServiceInterface, logger *util.Logger) *PostTypeHandler

NewPostTypeHandler creates a new post type handler

func (*PostTypeHandler) GetPostTypes

func (h *PostTypeHandler) GetPostTypes(w http.ResponseWriter, r *http.Request)

GetPostTypes returns all registered post types

func (*PostTypeHandler) GetPublicPostTypes

func (h *PostTypeHandler) GetPublicPostTypes(w http.ResponseWriter, r *http.Request)

GetPublicPostTypes returns all post types without requiring authentication

func (*PostTypeHandler) GetUserFieldsEndpoint

func (h *PostTypeHandler) GetUserFieldsEndpoint(w http.ResponseWriter, r *http.Request)

GetUserFieldsEndpoint returns user field schemas (custom and system)

type PostTypeServiceInterface

type PostTypeServiceInterface interface {
	GetAll() []posttype.PostType
	GetBySlug(slug string) (posttype.PostType, error)
	Register(pt posttype.PostType) error
	GetUserFields() []customfield.FieldSchema
	GetUserSystemFields() []customfield.FieldSchema
}

PostTypeServiceInterface defines the interface for post type service

type ProfileData

type ProfileData struct {
	Profile *ProfileInfo `json:"profile"`
}

ProfileData represents profile data in the response

type ProfileHandler

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

ProfileHandler handles profile management HTTP requests

func NewProfileHandler

func NewProfileHandler(
	profileService user.ProfileServiceInterface,
	accountDeletionService user.AccountDeletionServiceInterface,
	jwtManager *auth.JWTManager,
	logger *util.Logger,
	userFieldsProvider userFieldsProvider,
	profilePictureURLBuilder func(string) string,
) *ProfileHandler

NewProfileHandler creates a new profile handler

func (*ProfileHandler) ChangePassword

func (h *ProfileHandler) ChangePassword(w http.ResponseWriter, r *http.Request)

ChangePassword handles PUT /api/profile/password

func (*ProfileHandler) DeleteAccount

func (h *ProfileHandler) DeleteAccount(w http.ResponseWriter, r *http.Request)

DeleteAccount handles DELETE /api/profile/account

func (*ProfileHandler) ExportUserData

func (h *ProfileHandler) ExportUserData(w http.ResponseWriter, r *http.Request)

ExportUserData handles GET /api/profile/export

func (*ProfileHandler) GetProfile

func (h *ProfileHandler) GetProfile(w http.ResponseWriter, r *http.Request)

GetProfile handles GET /api/profile

func (*ProfileHandler) GetUserFields

func (h *ProfileHandler) GetUserFields(w http.ResponseWriter, r *http.Request)

GetUserFields handles GET /api/profile/user-fields

func (*ProfileHandler) UpdateCustomFields

func (h *ProfileHandler) UpdateCustomFields(w http.ResponseWriter, r *http.Request)

UpdateCustomFields handles PUT /api/profile/custom-fields

func (*ProfileHandler) UpdateEmail

func (h *ProfileHandler) UpdateEmail(w http.ResponseWriter, r *http.Request)

UpdateEmail handles PUT /api/profile/email

func (*ProfileHandler) UpdateName added in v0.2.0

func (h *ProfileHandler) UpdateName(w http.ResponseWriter, r *http.Request)

UpdateName handles PUT /api/profile/name

func (*ProfileHandler) VerifyEmailUpdate

func (h *ProfileHandler) VerifyEmailUpdate(w http.ResponseWriter, r *http.Request)

VerifyEmailUpdate handles GET /api/profile/verify-email This endpoint does NOT require authentication - the verification token is sufficient

type ProfileInfo

type ProfileInfo struct {
	ID             int            `json:"id"`
	Username       string         `json:"username"`
	Name           string         `json:"name,omitempty"`
	Email          string         `json:"email"`
	Role           string         `json:"role"`
	ProfilePicture string         `json:"profilePicture,omitempty"`
	CreatedAt      time.Time      `json:"createdAt"`
	UpdatedAt      time.Time      `json:"updatedAt,omitempty"`
	CustomFields   map[string]any `json:"customFields,omitempty"`
}

ProfileInfo represents user profile information

type ProfilePictureHandler

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

ProfilePictureHandler handles profile picture HTTP requests

func NewProfilePictureHandler

func NewProfilePictureHandler(
	service *profilepicture.Service,
	userRepo repository.UserRepo,
	logger *util.Logger,
) *ProfilePictureHandler

NewProfilePictureHandler creates a new profile picture handler

func (*ProfilePictureHandler) AdminDeleteUserPicture

func (h *ProfilePictureHandler) AdminDeleteUserPicture(w http.ResponseWriter, r *http.Request)

AdminDeleteUserPicture handles DELETE /api/admin/users/{id}/picture

func (*ProfilePictureHandler) AdminUploadUserPicture

func (h *ProfilePictureHandler) AdminUploadUserPicture(w http.ResponseWriter, r *http.Request)

AdminUploadUserPicture handles PUT /api/admin/users/{id}/picture

func (*ProfilePictureHandler) DeleteProfilePicture

func (h *ProfilePictureHandler) DeleteProfilePicture(w http.ResponseWriter, r *http.Request)

DeleteProfilePicture handles DELETE /api/profile/picture

func (*ProfilePictureHandler) UploadProfilePicture

func (h *ProfilePictureHandler) UploadProfilePicture(w http.ResponseWriter, r *http.Request)

UploadProfilePicture handles PUT /api/profile/picture

type ProfileResponse

type ProfileResponse struct {
	Data *ProfileData         `json:"data"`
	Meta *ProfileResponseMeta `json:"meta"`
}

ProfileResponse represents the response for profile information

type ProfileResponseMeta

type ProfileResponseMeta struct {
	Timestamp string `json:"timestamp"`
}

ProfileResponseMeta represents metadata in profile response

type PublicArchiveMonthResponse added in v0.6.0

type PublicArchiveMonthResponse struct {
	Year  int    `json:"year"`
	Month int    `json:"month"`
	Count int    `json:"count"`
	URL   string `json:"url"`
}

PublicArchiveMonthResponse is the public-facing shape for one month in a content archive. URL points to the listing page filtered by year/month.

type PublicAuthorResponse added in v0.5.0

type PublicAuthorResponse struct {
	Username     string   `json:"username"`
	DisplayName  string   `json:"displayName"`
	AvatarURL    string   `json:"avatarURL"`
	ProfileURL   string   `json:"profileURL"`
	ContentCount int      `json:"contentCount"`
	PostTypes    []string `json:"postTypes"`
}

PublicAuthorResponse is the safe, public-facing shape for a published author. It deliberately omits email, role, status, and custom fields — those stay behind authentication (per Lesstruct's no-enumeration model).

type RegisterUserRequest

type RegisterUserRequest struct {
	Username string `json:"username"`
	Name     string `json:"name"`
	Email    string `json:"email"`
	Password string `json:"password"`
}

RegisterUserRequest represents the registration request body

type RegisterUserResponse

type RegisterUserResponse struct {
	Message string `json:"message"`
	UserID  int    `json:"userId"`
}

RegisterUserResponse represents the successful registration response

type RejectUserResponse

type RejectUserResponse struct {
	Message  string `json:"message"`
	Username string `json:"username"`
	Email    string `json:"email"`
}

RejectUserResponse represents the response for reject user

type ResendVerificationRequest

type ResendVerificationRequest struct {
	Email string `json:"email"`
}

ResendVerificationRequest represents the resend verification request body

type ResendVerificationResponse

type ResendVerificationResponse struct {
	Message string `json:"message"`
}

ResendVerificationResponse represents the successful resend response

type ResetPasswordRequest

type ResetPasswordRequest struct {
	Token       string `json:"token"`
	NewPassword string `json:"newPassword"`
}

ResetPasswordRequest represents the reset password request body

type ResponseMeta

type ResponseMeta struct {
	Count     int    `json:"count"`
	Timestamp string `json:"timestamp"`
}

ResponseMeta represents metadata in API responses

type RestoreContentResponse

type RestoreContentResponse struct {
	Message string           `json:"message"`
	Content *RestoredContent `json:"content"`
}

RestoreContentResponse represents the response for restore content

type RestoredContent

type RestoredContent struct {
	ID   int    `json:"id"`
	Type string `json:"type"`
}

RestoredContent represents restored content details

type RevokeAPIKeyResponse

type RevokeAPIKeyResponse struct {
	ID        int        `json:"id"`
	RevokedAt *time.Time `json:"revokedAt"`
}

RevokeAPIKeyResponse is returned on successful (or idempotent) revoke.

type SEOHandler

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

func NewSEOHandler

func NewSEOHandler(
	contentService ContentServiceInterface,
	baseURL string,
	logger *util.Logger,
) *SEOHandler

func (*SEOHandler) GetRobotsTxt

func (h *SEOHandler) GetRobotsTxt(w http.ResponseWriter, r *http.Request)

func (*SEOHandler) GetSitemapData

func (h *SEOHandler) GetSitemapData(w http.ResponseWriter, r *http.Request)

func (*SEOHandler) GetSitemapXML added in v0.2.0

func (h *SEOHandler) GetSitemapXML(w http.ResponseWriter, r *http.Request)

GetSitemapXML serves the sitemaps.org XML document crawlers expect at /sitemap.xml (the path robots.txt advertises). The JSON shape served at /api/v1/sitemap is for programmatic callers; crawlers need XML.

type SearchResult

type SearchResult struct {
	Slug            string `json:"slug"`
	Title           string `json:"title"`
	MetaDescription string `json:"metaDescription"`
}

type SoftDeleteContentRequest

type SoftDeleteContentRequest struct {
	Confirmed bool   `json:"confirmed"`
	Reason    string `json:"reason"`
}

SoftDeleteContentRequest represents the request for soft delete

type SoftDeleteUserResponse

type SoftDeleteUserResponse struct {
	Message             string      `json:"message"`
	User                *UserDetail `json:"user"`
	DeletedContentCount int         `json:"deletedContentCount"`
}

SoftDeleteUserResponse represents the response for soft delete user

type SuspendUserResponse

type SuspendUserResponse struct {
	Message string      `json:"message"`
	User    *UserDetail `json:"user"`
}

SuspendUserResponse represents the response for suspend user

type TextGenHandler

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

TextGenHandler handles AI text generation requests.

func NewTextGenHandler

func NewTextGenHandler(
	textGenService TextGenerationService,
	mediaService MediaLister,
	logger *util.Logger,
) *TextGenHandler

NewTextGenHandler creates a new TextGenHandler.

func (*TextGenHandler) Enhance

func (h *TextGenHandler) Enhance(w http.ResponseWriter, r *http.Request)

Enhance handles the "Enhance with AI" / "Generate with AI" endpoint.

func (*TextGenHandler) Translate

func (h *TextGenHandler) Translate(w http.ResponseWriter, r *http.Request)

Translate handles the "Translate with AI" endpoint.

type TextGenerationService

type TextGenerationService interface {
	EnhanceText(ctx context.Context, content, format, mediaContext string) (string, error)
	TranslateText(ctx context.Context, content, sourceLang, targetLang, format string) (string, error)
}

TextGenerationService defines the interface for AI text generation.

type UnsuspendUserResponse

type UnsuspendUserResponse struct {
	Message string      `json:"message"`
	User    *UserDetail `json:"user"`
}

UnsuspendUserResponse represents the response for unsuspend user

type UpdateCommentStatusRequest

type UpdateCommentStatusRequest struct {
	Status string `json:"status"`
}

type UpdateUserProfileRequest

type UpdateUserProfileRequest struct {
	Name         string         `json:"name"`
	Email        string         `json:"email"`
	Role         string         `json:"role"`
	CustomFields map[string]any `json:"customFields,omitempty"`
}

UpdateUserProfileRequest represents the request body for updating a user profile

type UpdateUserProfileResponse

type UpdateUserProfileResponse struct {
	Message string      `json:"message"`
	User    *UserDetail `json:"user"`
}

UpdateUserProfileResponse represents the response for updating a user profile

type UserDetail

type UserDetail struct {
	ID             int            `json:"id"`
	Username       string         `json:"username"`
	Email          string         `json:"email"`
	Role           string         `json:"role,omitempty"`
	Status         string         `json:"status"`
	ProfilePicture string         `json:"profilePicture,omitempty"`
	CustomFields   map[string]any `json:"customFields,omitempty"`
	CreatedAt      time.Time      `json:"createdAt,omitempty"`
}

UserDetail represents user details in responses

type UserInList

type UserInList struct {
	ID             int            `json:"id"`
	Username       string         `json:"username"`
	Email          string         `json:"email"`
	Status         string         `json:"status"`
	Role           string         `json:"role"`
	ProfilePicture string         `json:"profilePicture,omitempty"`
	CustomFields   map[string]any `json:"customFields,omitempty"`
	CreatedAt      time.Time      `json:"createdAt"`
}

UserInList represents a user in the list response

type UserInfoRef

type UserInfoRef struct {
	ID       string `json:"id"`
	Username string `json:"username"`
	Role     string `json:"role"`
}

UserInfoRef represents user information returned in login response

type UserManagementHandler

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

UserManagementHandler handles user management HTTP requests

func NewUserManagementHandler

func NewUserManagementHandler(
	userService *user.UserManagementService,
	adminCreateService *user.AdminCreateUserService,
	userRepo repository.UserRepo,
	softDeleteRepo repository.SoftDeleteRepo,
	jwtManager *auth.JWTManager,
	emailService email.EmailService,
	logger *util.Logger,
	profilePictureURLBuilder func(string) string,
) *UserManagementHandler

NewUserManagementHandler creates a new user management handler

func (*UserManagementHandler) ApproveUser

func (h *UserManagementHandler) ApproveUser(w http.ResponseWriter, r *http.Request)

ApproveUser handles POST /api/admin/users/:id/approve

func (*UserManagementHandler) CreateUser

func (h *UserManagementHandler) CreateUser(w http.ResponseWriter, r *http.Request)

CreateUser handles POST /api/admin/users

func (*UserManagementHandler) GetAllUsers

func (h *UserManagementHandler) GetAllUsers(w http.ResponseWriter, r *http.Request)

GetAllUsers handles GET /api/admin/users

func (*UserManagementHandler) GetPendingUsers

func (h *UserManagementHandler) GetPendingUsers(w http.ResponseWriter, r *http.Request)

GetPendingUsers handles GET /api/admin/pending-users

func (*UserManagementHandler) GetSoftDeletedContent

func (h *UserManagementHandler) GetSoftDeletedContent(w http.ResponseWriter, r *http.Request)

GetSoftDeletedContent handles GET /api/admin/users/:id/deleted-content

func (*UserManagementHandler) MarkUserAsSpam

func (h *UserManagementHandler) MarkUserAsSpam(w http.ResponseWriter, r *http.Request)

MarkUserAsSpam handles POST /api/admin/users/:id/mark-spam

func (*UserManagementHandler) RejectUser

func (h *UserManagementHandler) RejectUser(w http.ResponseWriter, r *http.Request)

RejectUser handles POST /api/admin/users/:id/reject

func (*UserManagementHandler) RestoreContent

func (h *UserManagementHandler) RestoreContent(w http.ResponseWriter, r *http.Request)

RestoreContent handles POST /api/admin/content/:id/restore

func (*UserManagementHandler) SoftDeleteUser

func (h *UserManagementHandler) SoftDeleteUser(w http.ResponseWriter, r *http.Request)

SoftDeleteUser handles POST /api/admin/users/:id/soft-delete

func (*UserManagementHandler) SuspendUser

func (h *UserManagementHandler) SuspendUser(w http.ResponseWriter, r *http.Request)

SuspendUser handles POST /api/admin/users/:id/suspend

func (*UserManagementHandler) UnsuspendUser

func (h *UserManagementHandler) UnsuspendUser(w http.ResponseWriter, r *http.Request)

UnsuspendUser handles POST /api/admin/users/:id/unsuspend

func (*UserManagementHandler) UpdateUser

func (h *UserManagementHandler) UpdateUser(w http.ResponseWriter, r *http.Request)

UpdateUser handles PUT /api/admin/users/:id

type UsersMeta

type UsersMeta struct {
	Count     int    `json:"count"`
	Limit     int    `json:"limit"`
	Offset    int    `json:"offset"`
	Timestamp string `json:"timestamp"`
}

UsersMeta represents metadata for users list

type VerifyEmailResponse

type VerifyEmailResponse struct {
	Message  string `json:"message"`
	Redirect string `json:"redirect"`
}

VerifyEmailResponse represents the successful email verification response

type VerifyEmailUpdateData

type VerifyEmailUpdateData struct {
	Message string `json:"message"`
	Email   string `json:"email"`
}

VerifyEmailUpdateData represents email verification data in the response

type VerifyEmailUpdateResponse

type VerifyEmailUpdateResponse struct {
	Data *VerifyEmailUpdateData `json:"data"`
	Meta *ProfileResponseMeta   `json:"meta"`
}

VerifyEmailUpdateResponse represents the response for email verification

type WordPressHandler

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

WordPressHandler exposes the WordPress import endpoint to administrators.

func NewWordPressHandler

func NewWordPressHandler(importer *wordpress.Importer, logger *util.Logger, maxImportBytes int64) *WordPressHandler

NewWordPressHandler creates a WordPressHandler. maxImportBytes is the total upload ceiling (from IMPORT_MAX_SIZE_MB) applied via MaxBytesReader.

func (*WordPressHandler) Import

func (h *WordPressHandler) Import(w http.ResponseWriter, r *http.Request)

Import accepts a WordPress WXR XML file upload and imports its posts and pages. The endpoint is admin-only (enforced by route middleware).

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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