service

package
v0.0.0-...-500fbbb Latest Latest
Warning

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

Go to latest
Published: Aug 23, 2026 License: MIT Imports: 39 Imported by: 0

Documentation

Overview

Package service — newgroup(소모임 개설 신청) 안내 자동 댓글.

Index

Constants

View Source
const (
	PostsIndex    = "angple_posts"
	CommentsIndex = "angple_comments"
)
View Source
const AdvertiserPolicyModeShadow = "shadow"
View Source
const MaxBlocksJSONBytes = 100 * 1024

MaxBlocksJSONBytes caps the size of the blocks JSON document to keep DB rows small. 100 KB matches the §6 R2 risk mitigation in the PoC Sprint Contract.

Variables

View Source
var (
	// ErrRatingOutOfRange 별점 범위(1~5) 밖 → 400
	ErrRatingOutOfRange = errors.New("별점은 1~5 사이여야 합니다")
	// ErrRatingDisabled features.rating 미설정 보드 → 403
	ErrRatingDisabled = errors.New("이 게시판에서는 별점 기능을 사용할 수 없습니다")
	// ErrRatingLevelTooLow 등급 미달 → 403
	ErrRatingLevelTooLow = errors.New("앙님 등급부터 별점을 남길 수 있습니다")
)

Post rating errors — handler 가 HTTP 상태코드로 매핑한다.

View Source
var (
	ErrSiteNotFound     = errors.New("site not found")
	ErrSubdomainTaken   = errors.New("subdomain already taken")
	ErrInvalidSubdomain = errors.New("invalid subdomain format")
	ErrSiteInactive     = errors.New("site is inactive")
	ErrSiteSuspended    = errors.New("site is suspended")
	ErrUnauthorized     = errors.New("unauthorized access")
	ErrInvalidPlan      = errors.New("invalid plan")
)

Functions

func ApplyReportAutoLock

func ApplyReportAutoLock(db *gorm.DB, boTable string, sgID, sgParent int)

ApplyReportAutoLock 은 신고 접수 직후 호출되어, 해당 콘텐츠의 고유 신고자 수가 임계값 이상이면 wr_7 = 'lock' 을 세팅한다.

게시글 신고는 sgID == sgParent, 댓글 신고는 sgID != sgParent 로 구분한다. 게시글과 댓글은 각각 자기 자신에 대한 신고만 집계한다. 댓글 신고를 부모 글에 합산하면 본문 신고가 없는 글이 댓글 신고만으로 잠기기 때문이다.

이미 잠긴 콘텐츠는 조기 반환한다. 실패는 신고 접수 자체를 실패시키지 않으며, 로그만 남긴다.

func ApplyReportFreeze

func ApplyReportFreeze(db *gorm.DB, mbID string, reason string)

ApplyReportFreeze 는 작성자에게 냉각을 건다. 이미 더 긴 냉각이 있으면 연장하지 않는다. 실패는 잠금 자체를 실패시키지 않는다(로그만).

func ComputeFreezeUntil

func ComputeFreezeUntil(now time.Time, cfg FreezeConfig) time.Time

ComputeFreezeUntil 은 지금 잠긴 작성자의 냉각 만료 시각을 계산한다. 비활성이거나 계산 불가면 zero time 을 돌려준다(=냉각 없음).

func FrozenUntil

func FrozenUntil(db *gorm.DB, mbID string) time.Time

FrozenUntil 은 회원이 냉각 중이면 만료 시각을, 아니면 zero time 을 돌려준다. 만료된 행은 조회에서 자연히 제외되므로 해제 cron 이 필요 없다.

func IsGroupBoard

func IsGroupBoard(db *gorm.DB, slug string) bool

IsGroupBoard 는 slug 가 실제 존재하는 소모임 게시판인지 확인한다.

댓글의 유입 소모임은 클라이언트가 URL 파라미터로 보내는 값이라 위조가 가능하다. 반드시 이 화이트리스트를 통과한 값만 저장한다.

func IsNotFound

func IsNotFound(err error) bool

