app

package
v0.0.0-...-caa8b03 Latest Latest
Warning

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

Go to latest
Published: Feb 1, 2026 License: MIT Imports: 52 Imported by: 0

Documentation

Index

Constants

View Source
const (
	BOOK_COVER_DIRECTORY = "book-covers"
)

Variables

View Source
var (
	ErrTypeSignUp    = apperror.AppErrors.NewType("signup")
	ErrUsernameTaken = ErrTypeSignUp.New("username is already taken")

	ErrTypeAuthenticationError = apperror.AppErrors.NewType("authentication", apperror.ErrTraitAuthorizationIssue)
	ErrInvalidCredentials      = ErrTypeAuthenticationError.New("invalid credentials")
)
View Source
var (
	ErrTypeBookNotFound = apperror.AppErrors.NewType("book404", apperror.ErrTraitEntityNotFound)
	ErrTypeBookPrivated = apperror.AppErrors.NewType("access_denied_book_private", apperror.ErrTraitForbidden)
)
View Source
var (
	ErrTypeBookSanitizationFailed = apperror.AppErrors.NewType("content_sanitization_failed")
	ErrTypeChaptersReorder        = apperror.AppErrors.NewType("chapters_reorder")
	ErrDraftNotFound              = apperror.AppErrors.NewType("draft_not_found", errorx.NotFound(), apperror.ErrTraitEntityNotFound).New("draft not found")
	ErrTypeChapterDoesNotExist    = apperror.AppErrors.NewType("chapter_not_found", apperror.ErrTraitEntityNotFound)
)
View Source
var (
	ErrEmptyBookName   = errors.New("empty book name")
	ErrBookNameTooLong = errors.New("invalid book name")
	BookSummaryTooLong = errors.New("book summary is too long")
)
View Source
var (
	CollectionErrors       = apperror.AppErrors.NewSubNamespace("collection")
	ErrCollectionNotExists = CollectionErrors.NewType("404", apperror.ErrTraitEntityNotFound).New("collection not found")
)
View Source
var (
	CommentErrors                = apperror.AppErrors.NewSubNamespace("comment")
	ErrTypeCommentNotFound       = CommentErrors.NewType("not_found", apperror.ErrTraitEntityNotFound)
	ErrTypeCommentContentInvalid = CommentErrors.NewType("invalid_content", apperror.ErrTraitValidationError)
	ErrCommentContentEmpty       = ErrTypeCommentContentInvalid.New("comment content is empty")
	ErrCommentContentTooLarge    = ErrTypeCommentContentInvalid.New("comment content is too large")
)
View Source
var (
	ModerationBookErrors                = apperror.AppErrors.NewSubNamespace("mod_books")
	InvalidModerationActionError        = ModerationBookErrors.NewType("invalid_mod_action")
	ErrInvalidModerationAction_NoReason = InvalidModerationActionError.New("no reason provided")
	ModerationBookNotFoundError         = ModerationBookErrors.NewType("book_404", apperror.ErrTraitEntityNotFound)
)
View Source
var (
	ReadingListErrors            = apperror.AppErrors.NewSubNamespace("reading_list")
	ReadingListInvalidTransition = ReadingListErrors.NewType("invalid_transition")
	ErrReadingListEmptyBook      = ReadingListInvalidTransition.NewSubtype("empty_book").New("cannot update reading list for empty book")
	ReadingListChapterNotFound   = ReadingListErrors.NewType("chapter404")
)
View Source
var (
	SignUpErrors                       = apperror.AppErrors.NewSubNamespace("signup")
	SignUpInvalidInput                 = SignUpErrors.NewType("invalid")
	SignUpEmailVerificationErrors      = SignUpErrors.NewSubNamespace("email_verification")
	SignUpEmailVerificationNA          = SignUpEmailVerificationErrors.NewType("na")
	SignUpEmailVerificationRateLimit   = SignUpEmailVerificationErrors.NewType("rate_limit")
	SignUpEmailVerificationTimedOut    = SignUpEmailVerificationErrors.NewType("timedout")
	SignUpEmailVerificationInvalidCode = SignUpEmailVerificationErrors.NewType("invalid_code")
)
View Source
var (
	RoleUser      = UserRole("user")
	RoleAdmin     = UserRole("admin")
	RoleSystem    = UserRole("system")
	RoleModerator = UserRole("moderator")

	AllRoles = []UserRole{
		RoleUser,
		RoleAdmin,
		RoleSystem,
		RoleModerator,
	}
)
View Source
var (
	ErrUserNotFound    = apperror.AppErrors.NewType("user_not_found", apperror.ErrTraitEntityNotFound).New("user not found")
	ErrFollowYourself  = apperror.AppErrors.NewType("follow_yourself").New("you can't follow yourself")
	ErrInvalidUserRole = apperror.AppErrors.NewType("invalid_user_role").New("invalid user role")
	ErrUserNameInvalid = apperror.AppErrors.NewType("invalid_username")
	ErrEmailInvalid    = apperror.AppErrors.NewType("invalid_email")
)
View Source
var (
	DefaultPaginationRestrictions = PaginationRestrictions{
		MaxPageSize:  100,
		MaxPageCount: 1000,
	}
)
View Source
var (
	ErrInvalidUploadURI = errors.New("invalid upload uri schema")
)
View Source
var (
	ErrSessionNotFound = apperror.AppErrors.NewType("session_not_found").New("session not found")
)
View Source
var (
	ErrTagNotFound = apperror.AppErrors.NewType("tag404", apperror.ErrTraitEntityNotFound).New("tag with this ID cannot be found")
)
View Source
var (
	GlobalFeatureFlags struct {
		DisableCache bool
	}
)
View Source
var (
	PasswordError = apperror.AppErrors.NewType("password")
)

Functions

func AppVersion

func AppVersion() string

func ArrInt64StringToInt64

func ArrInt64StringToInt64(v []Int64String) []int64

func CountWordsHtml

func CountWordsHtml(html string) int32

func FixHTML

func FixHTML(htmlSnippet string) (string, error)

func GenID

func GenID() int64

func ImportPredefinedTags

func ImportPredefinedTags(ctx context.Context, queries *store.Queries) error

func IsCommonPageSize

func IsCommonPageSize(pageSize int32) bool

func MapSlice

func MapSlice[T, U any](ts []T, f func(T) U) []U

func MoveItem

func MoveItem[T comparable](arr []T, item T, newPositionIndex int) (int, bool)

MoveItem moves an item in the list, returns new position of item and a boolean representing the successfullness of the operation (true if successful), if operation was unsuccessful then newPosition returned SHOULD be -1

func SanitizeHtml

func SanitizeHtml(html string) string

SanitizeHtml takes a string of HTML content and returns a sanitized version of it, free of potentially malicious tags and attributes.

func ValidateEmail

func ValidateEmail(email string) error

func ValidatePassword

func ValidatePassword(pwd string, r PasswordRequirements) error

func ValidateUserName

func ValidateUserName(value string) error

Types

type AddCommentCommand

type AddCommentCommand struct {
	UserID          uuid.UUID
	ChapterID       int64
	ParentCommentID Nullable[int64]
	Content         string
}

func (*AddCommentCommand) Validate

func (c *AddCommentCommand) Validate() error

type AddCommentResult

type AddCommentResult struct {
	Comment CommentDto
}

type AddToCollectionsCommand

type AddToCollectionsCommand struct {
	ActorUserID  uuid.UUID
	CollectionID []int64
	BookID       int64
}

type AgeRating

