implement graphQL and init postgres
This commit is contained in:
148
local/model/project.go
Normal file
148
local/model/project.go
Normal file
@@ -0,0 +1,148 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// Project represents a project in the system
|
||||
type Project struct {
|
||||
BaseModel
|
||||
Name string `json:"name" gorm:"not null;type:varchar(255)"`
|
||||
Description string `json:"description" gorm:"type:text"`
|
||||
OwnerID string `json:"owner_id" gorm:"not null;type:uuid;index;references:users(id)"`
|
||||
TypeID string `json:"type_id" gorm:"not null;type:uuid;index;references:types(id)"`
|
||||
Owner User `json:"owner,omitempty" gorm:"foreignKey:OwnerID"`
|
||||
Type Type `json:"type,omitempty" gorm:"foreignKey:TypeID"`
|
||||
Tasks []Task `json:"tasks,omitempty" gorm:"foreignKey:ProjectID"`
|
||||
Members []User `json:"members,omitempty" gorm:"many2many:project_members;"`
|
||||
}
|
||||
|
||||
// ProjectCreateRequest represents the request to create a new project
|
||||
type ProjectCreateRequest struct {
|
||||
Name string `json:"name" validate:"required,min=1,max=255"`
|
||||
Description string `json:"description" validate:"max=1000"`
|
||||
OwnerID string `json:"owner_id" validate:"required,uuid"`
|
||||
TypeID string `json:"type_id" validate:"required,uuid"`
|
||||
}
|
||||
|
||||
// ProjectUpdateRequest represents the request to update a project
|
||||
type ProjectUpdateRequest struct {
|
||||
Name *string `json:"name,omitempty" validate:"omitempty,min=1,max=255"`
|
||||
Description *string `json:"description,omitempty" validate:"omitempty,max=1000"`
|
||||
TypeID *string `json:"type_id,omitempty" validate:"omitempty,uuid"`
|
||||
}
|
||||
|
||||
// ProjectInfo represents public project information
|
||||
type ProjectInfo struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
OwnerID string `json:"owner_id"`
|
||||
TypeID string `json:"type_id"`
|
||||
Owner UserInfo `json:"owner,omitempty"`
|
||||
Type TypeInfo `json:"type,omitempty"`
|
||||
TaskCount int64 `json:"task_count"`
|
||||
MemberCount int64 `json:"member_count"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
}
|
||||
|
||||
// ProjectMember represents the many-to-many relationship between projects and users
|
||||
type ProjectMember struct {
|
||||
ProjectID string `json:"project_id" gorm:"type:uuid;primaryKey"`
|
||||
UserID string `json:"user_id" gorm:"type:uuid;primaryKey"`
|
||||
RoleID string `json:"role_id" gorm:"type:uuid;not null;references:roles(id)"`
|
||||
Project Project `json:"project,omitempty" gorm:"foreignKey:ProjectID"`
|
||||
User User `json:"user,omitempty" gorm:"foreignKey:UserID"`
|
||||
Role Role `json:"role,omitempty" gorm:"foreignKey:RoleID"`
|
||||
}
|
||||
|
||||
// BeforeCreate is called before creating a project
|
||||
func (p *Project) BeforeCreate(tx *gorm.DB) error {
|
||||
p.BaseModel.BeforeCreate()
|
||||
|
||||
// Normalize name and description
|
||||
p.Name = strings.TrimSpace(p.Name)
|
||||
p.Description = strings.TrimSpace(p.Description)
|
||||
|
||||
return p.Validate()
|
||||
}
|
||||
|
||||
// BeforeUpdate is called before updating a project
|
||||
func (p *Project) BeforeUpdate(tx *gorm.DB) error {
|
||||
p.BaseModel.BeforeUpdate()
|
||||
|
||||
// Normalize fields if they're being updated
|
||||
if p.Name != "" {
|
||||
p.Name = strings.TrimSpace(p.Name)
|
||||
}
|
||||
if p.Description != "" {
|
||||
p.Description = strings.TrimSpace(p.Description)
|
||||
}
|
||||
|
||||
return p.Validate()
|
||||
}
|
||||
|
||||
// Validate validates project data
|
||||
func (p *Project) Validate() error {
|
||||
if p.Name == "" {
|
||||
return errors.New("name is required")
|
||||
}
|
||||
|
||||
if len(p.Name) > 255 {
|
||||
return errors.New("name must not exceed 255 characters")
|
||||
}
|
||||
|
||||
if p.OwnerID == "" {
|
||||
return errors.New("owner_id is required")
|
||||
}
|
||||
|
||||
if p.TypeID == "" {
|
||||
return errors.New("type_id is required")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ToProjectInfo converts Project to ProjectInfo (public information)
|
||||
func (p *Project) ToProjectInfo() ProjectInfo {
|
||||
projectInfo := ProjectInfo{
|
||||
ID: p.ID,
|
||||
Name: p.Name,
|
||||
Description: p.Description,
|
||||
OwnerID: p.OwnerID,
|
||||
TypeID: p.TypeID,
|
||||
CreatedAt: p.CreatedAt.Format("2006-01-02T15:04:05Z07:00"),
|
||||
UpdatedAt: p.UpdatedAt.Format("2006-01-02T15:04:05Z07:00"),
|
||||
}
|
||||
|
||||
// Add owner info if loaded
|
||||
if p.Owner.ID != "" {
|
||||
projectInfo.Owner = p.Owner.ToUserInfo()
|
||||
}
|
||||
|
||||
// Add type info if loaded
|
||||
if p.Type.ID != "" {
|
||||
projectInfo.Type = p.Type.ToTypeInfo()
|
||||
}
|
||||
|
||||
return projectInfo
|
||||
}
|
||||
|
||||
// HasMember checks if a user is a member of the project
|
||||
func (p *Project) HasMember(userID string) bool {
|
||||
for _, member := range p.Members {
|
||||
if member.ID == userID {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IsOwner checks if a user is the owner of the project
|
||||
func (p *Project) IsOwner(userID string) bool {
|
||||
return p.OwnerID == userID
|
||||
}
|
||||
Reference in New Issue
Block a user