IsNotFound is a convenience helper for handler error mapping.

func PostNewgroupGuideComment

func PostNewgroupGuideComment(db *gorm.DB, wrID int) error

PostNewgroupGuideComment 는 newgroup 새 글(신청)에 안내 댓글을 단다.

멱등: 같은 글에 ai 계정 댓글이 이미 있으면 아무것도 하지 않는다 — write_after 이벤트 재시도·중복 발행에 안전하다. 공지 등 신청이 아닌 글을 거르는 판단은 하지 않는다(신청 카테고리 여부는 작성 시점에 알 수 없는 경우가 있어, newgroup 의 원글 전체를 대상으로 한다).

func ReportLockThreshold

func ReportLockThreshold(db *gorm.DB) int

ReportLockThreshold 는 자동 잠금 임계값(고유 신고자 수)을 반환한다. 값이 없거나 0 이하이면 0 을 반환하며, 이 경우 자동 잠금은 수행하지 않는다.

Types

type AdvertiserBoardPolicyService

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

AdvertiserBoardPolicyService evaluates board-specific advertiser policy. The service is designed to be safe-by-default: - no policy row => no effect - disabled policy => no effect - current rollout uses shadow mode only

func (*AdvertiserBoardPolicyService) EvaluateWrite

type BoardWriteRestrictionService

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

BoardWriteRestrictionService enforces per-board writing restrictions based on v2_board_extended_settings WritingSettings.

func NewBoardWriteRestrictionService

func NewBoardWriteRestrictionService(db *gorm.DB, repo v2repo.BoardExtendedSettingsRepository) *BoardWriteRestrictionService

NewBoardWriteRestrictionService creates a new BoardWriteRestrictionService.

func (*BoardWriteRestrictionService) Check

func (s *BoardWriteRestrictionService) Check(boardSlug, memberID string, memberLevel int) (*WriteRestrictionResult, error)

Check verifies whether the given member can write to the specified board.

func (*BoardWriteRestrictionService) CompareWithAdvertiserPolicy

func (s *BoardWriteRestrictionService) CompareWithAdvertiserPolicy(boardSlug, memberID string, memberLevel int) (*PolicyComparison, error)

CompareWithAdvertiserPolicy performs a dry-run comparison of base write restriction versus advertiser-policy-adjusted restriction.

func (*BoardWriteRestrictionService) SetAdvertiserPolicyService

func (s *BoardWriteRestrictionService) SetAdvertiserPolicyService(svc *AdvertiserBoardPolicyService)

SetAdvertiserPolicyService sets the advertiser policy service for shadow-mode comparison.

type CommentDocument

type CommentDocument struct {
	BoardID   string `json:"board_id"`
	PostID    int    `json:"post_id"`
	CommentID int    `json:"comment_id"`
	Content   string `json:"content"`
	Author    string `json:"author"`
	AuthorID  string `json:"author_id"`
	CreatedAt string `json:"created_at"`
}

CommentDocument represents a comment indexed in Elasticsearch

type ExtendedSettingsJSON

type ExtendedSettingsJSON struct {
	Writing *WritingSettings `json:"writing,omitempty"`
}

ExtendedSettingsJSON represents the top-level JSON structure of v2_board_extended_settings.settings.

type FreezeConfig

type FreezeConfig struct {
	DayMinutes   int    // system:report_freeze_minutes (0 = 비활성)
	NightStart   string // system:report_freeze_night_start  "00:00"
	NightUntil   string // system:report_freeze_night_until  "09:00" (빈값 = 야간도 주간 규칙)
	WeekendUntil string // system:report_freeze_weekend_until (빈값 = 주말도 야간/주간 규칙 = A)
}

FreezeConfig 는 kv_store 에서 읽은 냉각 설정이다.

func LoadFreezeConfig

func LoadFreezeConfig(db *gorm.DB) FreezeConfig

LoadFreezeConfig 는 kv_store 에서 냉각 설정을 읽는다. 미설정이면 비활성(0분).

type GroupGlobalNotice