type AgeRating string
const (
	AgeRatingUnknown AgeRating = "?"
	AgeRatingG       AgeRating = "G"
	AgeRatingPG      AgeRating = "PG"
	AgeRatingPG13    AgeRating = "PG-13"
	AgeRatingR       AgeRating = "R"
	AgeRatingNC17    AgeRating = "NC-17"
)

func AsRating

func AsRating(v string) AgeRating

func (AgeRating) IsAdult

func (r AgeRating) IsAdult() bool

type AuthService

type AuthService interface {
	SignIn(ctx context.Context, input SignInCommand) (SignInResult, error)
	CreateSessionForUser(ctx context.Context, userID uuid.UUID, userAgent, ip string) (string, error)
	SignOut(ctx context.Context, sessionID string) error
	EnsureAdminUserExists(ctx context.Context) error
}

func NewAuthService

func NewAuthService(db DB, sessions SessionService) AuthService

type BookAdultWarning

type BookAdultWarning struct {
	IsBookAdult bool
	HasAdultTag bool
}

func (BookAdultWarning) ShouldShowWarning

func (w BookAdultWarning) ShouldShowWarning() bool

type BookBackgroundService

type BookBackgroundService interface {
	BookRecalculationIngest
	Start() error
	Stop()
}

func NewBookBackgroundService

func NewBookBackgroundService(db DB, lc fx.Lifecycle, log *zap.SugaredLogger) BookBackgroundService

func NewDummyBookBackgroundService

func NewDummyBookBackgroundService() BookBackgroundService

type BookCollectionDto

type BookCollectionDto struct {
	ID       int64  `json:"id,string"`
	Name     string `json:"name"`
	Position int    `json:"pos"`
	Size     int    `json:"size"`
}

type BookDetailsAuthorDto

type BookDetailsAuthorDto struct {
	ID   uuid.UUID `json:"id"`
	Name string    `json:"name"`
}

type BookDetailsDto

type BookDetailsDto struct {
	ID                  int64                 `json:"id,string"`
	Name                string                `json:"name"`
	AgeRating           AgeRating             `json:"ageRating"`
	IsAdult             bool                  `json:"adult"`
	Tags                []DefinedTagDto       `json:"tags"`
	Words               int                   `json:"words"`
	WordsPerChapter     int                   `json:"wordsPerChapter"`
	CreatedAt           time.Time             `json:"createdAt"`
	Collections         []BookCollectionDto   `json:"collections"`
	Author              BookDetailsAuthorDto  `json:"author"`
	Permissions         BookUserPermissions   `json:"permissions"`
	Summary             string                `json:"summary"`
	Notifications       []GenericNotification `json:"notifications,omitempty"`
	Cover               string                `json:"cover"`
	Rating              Nullable[float64]     `json:"rating"`
	Votes               int32                 `json:"votes"`
	Reviews             int32                 `json:"reviews"`
	IsPubliclyAvailable bool                  `json:"isPubliclyAvailable"`
	Slug                string                `json:"slug"`
	FirstChapterID      Nullable[int64]       `json:"firstChapterId"`
}

func (BookDetailsDto) GetAdultWarning

func (d BookDetailsDto) GetAdultWarning() (warnData BookAdultWarning)

type BookExtremes

type BookExtremes struct {
	Words           Int32Range `json:"words"`
	Chapters        Int32Range `json:"chapters"`
	WordsPerChapter Int32Range `json:"wordsPerChapter"`
	Favorites       Int32Range `json:"favorites"`
}

type BookLibraryDto

type BookLibraryDto struct {
	ID          int64                                       `json:"id,string"`
	Name        string                                      `json:"name"`
	Cover       string                                      `json:"cover"`
	AgeRating   AgeRating                                   `json:"ageRating"`
	LastChapter Nullable[BookReadingListItemLastChapterDto] `json:"lastChapter"`
}

type BookListDto

type BookListDto struct {
	ID              int64     `json:"id,string"`
	Name            string    `json:"name"`
	CreatedAt       time.Time `json:"createdAt"`
	AgeRating       AgeRating `json:"ageRating"`
	Words           int       `json:"words"`
	WordsPerChapter int       `json:"wordsPerChapter"`
	Chapters        int       `json:"chapters"`
	Cover           string    `json:"cover"`
	IsPinned        bool      `json:"isPinned"`
}

type BookLogResult

type BookLogResult struct {
	Entries         []BookModerationLog
	Page            int32
	PageSize        int32
	HasNextPage     bool
	HasPreviousPage bool
	TotalPages      uint32
}

type BookManagerService

type BookManagerService interface {
	GetUserBooks(ctx context.Context, input GetUserBooksQuery) (GetUserBooksResult, error)
	GetBook(ctx context.Context, query ManagerGetBookQuery) (ManagerGetBookResult, error)
	CreateBook(ctx context.Context, input CreateBookCommand) (int64, error)
	UpdateBook(ctx context.Context, input UpdateBookCommand) error
	UploadBookCover(ctx context.Context, input UploadBookCoverCommand) (UploadBookCoverResult, error)
	TrashBook(ctx context.Context, input TrashBookCommand) error
	UntrashBook(ctx context.Context, input UntrashBookCommand) error

	UpdateBookChaptersOrder(ctx context.Context, input UpdateBookChapterOrdersCommand) (UpdateBookChapterOrdersResult, error)
	CreateBookChapter(ctx context.Context, input CreateBookChapterCommand) (CreateBookChapterResult, error)
	ReorderChapters(ctx context.Context, input ReorderChaptersCommand) error
	GetBookChapters(ctx context.Context, query ManagerGetBookChaptersQuery) (ManagerGetBookChapterResult, error)
	GetChapter(ctx context.Context, query ManagerGetChapterQuery) (ManagerGetChapterResult, error)

	GetDraft(ctx context.Context, query GetDraftQuery) (DraftDto, error)
	// GetBookDrafts(ctx context.Context, query GetBookDraftsQuery)
	UpdateDraft(ctx context.Context, cmd UpdateDraftCommand) error
	UpdateDraftChapterName(ctx context.Context, cmd UpdateDraftChapterNameCommand) error
	UpdateDraftContent(ctx context.Context, cmd UpdateDraftContentCommand) error
	DeleteDraft(ctx context.Context, cmd DeleteDraftCommand) error
	PublishDraft(ctx context.Context, cmd PublishDraftCommand) error
	CreateDraft(ctx context.Context, cmd CreateDraftCommand) (int64, error)
	GetLatestDraft(ctx context.Context, cmd GetLatestDraftQuery) (Nullable[int64], error)
}

func NewBookManagerService

func NewBookManagerService(db DB, tagsService TagsService, uploadService *UploadService, usersService UserService, bookReindexService BookReindexService) BookManagerService

type BookModerationInfo

type BookModerationInfo struct {
	ID             int64
	Name           string
	Summary        string
	IsBanned       bool
	IsShadowBanned bool
	IsPermDeleted  bool
}

type BookModerationLog

type BookModerationLog struct {
	Time          time.Time
	Action        store.BookActionType
	Payload       json.RawMessage
	Reason        string
	ActorUserID   uuid.UUID
	ActorUserName string
}

type BookReadingListDto

type BookReadingListDto struct {
	Status        ReadingListStatus     `json:"status"`
	ChapterID     Nullable[Int64String] `json:"chapterId"`
	ChapterName   string                `json:"chapterName"`
	ChapterOrder  int32                 `json:"chapterOrder"`
	LastUpdatedAt time.Time             `json:"lastUpdatedAt"`
}

type BookReadingListItemLastChapterDto

type BookReadingListItemLastChapterDto struct {
	ID    int64  `json:"id,string"`
	Name  string `json:"name"`
	Order int32  `json:"order"`
}

