initial commit

This commit is contained in:
m.zare
2026-04-10 18:25:21 +03:30
commit 77ca6c34a3
263 changed files with 34470 additions and 0 deletions

17
internal/dto/account.go Normal file
View File

@@ -0,0 +1,17 @@
package dto
import (
"github.com/google/uuid"
)
// UserInfoResponse is a flat response with user and profile_id.
type UserInfoResponse struct {
ID uuid.UUID `json:"id"`
Email string `json:"email"`
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
PhoneNumber string `json:"phone_number"`
EmailVerified bool `json:"email_verified"`
Status string `json:"status"`
ProfileID *uuid.UUID `json:"profile_id,omitempty"`
}

138
internal/dto/asset.go Normal file
View File

@@ -0,0 +1,138 @@
package dto
import (
"base/pkg/validation"
"github.com/google/uuid"
)
type CreateAssetRequest struct {
ProfileID string `json:"profile_id"`
AssetCategoryID string `json:"asset_category_id"`
Title string `json:"title"`
Description string `json:"description"`
Link string `json:"link"`
}
func (*CreateAssetRequest) Schema() validation.Schema {
return validation.Schema{
"profile_id": validation.Rule{Field: "profile_id", Type: validation.ValidationTypeString, Required: true},
"asset_category_id": validation.Rule{Field: "asset_category_id", Type: validation.ValidationTypeString, Required: true},
"title": validation.Rule{Field: "title", Type: validation.ValidationTypeString, Required: true},
}
}
type UpdateAssetRequest struct {
ID string `uri:"id"`
AssetCategoryID string `json:"asset_category_id"`
Title string `json:"title"`
Description string `json:"description"`
Link string `json:"link"`
Status *int `json:"status"`
}
func (*UpdateAssetRequest) Schema() validation.Schema {
return validation.Schema{
"id": validation.Rule{Field: "id", Type: validation.ValidationTypeString, Required: true},
}
}
type GetAssetRequest struct {
ID string `uri:"id"`
}
func (*GetAssetRequest) Schema() validation.Schema {
return validation.Schema{
"id": validation.Rule{Field: "id", Type: validation.ValidationTypeString, Required: true},
}
}
type ListAssetsByProfileRequest struct {
ProfileID string `uri:"id"`
}
func (*ListAssetsByProfileRequest) Schema() validation.Schema {
return validation.Schema{
"ProfileID": validation.Rule{Field: "profile_id", Type: validation.ValidationTypeString, Required: true},
}
}
type DeleteAssetRequest struct {
ID string `uri:"id"`
}
func (*DeleteAssetRequest) Schema() validation.Schema {
return validation.Schema{
"id": validation.Rule{Field: "id", Type: validation.ValidationTypeString, Required: true},
}
}
type AssetResponse struct {
ID uuid.UUID `json:"id"`
ProfileID uuid.UUID `json:"profile_id"`
OwnerID *uuid.UUID `json:"owner_id,omitempty"`
AssetCategoryID uuid.UUID `json:"asset_category_id"`
Title string `json:"title"`
Description string `json:"description"`
Link string `json:"link"`
CoverImage string `json:"cover_image,omitempty"`
Status int `json:"status"`
Category CategoryDTO `json:"category"`
CreatedAt string `json:"created_at"`
UpdatedAt string `json:"updated_at"`
}
type CategoryDTO struct {
ID uuid.UUID `json:"id"`
Name string `json:"name"`
Icon string `json:"icon"`
Color string `json:"color"`
CardType string `json:"card_type"`
Featured bool `json:"featured"`
Description string `json:"description"`
}
type ListAssetsResponse struct {
Assets []AssetResponse `json:"assets"`
}
// ListAssetsByCategoryIDResponse is paginated assets for a single category (Phase 2 of two-phase loading).
type ListAssetsByCategoryIDResponse struct {
Category CategoryDTO `json:"category"`
Assets []AssetResponse `json:"assets"`
Total int `json:"total"`
Page int `json:"page"`
PageSize int `json:"page_size"`
TotalPages int `json:"total_pages"`
}
type ListCategoriesResponse struct {
Categories []CategoryDTO `json:"categories"`
}
// CategoriesPreviewRequest holds the request body for POST /assets/categories/preview.
type CategoriesPreviewRequest struct {
CategoryIDs []string `json:"category_ids"`
AssetsPerCategory int `json:"assets_per_category"`
FeaturedOnly bool `json:"featured_only"`
}
func (*CategoriesPreviewRequest) Schema() validation.Schema {
return validation.Schema{
"category_ids": validation.Rule{Field: "category_ids", Type: validation.ValidationTypeArray, Required: false},
"assets_per_category": validation.Rule{Field: "assets_per_category", Type: validation.ValidationTypeInt, Required: false},
"featured_only": validation.Rule{Field: "featured_only", Type: validation.ValidationTypeBool, Required: false},
}
}
// CategoryWithPreviewAssetsDTO groups a category with up to N sample assets.
type CategoryWithPreviewAssetsDTO struct {
Category CategoryDTO `json:"category"`
Assets []AssetResponse `json:"assets"`
TotalAssets int `json:"total_assets,omitempty"`
HasMore bool `json:"has_more,omitempty"`
}
// CategoriesPreviewResponse is the response for POST /assets/categories/preview.
type CategoriesPreviewResponse struct {
Categories []CategoryWithPreviewAssetsDTO `json:"categories"`
}