type GroupGlobalNotice struct {
	Board   string `json:"board"`
	WrID    int    `json:"wr_id"`
	Enabled bool   `json:"enabled"`
}

GroupGlobalNotice 는 소모임(gr_id='group') 전 게시판 상단에 공통으로 노출할 공지 1건의 설정이다.

소모임마다 글을 복제하지 않고 원본 글 하나를 각 게시판 공지 응답에 끼워 넣는다. 복제하지 않는 이유는 댓글 때문이다 — 글이 91개로 갈라지면 의견도 91곳에 흩어진다.

설정은 g5_kv_store 에 두어 배포 없이 켜고 끌 수 있다.

`key`      system:group_global_notice
value_text {"board":"notice","wr_id":18300,"enabled":true}

func LoadGroupGlobalNotice

func LoadGroupGlobalNotice(db *gorm.DB) *GroupGlobalNotice

LoadGroupGlobalNotice 는 전역 공지 설정을 반환한다. 미설정·비활성·파싱 실패면 nil 이다.

설정이 깨져 있다고 공지 API 전체가 죽으면 안 되므로 모든 실패는 nil 로 떨어진다 (= 전역 공지 기능만 꺼진 상태, 기존 게시판 공지는 그대로 동작).

type MediaService

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

MediaService handles file uploads with image processing and S3 storage

func NewMediaService

func NewMediaService(s3Client *storage.S3Client) *MediaService

NewMediaService creates a new MediaService

func (*MediaService) DeleteFile

func (s *MediaService) DeleteFile(ctx context.Context, key string) error

DeleteFile removes a file from storage after validating the key prefix

func (*MediaService) GetCDNURL

func (s *MediaService) GetCDNURL(key string) string

GetCDNURL returns the CDN URL for a storage key

func (*MediaService) UploadAttachment

func (s *MediaService) UploadAttachment(ctx context.Context, file *multipart.FileHeader) (*MediaUploadResult, error)

UploadAttachment uploads a general file attachment

func (*MediaService) UploadImage

func (s *MediaService) UploadImage(ctx context.Context, file *multipart.FileHeader, maxWidth int) (*MediaUploadResult, error)

UploadImage uploads an image, optionally converting to JPEG and resizing

func (*MediaService) UploadVideo

func (s *MediaService) UploadVideo(ctx context.Context, file *multipart.FileHeader) (*MediaUploadResult, error)

UploadVideo uploads a video file

type MediaUploadResult

type MediaUploadResult struct {
	Key         string `json:"key"`
	URL         string `json:"url"`
	CDNURL      string `json:"cdn_url,omitempty"`
	OriginURL   string `json:"origin_url,omitempty"`
	Filename    string `json:"filename"`
	ContentType string `json:"content_type"`
	Size        int64  `json:"size"`
	Width       int    `json:"width,omitempty"`
	Height      int    `json:"height,omitempty"`
}

UploadResult represents the result of an upload operation

type MemberActivityBackfillReport

type MemberActivityBackfillReport struct {
	Scope             string
	BoardSlug         string
	PostCount         int64
	CommentCount      int64
	ProcessedPosts    int64
	ProcessedComments int64
}

type MemberActivitySyncService

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

func NewMemberActivitySyncService

func NewMemberActivitySyncService(db *gorm.DB) *MemberActivitySyncService

func (*MemberActivitySyncService) BackfillLegacyBoard

func (s *MemberActivitySyncService) BackfillLegacyBoard(boardSlug string, batchSize int) (*MemberActivityBackfillReport, error)

func (*MemberActivitySyncService) BackfillV2

func (s *MemberActivitySyncService) BackfillV2(batchSize int) (*MemberActivityBackfillReport, error)

func (*MemberActivitySyncService) RemoveLegacyComment

func (s *MemberActivitySyncService) RemoveLegacyComment(boardSlug string, wrID int) error

func (*MemberActivitySyncService) RemoveLegacyPost

func (s *MemberActivitySyncService) RemoveLegacyPost(boardSlug string, wrID int) error