type BookRecalculationIngest

type BookRecalculationIngest interface {
	ScheduleBookRecalculation(bookID int64)
}

type BookReindexService

type BookReindexService interface {
	Reindex(ctx context.Context, id int64) error
	ScheduleReindex(ctx context.Context, id int64)
	ScheduleReindexAll() error
}

func NewBookFullReindexService

func NewBookFullReindexService(db store.DBTX, osClient *opensearchapi.Client, log *zap.SugaredLogger) BookReindexService

func NewDummyBookReindexService

func NewDummyBookReindexService() BookReindexService

type BookReviewsDistribution

type BookReviewsDistribution [10]int32

type BookSearchItem

type BookSearchItem struct {
	ID              int64                `json:"id,string"`
	Name            string               `json:"name"`
	Slug            string               `json:"slug"`
	CreatedAt       time.Time            `json:"createdAt"`
	AgeRating       AgeRating            `json:"ageRating"`
	Words           int                  `json:"words"`
	WordsPerChapter int                  `json:"wordsPerChapter"`
	Chapters        int                  `json:"chapters"`
	Summary         string               `json:"summary"`
	Author          BookDetailsAuthorDto `json:"author"`
	Cover           string               `json:"cover"`
	Tags            []Int64String        `json:"tags"`
	Collections     []BookCollectionDto  `json:"collections"`
}

type BookSearchQuery

type BookSearchQuery struct {
	UserID uuid.NullUUID

	Query string

	Words           Int32Range
	Chapters        Int32Range
	WordsPerChapter Int32Range

	IncludeTags  []int64
	ExcludeTags  []int64
	IncludeUsers []uuid.UUID
	ExcludeUsers []uuid.UUID

	IncludeBanned bool
	IncludeHidden bool
	IncludeEmpty  bool

	Page     uint32
	PageSize uint
}

type BookSearchResult

type BookSearchResult struct {
	TookUSTotal int64
	TookUS      int64
	Meta        BookSearchResultMeta
	Books       []BookSearchItem
	PageSize    uint32
	Page        uint32
	TotalPages  uint32
	Total       int64
	Tags        []DefinedTagDto
}

type BookSearchResultMeta

type BookSearchResultMeta struct {
	CacheKey    string `json:"cacheKey"`
	CacheHit    bool   `json:"cacheHit"`
	CacheTookUS int64  `json:"cacheTook"`
}

type BookService

type BookService interface {
	GetBookDetails(ctx context.Context, query GetBookQuery) (BookDetailsDto, error)
	GetBookChapters(ctx context.Context, query GetBookChaptersQuery) ([]ChapterListDto, error)
	GetBookChapter(ctx context.Context, query GetBookChapterQuery) (GetBookChapterResult, error)
	GetRandomBookID(ctx context.Context) (Nullable[int64], error)
	GetPinnedBooks(ctx context.Context, input GetPinnedUserBooksQuery) (GetPinnedUserBooksResult, error)
	GetBooksById(ctx context.Context, ids []int64) ([]BookListDto, error)
}

func NewBookService

func NewBookService(
	db store.DBTX,
	tagsService TagsService,
	uploadService *UploadService,
	readingListService ReadingListService,
	reviewService ReviewsService,
) BookService

type BookTags

type BookTags struct {
	ParentTagIds []int64
	TagIds       []int64
}

type BookUserPermissions

type BookUserPermissions struct {
	CanEdit bool `json:"canEdit"`
}

type CaptchaSettings

type CaptchaSettings struct {
	GoogleRecaptchaKey string
	Type               string
}

type CensorMode

type CensorMode store.CensorMode

type ChapterDto

type ChapterDto struct {
	ID              int64                        `json:"id,string"`
	Name            string                       `json:"name"`
	Words           int32                        `json:"words"`
	Content         string                       `json:"content"`
	IsAdultOverride bool                         `json:"isAdultOverride"`
	CreatedAt       time.Time                    `json:"createdAt"`
	Order           int32                        `json:"order"`
	Summary         string                       `json:"summary"`
	NextChapter     Nullable[ChapterNextPrevDto] `json:"nextChapter"`
	PrevChapter     Nullable[ChapterNextPrevDto] `json:"prevChapter"`
	BookID          int64                        `json:"bookId"`
	CommentsCount   int64                        `json:"commentsCount"`
}

type ChapterListDto

type ChapterListDto struct {
	ID        int64     `json:"id,string"`
	Order     int       `json:"order"`
	Name      string    `json:"name"`
	Words     int       `json:"words"`
	CreatedAt time.Time `json:"createdAt"`
	Summary   string    `json:"summary"`
}

type ChapterNextPrevDto

type ChapterNextPrevDto struct {
	ID    int64  `json:"id,string"`
	Name  string `json:"name"`
	Order int32  `json:"order"`
}

type ChapterOrderModification

type ChapterOrderModification struct {
	ChapterID        int64
	NewPositionIndex int
}

type CollectionBook2Dto

type CollectionBook2Dto struct {
	ID         int64
	Name       string
	Slug       string
	Summary    string
	AuthorName string
	AuthorID   uuid.UUID
	Cover      string
	Tags       []DefinedTagDto
}

type CollectionBookDto

type CollectionBookDto struct {
	ID    int64
	Name  string
	Cover string
}

type CollectionDto

type CollectionDto struct {
	ID            int64
	Name          string
	Slug          string
	BooksCount    int
	LastUpdatedAt Nullable[time.Time]
	UserID        uuid.UUID
	UserName      string
	IsPublic      bool
	Summary       string
}

type CollectionService

type CollectionService interface {
	GetUserCollections(ctx context.Context, query GetUserCollectionsQuery) (GetUserCollectionsResult, error)
	GetRecentUserCollections(ctx context.Context, query GetRecentCollectionsQuery) ([]CollectionDto, error)
	CreateCollection(ctx context.Context, cmd CreateCollectionCommand) (int64, error)
	UpdateCollection(ctx context.Context, cmd UpdateCollectionCommand) error
	AddToCollections(ctx context.Context, cmd AddToCollectionsCommand) error
	RemoveFromCollection(ctx context.Context, cmd RemoveFromCollectionCommand) error
	GetBookCollections(ctx context.Context, query GetBookCollectionsQuery) ([]CollectionDto, error)

	GetCollectionBooks(ctx context.Context, query GetCollectionBooksQuery) (GetCollectionBooksResult, error)
	GetCollectionBooksMap(ctx context.Context, collections []CollectionDto) (map[int64][]CollectionBookDto, error)
	GetCollection(ctx context.Context, id int64) (Nullable[CollectionDto], error)
	DeleteCollection(ctx context.Context, cmd DeleteCollectionCommand) error
}

func NewCollectionsService

func NewCollectionsService(db DB, tagsService TagsService, uploadService *UploadService) CollectionService

type CommentDto

type CommentDto struct {
	ID             int64               `json:"id,string"`
	Content        string              `json:"content"`
	User           CommentUserDto      `json:"user"`
	CreatedAt      time.Time           `json:"createdAt"`
	UpdatedAt      Nullable[time.Time] `json:"updatedAt"`
	LikedAt        Nullable[time.Time] `json:"likedAt"`
	Likes          int64               `json:"likes"`
	LikesUpdatedAt time.Time           `json:"likesUpdatedAt"`
	Subcomments    int                 `json:"subcomments"`
}

func (CommentDto) RealLikesCount

func (c CommentDto) RealLikesCount() int64

type CommentUserDto

type CommentUserDto struct {
	ID     uuid.UUID `json:"id"`
	Name   string    `json:"name"`
	Avatar string    `json:"avatar"`
}

