Création/mise à jour basique d'un DAD

This commit is contained in:
2020-08-26 14:51:53 +02:00
parent f03a0c96dc
commit 39d266f701
19 changed files with 536 additions and 97 deletions

View File

@ -0,0 +1,59 @@
package graph
import (
"context"
"encoding/json"
"forge.cadoles.com/Cadoles/daddy/internal/orm"
"gitlab.com/wpetit/goweb/middleware/container"
"forge.cadoles.com/Cadoles/daddy/internal/model"
errs "github.com/pkg/errors"
)
func handleCreateDecisionSupportFile(ctx context.Context, changes *model.DecisionSupportFileChanges) (*model.DecisionSupportFile, error) {
ctn := container.Must(ctx)
db := orm.Must(ctn).DB()
repo := model.NewDSFRepository(db)
dsf, err := repo.Create(ctx, changes)
if err != nil {
return nil, errs.WithStack(err)
}
return dsf, nil
}
func handleUpdateDecisionSupportFile(ctx context.Context, id string, changes *model.DecisionSupportFileChanges) (*model.DecisionSupportFile, error) {
ctn := container.Must(ctx)
db := orm.Must(ctn).DB()
repo := model.NewDSFRepository(db)
dsf, err := repo.Update(ctx, id, changes)
if err != nil {
return nil, errs.WithStack(err)
}
return dsf, nil
}
func handleDecisionSupportFiles(ctx context.Context, filter *model.DecisionSupportFileFilter) ([]*model.DecisionSupportFile, error) {
ctn := container.Must(ctx)
db := orm.Must(ctn).DB()
repo := model.NewDSFRepository(db)
return repo.Search(ctx, filter)
}
func handleSections(ctx context.Context, dsf *model.DecisionSupportFile) (map[string]interface{}, error) {
sections := make(map[string]interface{})
if err := json.Unmarshal(dsf.Sections.RawMessage, &sections); err != nil {
return nil, errs.WithStack(err)
}
return sections, nil
}

View File

