diff --git a/kontor-gin/cmd/kontor/main.go b/kontor-gin/cmd/kontor/main.go index fb25c13..f918fa7 100644 --- a/kontor-gin/cmd/kontor/main.go +++ b/kontor-gin/cmd/kontor/main.go @@ -51,6 +51,7 @@ func main() { r := router.New( handlers.NewAdminHandler(db, []byte(viper.GetString("api_secret"))), + handlers.NewBookshelfHandler(db), handlers.NewComicsHandler(db), handlers.NewMediaHandler(db), handlers.NewTyscHandler(db), diff --git a/kontor-gin/internal/cmd/export.go b/kontor-gin/internal/cmd/export.go index ca11726..77227cc 100644 --- a/kontor-gin/internal/cmd/export.go +++ b/kontor-gin/internal/cmd/export.go @@ -24,121 +24,147 @@ var exportCmd = &cobra.Command{ PostJSON(client, "http://127.0.0.1:8550/api/login", &login) type ExportData struct { - Sport []models.SportDTO `json:"sport"` - Player []models.PlayerDTO `json:"player"` - Team []models.TeamDTO `json:"team"` - Position []models.PositionDTO `json:"field_position"` - Rooster []models.RoosterDTO `json:"rooster"` - Vendor []models.VendorDTO `json:"vendor"` - CardSet []models.CardSetDTO `json:"card_set"` - Card []models.CardDTO `json:"card"` - Artist []models.ArtistDTO `json:"artist"` - Publisher []models.PublisherDTO `json:"publisher"` - Worktype []models.WorkTypeDTO `json:"worktype"` - Comic []models.ComicDTO `json:"comic"` - Volume []models.VolumeDTO `json:"volume"` - StoryArc []models.StoryArcDTO `json:"story_arc"` - Issue []models.IssueDTO `json:"issue"` - TradePaperback []models.TradePaperbackDTO `json:"trade_paperback"` - ComicWork []models.ComicworkDTO `json:"comic_work"` - IssueWork []models.IssueworkDTO `json:"issue_work"` - MediaArticle []models.MediaArticleDTO `json:"media_article"` - MediaVideo []models.MediaVideoDTO `json:"media_video"` - MediaLoFi []models.MediaLoFiDTO `json:"media_lofi"` - MediaFile []models.MediaFileDTO `json:"media_file"` - Profile []models.ProfileDTO `json:"profile"` - Permission []models.PermissionDTO `json:"permission"` - Assignment []models.AssignmentDTO `json:"assignment"` - Token []models.TokenDTO `json:"token"` + Sport []models.SportDTO `json:"sport"` + Player []models.PlayerDTO `json:"player"` + Team []models.TeamDTO `json:"team"` + Position []models.PositionDTO `json:"field_position"` + Rooster []models.RoosterDTO `json:"rooster"` + Vendor []models.VendorDTO `json:"vendor"` + CardSet []models.CardSetDTO `json:"card_set"` + Card []models.CardDTO `json:"card"` + Artist []models.ArtistDTO `json:"artist"` + Publisher []models.PublisherDTO `json:"publisher"` + Worktype []models.WorkTypeDTO `json:"worktype"` + Comic []models.ComicDTO `json:"comic"` + Volume []models.VolumeDTO `json:"volume"` + StoryArc []models.StoryArcDTO `json:"story_arc"` + Issue []models.IssueDTO `json:"issue"` + TradePaperback []models.TradePaperbackDTO `json:"trade_paperback"` + ComicWork []models.ComicworkDTO `json:"comic_work"` + IssueWork []models.IssueworkDTO `json:"issue_work"` + Article []models.ArticleDTO `json:"article"` + BookshelfPublisher []models.BookshelfPublisherDTO `json:"bookshelf_publisher"` + Book []models.BookDTO `json:"book"` + Author []models.AuthorDTO `json:"author"` + ArticleAuthor []models.ArticleAuthorDTO `json:"article_author"` + BookAuthor []models.BookAuthorDTO `json:"book_author"` + MediaArticle []models.MediaArticleDTO `json:"media_article"` + MediaVideo []models.MediaVideoDTO `json:"media_video"` + MediaLoFi []models.MediaLoFiDTO `json:"media_lofi"` + MediaFile []models.MediaFileDTO `json:"media_file"` + MediaActor []models.MediaActorDTO `json:"media_actor"` + MediaActorFile []models.MediaActorFileDTO `json:"media_actor_file"` + Profile []models.ProfileDTO `json:"profile"` + Permission []models.PermissionDTO `json:"permission"` + Assignment []models.AssignmentDTO `json:"assignment"` + Token []models.TokenDTO `json:"token"` } var ( - sports []models.SportDTO - players []models.PlayerDTO - teams []models.TeamDTO - positions []models.PositionDTO - roosters []models.RoosterDTO - vendors []models.VendorDTO - cardsets []models.CardSetDTO - cards []models.CardDTO - artists []models.ArtistDTO - publishers []models.PublisherDTO - worktypes []models.WorkTypeDTO - comics []models.ComicDTO - volumes []models.VolumeDTO - storyarcs []models.StoryArcDTO - issues []models.IssueDTO - tradepaperbacks []models.TradePaperbackDTO - comicworks []models.ComicworkDTO - issueworks []models.IssueworkDTO - mediaarticles []models.MediaArticleDTO - mediavideos []models.MediaVideoDTO - mediafiles []models.MediaFileDTO - medialofis []models.MediaLoFiDTO - profiles []models.ProfileDTO - permissions []models.PermissionDTO - assignments []models.AssignmentDTO - tokens []models.TokenDTO + sports []models.SportDTO + players []models.PlayerDTO + teams []models.TeamDTO + positions []models.PositionDTO + roosters []models.RoosterDTO + vendors []models.VendorDTO + cardsets []models.CardSetDTO + cards []models.CardDTO + artists []models.ArtistDTO + publishers []models.PublisherDTO + worktypes []models.WorkTypeDTO + comics []models.ComicDTO + volumes []models.VolumeDTO + storyarcs []models.StoryArcDTO + issues []models.IssueDTO + tradepaperbacks []models.TradePaperbackDTO + comicworks []models.ComicworkDTO + issueworks []models.IssueworkDTO + articles []models.ArticleDTO + bookshelf_publishers []models.BookshelfPublisherDTO + books []models.BookDTO + autors []models.AuthorDTO + article_authors []models.ArticleAuthorDTO + book_authors []models.BookAuthorDTO + mediaarticles []models.MediaArticleDTO + mediavideos []models.MediaVideoDTO + mediafiles []models.MediaFileDTO + medialofis []models.MediaLoFiDTO + profiles []models.ProfileDTO + permissions []models.PermissionDTO + assignments []models.AssignmentDTO + tokens []models.TokenDTO ) registry := map[string]any{ - "http://127.0.0.1:8550/api/v1/tysc/sports": &sports, - "http://127.0.0.1:8550/api/v1/tysc/players": &players, - "http://127.0.0.1:8550/api/v1/tysc/teams": &teams, - "http://127.0.0.1:8550/api/v1/tysc/positions": &positions, - "http://127.0.0.1:8550/api/v1/tysc/roosters": &roosters, - "http://127.0.0.1:8550/api/v1/tysc/vendors": &vendors, - "http://127.0.0.1:8550/api/v1/tysc/cardsets": &cardsets, - "http://127.0.0.1:8550/api/v1/tysc/cards": &cards, - "http://127.0.0.1:8550/api/v1/comics/artists": &artists, - "http://127.0.0.1:8550/api/v1/comics/publishers": &publishers, - "http://127.0.0.1:8550/api/v1/comics/worktypes": &worktypes, - "http://127.0.0.1:8550/api/v1/comics/comics": &comics, - "http://127.0.0.1:8550/api/v1/comics/volumes": &volumes, - "http://127.0.0.1:8550/api/v1/comics/storyarcs": &storyarcs, - "http://127.0.0.1:8550/api/v1/comics/issues": &issues, - "http://127.0.0.1:8550/api/v1/comics/tradepaperbacks": &tradepaperbacks, - "http://127.0.0.1:8550/api/v1/comics/comicworks": &comicworks, - "http://127.0.0.1:8550/api/v1/comics/issueworks": &issueworks, - "http://127.0.0.1:8550/api/v1/media/articles": &mediaarticles, - "http://127.0.0.1:8550/api/v1/media/videos": &mediavideos, - "http://127.0.0.1:8550/api/v1/media/files": &mediafiles, - "http://127.0.0.1:8550/api/v1/media/lofis": &medialofis, - "http://127.0.0.1:8550/api/v1/user/profiles": &profiles, - "http://127.0.0.1:8550/api/v1/user/permissions": &permissions, - "http://127.0.0.1:8550/api/v1/user/assignments": &assignments, - "http://127.0.0.1:8550/api/v1/user/tokens": &tokens, + "http://127.0.0.1:8550/api/v1/tysc/sports": &sports, + "http://127.0.0.1:8550/api/v1/tysc/players": &players, + "http://127.0.0.1:8550/api/v1/tysc/teams": &teams, + "http://127.0.0.1:8550/api/v1/tysc/positions": &positions, + "http://127.0.0.1:8550/api/v1/tysc/roosters": &roosters, + "http://127.0.0.1:8550/api/v1/tysc/vendors": &vendors, + "http://127.0.0.1:8550/api/v1/tysc/cardsets": &cardsets, + "http://127.0.0.1:8550/api/v1/tysc/cards": &cards, + "http://127.0.0.1:8550/api/v1/comics/artists": &artists, + "http://127.0.0.1:8550/api/v1/comics/publishers": &publishers, + "http://127.0.0.1:8550/api/v1/comics/worktypes": &worktypes, + "http://127.0.0.1:8550/api/v1/comics/comics": &comics, + "http://127.0.0.1:8550/api/v1/comics/volumes": &volumes, + "http://127.0.0.1:8550/api/v1/comics/storyarcs": &storyarcs, + "http://127.0.0.1:8550/api/v1/comics/issues": &issues, + "http://127.0.0.1:8550/api/v1/comics/tradepaperbacks": &tradepaperbacks, + "http://127.0.0.1:8550/api/v1/comics/comicworks": &comicworks, + "http://127.0.0.1:8550/api/v1/comics/issueworks": &issueworks, + "http://127.0.0.1:8550/api/v1/bookshelf/articles": &articles, + "http://127.0.0.1:8550/api/v1/bookshelf/publishers": &bookshelf_publishers, + "http://127.0.0.1:8550/api/v1/bookshelf/books": &books, + "http://127.0.0.1:8550/api/v1/bookshelf/authors": &autors, + "http://127.0.0.1:8550/api/v1/bookshelf/articleauthors": &article_authors, + "http://127.0.0.1:8550/api/v1/bookshelf/bookauthors": &book_authors, + "http://127.0.0.1:8550/api/v1/media/articles": &mediaarticles, + "http://127.0.0.1:8550/api/v1/media/videos": &mediavideos, + "http://127.0.0.1:8550/api/v1/media/files": &mediafiles, + "http://127.0.0.1:8550/api/v1/media/lofis": &medialofis, + "http://127.0.0.1:8550/api/v1/user/profiles": &profiles, + "http://127.0.0.1:8550/api/v1/user/permissions": &permissions, + "http://127.0.0.1:8550/api/v1/user/assignments": &assignments, + "http://127.0.0.1:8550/api/v1/user/tokens": &tokens, } for url, value := range registry { GetJSON(client, login.Token, url, value) } export := ExportData{ - Sport: sports, - Player: players, - Team: teams, - Position: positions, - Rooster: roosters, - Vendor: vendors, - CardSet: cardsets, - Card: cards, - Artist: artists, - Publisher: publishers, - Worktype: worktypes, - Comic: comics, - Volume: volumes, - StoryArc: storyarcs, - Issue: issues, - TradePaperback: tradepaperbacks, - ComicWork: comicworks, - IssueWork: issueworks, - MediaArticle: mediaarticles, - MediaVideo: mediavideos, - MediaFile: mediafiles, - MediaLoFi: medialofis, - Profile: profiles, - Permission: permissions, - Assignment: assignments, - Token: tokens, + Sport: sports, + Player: players, + Team: teams, + Position: positions, + Rooster: roosters, + Vendor: vendors, + CardSet: cardsets, + Card: cards, + Artist: artists, + Publisher: publishers, + Worktype: worktypes, + Comic: comics, + Volume: volumes, + StoryArc: storyarcs, + Issue: issues, + TradePaperback: tradepaperbacks, + ComicWork: comicworks, + IssueWork: issueworks, + Article: articles, + BookshelfPublisher: bookshelf_publishers, + Book: books, + Author: autors, + ArticleAuthor: article_authors, + BookAuthor: book_authors, + MediaArticle: mediaarticles, + MediaVideo: mediavideos, + MediaFile: mediafiles, + MediaLoFi: medialofis, + Profile: profiles, + Permission: permissions, + Assignment: assignments, + Token: tokens, } defer client.Close() jsonData, err := json.MarshalIndent(export, "", " ") diff --git a/kontor-gin/internal/handlers/article.go b/kontor-gin/internal/handlers/article.go new file mode 100644 index 0000000..3885369 --- /dev/null +++ b/kontor-gin/internal/handlers/article.go @@ -0,0 +1,30 @@ +package handlers + +import ( + "kontor-api-gin/internal/models" + "kontor-api-gin/internal/repository" + "kontor-api-gin/internal/service" + "net/http" + + "github.com/gin-gonic/gin" + "gorm.io/gorm" +) + +type ArticleHandler struct { + Service *service.ArticleService +} + +func NewArticleHandler(db *gorm.DB) *ArticleHandler { + handler := &ArticleHandler{Service: service.NewArticleService(repository.NewArticleRepository(db))} + return handler +} + +func (handler *ArticleHandler) List(c *gin.Context) { + articles, err := handler.Service.List(c.Request.Context()) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + return + } + dtos := models.ConvertArticlesToDtos(articles) + c.JSON(http.StatusOK, dtos) +} diff --git a/kontor-gin/internal/handlers/article_author.go b/kontor-gin/internal/handlers/article_author.go new file mode 100644 index 0000000..33270ff --- /dev/null +++ b/kontor-gin/internal/handlers/article_author.go @@ -0,0 +1,30 @@ +package handlers + +import ( + "kontor-api-gin/internal/models" + "kontor-api-gin/internal/repository" + "kontor-api-gin/internal/service" + "net/http" + + "github.com/gin-gonic/gin" + "gorm.io/gorm" +) + +type ArticleAuthorHandler struct { + Service *service.ArticleAuthorService +} + +func NewArticleAuthorHandler(db *gorm.DB) *ArticleAuthorHandler { + handler := &ArticleAuthorHandler{Service: service.NewArticleAuthorService(repository.NewArticleAuthorRepository(db))} + return handler +} + +func (handler *ArticleAuthorHandler) List(c *gin.Context) { + authors, err := handler.Service.List(c.Request.Context()) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + return + } + dtos := models.ConvertArticleAuthorsToDtos(authors) + c.JSON(http.StatusOK, dtos) +} diff --git a/kontor-gin/internal/handlers/author.go b/kontor-gin/internal/handlers/author.go new file mode 100644 index 0000000..cea8206 --- /dev/null +++ b/kontor-gin/internal/handlers/author.go @@ -0,0 +1,30 @@ +package handlers + +import ( + "kontor-api-gin/internal/models" + "kontor-api-gin/internal/repository" + "kontor-api-gin/internal/service" + "net/http" + + "github.com/gin-gonic/gin" + "gorm.io/gorm" +) + +type AuthorHandler struct { + Service *service.AuthorService +} + +func NewAuthorHandler(db *gorm.DB) *AuthorHandler { + handler := &AuthorHandler{Service: service.NewAuthorService(repository.NewAuthorRepository(db))} + return handler +} + +func (handler *AuthorHandler) List(c *gin.Context) { + artists, err := handler.Service.List(c.Request.Context()) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + return + } + dtos := models.ConvertAuthorsToDtos(artists) + c.JSON(http.StatusOK, dtos) +} diff --git a/kontor-gin/internal/handlers/book.go b/kontor-gin/internal/handlers/book.go new file mode 100644 index 0000000..eaa9df4 --- /dev/null +++ b/kontor-gin/internal/handlers/book.go @@ -0,0 +1,30 @@ +package handlers + +import ( + "kontor-api-gin/internal/models" + "kontor-api-gin/internal/repository" + "kontor-api-gin/internal/service" + "net/http" + + "github.com/gin-gonic/gin" + "gorm.io/gorm" +) + +type BookHandler struct { + Service *service.BookService +} + +func NewBookHandler(db *gorm.DB) *BookHandler { + handler := &BookHandler{Service: service.NewBookService(repository.NewBookRepository(db))} + return handler +} + +func (handler *BookHandler) List(c *gin.Context) { + books, err := handler.Service.List(c.Request.Context()) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + return + } + dtos := models.ConvertBooksToDtos(books) + c.JSON(http.StatusOK, dtos) +} diff --git a/kontor-gin/internal/handlers/book_author.go b/kontor-gin/internal/handlers/book_author.go new file mode 100644 index 0000000..b264ba5 --- /dev/null +++ b/kontor-gin/internal/handlers/book_author.go @@ -0,0 +1,30 @@ +package handlers + +import ( + "kontor-api-gin/internal/models" + "kontor-api-gin/internal/repository" + "kontor-api-gin/internal/service" + "net/http" + + "github.com/gin-gonic/gin" + "gorm.io/gorm" +) + +type BookAuthorHandler struct { + Service *service.BookAuthorService +} + +func NewBookAuthorHandler(db *gorm.DB) *BookAuthorHandler { + handler := &BookAuthorHandler{Service: service.NewBookAuthorService(repository.NewBookAuthorRepository(db))} + return handler +} + +func (handler *BookAuthorHandler) List(c *gin.Context) { + authors, err := handler.Service.List(c.Request.Context()) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + return + } + dtos := models.ConvertBookAuthorsToDtos(authors) + c.JSON(http.StatusOK, dtos) +} diff --git a/kontor-gin/internal/handlers/bookshelf.go b/kontor-gin/internal/handlers/bookshelf.go new file mode 100644 index 0000000..1f9c099 --- /dev/null +++ b/kontor-gin/internal/handlers/bookshelf.go @@ -0,0 +1,26 @@ +package handlers + +import ( + "gorm.io/gorm" +) + +type BookshelfHandler struct { + ArticleHandler *ArticleHandler + BookshelfPublisherHandler *BookshelfPublisherHandler + BookHandler *BookHandler + AuthorHandler *AuthorHandler + ArticleAuthorHandler *ArticleAuthorHandler + BookAuthorHandler *BookAuthorHandler +} + +func NewBookshelfHandler(db *gorm.DB) *BookshelfHandler { + bookshelfHandler := &BookshelfHandler{ + ArticleHandler: NewArticleHandler(db), + BookshelfPublisherHandler: NewBookshelfPublisherHandler(db), + BookHandler: NewBookHandler(db), + AuthorHandler: NewAuthorHandler(db), + ArticleAuthorHandler: NewArticleAuthorHandler(db), + BookAuthorHandler: NewBookAuthorHandler(db), + } + return bookshelfHandler +} diff --git a/kontor-gin/internal/handlers/bookshelf_publisher.go b/kontor-gin/internal/handlers/bookshelf_publisher.go new file mode 100644 index 0000000..b1f329f --- /dev/null +++ b/kontor-gin/internal/handlers/bookshelf_publisher.go @@ -0,0 +1,30 @@ +package handlers + +import ( + "kontor-api-gin/internal/models" + "kontor-api-gin/internal/repository" + "kontor-api-gin/internal/service" + "net/http" + + "github.com/gin-gonic/gin" + "gorm.io/gorm" +) + +type BookshelfPublisherHandler struct { + Service *service.BookshelfPublisherService +} + +func NewBookshelfPublisherHandler(db *gorm.DB) *BookshelfPublisherHandler { + handler := &BookshelfPublisherHandler{Service: service.NewBookshelfPublisherService(repository.NewBookshelfPublisherRepository(db))} + return handler +} + +func (handler *BookshelfPublisherHandler) List(c *gin.Context) { + publishers, err := handler.Service.List(c.Request.Context()) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + return + } + dtos := models.ConvertBookshelfPublishersToDtos(publishers) + c.JSON(http.StatusOK, dtos) +} diff --git a/kontor-gin/internal/models/article.go b/kontor-gin/internal/models/article.go new file mode 100644 index 0000000..c51efb0 --- /dev/null +++ b/kontor-gin/internal/models/article.go @@ -0,0 +1,53 @@ +package models + +import ( + "kontor-api-gin/internal/helpers" + "time" +) + +type Article struct { + ID string `gorm:"type:string;primary_key;" json:"id"` + CreatedAt time.Time `gorm:"column:created_date" json:"created_date"` + UpdatedAt time.Time `gorm:"column:last_modified_date" json:"last_modified_date"` + DeletedAt *time.Time `gorm:"column:deleted_date" json:"deleted_date"` + Version int `gorm:"default:0" json:"version"` + Title string `gorm:"uniqueIndex" json:"title"` + ArticleAuthors []ArticleAuthor `gorm:"foreignKey:ArticleID" json:"article_authors"` +} + +func (article *Article) TableName() string { + return "article" +} + +type ArticleDTO struct { + ID string `json:"id" binding:"required"` + CreatedAt helpers.KontorTime `json:"created_date"` + UpdatedAt helpers.KontorTime `json:"last_modified_date"` + DeletedAt *time.Time `json:"deleted_date,omitempty"` + Version int `json:"version"` + Title string `json:"title"` +} + +func ConvertArticlesToDtos(articles []Article) []ArticleDTO { + dtos := make([]ArticleDTO, len(articles)) + for i, article := range articles { + dtos[i] = ArticleDTO{ + ID: article.ID, + CreatedAt: helpers.KontorTime{Time: article.CreatedAt}, + UpdatedAt: helpers.KontorTime{Time: article.UpdatedAt}, + DeletedAt: article.DeletedAt, + Version: article.Version, + Title: article.Title, + } + } + return dtos +} + +type CreateArticleDTO struct { + Title string `json:"title" binding:"required"` +} + +type UpdateArticleDTO struct { + Title *string `json:"title,omitempty" binding:"omitempty"` +} + diff --git a/kontor-gin/internal/models/article_author.go b/kontor-gin/internal/models/article_author.go new file mode 100644 index 0000000..8fe9690 --- /dev/null +++ b/kontor-gin/internal/models/article_author.go @@ -0,0 +1,48 @@ +package models + +import ( + "kontor-api-gin/internal/helpers" + "time" +) + +type ArticleAuthor struct { + ID string `gorm:"type:string;primary_key;" json:"id"` + CreatedAt time.Time `gorm:"column:created_date" json:"created_date"` + UpdatedAt time.Time `gorm:"column:last_modified_date" json:"last_modified_date"` + DeletedAt *time.Time `gorm:"column:deleted_date" json:"deleted_date"` + Version int `gorm:"default:0" json:"version"` + ArticleID *string `gorm:"column:article_id" json:"article_id"` + Article *Article `gorm:"foreignKey:ArticleID" json:"article"` + AuthorID *string `form:"column:author_id" json:"author_id"` + Author *Author `gorm:"foreignKey:AuthorID" json:"author"` +} + +func (article_author *ArticleAuthor) TableName() string { + return "article_author" +} + +type ArticleAuthorDTO struct { + ID string `json:"id" binding:"required"` + CreatedAt helpers.KontorTime `json:"created_date"` + UpdatedAt helpers.KontorTime `json:"last_modified_date"` + DeletedAt *time.Time `json:"deleted_date"` + Version int `json:"version"` + ArticleID *string `json:"article_id"` + AuthorID *string `json:"author_id"` +} + +func ConvertArticleAuthorsToDtos(article_authors []ArticleAuthor) []ArticleAuthorDTO { + dtos := make([]ArticleAuthorDTO, len(article_authors)) + for i, article_author := range article_authors { + dtos[i] = ArticleAuthorDTO{ + ID: article_author.ID, + CreatedAt: helpers.KontorTime{Time: article_author.CreatedAt}, + UpdatedAt: helpers.KontorTime{Time: article_author.UpdatedAt}, + DeletedAt: article_author.DeletedAt, + Version: article_author.Version, + ArticleID: article_author.ArticleID, + AuthorID: article_author.AuthorID, + } + } + return dtos +} diff --git a/kontor-gin/internal/models/author.go b/kontor-gin/internal/models/author.go new file mode 100644 index 0000000..5e50399 --- /dev/null +++ b/kontor-gin/internal/models/author.go @@ -0,0 +1,48 @@ +package models + +import ( + "kontor-api-gin/internal/helpers" + "time" +) + +type Author struct { + ID string `gorm:"type:string;primary_key;" json:"id"` + CreatedAt time.Time `gorm:"column:created_date" json:"created_date"` + UpdatedAt time.Time `gorm:"column:last_modified_date" json:"last_modified_date"` + DeletedAt *time.Time `gorm:"column:deleted_date" json:"deleted_date"` + Version int `gorm:"default:0" json:"version"` + FirstName string `gorm:"column:first_name" json:"first_name"` + LastName string `gorm:"column:last_name" json:"last_name"` + ArticleAuthors []ArticleAuthor `gorm:"foreignKey:AuthorID" json:"article_authors"` + BookAuthors []BookAuthor `gorm:"foreignKey:AuthorID" json:"book_authors"` +} + +func (author *Author) TableName() string { + return "author" +} + +type AuthorDTO struct { + ID string `json:"id" binding:"required"` + CreatedAt helpers.KontorTime `json:"created_date"` + UpdatedAt helpers.KontorTime `json:"last_modified_date"` + DeletedAt *time.Time `json:"deleted_date,omitempty"` + Version int `json:"version"` + FirstName string `json:"first_name"` + LastName string `json:"last_name"` +} + +func ConvertAuthorsToDtos(authors []Author) []AuthorDTO { + dtos := make([]AuthorDTO, len(authors)) + for i, author := range authors { + dtos[i] = AuthorDTO{ + ID: author.ID, + CreatedAt: helpers.KontorTime{Time: author.CreatedAt}, + UpdatedAt: helpers.KontorTime{Time: author.UpdatedAt}, + DeletedAt: author.DeletedAt, + Version: author.Version, + FirstName: author.FirstName, + LastName: author.LastName, + } + } + return dtos +} diff --git a/kontor-gin/internal/models/book.go b/kontor-gin/internal/models/book.go new file mode 100644 index 0000000..6fe5921 --- /dev/null +++ b/kontor-gin/internal/models/book.go @@ -0,0 +1,48 @@ +package models + +import ( + "kontor-api-gin/internal/helpers" + "time" +) + +type Book struct { + ID string `gorm:"type:string;primary_key;" json:"id"` + CreatedAt time.Time `gorm:"column:created_date" json:"created_date"` + UpdatedAt time.Time `gorm:"column:last_modified_date" json:"last_modified_date"` + DeletedAt *time.Time `gorm:"column:deleted_date" json:"deleted_date"` + Version int `gorm:"default:0" json:"version"` + ISBN string `gorm:"column:isbn;uniqueIndex" json:"isbn"` + Title string `gorm:"column:title" json:"title"` + Year int `gorm:"column:year" json:"year"` + PublisherID string `gorm:"column:publisher_id" json:"publisher_id"` + Publisher BookshelfPublisher `gorm:"foreignKey:PublisherID" json:"publisher"` + BookAuthors []BookAuthor `gorm:"foreignKey:BookID" json:"book_authors"` +} + +func (book *Book) TableName() string { + return "book" +} + +type BookDTO struct { + ID string `json:"id" binding:"required"` + CreatedAt helpers.KontorTime `json:"created_date"` + UpdatedAt helpers.KontorTime `json:"last_modified_date"` + DeletedAt *time.Time `json:"deleted_date,omitempty"` + Version int `json:"version"` + Title string `json:"title"` +} + +func ConvertBooksToDtos(books []Book) []BookDTO { + dtos := make([]BookDTO, len(books)) + for i, book := range books { + dtos[i] = BookDTO{ + ID: book.ID, + CreatedAt: helpers.KontorTime{Time: book.CreatedAt}, + UpdatedAt: helpers.KontorTime{Time: book.UpdatedAt}, + DeletedAt: book.DeletedAt, + Version: book.Version, + Title: book.Title, + } + } + return dtos +} diff --git a/kontor-gin/internal/models/book_author.go b/kontor-gin/internal/models/book_author.go new file mode 100644 index 0000000..78053f3 --- /dev/null +++ b/kontor-gin/internal/models/book_author.go @@ -0,0 +1,48 @@ +package models + +import ( + "kontor-api-gin/internal/helpers" + "time" +) + +type BookAuthor struct { + ID string `gorm:"type:string;primary_key;" json:"id"` + CreatedAt time.Time `gorm:"column:created_date" json:"created_date"` + UpdatedAt time.Time `gorm:"column:last_modified_date" json:"last_modified_date"` + DeletedAt *time.Time `gorm:"column:deleted_date" json:"deleted_date"` + Version int `gorm:"default:0" json:"version"` + BookID *string `gorm:"column:book_id" json:"book_id"` + Book *Book `gorm:"foreignKey:BookID" json:"book"` + AuthorID *string `form:"column:author_id" json:"author_id"` + Author *Author `gorm:"foreignKey:AuthorID" json:"author"` +} + +func (book_author *BookAuthor) TableName() string { + return "book_author" +} + +type BookAuthorDTO struct { + ID string `json:"id" binding:"required"` + CreatedAt helpers.KontorTime `json:"created_date"` + UpdatedAt helpers.KontorTime `json:"last_modified_date"` + DeletedAt *time.Time `json:"deleted_date"` + Version int `json:"version"` + BookID *string `json:"book_id"` + AuthorID *string `json:"author_id"` +} + +func ConvertBookAuthorsToDtos(book_authors []BookAuthor) []BookAuthorDTO { + dtos := make([]BookAuthorDTO, len(book_authors)) + for i, book_author := range book_authors { + dtos[i] = BookAuthorDTO{ + ID: book_author.ID, + CreatedAt: helpers.KontorTime{Time: book_author.CreatedAt}, + UpdatedAt: helpers.KontorTime{Time: book_author.UpdatedAt}, + DeletedAt: book_author.DeletedAt, + Version: book_author.Version, + BookID: book_author.BookID, + AuthorID: book_author.AuthorID, + } + } + return dtos +} diff --git a/kontor-gin/internal/models/bookshelf_publisher.go b/kontor-gin/internal/models/bookshelf_publisher.go new file mode 100644 index 0000000..1224a0f --- /dev/null +++ b/kontor-gin/internal/models/bookshelf_publisher.go @@ -0,0 +1,44 @@ +package models + +import ( + "kontor-api-gin/internal/helpers" + "time" +) + +type BookshelfPublisher struct { + ID string `gorm:"type:string;primary_key;"` + CreatedAt time.Time `gorm:"column:created_date" json:"created_date"` + UpdatedAt time.Time `gorm:"column:last_modified_date" json:"last_modified_date"` + DeletedAt *time.Time `gorm:"column:deleted_date" json:"deleted_date"` + Version int `gorm:"default:0" json:"version"` + Name string `gorm:"uniqueIndex" json:"name"` + Books []Book `gorm:"foreignKey:PublisherID"` +} + +func (publisher *BookshelfPublisher) TableName() string { + return "bookshelf_publisher" +} + +type BookshelfPublisherDTO struct { + ID string `json:"id" binding:"required"` + CreatedAt helpers.KontorTime `json:"created_date"` + UpdatedAt helpers.KontorTime `json:"last_modified_date"` + DeletedAt *time.Time `json:"deleted_date,omitempty"` + Version int `json:"version"` + Name string `json:"name"` +} + +func ConvertBookshelfPublishersToDtos(publishers []BookshelfPublisher) []BookshelfPublisherDTO { + dtos := make([]BookshelfPublisherDTO, len(publishers)) + for i, publisher := range publishers { + dtos[i] = BookshelfPublisherDTO{ + ID: publisher.ID, + CreatedAt: helpers.KontorTime{Time: publisher.CreatedAt}, + UpdatedAt: helpers.KontorTime{Time: publisher.UpdatedAt}, + DeletedAt: publisher.DeletedAt, + Version: publisher.Version, + Name: publisher.Name, + } + } + return dtos +} diff --git a/kontor-gin/internal/repository/article.go b/kontor-gin/internal/repository/article.go new file mode 100644 index 0000000..dd05c23 --- /dev/null +++ b/kontor-gin/internal/repository/article.go @@ -0,0 +1,27 @@ +package repository + +import ( + "context" + "kontor-api-gin/internal/models" + "log/slog" + + "gorm.io/gorm" +) + +type ArticleRepository struct { + db *gorm.DB +} + +func NewArticleRepository(db *gorm.DB) *ArticleRepository { + repo := &ArticleRepository{db: db} + return repo +} + +func (repository *ArticleRepository) FindAll(context context.Context) ([]models.Article, error) { + var articles []models.Article + + result := repository.db.Find(&articles) + slog.Info("ArticleRepository#FindAll", "count", result.RowsAffected) + + return articles, nil +} diff --git a/kontor-gin/internal/repository/article_author.go b/kontor-gin/internal/repository/article_author.go new file mode 100644 index 0000000..fac6549 --- /dev/null +++ b/kontor-gin/internal/repository/article_author.go @@ -0,0 +1,27 @@ +package repository + +import ( + "context" + "kontor-api-gin/internal/models" + "log/slog" + + "gorm.io/gorm" +) + +type ArticleAuthorRepository struct { + db *gorm.DB +} + +func NewArticleAuthorRepository(db *gorm.DB) *ArticleAuthorRepository { + repo := &ArticleAuthorRepository{db: db} + return repo +} + +func (repository *ArticleAuthorRepository) FindAll(context context.Context) ([]models.ArticleAuthor, error) { + var articleAuthors []models.ArticleAuthor + + result := repository.db.Find(&articleAuthors) + slog.Info("ArticleAuthorRepository#FindAll", "count", result.RowsAffected) + + return articleAuthors, nil +} diff --git a/kontor-gin/internal/repository/author.go b/kontor-gin/internal/repository/author.go new file mode 100644 index 0000000..c498f86 --- /dev/null +++ b/kontor-gin/internal/repository/author.go @@ -0,0 +1,27 @@ +package repository + +import ( + "context" + "kontor-api-gin/internal/models" + "log/slog" + + "gorm.io/gorm" +) + +type AuthorRepository struct { + db *gorm.DB +} + +func NewAuthorRepository(db *gorm.DB) *AuthorRepository { + repo := &AuthorRepository{db: db} + return repo +} + +func (repository *AuthorRepository) FindAll(context context.Context) ([]models.Author, error) { + var authors []models.Author + + result := repository.db.Find(&authors) + slog.Info("AuthorRepository#FindAll", "count", result.RowsAffected) + + return authors, nil +} diff --git a/kontor-gin/internal/repository/book.go b/kontor-gin/internal/repository/book.go new file mode 100644 index 0000000..bf185e8 --- /dev/null +++ b/kontor-gin/internal/repository/book.go @@ -0,0 +1,27 @@ +package repository + +import ( + "context" + "kontor-api-gin/internal/models" + "log/slog" + + "gorm.io/gorm" +) + +type BookRepository struct { + db *gorm.DB +} + +func NewBookRepository(db *gorm.DB) *BookRepository { + repo := &BookRepository{db: db} + return repo +} + +func (repository *BookRepository) FindAll(context context.Context) ([]models.Book, error) { + var books []models.Book + + result := repository.db.Find(&books) + slog.Info("BookRepository#FindAll", "count", result.RowsAffected) + + return books, nil +} diff --git a/kontor-gin/internal/repository/book_author.go b/kontor-gin/internal/repository/book_author.go new file mode 100644 index 0000000..d90bab8 --- /dev/null +++ b/kontor-gin/internal/repository/book_author.go @@ -0,0 +1,27 @@ +package repository + +import ( + "context" + "kontor-api-gin/internal/models" + "log/slog" + + "gorm.io/gorm" +) + +type BookAuthorRepository struct { + db *gorm.DB +} + +func NewBookAuthorRepository(db *gorm.DB) *BookAuthorRepository { + repo := &BookAuthorRepository{db: db} + return repo +} + +func (repository *BookAuthorRepository) FindAll(context context.Context) ([]models.BookAuthor, error) { + var bookAuthors []models.BookAuthor + + result := repository.db.Find(&bookAuthors) + slog.Info("BookAuthorRepository#FindAll", "count", result.RowsAffected) + + return bookAuthors, nil +} diff --git a/kontor-gin/internal/repository/bookshelf_publisher.go b/kontor-gin/internal/repository/bookshelf_publisher.go new file mode 100644 index 0000000..b3c60f5 --- /dev/null +++ b/kontor-gin/internal/repository/bookshelf_publisher.go @@ -0,0 +1,27 @@ +package repository + +import ( + "context" + "kontor-api-gin/internal/models" + "log/slog" + + "gorm.io/gorm" +) + +type BookshelfPublisherRepository struct { + db *gorm.DB +} + +func NewBookshelfPublisherRepository(db *gorm.DB) *BookshelfPublisherRepository { + repo := &BookshelfPublisherRepository{db: db} + return repo +} + +func (repository *BookshelfPublisherRepository) FindAll(context context.Context) ([]models.BookshelfPublisher, error) { + var bookshelfPublishers []models.BookshelfPublisher + + result := repository.db.Find(&bookshelfPublishers) + slog.Info("BookshelfPublisherRepository#FindAll", "count", result.RowsAffected) + + return bookshelfPublishers, nil +} diff --git a/kontor-gin/internal/router/router.go b/kontor-gin/internal/router/router.go index f72ebe1..99bccac 100644 --- a/kontor-gin/internal/router/router.go +++ b/kontor-gin/internal/router/router.go @@ -18,7 +18,7 @@ import ( "github.com/gin-gonic/gin" ) -func New(admin *handlers.AdminHandler, comics *handlers.ComicsHandler, media *handlers.MediaHandler, tysc *handlers.TyscHandler, webApp *handlers.WebAppHandler) *gin.Engine { +func New(admin *handlers.AdminHandler, bookshelf *handlers.BookshelfHandler, comics *handlers.ComicsHandler, media *handlers.MediaHandler, tysc *handlers.TyscHandler, webApp *handlers.WebAppHandler) *gin.Engine { router := gin.New() router.Use(gin.Recovery()) router.Use(gin_slog.SetLogger( @@ -83,6 +83,12 @@ func New(admin *handlers.AdminHandler, comics *handlers.ComicsHandler, media *ha secured.GET("tysc/vendors", tysc.VendorHandler.List) secured.GET("tysc/cardsets", tysc.CardSetHandler.List) secured.GET("tysc/cards", tysc.CardHandler.List) + secured.GET("bookshelf/articles", bookshelf.ArticleHandler.List) + secured.GET("bookshelf/publishers", bookshelf.BookshelfPublisherHandler.List) + secured.GET("bookshelf/books", bookshelf.BookHandler.List) + secured.GET("bookshelf/authors", bookshelf.AuthorHandler.List) + secured.GET("bookshelf/articleauthors", bookshelf.ArticleAuthorHandler.List) + secured.GET("bookshelf/bookauthors", bookshelf.BookAuthorHandler.List) secured.GET("/comics/comics", comics.ComicHandler.List) secured.GET("/comics/publishers", comics.PublisherHandler.List) secured.GET("/comics/artists", comics.ArtistHandler.List) diff --git a/kontor-gin/internal/service/article.go b/kontor-gin/internal/service/article.go new file mode 100644 index 0000000..27aa3c8 --- /dev/null +++ b/kontor-gin/internal/service/article.go @@ -0,0 +1,22 @@ +package service + +import ( + "context" + "kontor-api-gin/internal/models" + "kontor-api-gin/internal/repository" + "log/slog" +) + +type ArticleService struct { + repository *repository.ArticleRepository +} + +func NewArticleService(repo *repository.ArticleRepository) *ArticleService { + service := &ArticleService{repository: repo} + return service +} + +func (service *ArticleService) List(context context.Context) ([]models.Article, error) { + slog.Info("ArticleService#List") + return service.repository.FindAll(context) +} diff --git a/kontor-gin/internal/service/article_author.go b/kontor-gin/internal/service/article_author.go new file mode 100644 index 0000000..f61dc56 --- /dev/null +++ b/kontor-gin/internal/service/article_author.go @@ -0,0 +1,22 @@ +package service + +import ( + "context" + "kontor-api-gin/internal/models" + "kontor-api-gin/internal/repository" + "log/slog" +) + +type ArticleAuthorService struct { + repository *repository.ArticleAuthorRepository +} + +func NewArticleAuthorService(repo *repository.ArticleAuthorRepository) *ArticleAuthorService { + service := &ArticleAuthorService{repository: repo} + return service +} + +func (service *ArticleAuthorService) List(context context.Context) ([]models.ArticleAuthor, error) { + slog.Info("ArticleAuthorService#List") + return service.repository.FindAll(context) +} diff --git a/kontor-gin/internal/service/author.go b/kontor-gin/internal/service/author.go new file mode 100644 index 0000000..707818a --- /dev/null +++ b/kontor-gin/internal/service/author.go @@ -0,0 +1,22 @@ +package service + +import ( + "context" + "kontor-api-gin/internal/models" + "kontor-api-gin/internal/repository" + "log/slog" +) + +type AuthorService struct { + repository *repository.AuthorRepository +} + +func NewAuthorService(repo *repository.AuthorRepository) *AuthorService { + service := &AuthorService{repository: repo} + return service +} + +func (service *AuthorService) List(context context.Context) ([]models.Author, error) { + slog.Info("AuthorService#List") + return service.repository.FindAll(context) +} diff --git a/kontor-gin/internal/service/book.go b/kontor-gin/internal/service/book.go new file mode 100644 index 0000000..cae8d1d --- /dev/null +++ b/kontor-gin/internal/service/book.go @@ -0,0 +1,22 @@ +package service + +import ( + "context" + "kontor-api-gin/internal/models" + "kontor-api-gin/internal/repository" + "log/slog" +) + +type BookService struct { + repository *repository.BookRepository +} + +func NewBookService(repo *repository.BookRepository) *BookService { + service := &BookService{repository: repo} + return service +} + +func (service *BookService) List(context context.Context) ([]models.Book, error) { + slog.Info("BookService#List") + return service.repository.FindAll(context) +} diff --git a/kontor-gin/internal/service/book_author.go b/kontor-gin/internal/service/book_author.go new file mode 100644 index 0000000..45889e6 --- /dev/null +++ b/kontor-gin/internal/service/book_author.go @@ -0,0 +1,22 @@ +package service + +import ( + "context" + "kontor-api-gin/internal/models" + "kontor-api-gin/internal/repository" + "log/slog" +) + +type BookAuthorService struct { + repository *repository.BookAuthorRepository +} + +func NewBookAuthorService(repo *repository.BookAuthorRepository) *BookAuthorService { + service := &BookAuthorService{repository: repo} + return service +} + +func (service *BookAuthorService) List(context context.Context) ([]models.BookAuthor, error) { + slog.Info("BookAuthorService#List") + return service.repository.FindAll(context) +} diff --git a/kontor-gin/internal/service/bookshelf_publisher.go b/kontor-gin/internal/service/bookshelf_publisher.go new file mode 100644 index 0000000..7e8a26c --- /dev/null +++ b/kontor-gin/internal/service/bookshelf_publisher.go @@ -0,0 +1,22 @@ +package service + +import ( + "context" + "kontor-api-gin/internal/models" + "kontor-api-gin/internal/repository" + "log/slog" +) + +type BookshelfPublisherService struct { + repository *repository.BookshelfPublisherRepository +} + +func NewBookshelfPublisherService(repo *repository.BookshelfPublisherRepository) *BookshelfPublisherService { + service := &BookshelfPublisherService{repository: repo} + return service +} + +func (service *BookshelfPublisherService) List(context context.Context) ([]models.BookshelfPublisher, error) { + slog.Info("BookshelfPublisherService#List") + return service.repository.FindAll(context) +}