type CommentsService

type CommentsService interface {
	GetList(ctx context.Context, query GetCommentsQuery) (GetCommentsResult, error)
	GetReplies(ctx context.Context, query GetCommentRepliesQuery) (GetCommentRepliesResult, error)

	AddComment(ctx context.Context, command AddCommentCommand) (AddCommentResult, error)
	UpdateComment(ctx context.Context, command UpdateCommentCommand) (UpdateCommentResult, error)
	LikeComment(ctx context.Context, command LikeCommentCommand) (bool, error)
}

func NewCommentsService

func NewCommentsService(db store.DBTX) CommentsService

type ContentRestrictions

type ContentRestrictions struct {
	// if true - whole website is considered "adult"
	AdultWebsite bool
}

type CreateBookChapterCommand

type CreateBookChapterCommand struct {
	BookID            int64
	Name              string
	Content           string
	IsAdultOverride   bool
	Summary           string
	UserID            uuid.UUID
	IsPubliclyVisible bool
}

type CreateBookChapterResult

type CreateBookChapterResult struct {
	ID int64
}

type CreateBookCommand

type CreateBookCommand struct {
	Name              string
	UserID            uuid.UUID
	AgeRating         AgeRating
	Tags              []int64
	Summary           string
	IsPubliclyVisible bool
}

type CreateCollectionCommand

type CreateCollectionCommand struct {
	Name        string
	Description string
	UserID      uuid.UUID
}

type CreateDraftCommand

type CreateDraftCommand struct {
	ChapterID int64
	UserID    uuid.UUID
}

type CreateSessionCommand

type CreateSessionCommand struct {
	UserID    uuid.UUID
	UserAgent string
	IpAddress string
	ExpiresAt time.Time
}

type CreateTagsCommand

type CreateTagsCommand struct {
	Tags []TagDescriptor
}

type DB

type DB interface {
	store.DBTX
	// contains filtered or unexported methods
}

type DefinedTagDto

type DefinedTagDto struct {
	ID          int64        `json:"id,string"`
	Name        string       `json:"name"`
	Description string       `json:"desc"`
	IsAdult     bool         `json:"adult"`
	IsSpoiler   bool         `json:"spoiler"`
	Category    TagsCategory `json:"cat"`
}

type DeleteCollectionCommand

type DeleteCollectionCommand struct {
	ActorUserID  uuid.UUID
	CollectionID int64
}

type DeleteDraftCommand

type DeleteDraftCommand struct {
	DraftID int64
	UserID  uuid.UUID
}

type DeleteReviewCommand

type DeleteReviewCommand struct {
	UserID uuid.UUID
	BookID int64
}

type DetailedBookSearchQuery

type DetailedBookSearchQuery struct {
	Query string `json:"query"`

	Words           Int32Range `json:"words"`
	Chapters        Int32Range `json:"chapters"`
	WordsPerChapter Int32Range `json:"wordsPerChapter"`

	IncludeTags  []DefinedTagDto            `json:"includeTags"`
	ExcludeTags  []DefinedTagDto            `json:"excludeTags"`
	IncludeUsers []UserFromSearchRequestDto `json:"includeUsers"`
	ExcludeUsers []UserFromSearchRequestDto `json:"excludeUsers"`

	IncludeBanned bool `json:"includeBanned"`
	IncludeHidden bool `json:"includeHidden"`
	IncludeEmpty  bool `json:"includeEmpty"`

	Page     uint32 `json:"page"`
	PageSize uint   `json:"pageSize"`
}

func (*DetailedBookSearchQuery) ActiveFilters

func (d *DetailedBookSearchQuery) ActiveFilters() int

type DraftDto

type DraftDto struct {
	ID          int64               `json:"id,string"`
	ChapterName string              `json:"chapterName"`
	Content     string              `json:"content"`
	CreatedAt   time.Time           `json:"createdAt"`
	UpdatedAt   Nullable[time.Time] `json:"updatedAt"`
	CreatedBy   struct {
		ID   uuid.UUID `json:"id"`
		Name string    `json:"name"`
	} `json:"createdBy"`
	Book struct {
		ID   int64  `json:"id,string"`
		Name string `json:"name"`
	} `json:"book"`
	Chapter struct {
		ID               int64     `json:"id,string"`
		ContentUpdatedAt time.Time `json:"contentUpdatedAt"`
	} `json:"chapter"`
	IsChapterPubliclyAvailable bool `json:"isChapterPubliclyAvailable"`
}

type EmailVerificationStatus

type EmailVerificationStatus struct {
	CanSendAgainAfter Nullable[time.Time]
	WasSent           bool
}

type FollowUserCommand

type FollowUserCommand struct {
	UserID   uuid.UUID
	Follower uuid.UUID
}

type GenericNotification

type GenericNotification struct {
	ID   string `json:"id"`
	Text string `json:"text"`
}

type GetBookChapterQuery

type GetBookChapterQuery struct {
	BookID      int64
	ChapterID   int64
	ActorUserID uuid.NullUUID
}

type GetBookChapterResult

type GetBookChapterResult struct {
	Chapter ChapterDto
}

type GetBookChaptersQuery

type GetBookChaptersQuery struct {
	ID int64
}

type GetBookCollectionsQuery

type GetBookCollectionsQuery struct {
	ActorUserID uuid.UUID
	BookID      int64
}

type GetBookDraftsQuery

type GetBookDraftsQuery struct {
	Page int
}

type GetBookInfoQuery

type GetBookInfoQuery struct {
	ActorUserID uuid.UUID
	BookID      int64
}

type GetBookLogQuery

type GetBookLogQuery struct {
	Page        uint32
	PageSize    uint32
	OfTypes     []store.BookActionType
	BookID      int64
	ActorUserID uuid.UUID
}

type GetBookQuery

type GetBookQuery struct {
	ID          int64
	ActorUserID uuid.NullUUID
}

type GetBookReviewsDistributionResult

type GetBookReviewsDistributionResult struct {
	Distribution BookReviewsDistribution
}

type GetBookReviewsQuery

type GetBookReviewsQuery struct {
	BookID   int64
	PageSize int32
	Page     int32
}

type GetBookReviewsResult

type GetBookReviewsResult struct {
	Reviews    []ReviewDto
	Pagination PaginationOptions
}

type GetCollectionBooksQuery

type GetCollectionBooksQuery struct {
	CollectionID int64
	Page         int32
	PageSize     int32
}

type GetCollectionBooksResult

type GetCollectionBooksResult struct {
	Books      []CollectionBook2Dto
	Page       int32
	TotalPages int32
	PageSize   int32
}

type GetCommentRepliesQuery

type GetCommentRepliesQuery struct {
	ActorUserID uuid.NullUUID
	Limit       int32
	Cursor      uint32
	CommentID   int64
}

type GetCommentRepliesResult

type GetCommentRepliesResult struct {
	Cursor     uint32
	NextCursor uint32
	Comments   []CommentDto
}

type GetCommentsQuery

type GetCommentsQuery struct {
	ActorUserID uuid.NullUUID
	Limit       int32
	Cursor      uint32
	ChapterID   int64
}

type GetCommentsResult

type GetCommentsResult struct {
	Cursor     uint32
	NextCursor uint32
	Comments   []CommentDto
}

type GetDraftQuery

type GetDraftQuery struct {
	UserID    uuid.UUID
	DraftID   int64
	ChapterID int64
	BookID    int64
}

type GetLatestDraftQuery

type GetLatestDraftQuery struct {
	ChapterID int64
	UserID    uuid.UUID
}

type GetPinnedUserBooksQuery