func (*MemberActivitySyncService) SyncComment

func (s *MemberActivitySyncService) SyncComment(commentID uint64) error

func (*MemberActivitySyncService) SyncLegacyComment

func (s *MemberActivitySyncService) SyncLegacyComment(boardSlug string, wrID int) error

func (*MemberActivitySyncService) SyncLegacyPost

func (s *MemberActivitySyncService) SyncLegacyPost(boardSlug string, wrID int) error

func (*MemberActivitySyncService) SyncPost

func (s *MemberActivitySyncService) SyncPost(postID uint64) error

func (*MemberActivitySyncService) VerifyLegacyBoard

func (s *MemberActivitySyncService) VerifyLegacyBoard(boardSlug string) (*MemberActivityVerifyReport, error)

func (*MemberActivitySyncService) VerifyV2

type MemberActivityVerifyReport

type MemberActivityVerifyReport struct {
	Scope                 string
	BoardSlug             string
	SourcePosts           int64
	FeedPosts             int64
	SourceComments        int64
	FeedComments          int64
	SourceDeletedPosts    int64
	FeedDeletedPosts      int64
	SourceDeletedComments int64
	FeedDeletedComments   int64
}

type MemberService

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

MemberService handles member profile image operations

func NewMemberService

func NewMemberService(s3Client *storage.S3Client, memberRepo gnurepo.MemberRepository) *MemberService

NewMemberService creates a new MemberService

func (*MemberService) DeleteMemberImage

func (s *MemberService) DeleteMemberImage(ctx context.Context, mbID string) error

DeleteMemberImage removes a member's profile image

func (*MemberService) UpdateMemberImage

func (s *MemberService) UpdateMemberImage(ctx context.Context, mbID string, file *multipart.FileHeader) (string, error)

UpdateMemberImage processes and uploads a member profile image

type OAuthService

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

OAuthService handles OAuth2 social login flows

func NewOAuthService

func NewOAuthService(db *gorm.DB, jwtManager *jwt.Manager) *OAuthService

NewOAuthService creates a new OAuthService

func (*OAuthService) GenerateAPIKey

func (s *OAuthService) GenerateAPIKey(ctx context.Context, userID, name, scopes string) (*domain.APIKey, error)

GenerateAPIKey creates a new API key for a user

func (*OAuthService) GetAuthURL

func (s *OAuthService) GetAuthURL(provider domain.OAuthProvider, state string) (string, error)

GetAuthURL returns the OAuth authorization URL for the given provider

func (*OAuthService) HandleCallback

func (s *OAuthService) HandleCallback(ctx context.Context, provider domain.OAuthProvider, code string) (*domain.OAuthLoginResponse, error)

HandleCallback exchanges the authorization code for tokens and user info

func (*OAuthService) RegisterProvider

func (s *OAuthService) RegisterProvider(provider domain.OAuthProvider, cfg *domain.OAuthConfig)

RegisterProvider registers an OAuth provider configuration

func (*OAuthService) ValidateAPIKey

func (s *OAuthService) ValidateAPIKey(ctx context.Context, key string) (*domain.APIKey, error)

ValidateAPIKey checks if a key is valid and returns the associated record

type PolicyComparison

type PolicyComparison struct {
	Base      *WriteRestrictionResult `json:"base"`
	Policy    interface{}             `json:"policy"`
	Candidate *WriteRestrictionResult `json:"candidate"`
}

PolicyComparison holds the base and candidate restriction results for dry-run comparison.

type PostDocument

type PostDocument struct {
	BoardID   string `json:"board_id"`
	PostID    int    `json:"post_id"`
	Title     string `json:"title"`
	Content   string `json:"content"`
	Author    string `json:"author"`
	AuthorID  string `json:"author_id"`
	Category  string `json:"category"`
	CreatedAt string `json:"created_at"`
	Views     int    `json:"views"`
	Good      int    `json:"good"`
	// For autocomplete
	TitleSuggest map[string]interface{} `json:"title_suggest,omitempty"`
}

