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.

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