@ -6,8 +6,21 @@ input WorkgroupChanges {
name: String
}
input DecisionSupportFileChanges {
title: String
sections: Map
status: String
workgroupId: ID
votedAt: Time
closedAt: Time
}
type Mutation {
createDecisionSupportFile(changes: DecisionSupportFileChanges): DecisionSupportFile!
updateDecisionSupportFile(id: ID!, changes: DecisionSupportFileChanges): DecisionSupportFile!
updateProfile(changes: ProfileChanges!): User!
joinWorkgroup(workgroupId: ID!): Workgroup!
leaveWorkgroup(workgroupId: ID!): Workgroup!
createWorkgroup(changes: WorkgroupChanges!): Workgroup!

View File

@ -10,6 +10,14 @@ import (
"forge.cadoles.com/Cadoles/daddy/internal/model"
)
func (r *mutationResolver) CreateDecisionSupportFile(ctx context.Context, changes *model.DecisionSupportFileChanges) (*model.DecisionSupportFile, error) {
return handleCreateDecisionSupportFile(ctx, changes)
}
func (r *mutationResolver) UpdateDecisionSupportFile(ctx context.Context, id string, changes *model.DecisionSupportFileChanges) (*model.DecisionSupportFile, error) {
return handleUpdateDecisionSupportFile(ctx, id, changes)
}
func (r *mutationResolver) UpdateProfile(ctx context.Context, changes model.ProfileChanges) (*model.User, error) {
return handleUpdateUserProfile(ctx, changes)
}

View File

@ -1,4 +1,5 @@
scalar Time
scalar Map
type User {
id: ID!
@ -21,7 +22,24 @@ input WorkgroupsFilter {
ids: [ID]
}
type DecisionSupportFile {
id: ID!
title: String
sections: Map
status: String
workgroup: Workgroup
createdAt: Time
updatedAt: Time
votedAt: Time
closedAt: Time
}
input DecisionSupportFileFilter {
ids: [ID]
}
type Query {
userProfile: User
workgroups(filter: WorkgroupsFilter): [Workgroup]!
decisionSupportFiles(filter: DecisionSupportFileFilter): [DecisionSupportFile]!
}

View File

@ -11,6 +11,14 @@ import (
model1 "forge.cadoles.com/Cadoles/daddy/internal/model"
)
func (r *decisionSupportFileResolver) ID(ctx context.Context, obj *model1.DecisionSupportFile) (string, error) {
return strconv.FormatUint(uint64(obj.ID), 10), nil
}
func (r *decisionSupportFileResolver) Sections(ctx context.Context, obj *model1.DecisionSupportFile) (map[string]interface{}, error) {
return handleSections(ctx, obj)
}
func (r *queryResolver) UserProfile(ctx context.Context) (*model1.User, error) {
return handleUserProfile(ctx)
}
@ -19,6 +27,10 @@ func (r *queryResolver) Workgroups(ctx context.Context, filter *model1.Workgroup
return handleWorkgroups(ctx, filter)
}
func (r *queryResolver) DecisionSupportFiles(ctx context.Context, filter *model1.DecisionSupportFileFilter) ([]*model1.DecisionSupportFile, error) {
return handleDecisionSupportFiles(ctx, filter)
}
func (r *userResolver) ID(ctx context.Context, obj *model1.User) (string, error) {
return strconv.FormatUint(uint64(obj.ID), 10), nil
}
@ -27,6 +39,11 @@ func (r *workgroupResolver) ID(ctx context.Context, obj *model1.Workgroup) (stri
return strconv.FormatUint(uint64(obj.ID), 10), nil
}
// DecisionSupportFile returns generated.DecisionSupportFileResolver implementation.
func (r *Resolver) DecisionSupportFile() generated.DecisionSupportFileResolver {
return &decisionSupportFileResolver{r}
}
// Query returns generated.QueryResolver implementation.
func (r *Resolver) Query() generated.QueryResolver { return &queryResolver{r} }
@ -36,6 +53,7 @@ func (r *Resolver) User() generated.UserResolver { return &userResolver{r} }
// Workgroup returns generated.WorkgroupResolver implementation.
func (r *Resolver) Workgroup() generated.WorkgroupResolver { return &workgroupResolver{r} }
type decisionSupportFileResolver struct{ *Resolver }
type queryResolver struct{ *Resolver }
type userResolver struct{ *Resolver }
type workgroupResolver struct{ *Resolver }

19
internal/model/dsf.go Normal file
View File

@ -0,0 +1,19 @@
package model
import (
"time"
"github.com/jinzhu/gorm"
"github.com/jinzhu/gorm/dialects/postgres"
)
type DecisionSupportFile struct {
gorm.Model
Title string `json:"title"`
Sections postgres.Jsonb `json:"sections"`
Status string `json:"status"`
WorkgroupID uint `json:"-"`
Workgroup *Workgroup `json:"workgroup"`
VotedAt time.Time `json:"votedAt"`
ClosedAt time.Time `json:"closedAt"`
}

View File

@ -0,0 +1,111 @@
package model
import (
"context"
"encoding/json"
"errors"
"github.com/jinzhu/gorm"
"github.com/jinzhu/gorm/dialects/postgres"
errs "github.com/pkg/errors"
)
var (
ErrMissingWorkgroup = errs.New("missing workgroup")
ErrInvalidWorkgroup = errs.New("invalid workgroup")
ErrDecisionSupportFileDoesNotExist = errs.New("decision support file does not exist")
)
type DSFRepository struct {
db *gorm.DB
}
func (r *DSFRepository) Create(ctx context.Context, changes *DecisionSupportFileChanges) (*DecisionSupportFile, error) {
dsf := &DecisionSupportFile{}
if err := r.updateFromChanges(dsf, changes); err != nil {
return nil, errs.WithStack(err)
}
if err := r.db.Save(&dsf).Error; err != nil {
return nil, errs.WithStack(err)
}
return dsf, nil
}
func (r *DSFRepository) Update(ctx context.Context, id string, changes *DecisionSupportFileChanges) (*DecisionSupportFile, error) {
dsf := &DecisionSupportFile{}
if err := r.db.Find(dsf, "id = ?", id).Error; err != nil {
return nil, errs.WithStack(err)
}
if err := r.updateFromChanges(dsf, changes); err != nil {
return nil, errs.WithStack(err)
}
if err := r.db.Save(dsf).Error; err != nil {
return nil, errs.WithStack(err)
}
return dsf, nil
}
func (r *DSFRepository) updateFromChanges(dsf *DecisionSupportFile, changes *DecisionSupportFileChanges) error {
if changes.WorkgroupID == nil {
return errs.WithStack(ErrMissingWorkgroup)
}
wg := &Workgroup{}
if err := r.db.Model(wg).First(wg, "id = ?", changes.WorkgroupID).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return errs.WithStack(ErrInvalidWorkgroup)
}
return errs.WithStack(err)
}
dsf.Workgroup = wg
if changes.Sections != nil {
rawSections, err := json.Marshal(changes.Sections)
if err != nil {
return errs.WithStack(err)
}
dsf.Sections = postgres.Jsonb{RawMessage: rawSections}
}
if changes.Title != nil {
dsf.Title = *changes.Title
}
if changes.Status != nil {
dsf.Status = *changes.Status
}
return nil
}
func (r *DSFRepository) Search(ctx context.Context, filter *DecisionSupportFileFilter) ([]*DecisionSupportFile, error) {
query := r.db.Model(&DecisionSupportFile{}).Preload("Workgroup")
if filter != nil {
if filter.Ids != nil {
query = query.Where("id in (?)", filter.Ids)
}
}
dsfs := make([]*DecisionSupportFile, 0)
if err := query.Find(&dsfs).Error; err != nil {
return nil, errs.WithStack(err)
}
return dsfs, nil
}
func NewDSFRepository(db *gorm.DB) *DSFRepository {
return &DSFRepository{db}
}