PostDocument represents a post indexed in Elasticsearch

type PostRatingService

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

PostRatingService implements the post star rating feature (★1~5, 회원당 1표). features.rating 토글이 켜진 게시판에서만 투표를 허용한다.

func NewPostRatingService

func NewPostRatingService(repo repository.PostRatingRepository, extendedSettingsRepo v2repo.BoardExtendedSettingsRepository) *PostRatingService

NewPostRatingService creates a new PostRatingService.

func (*PostRatingService) Enabled

func (s *PostRatingService) Enabled(boardSlug string) bool

Enabled reports whether the board has features.rating turned on (v2_board_extended_settings.settings → $.features.rating == true). 설정 누락·파싱 오류 시 비활성으로 간주한다(fail-closed).

func (*PostRatingService) Rate

func (s *PostRatingService) Rate(boardSlug string, wrID int, mbID string, mbLevel int, rating int) (*RatingSummary, error)

Rate records (or updates) the member's star rating and returns the new aggregate.

func (*PostRatingService) Summary

func (s *PostRatingService) Summary(boardSlug string, wrID int, mbID string) (*RatingSummary, error)

Summary returns the aggregate rating for a post (my=0 for guests / non-voters). avg 는 소수 1자리 반올림.

type ProvisioningService

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

ProvisioningService handles one-click community creation and subscription management

func NewProvisioningService

func NewProvisioningService(
	siteRepo *repository.SiteRepository,
	subRepo *repository.SubscriptionRepository,
	dbResolver *middleware.TenantDBResolver,
	db *gorm.DB,
	baseDomain string,
) *ProvisioningService

NewProvisioningService creates a new ProvisioningService

func (*ProvisioningService) CancelSubscription

func (s *ProvisioningService) CancelSubscription(ctx context.Context, siteID string) error

CancelSubscription cancels the subscription at period end

func (*ProvisioningService) ChangePlan

func (s *ProvisioningService) ChangePlan(ctx context.Context, siteID string, req *domain.ChangePlanRequest) error

ChangePlan upgrades or downgrades the subscription

func (*ProvisioningService) DeleteCommunity

func (s *ProvisioningService) DeleteCommunity(ctx context.Context, siteID string) error

DeleteCommunity deactivates a community and its subscription

func (*ProvisioningService) GetInvoices

func (s *ProvisioningService) GetInvoices(ctx context.Context, siteID string, page, perPage int) ([]domain.Invoice, int64, error)

GetInvoices returns invoices for a site

func (*ProvisioningService) GetPricing

func (s *ProvisioningService) GetPricing() []domain.PlanPricing

GetPricing returns plan pricing info

func (*ProvisioningService) GetSubscription

func (s *ProvisioningService) GetSubscription(ctx context.Context, siteID string) (*domain.SubscriptionResponse, error)

GetSubscription returns the subscription for a site

func (*ProvisioningService) ProvisionCommunity

ProvisionCommunity creates a new community site with all required infrastructure

type RatingSummary

type RatingSummary struct {
	Avg   float64 `json:"avg"`
	Count int64   `json:"count"`
	My    int     `json:"my"`
}

RatingSummary is the aggregate response payload: {"avg", "count", "my"}.

type SearchService

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

SearchService provides Elasticsearch-based search

func NewSearchService

func NewSearchService(esClient *es.Client, db *gorm.DB) *SearchService

NewSearchService creates a new SearchService

func (*SearchService) Autocomplete

func (s *SearchService) Autocomplete(ctx context.Context, prefix string, size int) ([]string, error)

Autocomplete returns title suggestions

func (*SearchService) BulkIndexPosts

func (s *SearchService) BulkIndexPosts(ctx context.Context, boardID string, limit int) (int, error)

BulkIndexPosts indexes multiple posts from the database (for initial sync)

func (*SearchService) DeleteComment

func (s *SearchService) DeleteComment(ctx context.Context, boardID string, postID, commentID int) error

DeleteComment removes a comment from the index

func (*SearchService) DeletePost