type GetPinnedUserBooksQuery struct {
	UserID uuid.UUID
	Limit  int
	Offset int
}

type GetPinnedUserBooksResult

type GetPinnedUserBooksResult struct {
	Books   []BookListDto `json:"books"`
	HasMore bool          `json:"hasMore"`
}

type GetReadingListItemsQuery

type GetReadingListItemsQuery struct {
	UserID uuid.UUID
	Limit  uint32
	Status ReadingListStatus
}

type GetRecentCollectionsQuery

type GetRecentCollectionsQuery struct {
	UserID uuid.UUID
	Limit  int32
}

type GetReviewQuery

type GetReviewQuery struct {
	UserID uuid.UUID
	BookID int64
}

type GetUserBooksQuery

type GetUserBooksQuery struct {
	UserID      uuid.UUID
	ActorUserID Nullable[uuid.UUID]
	Page        uint32
	PageSize    uint32
	SearchQuery string
}

type GetUserBooksResult

type GetUserBooksResult struct {
	Books      []ManagerAuthorBookDto
	TotalPages uint32
	PageSize   uint32
	Page       uint32
}

type GetUserCollectionsQuery

type GetUserCollectionsQuery struct {
	UserID   uuid.UUID
	Page     int32
	PageSize int32
}

type GetUserCollectionsResult

type GetUserCollectionsResult struct {
	Collections []CollectionDto
	TotalPages  int32
	Page        int32
}

type GetUserQuery

type GetUserQuery struct {
	ID     uuid.UUID
	UserID uuid.NullUUID
}

type Int32

type Int32 struct {
	Valid bool
	Int32 int32
}

func Int32FromPtr

func Int32FromPtr(i *int32) Int32

func (Int32) MarshalJSON

func (i Int32) MarshalJSON() ([]byte, error)

func (Int32) Ptr

func (i Int32) Ptr() *int32

func (*Int32) UnmarshalJSON

func (i *Int32) UnmarshalJSON(b []byte) error

type Int32Range

type Int32Range struct {
	Min Int32 `json:"min"`
	Max Int32 `json:"max"`
}

type Int64String

type Int64String int64

func (Int64String) MarshalJSON

func (i Int64String) MarshalJSON() ([]byte, error)

func (*Int64String) UnmarshalJSON

func (i *Int64String) UnmarshalJSON(b []byte) error

type LikeCommentCommand

type LikeCommentCommand struct {
	CommentID int64
	UserID    uuid.UUID
	Like      bool
}

type ListTagsQuery

type ListTagsQuery struct {
	SearchQuery    string
	Page           uint32
	PageSize       uint32
	OnlyParentTags bool
	OnlyAdultTags  bool
}

type ListTagsResult

type ListTagsResult struct {
	Tags       []TagDetailsItemDto
	Page       uint32
	TotalPages uint32
}

type ManagerAuthorBookDto

type ManagerAuthorBookDto struct {
	ID                int64               `json:"id,string"`
	Slug              string              `json:"slug"`
	Name              string              `json:"name"`
	CreatedAt         time.Time           `json:"createdAt"`
	AgeRating         AgeRating           `json:"ageRating"`
	Tags              []DefinedTagDto     `json:"tags"`
	Words             int                 `json:"words"`
	WordsPerChapter   int                 `json:"wordsPerChapter"`
	Chapters          int                 `json:"chapters"`
	Collections       []BookCollectionDto `json:"collections"`
	IsPubliclyVisible bool                `json:"isPubliclyVisible"`
	IsBanned          bool                `json:"isBanned"`
	IsTrashed         bool                `json:"isTrashed"`
	Summary           string              `json:"summary"`
	Cover             string              `json:"cover"`
}

type ManagerBookChapterDetailsDto

type ManagerBookChapterDetailsDto struct {
	ID                int64     `json:"id,string"`
	Name              string    `json:"name"`
	CreatedAt         time.Time `json:"createdAt"`
	Words             int       `json:"words"`
	Summary           string    `json:"summary"`
	Order             int32     `json:"order"`
	IsAdultOverride   bool      `json:"isAdultOverride"`
	Content           string    `json:"content"`
	IsPubliclyVisible bool      `json:"isPubliclyVisible"`
}

type ManagerBookChapterDto

type ManagerBookChapterDto struct {
	ID                int64                 `json:"id,string"`
	Name              string                `json:"name"`
	CreatedAt         time.Time             `json:"createdAt"`
	Words             int                   `json:"words"`
	Summary           string                `json:"summary"`
	Order             int32                 `json:"order"`
	IsAdultOverride   bool                  `json:"isAdultOverride"`
	IsPubliclyVisible bool                  `json:"isPubliclyVisible"`
	DraftID           Nullable[Int64String] `json:"draftId"`
}

type ManagerBookDetailsDto

type ManagerBookDetailsDto struct {
	ID                int64                   `json:"id,string"`
	Name              string                  `json:"name"`
	AgeRating         AgeRating               `json:"ageRating"`
	IsAdult           bool                    `json:"adult"`
	Tags              []DefinedTagDto         `json:"tags"`
	Words             int                     `json:"words"`
	WordsPerChapter   int                     `json:"wordsPerChapter"`
	CreatedAt         time.Time               `json:"createdAt"`
	Collections       []BookCollectionDto     `json:"collections"`
	Chapters          []ManagerBookChapterDto `json:"chapters"`
	Author            BookDetailsAuthorDto    `json:"author"`
	Summary           string                  `json:"summary"`
	IsPubliclyVisible bool                    `json:"isPubliclyVisible"`
	IsBanned          bool                    `json:"isBanned"`
	Cover             string                  `json:"cover"`
}

type ManagerGetBookChapterResult

type ManagerGetBookChapterResult struct {
	Chapters []ManagerBookChapterDto
}

type ManagerGetBookChaptersQuery

type ManagerGetBookChaptersQuery struct {
	BookID int64
	UserID uuid.UUID
}

type ManagerGetBookQuery

type ManagerGetBookQuery struct {
	ActorUserID uuid.UUID
	BookID      int64
}

type ManagerGetBookResult

type ManagerGetBookResult struct {
	Book ManagerBookDetailsDto
}

type ManagerGetChapterQuery

type ManagerGetChapterQuery struct {
	BookID    int64
	ChapterID int64
	UserID    uuid.UUID
}

type ManagerGetChapterResult

type ManagerGetChapterResult struct {
	Chapter ManagerBookChapterDetailsDto
}

type MarkChapterCommand

type MarkChapterCommand struct {
	ChapterID int64
	UserID    uuid.UUID
}

type ModerationBookService

type ModerationBookService interface {
	GetBookInfo(ctx context.Context, query GetBookInfoQuery) (BookModerationInfo, error)
	GetBookLog(ctx context.Context, query GetBookLogQuery) (BookLogResult, error)
	BanBook(ctx context.Context, cmd ModerationPerformBookActionCommand) error
	ShadowBanBook(ctx context.Context, cmd ModerationPerformBookActionCommand) error
	PermanentlyRemoveBook(ctx context.Context, cmd ModerationPerformBookActionCommand) error

	UnBanBook(ctx context.Context, cmd ModerationPerformBookActionCommand) error
	UnShadowBanBook(ctx context.Context, cmd ModerationPerformBookActionCommand) error
}

func NewModerationBookService

func NewModerationBookService(db DB) ModerationBookService

type ModerationPerformBookActionCommand

type ModerationPerformBookActionCommand struct {
	Reason      string
	ActorUserID uuid.UUID
	BookID      int64
}

func (ModerationPerformBookActionCommand) Validate

type NormalizedSearchRequest

