GraphQL API and utilities for the rpdata project
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

203 lines
4.7 KiB

  1. package resolver
  2. import (
  3. "context"
  4. "time"
  5. "git.aiterp.net/rpdata/api/internal/session"
  6. "git.aiterp.net/rpdata/api/model/change"
  7. "git.aiterp.net/rpdata/api/model/story"
  8. )
  9. // ChapterResolver for the Chapter graphql type
  10. type ChapterResolver struct{ C story.Chapter }
  11. // ChapterArgs is args for chapter query
  12. type ChapterArgs struct {
  13. ID string
  14. }
  15. // Chapter implements the chapter query
  16. func (r *QueryResolver) Chapter(ctx context.Context, args *ChapterArgs) (*ChapterResolver, error) {
  17. chapter, err := story.FindChapterID(args.ID)
  18. if err != nil {
  19. return nil, err
  20. }
  21. return &ChapterResolver{C: chapter}, nil
  22. }
  23. // AddChapterArgs is args for the addChapter mutation
  24. type AddChapterArgs struct {
  25. Input *struct {
  26. StoryID string
  27. Title string
  28. Author *string
  29. Source string
  30. FictionalDate *string
  31. }
  32. }
  33. // AddChapter implements the addChapter mutation
  34. func (r *MutationResolver) AddChapter(ctx context.Context, args *AddChapterArgs) (*ChapterResolver, error) {
  35. input := args.Input
  36. user := session.FromContext(ctx).User()
  37. if user == nil || !user.Permitted("member", "chapter.add") {
  38. return nil, ErrUnauthorized
  39. }
  40. story, err := story.FindID(input.StoryID)
  41. if err != nil {
  42. return nil, err
  43. }
  44. author := user.ID
  45. if input.Author != nil {
  46. author = *input.Author
  47. if user.ID != author && !user.Permitted("chapter.add") {
  48. return nil, ErrPermissionDenied
  49. }
  50. }
  51. fictionalDate := time.Time{}
  52. if input.FictionalDate != nil {
  53. fictionalDate, err = time.Parse(time.RFC3339Nano, *input.FictionalDate)
  54. if err != nil {
  55. return nil, err
  56. }
  57. }
  58. chapter, err := story.AddChapter(input.Title, author, input.Source, time.Now(), fictionalDate)
  59. if err != nil {
  60. return nil, err
  61. }
  62. go change.Submit("Chapter", "add", user.ID, chapter.ID, map[string]interface{}{
  63. "title": input.Title,
  64. "author": author,
  65. "fictionalDate": fictionalDate,
  66. })
  67. return &ChapterResolver{C: chapter}, nil
  68. }
  69. // EditChapterArgs is args for the editChapter mutation
  70. type EditChapterArgs struct {
  71. Input *struct {
  72. ID string
  73. Title *string
  74. Source *string
  75. FictionalDate *string
  76. }
  77. }
  78. // EditChapter implements the editChapter mutation
  79. func (r *MutationResolver) EditChapter(ctx context.Context, args *EditChapterArgs) (*ChapterResolver, error) {
  80. input := args.Input
  81. user := session.FromContext(ctx).User()
  82. if user == nil || !user.Permitted("member", "chapter.edit") {
  83. return nil, ErrUnauthorized
  84. }
  85. chapter, err := story.FindChapterID(input.ID)
  86. if err != nil {
  87. return nil, err
  88. }
  89. if chapter.Author != user.ID && !user.Permitted("chapter.edit") {
  90. return nil, ErrPermissionDenied
  91. }
  92. var fictionalDate *time.Time
  93. if input.FictionalDate != nil {
  94. date, err := time.Parse(time.RFC3339Nano, *input.FictionalDate)
  95. if err != nil {
  96. return nil, err
  97. }
  98. fictionalDate = &date
  99. }
  100. err = chapter.Edit(input.Title, input.Source, fictionalDate)
  101. if err != nil {
  102. return nil, err
  103. }
  104. go change.Submit("Chapter", "edit", user.ID, chapter.ID, map[string]interface{}{
  105. "title": input.Title,
  106. "source": input.Source,
  107. "fictionalDate": fictionalDate,
  108. })
  109. return &ChapterResolver{C: chapter}, nil
  110. }
  111. // DeleteChapterArgs is args for the addChapter mutation
  112. type DeleteChapterArgs struct {
  113. ID string
  114. }
  115. // RemoveChapter implements the removeChapter mutation
  116. func (r *MutationResolver) RemoveChapter(ctx context.Context, args *DeleteChapterArgs) (*ChapterResolver, error) {
  117. user := session.FromContext(ctx).User()
  118. if user == nil || !user.Permitted("member", "chapter.edit") {
  119. return nil, ErrUnauthorized
  120. }
  121. chapter, err := story.FindChapterID(args.ID)
  122. if err != nil {
  123. return nil, err
  124. }
  125. err = chapter.Remove()
  126. if err != nil {
  127. return nil, err
  128. }
  129. go change.Submit("Chapter", "remove", user.ID, chapter.ID, nil)
  130. return &ChapterResolver{C: chapter}, nil
  131. }
  132. // ID resolves Chapter.id
  133. func (r *ChapterResolver) ID() string {
  134. return r.C.ID
  135. }
  136. // StoryID resolves Chapter.storyId
  137. func (r *ChapterResolver) StoryID() string {
  138. return r.C.StoryID
  139. }
  140. // Title resolves Chapter.title
  141. func (r *ChapterResolver) Title() string {
  142. return r.C.Title
  143. }
  144. // Author resolves Chapter.author
  145. func (r *ChapterResolver) Author() string {
  146. return r.C.Author
  147. }
  148. // Source resolves Chapter.source
  149. func (r *ChapterResolver) Source() string {
  150. return r.C.Source
  151. }
  152. // CreatedDate resolves Chapter.createdDate
  153. func (r *ChapterResolver) CreatedDate() string {
  154. return r.C.CreatedDate.Format(time.RFC3339Nano)
  155. }
  156. // FictionalDate resolves Chapter.fictionalDate
  157. func (r *ChapterResolver) FictionalDate() string {
  158. return r.C.FictionalDate.Format(time.RFC3339Nano)
  159. }
  160. // EditedDate resolves Chapter.editedDate
  161. func (r *ChapterResolver) EditedDate() string {
  162. return r.C.EditedDate.Format(time.RFC3339Nano)
  163. }