func (s *SearchService) DeletePost(ctx context.Context, boardID string, postID int) error

DeletePost removes a post from the index

func (*SearchService) IndexComment

func (s *SearchService) IndexComment(ctx context.Context, doc *CommentDocument) error

IndexComment indexes a single comment

func (*SearchService) IndexPost

func (s *SearchService) IndexPost(ctx context.Context, doc *PostDocument) error

IndexPost indexes a single post

func (*SearchService) SearchComments

func (s *SearchService) SearchComments(ctx context.Context, keyword, boardID string, page, perPage int) (*es.SearchResponse, error)

SearchComments searches comments with highlighting

func (*SearchService) SearchPosts

func (s *SearchService) SearchPosts(ctx context.Context, keyword, boardID string, page, perPage int) (*es.SearchResponse, error)

SearchPosts searches posts with highlighting

func (*SearchService) UnifiedSearch

func (s *SearchService) UnifiedSearch(ctx context.Context, keyword, boardID, searchType string, page, perPage int) (map[string]interface{}, error)

UnifiedSearch searches across both posts and comments

type SiteContentService

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

SiteContentService implements the business logic for the Angple Sites builder (issue #1288 PoC). All methods are safe to call concurrently.

func NewSiteContentService

func NewSiteContentService(repo *repository.SiteContentRepository) *SiteContentService

NewSiteContentService constructs a SiteContentService.

func (*SiteContentService) Delete

func (s *SiteContentService) Delete(
	ctx context.Context, siteID int64, contentKey string,
) error

Delete removes the content row for (site_id, content_key).

func (*SiteContentService) Get

func (s *SiteContentService) Get(
	ctx context.Context, siteID int64, contentKey string,
) (*domain.AngpleSiteContent, error)

Get returns the content row for (site_id, content_key). Returns common.ErrNotFound if the row does not exist.

func (*SiteContentService) Upsert

Upsert validates and persists the content for (site_id, content_key).

type SiteService

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

func NewSiteService

func NewSiteService(repo *repository.SiteRepository) *SiteService

func (*SiteService) AddOwnerPermission

func (s *SiteService) AddOwnerPermission(ctx context.Context, siteID, userID string) error

AddOwnerPermission adds owner permission to site creator

func (*SiteService) CheckUserPermission

func (s *SiteService) CheckUserPermission(ctx context.Context, siteID, userID string, requiredRole string) (bool, error)

CheckUserPermission checks if user has permission for a site

func (*SiteService) Create

Create creates a new site with initial settings

func (*SiteService) GetByID

func (s *SiteService) GetByID(ctx context.Context, siteID string) (*domain.SiteResponse, error)

GetByID retrieves a site by ID with settings

func (*SiteService) GetBySubdomain

func (s *SiteService) GetBySubdomain(ctx context.Context, subdomain string) (*domain.SiteResponse, error)

GetBySubdomain retrieves a site by subdomain with settings

func (*SiteService) GetSettings

func (s *SiteService) GetSettings(ctx context.Context, siteID string) (*domain.SiteSettings, error)

GetSettings retrieves site settings

func (*SiteService) ListActive

func (s *SiteService) ListActive(ctx context.Context, limit, offset int) ([]domain.SiteResponse, error)

ListActive retrieves all active sites

func (*SiteService) UpdateSettings

func (s *SiteService) UpdateSettings(ctx context.Context, siteID string, req *domain.UpdateSiteSettingsRequest) error

UpdateSettings updates site settings

func (*SiteService) ValidateSubdomain

func (s *SiteService) ValidateSubdomain(subdomain string) bool

ValidateSubdomain checks if subdomain follows rules: - 3-50 characters - alphanumeric and hyphens only - cannot start/end with hyphen - reserved subdomains blocked

type SocialInviteService

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

func (*SocialInviteService) ConfirmInvite

func (s *SocialInviteService) ConfirmInvite(token string, currentUserMbID string) error

func (*SocialInviteService) CreateInvite

func (s *SocialInviteService) CreateInvite(targetMbID string, adminID string) (*domain.SocialInviteCreateResponse, error)

func (*SocialInviteService) GetInviteInfo

func (s *SocialInviteService) GetInviteInfo(token string, currentUserMbID string) (*domain.SocialInviteInfoResponse, error)

type TenantDetail

type TenantDetail struct {
	Site     *domain.SiteResponse  `json:"site"`
	Settings *domain.SiteSettings  `json:"settings"`
	Limits   middleware.PlanLimits `json:"limits"`
	Users    []domain.SiteUser     `json:"users"`
}

TenantDetail tenant detail response

type TenantService

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

TenantService handles tenant management business logic

func NewTenantService

func NewTenantService(siteRepo *repository.SiteRepository, db *gorm.DB, dbResolver *middleware.TenantDBResolver) *TenantService

NewTenantService creates a new TenantService

func (*TenantService) ChangePlan

func (s *TenantService) ChangePlan(ctx context.Context, siteID, newPlan string) error

ChangePlan changes a tenant's subscription plan

func (*TenantService) GetTenantDetail

func (s *TenantService) GetTenantDetail(ctx context.Context, siteID string) (*TenantDetail, error)

GetTenantDetail returns full tenant details with limits and users

func (*TenantService) GetUsage

func (s *TenantService) GetUsage(ctx context.Context, siteID string, days int) (*UsageStats, error)

GetUsage returns usage stats for a tenant over the given number of days

func (*TenantService) ListTenants

func (s *TenantService) ListTenants(ctx context.Context, page, perPage int, status string) ([]domain.SiteResponse, int64, error)

ListTenants lists tenants with optional status filter

func (*TenantService) SuspendTenant

func (s *TenantService) SuspendTenant(ctx context.Context, siteID, _ string) error

SuspendTenant suspends a tenant

func (*TenantService) UnsuspendTenant

func (s *TenantService) UnsuspendTenant(ctx context.Context, siteID string) error

UnsuspendTenant unsuspends a tenant

type UsageStats

type UsageStats struct {
	SiteID          string             `json:"site_id"`
	Period          string             `json:"period"`
	TotalPageViews  int64              `json:"total_page_views"`
	TotalVisitors   int64              `json:"total_unique_visitors"`
	TotalAPICalls   int64              `json:"total_api_calls"`
	TotalPosts      int64              `json:"total_posts_created"`
	TotalComments   int64              `json:"total_comments_created"`
	StorageUsedMB   float64            `json:"storage_used_mb"`
	BandwidthUsedMB float64            `json:"bandwidth_used_mb"`
	DailyUsage      []domain.SiteUsage `json:"daily_usage"`
}

UsageStats represents usage statistics for a tenant

type WriteRestrictionResult

type WriteRestrictionResult struct {
	CanWrite   bool   `json:"can_write"`
	Remaining  int    `json:"remaining"`   // -1 = unlimited
	DailyLimit int    `json:"daily_limit"` // 0 = unlimited
	TotalLimit int    `json:"total_limit"` // 0 = unlimited
	TotalCount int    `json:"total_count"`
	Reason     string `json:"reason,omitempty"`
}

WriteRestrictionResult is returned by Check to indicate whether a member can write.

type WritingSettings

type WritingSettings struct {
	MaxPosts            int    `json:"maxPosts,omitempty"`
	MaxPostsTotal       int    `json:"maxPostsTotal,omitempty"`
	AllowedLevels       string `json:"allowedLevels,omitempty"`
	RestrictedUsers     bool   `json:"restrictedUsers,omitempty"`
	MemberOnly          bool   `json:"memberOnly,omitempty"`
	MemberOnlyPermit    string `json:"memberOnlyPermit,omitempty"`
	AllowedMembersOne   string `json:"allowedMembersOne,omitempty"`
	AllowedMembersTwo   string `json:"allowedMembersTwo,omitempty"`
	AllowedMembersThree string `json:"allowedMembersThree,omitempty"`
}

WritingSettings mirrors the frontend WritingSettings interface from v2_board_extended_settings JSON.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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