132 lines
5.5 KiB
Go
132 lines
5.5 KiB
Go
package model
|
|
|
|
import "time"
|
|
|
|
// Admin DTOs — read-only projections served only to admins via /api/v1/admin/*.
|
|
// They deliberately differ from the public-facing models: they may expose
|
|
// fields (email, role, reporter identity) that the normal API hides.
|
|
|
|
// AdminUser is a row in the admin users table.
|
|
type AdminUser struct {
|
|
ID string `json:"id"`
|
|
Email *string `json:"email"`
|
|
Handle string `json:"handle"`
|
|
Name string `json:"name"`
|
|
AvatarURL *string `json:"avatar_url"`
|
|
Role string `json:"role"`
|
|
Plan string `json:"plan"`
|
|
EmailVerifiedAt *time.Time `json:"email_verified_at"`
|
|
BannedAt *time.Time `json:"banned_at"`
|
|
// AdminRole is the staff role key, nil for ordinary accounts.
|
|
AdminRole *string `json:"admin_role,omitempty"`
|
|
PostCount int `json:"post_count"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
|
|
// Connected auth methods. HasPassword means email+password login is set up;
|
|
// Providers lists linked OAuth providers (e.g. "google", "facebook").
|
|
HasPassword bool `json:"has_password"`
|
|
Providers []string `json:"providers"`
|
|
|
|
// Effective save limits in force for this user (plan default merged with any
|
|
// admin override); -1 means unlimited. The admin UI pre-fills the "Edit
|
|
// limits" modal with these.
|
|
BookmarkLimit int `json:"bookmark_limit"`
|
|
PublicCollectionLimit int `json:"public_collection_limit"`
|
|
PrivateCollectionLimit int `json:"private_collection_limit"`
|
|
|
|
// Direct-disciple link. DiscipleID is the raw Mongo ObjectID stored on the
|
|
// users row; DiscipleName is hydrated from Mongo by the admin service so the
|
|
// panel can show who the account is linked to (nil when unlinked, or when
|
|
// the id no longer resolves to a disciple document).
|
|
DiscipleID *string `json:"disciple_id"`
|
|
DiscipleName *string `json:"disciple_name"`
|
|
}
|
|
|
|
// AdminDisciple is one option in the admin panel's disciple picker — enough to
|
|
// disambiguate similarly-named disciples, plus the handle of the account that
|
|
// already claims it (nil when free to link).
|
|
type AdminDisciple struct {
|
|
ID string `json:"id"`
|
|
InitiatedName string `json:"initiated_name"`
|
|
Suffix string `json:"suffix"`
|
|
InitiationDate *time.Time `json:"initiation_date"`
|
|
InitiationPlace *string `json:"initiation_place"`
|
|
// LinkedHandle is the @handle of the user already linked to this disciple,
|
|
// so the picker can grey the row out instead of failing on submit.
|
|
LinkedHandle *string `json:"linked_handle"`
|
|
}
|
|
|
|
// AdminPost is a row in the admin posts table.
|
|
type AdminPost struct {
|
|
ID string `json:"id"`
|
|
UserID string `json:"user_id"`
|
|
Caption string `json:"caption"`
|
|
SourceTitle string `json:"source_title"`
|
|
SourceURL string `json:"source_url"`
|
|
IsHidden bool `json:"is_hidden"`
|
|
DeletedAt *time.Time `json:"deleted_at"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
AuthorName string `json:"author_name"`
|
|
AuthorHandle string `json:"author_handle"`
|
|
LikesCount int `json:"likes_count"`
|
|
CommentsCount int `json:"comments_count"`
|
|
}
|
|
|
|
// AdminCollection is a row in the admin collections table.
|
|
type AdminCollection struct {
|
|
ID string `json:"id"`
|
|
UserID string `json:"user_id"`
|
|
Title string `json:"title"`
|
|
Description *string `json:"description"`
|
|
IsPublic bool `json:"is_public"`
|
|
ItemCount int `json:"item_count"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
OwnerName string `json:"owner_name"`
|
|
OwnerHandle string `json:"owner_handle"`
|
|
}
|
|
|
|
// AdminFeedback is a row in the admin feedback table (includes the reply).
|
|
type AdminFeedback struct {
|
|
ID string `json:"id"`
|
|
Category string `json:"category"`
|
|
Message string `json:"message"`
|
|
ContactEmail *string `json:"contact_email"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
AcknowledgedAt *time.Time `json:"acknowledged_at"`
|
|
ResolvedAt *time.Time `json:"resolved_at"`
|
|
RepliedAt *time.Time `json:"replied_at"`
|
|
ReplyMessage *string `json:"reply_message"`
|
|
AuthorHandle *string `json:"author_handle"`
|
|
AuthorName *string `json:"author_name"`
|
|
AuthorEmail *string `json:"author_email"`
|
|
}
|
|
|
|
// AdminReport is a unified projection over the three report tables
|
|
// (post_reports, comment_reports, user_reports). Type says which one.
|
|
type AdminReport struct {
|
|
ID string `json:"id"`
|
|
Type string `json:"type"` // "post" | "comment" | "user"
|
|
Category string `json:"category"`
|
|
Reason string `json:"reason"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
ResolvedAt *time.Time `json:"resolved_at"`
|
|
|
|
ReporterHandle *string `json:"reporter_handle"`
|
|
ReporterName *string `json:"reporter_name"`
|
|
|
|
// ResolutionNote is the admin's note left when resolving (nil while open).
|
|
ResolutionNote *string `json:"resolution_note"`
|
|
// TargetRemoved is true when the reported content is currently removed —
|
|
// a soft-deleted post/comment, or a banned account — so the UI can offer
|
|
// "Undo" instead of "Delete"/"Ban".
|
|
TargetRemoved bool `json:"target_removed"`
|
|
|
|
// Target of the report. TargetID is the post/comment/user id; TargetText
|
|
// is the post caption, comment body, or reported user's handle so the
|
|
// admin sees what was flagged without a second fetch. TargetAuthorHandle
|
|
// is the handle of the content's author (nil for user reports).
|
|
TargetID string `json:"target_id"`
|
|
TargetText *string `json:"target_text"`
|
|
TargetAuthorHandle *string `json:"target_author_handle"`
|
|
}
|