type NormalizedSearchRequest struct {
	UserID uuid.NullUUID

	Words           Int32Range
	Chapters        Int32Range
	WordsPerChapter Int32Range
	Favorites       Int32Range

	IncludeTags  []int64
	ExcludeTags  []int64
	IncludeUsers []uuid.UUID
	ExcludeUsers []uuid.UUID

	IncludeBanned bool
	IncludeHidden bool
	IncludeEmpty  bool

	Limit  uint
	Offset uint
}

type Nullable

type Nullable[T any] struct {
	Value T
	Valid bool
}

func Null

func Null[T any]() Nullable[T]

func NullableFromPtr

func NullableFromPtr[T any](ptr *T) Nullable[T]

func Value

func Value[T any](v T) Nullable[T]

func (Nullable[T]) MarshalJSON

func (v Nullable[T]) MarshalJSON() ([]byte, error)

func (Nullable[T]) Or

func (v Nullable[T]) Or(vv T) T

func (Nullable[T]) Ptr

func (v Nullable[T]) Ptr() *T

func (*Nullable[T]) UnmarshalJSON

func (v *Nullable[T]) UnmarshalJSON(b []byte) error

type PaginationOptions

type PaginationOptions struct {
	Page     int32 `json:"page"`
	PageSize int32 `json:"pageSize"`
}

func (PaginationOptions) Limit

func (opt PaginationOptions) Limit() int32

func (PaginationOptions) Offset

func (opt PaginationOptions) Offset() int32

type PaginationRestrictions

type PaginationRestrictions struct {
	MaxPageSize  int32
	MaxPageCount int32
}

func (PaginationRestrictions) Validate

func (r PaginationRestrictions) Validate(page, pageSize int32) PaginationOptions

type PasswordRequirements

type PasswordRequirements struct {
	Digits         bool
	Symbols        string
	SymbolsEnabled bool
	DifferentCases bool
	MinLength      int
}

type ProcessedContentData

type ProcessedContentData struct {
	Sanitized string
	Words     int32
}

func ProcessContent

func ProcessContent(content string) (ProcessedContentData, error)

ProcessContent takes a string of HTML content and returns a ProcessedContentData containing both a sanitized version of the content (i.e. HTML tags removed and unsafe content stripped), and a count of the number of words in the content.

type PublishDraftCommand

type PublishDraftCommand struct {
	DraftID    int64
	UserID     uuid.UUID
	MakePublic bool
}

type RatingAndReview

type RatingAndReview struct {
	Rating Nullable[RatingValue] `json:"rating"`
	Review Nullable[ReviewDto]   `json:"review"`
}

type RatingValue

type RatingValue uint8

func CreateRatingValue

func CreateRatingValue(v int16) RatingValue

func (RatingValue) MarshalJSON

func (v RatingValue) MarshalJSON() ([]byte, error)

func (RatingValue) ToUint16

func (v RatingValue) ToUint16() int16

func (*RatingValue) UnmarshalJSON

func (v *RatingValue) UnmarshalJSON(data []byte) error

type ReadingListService

type ReadingListService interface {
	MarksAsWantToRead(ctx context.Context, userID uuid.UUID, bookID int64) error
	MarkAsDnf(ctx context.Context, userID uuid.UUID, bookID int64) error
	MarkAsRead(ctx context.Context, userID uuid.UUID, bookID int64) error
	MarkAsPaused(ctx context.Context, userID uuid.UUID, bookID int64) error
	MarkAsReading(ctx context.Context, userID uuid.UUID, bookID int64) error
	MarkAsReadingWithChapterID(ctx context.Context, userID uuid.UUID, bookID int64, chapterID int64) error
	GetStatus(ctx context.Context, userID uuid.UUID, bookID int64) (Nullable[BookReadingListDto], error)
	GetReadingListBooks(ctx context.Context, query GetReadingListItemsQuery) ([]BookLibraryDto, error)
	MarkChapterRead(ctx context.Context, command MarkChapterCommand) error
}

func NewReadingListService

func NewReadingListService(db store.DBTX, uploadService *UploadService) ReadingListService

type RemoveFromCollectionCommand

type RemoveFromCollectionCommand struct {
	CollectionID int64
	BookID       int64
	UserID       uuid.UUID
}

type RenewSessionCommand

type RenewSessionCommand struct {
	SessionID string
	UserAgent string
	IpAddress string
	ExpiresAt time.Time
}

type ReorderChaptersCommand

type ReorderChaptersCommand struct {
	UserID     uuid.UUID
	BookID     int64
	ChapterIDs []int64
}

type ReviewDto

type ReviewDto struct {
	User      ReviewUserDto       `json:"user"`
	Rating    RatingValue         `json:"rating"`
	Content   string              `json:"content"`
	CreatedAt time.Time           `json:"createdAt"`
	UpdatedAt Nullable[time.Time] `json:"updatedAt"`
	Likes     int32               `json:"likes"`
}

type ReviewUserDto

type ReviewUserDto struct {
	ID     uuid.UUID `json:"id"`
	Name   string    `json:"name"`
	Avatar string    `json:"avatar"`
}

type ReviewsService

type ReviewsService interface {
	GetBookReviewsDistribution(ctx context.Context, bookID int64) (GetBookReviewsDistributionResult, error)
	GetBookReviews(ctx context.Context, query GetBookReviewsQuery) (GetBookReviewsResult, error)

	UpdateReview(ctx context.Context, cmd UpdateReviewCommand) (ReviewDto, error)
	UpdateRating(ctx context.Context, cmd UpdateRatingCommand) error

	GetReview(ctx context.Context, query GetReviewQuery) (RatingAndReview, error)
	DeleteReview(ctx context.Context, cmd DeleteReviewCommand) error
}

func NewCachedReviewsService

func NewCachedReviewsService(inner ReviewsService, cache *cache.Cache) ReviewsService

func NewReviewsService

func NewReviewsService(db DB, userService UserService, backgroundService BookRecalculationIngest) ReviewsService

type SearchService

type SearchService interface {
	SearchBooks(ctx context.Context, req BookSearchQuery) (*BookSearchResult, error)
	GetBookExtremes(ctx context.Context) (*BookExtremes, error)
	ExplainSearchQuery(ctx context.Context, req BookSearchQuery) (DetailedBookSearchQuery, error)
}

func NewCachedSearchService

func NewCachedSearchService(inner SearchService, cache *cache.Cache) SearchService

func NewSearchService

func NewSearchService(db store.DBTX, tagsService TagsService, uploadService *UploadService, userService UserService, osClient *opensearchapi.Client) SearchService

type SearchUserBooksQuery

type SearchUserBooksQuery struct {
	UserID      uuid.UUID
	ActorUserID Nullable[uuid.UUID]
	Limit       int
	Offset      int
}

type SearchUserBooksResult

type SearchUserBooksResult struct {
}

type SelfUserDto

type SelfUserDto struct {
	ID     uuid.UUID `json:"id"`
	Name   string    `json:"name"`
	Email  string    `json:"email"`
	Role   UserRole  `json:"role"`
	Avatar struct {
		LG string `json:"lg"`
		MD string `json:"md"`
	} `json:"avatar"`
	JoinedAt          time.Time  `json:"joinedAt"`
	IsBanned          bool       `json:"isBlocked"`
	IsEmailVerified   bool       `json:"isEmailVerified"`
	PreferredTheme    string     `json:"preferredTheme"`
	ShowAdultContent  bool       `json:"showAdultContent"`
	BookCensoredTags  []string   `json:"bookCensoredTags"`
	BookCensoringMode CensorMode `json:"bookCensoringMode"`
}