291
internal/dto/auth.go Normal file
View File

@@ -0,0 +1,291 @@
package dto
import (
"github.com/google/uuid"
"base/internal/pkg/oauth"
"base/pkg/validation"
)
type RegisterRequest struct {
Email string `json:"email"`
Password string `json:"password"`
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
PhoneNumber string `json:"phone_number"`
}
func (*RegisterRequest) Schema() validation.Schema {
return validation.Schema{
"email": validation.Rule{
Field: "email",
Type: validation.ValidationTypeEmail,
Required: true,
},
"password": validation.Rule{
Field: "password",
Type: validation.ValidationTypeString,
MinLength: validation.IntPtr(8),
MaxLength: validation.IntPtr(32),
Required: true,
},
"first_name": validation.Rule{
Field: "first_name",
Type: validation.ValidationTypeString,
Required: true,
},
"last_name": validation.Rule{
Field: "last_name",
Type: validation.ValidationTypeString,
Required: true,
},
"phone_number": validation.Rule{
Field: "phone_number",
Type: validation.ValidationTypeString,
Required: false,
},
}
}
type LoginRequest struct {
Email string `json:"email"`
Password string `json:"password"`
}
func (*LoginRequest) Schema() validation.Schema {
return validation.Schema{
"email": validation.Rule{
Field: "email",
Type: validation.ValidationTypeEmail,
Required: true,
},
"password": validation.Rule{
Field: "password",
Type: validation.ValidationTypeString,
Required: true,
},
}
}
type TokenResponse struct {
AccessToken string `json:"access_token"`
RefreshToken string `json:"refresh_token"`
}
func (*TokenResponse) Schema() validation.Schema {
return validation.Schema{
"access_token": validation.Rule{
Field: "access_token",
Type: validation.ValidationTypeString,
Required: true,
},
"refresh_token": validation.Rule{
Field: "refresh_token",
Type: validation.ValidationTypeString,
Required: true,
},
}
}
type RefreshTokenRequest struct {
RefreshToken string `json:"refresh_token"`
}
func (*RefreshTokenRequest) Schema() validation.Schema {
return validation.Schema{
"refresh_token": validation.Rule{
Field: "refresh_token",
Type: validation.ValidationTypeString,
Required: true,
},
}
}
type SendVerificationEmailRequest struct {
Email string `json:"email"`
}
func (*SendVerificationEmailRequest) Schema() validation.Schema {
return validation.Schema{
"email": validation.Rule{
Field: "email",
Type: validation.ValidationTypeEmail,
Required: true,
},
}
}
type SetupProfileRequest struct {
Handle string `json:"handle"`
RoleID uuid.UUID `json:"role_id"`
RoleLevel string `json:"role_level"`
ShortDescription string `json:"short_description"`
}
func (*SetupProfileRequest) Schema() validation.Schema {
return validation.Schema{
"handle": validation.Rule{
Field: "handle",
Type: validation.ValidationTypeString,
MinLength: validation.IntPtr(2),
MaxLength: validation.IntPtr(80),
Required: true,
},
"role_id": validation.Rule{
Field: "role_id",
Type: validation.ValidationTypeUUID,
Required: false,
},
"role_level": validation.Rule{
Field: "role_level",
Type: validation.ValidationTypeString,
Required: false,
},
"short_description": validation.Rule{
Field: "short_description",
Type: validation.ValidationTypeString,
Required: false,
},
}
}
type VerifyAccountRequest struct {
Email string `json:"email"`
Code string `json:"code"`
}
func (*VerifyAccountRequest) Schema() validation.Schema {
return validation.Schema{
"email": validation.Rule{
Field: "email",
Type: validation.ValidationTypeEmail,
Required: true,
},
"code": validation.Rule{
Field: "code",
Type: validation.ValidationTypeString,
MinLength: validation.IntPtr(6),
MaxLength: validation.IntPtr(6),
Required: true,
},
}
}
type OAuthRedirectURLRequest struct {
Provider oauth.Provider `json:"provider"`
}
func (*OAuthRedirectURLRequest) Schema() validation.Schema {
return validation.Schema{
"provider": validation.Rule{
Field: "provider",
Path: "provider",
Type: validation.ValidationTypeString,
Required: true,
},
}
}
type OAuthRedirectURLResponse struct {
RedirectURL string `json:"redirect_url"`
}
func (*OAuthRedirectURLResponse) Schema() validation.Schema {
return validation.Schema{
"redirect_url": validation.Rule{
Field: "redirect_url",
Type: validation.ValidationTypeString,
Required: true,
},
}
}
type OAuthCallbackRequest struct {
Provider oauth.Provider `json:"provider"`
Code string `json:"code"`
}
func (*OAuthCallbackRequest) Schema() validation.Schema {
return validation.Schema{
"provider": validation.Rule{
Field: "provider",
Type: validation.ValidationTypeString,
Required: true,
},
"code": validation.Rule{
Field: "code",
Type: validation.ValidationTypeString,
Required: true,
},
}
}
type OAuthCallbackResponse struct {
AccessToken string `json:"access_token"`
RefreshToken string `json:"refresh_token"`
IsNewUser bool `json:"is_new_user"`
}
func (*OAuthCallbackResponse) Schema() validation.Schema {
return validation.Schema{
"access_token": validation.Rule{
Field: "access_token",
Type: validation.ValidationTypeString,
Required: true,
},
"refresh_token": validation.Rule{
Field: "refresh_token",
Type: validation.ValidationTypeString,
Required: true,
},
"is_new_user": validation.Rule{
Field: "is_new_user",
Type: validation.ValidationTypeBool,
Required: true,
},
}
}
type SendResetPasswordEmailRequest struct {
Email string `json:"email"`
}
func (*SendResetPasswordEmailRequest) Schema() validation.Schema {
return validation.Schema{
"email": validation.Rule{
Field: "email",
Type: validation.ValidationTypeEmail,
Required: true,
},
}
}
type ResetPasswordRequest struct {
Email string `json:"email"`
Code string `json:"code"`
Password string `json:"password"`
}
func (*ResetPasswordRequest) Schema() validation.Schema {
return validation.Schema{
"email": validation.Rule{
Field: "email",
Type: validation.ValidationTypeEmail,
Required: true,
},
"code": validation.Rule{
Field: "code",
Type: validation.ValidationTypeString,
MinLength: validation.IntPtr(6),
MaxLength: validation.IntPtr(6),
Required: true,
},
"password": validation.Rule{
Field: "password",
Type: validation.ValidationTypeString,
MinLength: validation.IntPtr(8),
MaxLength: validation.IntPtr(32),
Required: true,
},
}
}