type SendEmailVerificationCommand

type SendEmailVerificationCommand struct {
	UserID          uuid.UUID
	BypassRateLimit bool
}

type SendEmailVerificationResult

type SendEmailVerificationResult struct {
	CanResendAfter time.Time
}

type SessionInfo

type SessionInfo struct {
	ID           int64     `json:"id"`
	SID          string    `json:"sid"`
	CreatedAt    time.Time `json:"createdAt"`
	ExpiresAt    time.Time `json:"expiresAt"`
	UserID       uuid.UUID `json:"userId"`
	UserAgent    string    `json:"userAgent"`
	IpAddress    string    `json:"ipAddr"`
	UserName     string    `json:"userName"`
	UserJoinedAt time.Time `json:"userJoinedAt"`
	UserRole     UserRole  `json:"userRole"`
}

type SessionPublicInfo

type SessionPublicInfo struct {
	ID        int64         `json:"id,string"`
	UserAgent UserAgentInfo `json:"userAgent"`
	IpAddress string        `json:"ipAddress"`
	CreatedAt time.Time     `json:"createdAt"`
	ExpiresAt time.Time     `json:"expiresAt"`
}

func NewSessionPublicInfo

func NewSessionPublicInfo(session SessionInfo) SessionPublicInfo

func SessionPublicInfoArray

func SessionPublicInfoArray(sessions []SessionInfo) []SessionPublicInfo

type SessionService

type SessionService interface {
	GetBySID(ctx context.Context, sessionID string) (*SessionInfo, error)
	Create(ctx context.Context, command CreateSessionCommand) (*SessionInfo, error)
	GetByUserID(ctx context.Context, userID uuid.UUID) ([]SessionInfo, error)
	TerminateBySID(ctx context.Context, sessionID string) error
	TerminateAllByUserID(ctx context.Context, userID uuid.UUID) error
	Renew(ctx context.Context, command RenewSessionCommand) (*SessionInfo, error)
}

func NewCachedSessionService

func NewCachedSessionService(inner SessionService, cache *cache.Cache) SessionService

func NewSessionService

func NewSessionService(db DB) SessionService

type SignInCommand

type SignInCommand struct {
	Username  string
	Password  string
	UserAgent string
	IpAddress string
}

type SignInResult

type SignInResult struct {
	SessionID string
}

type SignUpCommand

type SignUpCommand struct {
	Username                  string
	Password                  string
	Email                     string
	UserAgent                 string
	IpAddress                 string
	BypassEmailRequirement    bool
	BypassPasswordRequirement bool
}

type SignUpResult

type SignUpResult struct {
	Created                   bool
	CreatedUserID             uuid.UUID
	EmailTaken                bool
	EmailVerificationRequired bool
}

type SignUpService

type SignUpService interface {
	SignUp(ctx context.Context, cmd SignUpCommand) (SignUpResult, error)
	VerifyEmail(ctx context.Context, cmd VerifyEmailCommand) error
	SendEmailVerification(ctx context.Context, cmd SendEmailVerificationCommand) (SendEmailVerificationResult, error)
	GetEmailVerificationStatus(ctx context.Context, userID uuid.UUID) (EmailVerificationStatus, error)
}

func NewSignUpService

func NewSignUpService(db DB, cfg *koanf.Koanf, siteConfig *SiteConfig, emailService email.Service) SignUpService

type SiteConfig

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

func NewSiteConfig

func NewSiteConfig(db DB, staticCfg *koanf.Koanf) *SiteConfig

func (*SiteConfig) Get

func (s *SiteConfig) Get() *SiteConfigData

func (*SiteConfig) Load

func (s *SiteConfig) Load(ctx context.Context) error

func (*SiteConfig) Save

func (s *SiteConfig) Save(ctx context.Context, force bool) error

type SiteConfigData

type SiteConfigData struct {
	CaptchaSettings      CaptchaSettings
	PasswordRequirements PasswordRequirements
	ContentRestrictions  ContentRestrictions
}

func (SiteConfigData) Equal

func (d SiteConfigData) Equal(other SiteConfigData) bool

type SiteConfigEntry

type SiteConfigEntry json.RawMessage

type TagDescriptor

type TagDescriptor struct {
	Name      string
	Category  TagsCategory
	IsAdult   bool
	IsWarning bool
	IsSpoiler bool
}

type TagDetailsItemDto

type TagDetailsItemDto struct {
	DefinedTagDto

	SynonymOf Nullable[struct {
		ID   int64
		Name string
	}]
	CreatedAt time.Time
	IsDefault bool
}

type TagsCategory

type TagsCategory uint8
const (
	TagsCategoryOther TagsCategory = iota
	TagsCategoryWarning
	TagsCategoryFandom
	TagsCategoryRelationship
	TagsCategoryRelationshipType
)

func TagsCategoryFromName

func TagsCategoryFromName(name string) TagsCategory

func (TagsCategory) MarshalJSON

func (t TagsCategory) MarshalJSON() ([]byte, error)

func (TagsCategory) String

func (t TagsCategory) String() string

func (*TagsCategory) UnmarshalJSON

func (t *TagsCategory) UnmarshalJSON(b []byte) error

type TagsService

type TagsService interface {
	GetTag(ctx context.Context, id int64) (TagDetailsItemDto, error)
	GetTagsByIds(ctx context.Context, ids []int64) ([]DefinedTagDto, error)
	SearchTags(ctx context.Context, query string) ([]DefinedTagDto, error)
	FindParentTagIds(ctx context.Context, names []int64) (BookTags, error)
	CreateTags(ctx context.Context, cmd CreateTagsCommand) ([]DefinedTagDto, error)
	List(ctx context.Context, query ListTagsQuery) (ListTagsResult, error)
	UpdateTag(ctx context.Context, command UpdateTagCommand) error
}

func NewTagsService

func NewTagsService(db store.DBTX) TagsService

type TrashBookCommand

type TrashBookCommand struct {
	BookID      int64
	ActorUserID uuid.UUID
}

type UnfollowUserCommand

type UnfollowUserCommand struct {
	UserID   uuid.UUID
	Follower uuid.UUID
}

type UntrashBookCommand

type UntrashBookCommand struct {
	BookID      int64
	ActorUserID uuid.UUID
}

type UpdateBookChapterOrdersCommand

type UpdateBookChapterOrdersCommand struct {
	BookID        int64
	Modifications []ChapterOrderModification
}

type UpdateBookChapterOrdersResult

type UpdateBookChapterOrdersResult struct {
	ModifiedPositions map[int64]int
}

type UpdateBookCommand

type UpdateBookCommand struct {
	BookID            int64
	UserID            uuid.UUID
	Name              string
	AgeRating         AgeRating
	Tags              []int64
	Summary           string
	IsPubliclyVisible bool
}

type UpdateCollectionCommand

type UpdateCollectionCommand struct {
	ID          int64
	Name        string
	Public      bool
	Summary     string
	ActorUserID uuid.UUID
}

type UpdateCommentCommand

type UpdateCommentCommand struct {
	ID      int64
	Content string
	UserID  uuid.UUID
}

type UpdateCommentResult

type UpdateCommentResult struct {
	Comment CommentDto
}

type UpdateDraftChapterNameCommand

type UpdateDraftChapterNameCommand struct {
	ChapterName string
	ChapterID   int64
	BookID      int64
	DraftID     int64
	UserID      uuid.UUID
}

type UpdateDraftCommand

type UpdateDraftCommand struct {
	Content         string
	Summary         string
	Name            string
	IsAdultOverride bool
	DraftID         int64
	ChapterID       int64
	BookID          int64
	UserID          uuid.UUID
}