7
internal/dto/base.go Normal file
View File

@@ -0,0 +1,7 @@
package dto
import "base/pkg/validation"
type DTO interface {
Schema() validation.Schema
}

26
internal/dto/blog.go Normal file
View File

@@ -0,0 +1,26 @@
package dto
import "time"
type Blog struct {
Id string `json:"id"`
Title string `json:"title"`
Content string `json:"content"`
Summary string `json:"summary"`
CoverImage string `json:"cover_image"`
ContentHtml string `json:"content_html"`
ContentJson interface{} `json:"content_json"`
Status string `json:"status"`
IsFeatured bool `json:"is_featured"`
ViewCount int `json:"view_count"`
Slug string `json:"slug"`
CategoryId string `json:"category_id"`
Category struct {
Id string `json:"id"`
Title string `json:"title"`
} `json:"category"`
MetaTags interface{} `json:"meta_tags"`
Author string `json:"author"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}

92
internal/dto/landing.go Normal file
View File

@@ -0,0 +1,92 @@
package dto
//type Landing struct {
// Message string `json:"message"`
// Data struct {
// Categories []struct {
// Id string `json:"id"`
// Title string `json:"title"`
// Featured bool `json:"featured"`
// Icon string `json:"icon"`
// Color string `json:"color"`
// CardType string `json:"card_type"`
// Order int `json:"order"`
// CreatedAt time.Time `json:"created_at"`
// UpdatedAt time.Time `json:"updated_at"`
// } `json:"categories"`
// SpecialistRole []struct {
// Id string `json:"id"`
// Title string `json:"title"`
// Status string `json:"status"`
// } `json:"specialist_role"`
// Assets []struct {
// Id string `json:"id"`
// Title string `json:"title"`
// Icon string `json:"icon"`
// Assets []struct {
// Id string `json:"id"`
// CoverImage string `json:"cover_image"`
// Title string `json:"title"`
// Avatar string `json:"avatar"`
// Description string `json:"description"`
// AuthorName string `json:"author_name"`
// Price int `json:"price"`
// Currency string `json:"currency"`
// CategoryId string `json:"category_id"`
// CategoryName string `json:"category_name"`
// CardType string `json:"card_type"`
// } `json:"assets"`
// } `json:"assets"`
// Specialists []struct {
// Id string `json:"id"`
// Handle string `json:"handle"`
// Avatar string `json:"avatar"`
// } `json:"specialists"`
// Blog []struct {
// Id string `json:"id"`
// Title string `json:"title"`
// Content string `json:"content"`
// Summary string `json:"summary"`
// CoverImage string `json:"cover_image"`
// ContentHtml string `json:"content_html"`
// ContentJson interface{} `json:"content_json"`
// Status string `json:"status"`
// IsFeatured bool `json:"is_featured"`
// ViewCount int `json:"view_count"`
// Slug string `json:"slug"`
// CategoryId string `json:"category_id"`
// Category struct {
// Id string `json:"id"`
// Title string `json:"title"`
// } `json:"category"`
// MetaTags interface{} `json:"meta_tags"`
// Author string `json:"author"`
// CreatedAt time.Time `json:"created_at"`
// UpdatedAt time.Time `json:"updated_at"`
// } `json:"blog"`
// } `json:"data"`
//}
type Landing struct {
Message string `json:"message"`
Data LandingPageData `json:"data"`
}
type AssetCategory struct {
Id string `json:"id"`
Title string `json:"title"`
Icon string `json:"icon"`
}
type LandingAssetData struct {
AssetCategory
Assets []AssetResponse `json:"assets"`
}
type LandingPageData struct {
Categories []CategoryDTO `json:"categories"`
SpecialistRoles []ProfileRole `json:"specialist_roles"`
Assets []LandingAssetData `json:"assets"`
Specialists []Specialist `json:"specialists"`
Blogs []Blog `json:"blogs"`
}

157
internal/dto/overview.go Normal file
View File

@@ -0,0 +1,157 @@
package dto
import "time"
// OverviewResponse is the dashboard response for authenticated users with a profile
type OverviewResponse struct {
Message string `json:"message"`
Data OverviewDataDTO `json:"data"`
}
type OverviewDataDTO struct {
Analytics AnalyticsDTO `json:"analytics"`
RecentlyJoined []FlatProfileDTO `json:"recently_joined"`
Assets []AssetResponse `json:"assets"`
CompletionPercent int `json:"completionPercent"`
Tasks TasksDTO `json:"tasks"`
}
// OverviewFetchedResponse matches "Overview fetched successfully" format (assets with content, cover_image, etc.)
type OverviewFetchedResponse struct {
Message string `json:"message"`
Data OverviewFetchedDataDTO `json:"data"`
}
type OverviewFetchedDataDTO struct {
Assets []OverviewAssetDTO `json:"assets"`
RecentlyJoined []FlatProfileDTO `json:"recently_joined"`
Analytics AnalyticsDTO `json:"analytics"`
}
// SpecialistOverviewFetchedDataDTO extends OverviewFetchedDataDTO with specialist's Profile, Skills, completionPercent, and tasks
type SpecialistOverviewFetchedDataDTO struct {
Assets []OverviewAssetDTO `json:"assets"`
RecentlyJoined []FlatProfileDTO `json:"recently_joined"`
Analytics AnalyticsDTO `json:"analytics"`
Profile *ProfileResponse `json:"profile,omitempty"`
Skills []SkillDTO `json:"skills,omitempty"`
CompletionPercent int `json:"completionPercent"`
Tasks TasksDTO `json:"tasks"`
}
// SpecialistOverviewFetchedResponse is the specialist overview response (includes Profile + Skills)
type SpecialistOverviewFetchedResponse struct {
Message string `json:"message"`
Data SpecialistOverviewFetchedDataDTO `json:"data"`
}
// OverviewAssetDTO is the full asset format for overview (content, cover_image, price, etc.)
type OverviewAssetDTO struct {
ID string `json:"id"`
Title string `json:"title"`
Description string `json:"description"`
Content string `json:"content"`
AssetCategoryID string `json:"asset_category_id"`
AssetCategory *CategoryDTO `json:"asset_category"`
CoverImage string `json:"cover_image"`
Link string `json:"link"`
OwnerID string `json:"owner_id"`
ProfileID string `json:"profile_id"`
Profile interface{} `json:"profile"`
Price int `json:"price"`
Currency string `json:"currency"`
Status string `json:"status"`
Rating int `json:"rating"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
type AnalyticsDTO struct {
TotalAssets int `json:"total_assets"`
TotalProfiles int `json:"total_profiles"`
}
// CategoryAssetsDTO groups assets under a category for discovery.
type CategoryAssetsDTO struct {
Category CategoryDTO `json:"category"`
Assets []OverviewAssetDTO `json:"assets"`
}
// CategoryAssetsPaginatedDTO groups paginated assets under a category.
type CategoryAssetsPaginatedDTO struct {
Category CategoryDTO `json:"category"`
Assets []OverviewAssetDTO `json:"assets"`
Total int `json:"total"`
Page int `json:"page"`
PageSize int `json:"page_size"`
TotalPages int `json:"total_pages"`
}
// ListAssetsByCategoryResponse is the paginated API response for assets by category.
type ListAssetsByCategoryResponse struct {
Data ListAssetsByCategoryResponseData `json:"data"`
}
// ListAssetsByCategoryResponseData holds the categories with paginated assets.
type ListAssetsByCategoryResponseData struct {
Categories []CategoryAssetsPaginatedDTO `json:"categories"`
}
// AssetsByCategoryResponse is the API response for assets grouped by category (at least 6 per category).
type AssetsByCategoryResponse struct {
Message string `json:"message"`
Data AssetsByCategoryResponseData `json:"data"`
}
type AssetsByCategoryResponseData struct {
Categories map[string]CategoryAssetsDTO `json:"categories"`
}
type TasksDTO struct {
ProfileAction bool `json:"profile_action"`
AboutAction bool `json:"about_action"`
PublishAction bool `json:"publish_action"`
WorksAction bool `json:"works_action"`
SkillsAction bool `json:"skills_action"`
SocialAction bool `json:"social_action"`
}
// FlatProfileDTO is the flat profile format for recently_joined and similar lists
type FlatProfileDTO struct {
ID string `json:"id"`
ProfileHandle string `json:"profile_handle"`
Status string `json:"status"`
BackgroundImage string `json:"background_image"`
ProfilePicture string `json:"profile_picture"`
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
DisplayName string `json:"display_name"`
RoleID string `json:"role_id"`
Role RoleDTO `json:"role"`
CurrentCompany string `json:"current_company"`
ShortDescription string `json:"short_description"`
CTAEnabled bool `json:"cta_enabled"`
CTAAction string `json:"cta_action"`
ResumeLink string `json:"resume_link"`
About string `json:"about"`
ContactEmail string `json:"contact_email"`
Achievements map[string]AchievementItemDTO `json:"achievements"`
ContactPhone string `json:"contact_phone"`
Country string `json:"country"`
CustomRoles string `json:"custom_roles"`
RoleLevel string `json:"role_level"`
SocialLinks []SocialLinkDTO `json:"social_links"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
HandleUpdatedAt time.Time `json:"handle_updated_at"`
}
type RoleDTO struct {
ID string `json:"ID"`
Name string `json:"Name"`
}
type AchievementItemDTO struct {
Value string `json:"value"`
Enabled bool `json:"enabled"`
}

190
internal/dto/profile.go Normal file
View File

@@ -0,0 +1,190 @@
package dto
import (
"base/pkg/validation"
"github.com/google/uuid"
)
type CreateProfileRequest struct {
Handle string `json:"handle"`
PageSectionOrder map[string]int `json:"page_section_order"`
Hero HeroDTO `json:"hero"`
About AboutDTO `json:"about"`
Skills []SkillDTO `json:"skills"`
Contact ContactDTO `json:"contact"`
PageSetting PageSettingDTO `json:"page_setting"`
}
func (*CreateProfileRequest) Schema() validation.Schema {
return validation.Schema{
"handle": validation.Rule{
Field: "handle",
Type: validation.ValidationTypeString,
Required: true,
},
}
}
type HeroDTO struct {
RoleID *uuid.UUID `json:"role_id"`
RoleLevel string `json:"role_level"`
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
Company string `json:"company"`
ShortDescription string `json:"short_description"`
ResumeLink string `json:"resume_link"`
CTAEnabled bool `json:"cta_enabled"`
Avatar string `json:"avatar"`
}
func (*HeroDTO) Schema() validation.Schema { return validation.Schema{} }
type AboutDTO struct {
ProfilePicture string `json:"profile_picture"`
About string `json:"about"`
Achievements []AchievementDTO `json:"achievements"`
}
type AchievementDTO struct {
Title string `json:"title"`
Value string `json:"value"`
Enabled bool `json:"enabled"`
}
type SkillDTO struct {
SkillName string `json:"skill_name"`
Level string `json:"level"`
}
type ContactDTO struct {
Email string `json:"email"`
Phone string `json:"phone"`
SocialLinks []SocialLinkDTO `json:"social_links"`
}
func (*ContactDTO) Schema() validation.Schema { return validation.Schema{} }
type SocialLinkDTO struct {
LinkType string `json:"link_type"`
Link string `json:"link"`
}
type PageSettingDTO struct {
VisibilityLevel string `json:"visibility_level"`
}
func (*PageSettingDTO) Schema() validation.Schema {
return validation.Schema{}
}
type UpdateProfileRequest struct {
ID string `uri:"id"`
Handle string `json:"handle"`
PageSectionOrder map[string]int `json:"page_section_order"`
Hero HeroDTO `json:"hero"`
About AboutDTO `json:"about"`
Skills []SkillDTO `json:"skills"`
Contact ContactDTO `json:"contact"`
PageSetting PageSettingDTO `json:"page_setting"`
}
func (*UpdateProfileRequest) Schema() validation.Schema {
return validation.Schema{
"id": validation.Rule{
Field: "id",
Type: validation.ValidationTypeString,
Required: true,
},
}
}
type GetProfileRequest struct {
ID string `uri:"id"`
}
func (*GetProfileRequest) Schema() validation.Schema {
return validation.Schema{
"id": validation.Rule{
Field: "id",
Type: validation.ValidationTypeString,
Required: true,
},
}
}
type GetProfileByHandleRequest struct {
Handle string `uri:"handle"`
}
func (*GetProfileByHandleRequest) Schema() validation.Schema {
return validation.Schema{
"handle": validation.Rule{
Field: "handle",
Type: validation.ValidationTypeString,
Required: true,
},
}
}
type ListProfilesRequest struct {
RoleID *uuid.UUID `form:"role_id"`
FirstName string `form:"first_name"`
LastName string `form:"last_name"`
Company string `form:"company"`
SkillName string `form:"skill_name"`
Page uint `form:"page"`
PageSize uint `form:"page_size"`
SortedBy string `form:"sorted_by"`
Ascending bool `form:"ascending"`
}
func (*ListProfilesRequest) Schema() validation.Schema {
return validation.Schema{}
}
type ProfileResponse struct {
ID uuid.UUID `json:"id"`
Handle string `json:"handle"`
PageSectionOrder map[string]int `json:"page_section_order"`
Hero HeroDTO `json:"hero"`
About AboutDTO `json:"about"`
Skills []SkillDTO `json:"skills"`
Contact ContactDTO `json:"contact"`
PageSetting PageSettingDTO `json:"page_setting"`
}
type ListProfilesResponse struct {
Profiles []ProfileResponse `json:"profiles"`
Total int `json:"total"`
Page uint `json:"page"`
PageSize uint `json:"page_size"`
}
type DeleteProfileRequest struct {
ID string `uri:"id"`
}
func (*DeleteProfileRequest) Schema() validation.Schema {
return validation.Schema{
"id": validation.Rule{
Field: "id",
Type: validation.ValidationTypeString,
Required: true,
},
}
}
// SkillsUpdateRequest for PUT page-sections/skills
type SkillsUpdateRequest struct {
Skills []SkillDTO `json:"skills"`
}
func (*SkillsUpdateRequest) Schema() validation.Schema { return validation.Schema{} }
// PageSectionsResponse for GET page-sections (hero, contact, skills, page_section_order)
type PageSectionsResponse struct {
Hero HeroDTO `json:"hero"`
Contact ContactDTO `json:"contact"`
Skills []SkillDTO `json:"skills"`
PageSectionOrder map[string]int `json:"page_section_order"`
}

107
internal/dto/response.go Normal file
View File

@@ -0,0 +1,107 @@
package dto
import "net/http"
// SuccessResponse represents a successful response for setting stock.
type SuccessResponse struct {
Message string `json:"message"`
Status int `json:"status" example:"200"`
}
// ErrorResponse represents a generic error response.
type ErrorResponse struct {
Message string `json:"message"`
Status int `json:"status" example:"400"`
}
type Response struct {
Message string `json:"message"`
Status int `json:"status"`
Data any `json:"data,omitempty"`
}
func OK() Response {
return Response{
Message: "OK",
Status: http.StatusOK,
}
}
func Created(data any) Response {
return Response{
Message: "Created",
Status: http.StatusCreated,
Data: data,
}
}
func BadRequest() Response {
return Response{
Message: "bad request",
Status: http.StatusBadRequest,
}
}
func NotFound() Response {
return Response{
Message: "not found",
Status: http.StatusNotFound,
}
}
func InternalServerError() Response {
return Response{
Message: "internal server error",
Status: http.StatusInternalServerError,
}
}
func UnprocessableEntity() Response {
return Response{
Message: "unprocessable entity",
Status: http.StatusUnprocessableEntity,
}
}
func UnprocessableEntityException() Response {
return Response{
Message: "unprocessable entity exception",
Status: http.StatusUnprocessableEntity,
}
}
func Forbidden() Response {
return Response{
Message: "forbidden",
Status: http.StatusForbidden,
}
}
func Unauthorized() Response {
return Response{
Message: "unauthorized",
Status: http.StatusUnauthorized,
}
}
func Conflict() Response {
return Response{
Message: "conflict",
Status: http.StatusConflict,
}
}
func (r Response) WithMessage(msg string) Response {
r.Message = msg
return r
}
func (r Response) WithStatus(status int) Response {
r.Status = status
return r
}
func (r Response) WithData(data any) Response {
r.Data = data
return r
}

50
internal/dto/role.go Normal file
View File

@@ -0,0 +1,50 @@
package dto
import "base/pkg/validation"
type ProfileRole struct {
Id string `json:"id"`
Title string `json:"title"`
}
type CreateProfileRoleRequest struct {
Title string `json:"title"`
}
func (*CreateProfileRoleRequest) Schema() validation.Schema {
return validation.Schema{
"title": validation.Rule{Field: "title", Type: validation.ValidationTypeString, Required: true},
"status": validation.Rule{Field: "status", Type: validation.ValidationTypeString, Required: true},
}
}
type UpdateProfileRoleRequest struct {
ID string `uri:"id"`
Title string `json:"title"`
}
func (*UpdateProfileRoleRequest) Schema() validation.Schema {
return validation.Schema{
"id": validation.Rule{Field: "id", Type: validation.ValidationTypeString, Required: true},
}
}
type GetProfileRoleRequest struct {
ID string `uri:"id"`
}
func (*GetProfileRoleRequest) Schema() validation.Schema {
return validation.Schema{
"id": validation.Rule{Field: "id", Type: validation.ValidationTypeString, Required: true},
}
}
type DeleteProfileRoleRequest struct {
ID string `uri:"id"`
}
func (*DeleteProfileRoleRequest) Schema() validation.Schema {
return validation.Schema{
"id": validation.Rule{Field: "id", Type: validation.ValidationTypeString, Required: true},
}
}

7
internal/dto/skill.go Normal file
View File

@@ -0,0 +1,7 @@
package dto
// Skill represents a selectable skill from the catalog (for profile skill selection).
type Skill struct {
ID string `json:"id"`
Name string `json:"name"`
}

View File

@@ -0,0 +1,7 @@
package dto
type Specialist struct {
Id string `json:"id"`
Handle string `json:"handle"`
Avatar string `json:"avatar"`
}