type UpdateDraftContentCommand

type UpdateDraftContentCommand struct {
	Content   string
	DraftID   int64
	ChapterID int64
	BookID    int64
	UserID    uuid.UUID
}

type UpdateRatingCommand

type UpdateRatingCommand struct {
	BookID int64
	UserID uuid.UUID
	Rating RatingValue
}

type UpdateReviewCommand

type UpdateReviewCommand struct {
	BookID  int64
	UserID  uuid.UUID
	Rating  RatingValue
	Content string
}

type UpdateTagCommand

type UpdateTagCommand struct {
	ID             int64
	Name           string
	Description    string
	IsAdult        bool
	IsSpoiler      bool
	SynonymOfTagID Nullable[int64]
	Type           TagsCategory
	UserID         uuid.UUID
}

type UpdateUserCommand

type UpdateUserCommand struct {
	UserID      uuid.UUID
	ActorUserID uuid.NullUUID
	Password    string
	Role        Nullable[UserRole]
	About       string
	Gender      string
}

type UploadBookCoverCommand

type UploadBookCoverCommand struct {
	UserID uuid.UUID
	BookID int64
	File   io.Reader
}

type UploadBookCoverResult

type UploadBookCoverResult struct {
	URL string
}

type UploadConfig

type UploadConfig struct {
	Endpoint     string
	Region       string
	AccessKey    string
	SecretKey    string
	MainBucket   string
	PublicBucket string
	Secure       bool
}

type UploadService

type UploadService struct {
	Client       *minio.Client
	MainBucket   string
	PublicBucket string
	Region       string
	Secure       bool
	Endpoint     string
}

func NewUploadService

func NewUploadService(cfg UploadConfig) *UploadService

func NewUploadServiceFromApplicationConfig

func NewUploadServiceFromApplicationConfig(cfg *koanf.Koanf) *UploadService

func (*UploadService) GetPublicURL

func (s *UploadService) GetPublicURL(path string) string

func (*UploadService) InitBuckets

func (s *UploadService) InitBuckets(ctx context.Context) error

type UploadURI

type UploadURI struct {
	Type UploadURIType
	Key  string
}

func ParseUploadURI

func ParseUploadURI(s string) (*UploadURI, error)

func (UploadURI) String

func (uu UploadURI) String() string

func (UploadURI) URL

func (uu UploadURI) URL() *url.URL

type UploadURIType

type UploadURIType int
const (
	UploadURITypePublicMinio UploadURIType = iota
	UploadURITypePrivateMinio
	UploadURITypeExternal
	UploadURITypeUnknown = 0xffff
)

func (UploadURIType) String

func (t UploadURIType) String() string

type UserAboutDto

type UserAboutDto struct {
	Bio    string `json:"bio"`
	Gender string `json:"gender"`
}

type UserAboutSettings

type UserAboutSettings struct {
	About  string `json:"about"`
	Status string `json:"status"`
	Gender string `json:"gender"`
}

type UserAgentInfo

type UserAgentInfo struct {
	Value   string `json:"value"`
	Version string `json:"ver"`
	Name    string `json:"name"`
	OS      string `json:"os"`
}

type UserCustomizationSetting

type UserCustomizationSetting struct {
	ProfileCSS       string `json:"profileCss"`
	DefaultTheme     string `json:"defaultTheme"`
	EnableProfileCSS bool   `json:"enableProfileCss"`
}

type UserDetailsDto

type UserDetailsDto struct {
	ID     uuid.UUID `json:"id"`
	Name   string    `json:"name"`
	Email  string    `json:"email"`
	Avatar struct {
		LG string `json:"lg"`
		MD string `json:"md"`
	} `json:"avatar"`
	JoinedAt       time.Time    `json:"joinedAt"`
	IsBanned       bool         `json:"isBlocked"`
	Role           UserRole     `json:"role"`
	HasCustomTheme bool         `json:"hasCustomTheme"`
	About          UserAboutDto `json:"about"`
	Followers      int32        `json:"followers"`
	Following      int32        `json:"following"`
	BooksTotal     int32        `json:"booksTotal"`
	HideEmail      bool         `json:"hideEmail"`
	HideStats      bool         `json:"hideStats"`
	HideFavorites  bool         `json:"hideFavorites"`
	IsFollowing    bool         `json:"isFollowing"`
}

type UserFromSearchRequestDto

type UserFromSearchRequestDto struct {
	ID     uuid.UUID `json:"id"`
	Name   string    `json:"name"`
	Avatar string    `json:"avatar"`
}

type UserListResponse

type UserListResponse struct {
	Users      []UserSearchItem `json:"users"`
	Total      int32            `json:"total"`
	Page       uint32           `json:"page"`
	TotalPages int32            `json:"totalPages"`
}

type UserModerationSettings

type UserModerationSettings struct {
	ShowAdultContent bool       `json:"showAdultContent"`
	CensoredTags     []string   `json:"censoredTags"`
	CensoredTagsMode CensorMode `json:"censoredTagsMode"`
}

type UserPrivacySettings

type UserPrivacySettings struct {
	HideStats      bool `json:"hideStats"`
	HideFavorites  bool `json:"hideFavorites"`
	HideComments   bool `json:"hideComments"`
	HideEmail      bool `json:"hideEmail"`
	AllowSearching bool `json:"allowSearching"`
}

type UserRole

type UserRole string

func ParseUserRole

func ParseUserRole(role string) (UserRole, error)

func (UserRole) IsAdmin

func (r UserRole) IsAdmin() bool

func (UserRole) IsModOrHigher

func (r UserRole) IsModOrHigher() bool

type UserSearchItem

type UserSearchItem struct {
	ID       uuid.UUID
	Name     string
	Role     UserRole
	IsBanned bool
	JoinedAt time.Time
	Avatar   string
}

type UserService

type UserService interface {
	GetUserPrivacySettings(ctx context.Context, userID uuid.UUID) (*UserPrivacySettings, error)
	GetUserModerationSettings(ctx context.Context, userID uuid.UUID) (*UserModerationSettings, error)
	GetUserCustomizationSettings(ctx context.Context, userID uuid.UUID) (*UserCustomizationSetting, error)
	GetUserAboutSettings(ctx context.Context, userID uuid.UUID) (*UserAboutSettings, error)

	UpdateUserPrivacySettings(ctx context.Context, userID uuid.UUID, settings UserPrivacySettings) error
	UpdateUserModerationSettings(ctx context.Context, userID uuid.UUID, settings UserModerationSettings) error
	UpdateUserCustomizationSettings(ctx context.Context, userID uuid.UUID, settings UserCustomizationSetting) error
	UpdateUserAboutSettings(ctx context.Context, userID uuid.UUID, settings UserAboutSettings) error

	UpdateUser(ctx context.Context, cmd UpdateUserCommand) error

	GetUserDetails(ctx context.Context, query GetUserQuery) (*UserDetailsDto, error)
	GetUserSelfData(ctx context.Context, userID uuid.UUID) (*SelfUserDto, error)

	FollowUser(ctx context.Context, cmd FollowUserCommand) error
	UnfollowUser(ctx context.Context, cmd UnfollowUserCommand) error

	ListUsers(ctx context.Context, req UsersQuery) (UserListResponse, error)
}

func NewUserService

func NewUserService(db DB) UserService

type UsersQuery

type UsersQuery struct {
	Banned bool
	Role   []UserRole
	Query  string

	Page     uint32
	PageSize uint32
}

type VerifyEmailCommand

type VerifyEmailCommand struct {
	UserID uuid.UUID
	Code   string
}

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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