mirror of
https://github.com/balzack/databag.git
synced 2025-02-12 03:29:16 +00:00
removing block concept from articla api
This commit is contained in:
parent
a713fd2174
commit
b1e0a17506
75
doc/api.oa3
75
doc/api.oa3
@ -1543,12 +1543,12 @@ paths:
|
|||||||
type: integer
|
type: integer
|
||||||
format: int64
|
format: int64
|
||||||
|
|
||||||
/content/articleBlocks:
|
/content/articles:
|
||||||
get:
|
get:
|
||||||
tags:
|
tags:
|
||||||
- content
|
- content
|
||||||
description: Get article blocks that should be updated based on revisions. Acess granted to account token or contact token. When the request is made with a contact token the account view revision will be added to the block revision.
|
description: Get article slots that should be updated based on revisions. Access granted to account token or contact token. When the request is made with a contact token the account view revision will be added to the block revision.
|
||||||
operationId: get-article-block-view
|
operationId: get-articles
|
||||||
security:
|
security:
|
||||||
- bearerAuth: []
|
- bearerAuth: []
|
||||||
parameters:
|
parameters:
|
||||||
@ -1579,74 +1579,6 @@ paths:
|
|||||||
description: account disabled
|
description: account disabled
|
||||||
'500':
|
'500':
|
||||||
description: internal server error
|
description: internal server error
|
||||||
|
|
||||||
/content/articleBlocks/{blockId}:
|
|
||||||
get:
|
|
||||||
tags:
|
|
||||||
- content
|
|
||||||
description: Get the articles within specified block. Access granted for app token or contact token. All of the articles are returned for the app token, but only the shared articles are returned for the contact token. An article is shared by assigning a common group to an article or assigning a label to an article that has assigned a common group.
|
|
||||||
operationId: get-articles
|
|
||||||
security:
|
|
||||||
- bearerAuth: []
|
|
||||||
parameters:
|
|
||||||
- name: blockId
|
|
||||||
in: path
|
|
||||||
description: specified group id
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: successful operation
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
$ref: '#/components/schemas/Article'
|
|
||||||
'401':
|
|
||||||
description: permission denied
|
|
||||||
'404':
|
|
||||||
description: block not found
|
|
||||||
'410':
|
|
||||||
description: account disabled
|
|
||||||
'500':
|
|
||||||
description: internal server error
|
|
||||||
|
|
||||||
/content/articleBlocks/{blockId}/view:
|
|
||||||
get:
|
|
||||||
tags:
|
|
||||||
- content
|
|
||||||
description: Get the article views within specified block. Access granted for app token or contact token. All of the articles are returned for the app token, but only the shared articles are returned for the contact token. An article is shared by assigning a common group to an article or assigning a label to an article that has assigned a common group.
|
|
||||||
operationId: get-article-views
|
|
||||||
security:
|
|
||||||
- bearerAuth: []
|
|
||||||
parameters:
|
|
||||||
- name: blockId
|
|
||||||
in: path
|
|
||||||
description: specified group id
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: successful operation
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
$ref: '#/components/schemas/ArticleView'
|
|
||||||
'401':
|
|
||||||
description: permission denied
|
|
||||||
'404':
|
|
||||||
description: block not found
|
|
||||||
'410':
|
|
||||||
description: account disabled
|
|
||||||
'500':
|
|
||||||
description: internal server error
|
|
||||||
|
|
||||||
/content/articles:
|
|
||||||
post:
|
post:
|
||||||
tags:
|
tags:
|
||||||
- content
|
- content
|
||||||
@ -4642,3 +4574,4 @@ components:
|
|||||||
scheme: bearer
|
scheme: bearer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package databag
|
package databag
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"time"
|
||||||
"errors"
|
"errors"
|
||||||
"net/http"
|
"net/http"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
@ -22,8 +23,8 @@ func AddArticle(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var groups []store.Group
|
var groups []store.Label
|
||||||
if err := store.DB.Where("group_id IN ?", articleAccess.Groups).Find(&groups).Error; err != nil {
|
if err := store.DB.Raw("select labels.* from labels inner join label_groups on labels.id = label_groups.label_id inner join groups on label_groups.group_id = groups.id where groups.group_id in ?", articleAccess.Groups).Scan(&groups).Error; err != nil {
|
||||||
ErrResponse(w, http.StatusInternalServerError, err)
|
ErrResponse(w, http.StatusInternalServerError, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -34,47 +35,43 @@ func AddArticle(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var articleBlock store.ArticleBlock
|
|
||||||
if err := store.DB.Preload("Articles").Where("account_id = ?", account.ID).Last(&articleBlock).Error; err != nil {
|
// save data and apply transaction
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
var article *store.Article
|
||||||
if err := addArticleBlock(account, &articleBlock); err != nil {
|
err = store.DB.Transaction(func(tx *gorm.DB) error {
|
||||||
ErrResponse(w, http.StatusInternalServerError, err)
|
|
||||||
return
|
articleData := &store.ArticleData{
|
||||||
}
|
DataRevision: 1,
|
||||||
} else {
|
Status: APP_ARTICLEUNCONFIRMED,
|
||||||
ErrResponse(w, http.StatusInternalServerError, err)
|
TagUpdated: time.Now().Unix(),
|
||||||
return
|
TagRevision: 1,
|
||||||
}
|
Labels: append(groups, labels...),
|
||||||
}
|
};
|
||||||
if len(articleBlock.Articles) >= APP_ARTICLEBLOCKSIZE {
|
if res := store.DB.Save(articleData).Error; res != nil {
|
||||||
if err := addArticleBlock(account, &articleBlock); err != nil {
|
return res;
|
||||||
ErrResponse(w, http.StatusInternalServerError, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
article := &store.Article{
|
if res := store.DB.Where("article_data_id is null AND account_id = ?", account.ID).First(&article).Error; res != nil {
|
||||||
|
if errors.Is(res, gorm.ErrRecordNotFound) {
|
||||||
|
article = &store.Article{
|
||||||
ArticleId: uuid.New().String(),
|
ArticleId: uuid.New().String(),
|
||||||
ArticleBlockID: articleBlock.ID,
|
|
||||||
AccountID: account.ID,
|
AccountID: account.ID,
|
||||||
Revision: 1,
|
Revision: 1,
|
||||||
Status: APP_ARTICLEUNCONFIRMED,
|
ArticleDataID: articleData.ID,
|
||||||
Expires: 0,
|
ArticleData: articleData,
|
||||||
TagUpdated: 0,
|
|
||||||
TagRevision: 0,
|
|
||||||
Groups: groups,
|
|
||||||
Labels: labels,
|
|
||||||
ArticleBlock: articleBlock,
|
|
||||||
}
|
}
|
||||||
err = store.DB.Transaction(func(tx *gorm.DB) error {
|
if ret := store.DB.Save(article).Error; ret != nil {
|
||||||
if res := tx.Save(article).Error; res != nil {
|
return ret;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
if res := tx.Model(&articleBlock).Update("revision", account.ContentRevision + 1).Error; res != nil {
|
|
||||||
return res
|
|
||||||
}
|
}
|
||||||
if res := tx.Model(&account).Update("content_revision", account.ContentRevision + 1).Error; res != nil {
|
if ret := store.DB.Model(article).Update("article_data_id", articleData.ID).Error; ret != nil {
|
||||||
return res
|
return ret;
|
||||||
|
}
|
||||||
|
if ret := store.DB.Preload("ArticleData.Labels.Groups").Where("id = ?", article.ID).First(article).Error; ret != nil {
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
@ -83,23 +80,9 @@ func AddArticle(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
articleEntry := &ArticleEntry{
|
|
||||||
BlockId: articleBlock.ArticleBlockId,
|
|
||||||
Article: getArticleModel(article, 0),
|
|
||||||
}
|
|
||||||
|
|
||||||
SetStatus(account)
|
|
||||||
SetContentNotification(account)
|
SetContentNotification(account)
|
||||||
WriteResponse(w, articleEntry)
|
SetStatus(account)
|
||||||
|
WriteResponse(w, getArticleModel(article, 0))
|
||||||
}
|
}
|
||||||
|
|
||||||
func addArticleBlock(account *store.Account, articleBlock *store.ArticleBlock) (err error) {
|
|
||||||
articleBlock.ArticleBlockId = uuid.New().String()
|
|
||||||
articleBlock.AccountID = account.ID
|
|
||||||
articleBlock.Revision = account.ContentRevision
|
|
||||||
if err = store.DB.Save(articleBlock).Error; err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -21,17 +21,41 @@ func AddGroup(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
group := &store.Group{
|
var group *store.Group
|
||||||
|
err = store.DB.Transaction(func(tx *gorm.DB) error {
|
||||||
|
|
||||||
|
label := &store.Label{
|
||||||
|
LabelId: uuid.New().String(),
|
||||||
|
AccountID: account.ID,
|
||||||
|
Revision: 1,
|
||||||
|
Direct: true,
|
||||||
|
}
|
||||||
|
if res := tx.Save(label).Error; res != nil {
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
group = &store.Group{
|
||||||
GroupId: uuid.New().String(),
|
GroupId: uuid.New().String(),
|
||||||
AccountID: account.ID,
|
AccountID: account.ID,
|
||||||
Revision: 0,
|
LabelID: label.ID,
|
||||||
|
Revision: 1,
|
||||||
DataType: subject.DataType,
|
DataType: subject.DataType,
|
||||||
Data: subject.Data,
|
Data: subject.Data,
|
||||||
}
|
}
|
||||||
err = store.DB.Transaction(func(tx *gorm.DB) error {
|
|
||||||
if res := tx.Save(group).Error; res != nil {
|
if res := tx.Save(group).Error; res != nil {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
label.Groups = []store.Group{*group}
|
||||||
|
if res := tx.Save(label).Error; res != nil {
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
PrintMsg("ADDED")
|
||||||
|
PrintMsg(group.GroupId)
|
||||||
|
PrintMsg(label.LabelId)
|
||||||
|
PrintMsg("***")
|
||||||
|
|
||||||
if res := tx.Model(&account).Update("group_revision", account.GroupRevision + 1).Error; res != nil {
|
if res := tx.Model(&account).Update("group_revision", account.GroupRevision + 1).Error; res != nil {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
@ -88,11 +88,6 @@ func GetArticleTags(w http.ResponseWriter, r *http.Request) {
|
|||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetArticleViews(w http.ResponseWriter, r *http.Request) {
|
|
||||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
|
||||||
w.WriteHeader(http.StatusOK)
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetArticles(w http.ResponseWriter, r *http.Request) {
|
func GetArticles(w http.ResponseWriter, r *http.Request) {
|
||||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
@ -157,3 +152,4 @@ func UpdateLabel(w http.ResponseWriter, r *http.Request) {
|
|||||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,102 +0,0 @@
|
|||||||
package databag
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strings"
|
|
||||||
"strconv"
|
|
||||||
"errors"
|
|
||||||
"net/http"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
"databag/internal/store"
|
|
||||||
)
|
|
||||||
|
|
||||||
func GetArticleBlocks(w http.ResponseWriter, r *http.Request) {
|
|
||||||
var err error
|
|
||||||
|
|
||||||
var contentRevision int64
|
|
||||||
if contentRevision, err = getArticleBlockRevision(r.FormValue("contentRevision")); err != nil {
|
|
||||||
ErrMsg(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// extract token
|
|
||||||
tokenType := r.Header.Get("TokenType")
|
|
||||||
auth := r.Header.Get("Authorization")
|
|
||||||
token := strings.TrimSpace(strings.TrimPrefix(auth, "Bearer"))
|
|
||||||
target, access, err := ParseToken(token)
|
|
||||||
if err != nil {
|
|
||||||
ErrResponse(w, http.StatusBadRequest, errors.New("invalid bearer token"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// retrieve updated blocks
|
|
||||||
var blocks []store.ArticleBlock
|
|
||||||
if tokenType == APP_TOKENAPP {
|
|
||||||
var app store.App
|
|
||||||
if err := store.DB.Preload("Account").Where("account_id = ? AND token = ?", target, access).First(&app).Error; err != nil {
|
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
||||||
ErrResponse(w, http.StatusNotFound, err)
|
|
||||||
} else {
|
|
||||||
ErrResponse(w, http.StatusInternalServerError, err)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// retrieve block ids
|
|
||||||
if err = getAccountArticleBlocks(&app.Account, contentRevision, &blocks); err != nil {
|
|
||||||
ErrResponse(w, http.StatusInternalServerError, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
} else if tokenType == APP_TOKENCONTACT {
|
|
||||||
var card store.Card
|
|
||||||
if err := store.DB.Preload("Account").Where("account_id = ? AND InToken = ?", target, access).First(&card).Error; err != nil {
|
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
||||||
ErrResponse(w, http.StatusNotFound, err)
|
|
||||||
} else {
|
|
||||||
ErrResponse(w, http.StatusInternalServerError, err)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var viewRevision int64
|
|
||||||
if viewRevision, err = getArticleBlockRevision(r.FormValue("viewRevision")); err != nil {
|
|
||||||
ErrMsg(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// retrieve block ids
|
|
||||||
if err = getCardArticleBlocks(&card, viewRevision, contentRevision, &blocks); err != nil {
|
|
||||||
ErrResponse(w, http.StatusInternalServerError, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ErrResponse(w, http.StatusBadRequest, errors.New("invalid token type"))
|
|
||||||
}
|
|
||||||
|
|
||||||
var ids []string
|
|
||||||
for _, block := range blocks {
|
|
||||||
ids = append(ids, block.ArticleBlockId)
|
|
||||||
}
|
|
||||||
WriteResponse(w, ids)
|
|
||||||
}
|
|
||||||
|
|
||||||
func getArticleBlockRevision(param string) (rev int64, err error) {
|
|
||||||
if param == "" {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
rev, err = strconv.ParseInt(param, 10, 64)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func getAccountArticleBlocks(act *store.Account, content int64, blocks *[]store.ArticleBlock) error {
|
|
||||||
return store.DB.Where("revision > ? AND account_id = ?", content, act.ID).Find(blocks).Error
|
|
||||||
}
|
|
||||||
|
|
||||||
func getCardArticleBlocks(card *store.Card, view int64, content int64, blocks *[]store.ArticleBlock) error {
|
|
||||||
if view != card.ViewRevision + card.Account.ViewRevision {
|
|
||||||
return store.DB.Where("revision > ? && account_id = ?", content, card.Account.ID).Find(blocks).Error
|
|
||||||
} else {
|
|
||||||
return store.DB.Where("account_id = ?", card.Account.ID).Find(blocks).Error
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
|||||||
package databag
|
package databag
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"net/http"
|
"net/http"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
@ -17,10 +18,27 @@ func RemoveGroup(w http.ResponseWriter, r *http.Request) {
|
|||||||
params := mux.Vars(r)
|
params := mux.Vars(r)
|
||||||
groupId := params["groupId"]
|
groupId := params["groupId"]
|
||||||
|
|
||||||
|
var group store.Group
|
||||||
|
if err := store.DB.Preload("Label").Where("account_id = ? AND group_id = ?", account.ID, groupId).First(&group).Error; err != nil {
|
||||||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
ErrResponse(w, http.StatusNotFound, err)
|
||||||
|
} else {
|
||||||
|
ErrResponse(w, http.StatusInternalServerError, err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
err = store.DB.Transaction(func(tx *gorm.DB) error {
|
err = store.DB.Transaction(func(tx *gorm.DB) error {
|
||||||
if res := tx.Where("account_id = ? AND group_id = ?", account.ID, groupId).Delete(&store.Group{}).Error; res != nil {
|
if res := tx.Delete(&group.Label).Error; res != nil {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
if res := tx.Delete(&group).Error; res != nil {
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
if res := tx.Model(&group.Label).Association("Groups").Delete(&group); res != nil {
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
if res := tx.Model(&account).Updates(store.Account{ViewRevision: account.ViewRevision + 1, GroupRevision: account.GroupRevision + 1}).Error; res != nil {
|
if res := tx.Model(&account).Updates(store.Account{ViewRevision: account.ViewRevision + 1, GroupRevision: account.GroupRevision + 1}).Error; res != nil {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
@ -51,32 +51,40 @@ func getGroupModel(group *store.Group) *Group {
|
|||||||
|
|
||||||
func getArticleModel(article *store.Article, tagCount int32) *Article {
|
func getArticleModel(article *store.Article, tagCount int32) *Article {
|
||||||
|
|
||||||
// populate group id list
|
if article.ArticleData == nil {
|
||||||
var groups []string;
|
return &Article{
|
||||||
for _, group := range article.Groups {
|
ArticleId: article.ArticleId,
|
||||||
groups = append(groups, group.GroupId)
|
Revision: article.Revision,
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
// populate label id list
|
// populate id list
|
||||||
|
var groups []string;
|
||||||
var labels []string;
|
var labels []string;
|
||||||
for _, label := range article.Labels {
|
for _, label := range article.ArticleData.Labels {
|
||||||
|
if label.Direct && len(label.Groups) > 0 {
|
||||||
|
groups = append(groups, label.Groups[0].GroupId)
|
||||||
|
} else {
|
||||||
labels = append(labels, label.LabelId)
|
labels = append(labels, label.LabelId)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return &Article{
|
return &Article{
|
||||||
ArticleId: article.ArticleId,
|
ArticleId: article.ArticleId,
|
||||||
ArticleBlockId: article.ArticleBlock.ArticleBlockId,
|
|
||||||
Revision: article.Revision,
|
Revision: article.Revision,
|
||||||
DataType: article.DataType,
|
ArticleData: &ArticleData{
|
||||||
Data: article.Data,
|
DataType: article.ArticleData.DataType,
|
||||||
Created: article.Created,
|
Data: article.ArticleData.Data,
|
||||||
Updated: article.Updated,
|
Status: article.ArticleData.Status,
|
||||||
Status: article.Status,
|
|
||||||
Labels: labels,
|
Labels: labels,
|
||||||
Groups: groups,
|
Groups: groups,
|
||||||
TagCount: tagCount,
|
TagCount: tagCount,
|
||||||
TagUpdated: article.TagUpdated,
|
Created: article.ArticleData.Created,
|
||||||
TagRevision: article.TagRevision,
|
Updated: article.ArticleData.Updated,
|
||||||
|
TagUpdated: article.ArticleData.TagUpdated,
|
||||||
|
TagRevision: article.ArticleData.TagRevision,
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,15 +43,13 @@ type Subject struct {
|
|||||||
Data string `json:"data"`
|
Data string `json:"data"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ArticleEntry struct {
|
type Article struct {
|
||||||
BlockId string `json:"blockId"`
|
ArticleId string `json:"article_id"`
|
||||||
Article *Article `json:"article"`
|
Revision int64 `json:"revision"`
|
||||||
|
ArticleData *ArticleData `json:"articleData"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Article struct {
|
type ArticleData struct {
|
||||||
ArticleId string `json:"articleId"`
|
|
||||||
ArticleBlockId string `json:"articleBlockId"`
|
|
||||||
Revision int64 `json:"revision"`
|
|
||||||
DataType string `json:"type"`
|
DataType string `json:"type"`
|
||||||
Data string `json:"data"`
|
Data string `json:"data"`
|
||||||
Created int64 `json:"created"`
|
Created int64 `json:"created"`
|
||||||
|
@ -397,13 +397,6 @@ var routes = Routes{
|
|||||||
SetOpenMessage,
|
SetOpenMessage,
|
||||||
},
|
},
|
||||||
|
|
||||||
Route{
|
|
||||||
"SetViewRevision",
|
|
||||||
strings.ToUpper("Put"),
|
|
||||||
"/contact/view/revision",
|
|
||||||
SetViewRevision,
|
|
||||||
},
|
|
||||||
|
|
||||||
Route{
|
Route{
|
||||||
"SetProfileRevision",
|
"SetProfileRevision",
|
||||||
strings.ToUpper("Put"),
|
strings.ToUpper("Put"),
|
||||||
@ -411,6 +404,13 @@ var routes = Routes{
|
|||||||
SetProfileRevision,
|
SetProfileRevision,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
Route{
|
||||||
|
"SetViewRevision",
|
||||||
|
strings.ToUpper("Put"),
|
||||||
|
"/contact/view/revision",
|
||||||
|
SetViewRevision,
|
||||||
|
},
|
||||||
|
|
||||||
Route{
|
Route{
|
||||||
"AddArticle",
|
"AddArticle",
|
||||||
strings.ToUpper("Post"),
|
strings.ToUpper("Post"),
|
||||||
@ -481,13 +481,6 @@ var routes = Routes{
|
|||||||
GetArticleAssets,
|
GetArticleAssets,
|
||||||
},
|
},
|
||||||
|
|
||||||
Route{
|
|
||||||
"GetArticleBlocks",
|
|
||||||
strings.ToUpper("Get"),
|
|
||||||
"/content/articleBlocks",
|
|
||||||
GetArticleBlocks,
|
|
||||||
},
|
|
||||||
|
|
||||||
Route{
|
Route{
|
||||||
"GetArticleSubjectField",
|
"GetArticleSubjectField",
|
||||||
strings.ToUpper("Get"),
|
strings.ToUpper("Get"),
|
||||||
@ -530,17 +523,10 @@ var routes = Routes{
|
|||||||
GetArticleTags,
|
GetArticleTags,
|
||||||
},
|
},
|
||||||
|
|
||||||
Route{
|
|
||||||
"GetArticleViews",
|
|
||||||
strings.ToUpper("Get"),
|
|
||||||
"/content/articleBlocks/{blockId}/view",
|
|
||||||
GetArticleViews,
|
|
||||||
},
|
|
||||||
|
|
||||||
Route{
|
Route{
|
||||||
"GetArticles",
|
"GetArticles",
|
||||||
strings.ToUpper("Get"),
|
strings.ToUpper("Get"),
|
||||||
"/content/articleBlocks/{blockId}",
|
"/content/articles",
|
||||||
GetArticles,
|
GetArticles,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ func AutoMigrate(db *gorm.DB) {
|
|||||||
db.AutoMigrate(&Card{});
|
db.AutoMigrate(&Card{});
|
||||||
db.AutoMigrate(&Asset{});
|
db.AutoMigrate(&Asset{});
|
||||||
db.AutoMigrate(&Article{});
|
db.AutoMigrate(&Article{});
|
||||||
db.AutoMigrate(&ArticleBlock{});
|
db.AutoMigrate(&ArticleData{});
|
||||||
db.AutoMigrate(&ArticleAsset{});
|
db.AutoMigrate(&ArticleAsset{});
|
||||||
db.AutoMigrate(&ArticleTag{});
|
db.AutoMigrate(&ArticleTag{});
|
||||||
db.AutoMigrate(&Dialogue{});
|
db.AutoMigrate(&Dialogue{});
|
||||||
@ -100,11 +100,13 @@ type Group struct {
|
|||||||
ID uint `gorm:"primaryKey;not null;unique;autoIncrement"`
|
ID uint `gorm:"primaryKey;not null;unique;autoIncrement"`
|
||||||
GroupId string `gorm:"not null;index:group,unqiue"`
|
GroupId string `gorm:"not null;index:group,unqiue"`
|
||||||
AccountID uint `gorm:"not null;index:group,unique"`
|
AccountID uint `gorm:"not null;index:group,unique"`
|
||||||
|
LabelID uint `gorm:"not null;index:direct"`
|
||||||
Revision int64 `gorm:"not null"`
|
Revision int64 `gorm:"not null"`
|
||||||
DataType string `gorm:"index"`
|
DataType string `gorm:"index"`
|
||||||
Data string
|
Data string
|
||||||
Created int64 `gorm:"autoCreateTime"`
|
Created int64 `gorm:"autoCreateTime"`
|
||||||
Updated int64 `gorm:"autoUpdateTime"`
|
Updated int64 `gorm:"autoUpdateTime"`
|
||||||
|
Label Label //reference to label for direct assignment to articles
|
||||||
Account Account
|
Account Account
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,6 +119,7 @@ type Label struct {
|
|||||||
Data string
|
Data string
|
||||||
Created int64 `gorm:"autoCreateTime"`
|
Created int64 `gorm:"autoCreateTime"`
|
||||||
Updated int64 `gorm:"autoUpdateTime"`
|
Updated int64 `gorm:"autoUpdateTime"`
|
||||||
|
Direct bool //special label indicating direct assignment of a group
|
||||||
Groups []Group `gorm:"many2many:label_groups;"`
|
Groups []Group `gorm:"many2many:label_groups;"`
|
||||||
Account Account
|
Account Account
|
||||||
}
|
}
|
||||||
@ -164,20 +167,19 @@ type Asset struct {
|
|||||||
Account Account
|
Account Account
|
||||||
}
|
}
|
||||||
|
|
||||||
type ArticleBlock struct {
|
|
||||||
ID uint `gorm:"primaryKey;not null;unique;autoIncrement"`
|
|
||||||
ArticleBlockId string `gorm:"not null;index:articleblock,unique"`
|
|
||||||
AccountID uint `gorm:"not null;index:articleblock,unique"`
|
|
||||||
Revision int64 `gorm:"not null"`
|
|
||||||
Articles []Article
|
|
||||||
}
|
|
||||||
|
|
||||||
type Article struct {
|
type Article struct {
|
||||||
ID uint `gorm:"primaryKey;not null;unique;autoIncrement"`
|
ID uint `gorm:"primaryKey;not null;unique;autoIncrement"`
|
||||||
ArticleId string `gorm:"not null;index:article,unique"`
|
ArticleId string `gorm:"not null;index:article,unique"`
|
||||||
AccountID uint `gorm:"not null;index:article,unique"`
|
AccountID uint `gorm:"not null;index:article,unique"`
|
||||||
ArticleBlockID uint `gorm:"not null;index:articleblockid"`
|
|
||||||
Revision int64 `gorm:"not null"`
|
Revision int64 `gorm:"not null"`
|
||||||
|
ArticleDataID uint
|
||||||
|
ArticleData *ArticleData
|
||||||
|
Account Account
|
||||||
|
}
|
||||||
|
|
||||||
|
type ArticleData struct {
|
||||||
|
ID uint `gorm:"primaryKey;not null;unique;autoIncrement"`
|
||||||
|
DataRevision int64 `gorm:"not null"`
|
||||||
DataType string `gorm:"index"`
|
DataType string `gorm:"index"`
|
||||||
Data string
|
Data string
|
||||||
Status string `gorm:"not null;index"`
|
Status string `gorm:"not null;index"`
|
||||||
@ -186,10 +188,7 @@ type Article struct {
|
|||||||
Updated int64 `gorm:"autoUpdateTime"`
|
Updated int64 `gorm:"autoUpdateTime"`
|
||||||
TagUpdated int64 `gorm:"not null"`
|
TagUpdated int64 `gorm:"not null"`
|
||||||
TagRevision int64 `gorm:"not null"`
|
TagRevision int64 `gorm:"not null"`
|
||||||
Groups []Group `gorm:"many2many:article_groups;"`
|
|
||||||
Labels []Label `gorm:"many2many:article_labels;"`
|
Labels []Label `gorm:"many2many:article_labels;"`
|
||||||
Account Account
|
|
||||||
ArticleBlock ArticleBlock
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type ArticleAsset struct {
|
type ArticleAsset struct {
|
||||||
|
@ -9,9 +9,7 @@ func TestAddArticle(t *testing.T) {
|
|||||||
var set *TestGroup
|
var set *TestGroup
|
||||||
var err error
|
var err error
|
||||||
var rev *Revision
|
var rev *Revision
|
||||||
var articleEntry ArticleEntry
|
var article Article
|
||||||
var contentRevision int64
|
|
||||||
var ids []string
|
|
||||||
|
|
||||||
// setup testing group
|
// setup testing group
|
||||||
set, err = AddTestGroup("addarticle")
|
set, err = AddTestGroup("addarticle")
|
||||||
@ -19,20 +17,15 @@ func TestAddArticle(t *testing.T) {
|
|||||||
|
|
||||||
// initial revision
|
// initial revision
|
||||||
rev = GetTestRevision(set.A.Revisions)
|
rev = GetTestRevision(set.A.Revisions)
|
||||||
contentRevision = rev.Content
|
|
||||||
|
|
||||||
// create article
|
// create article
|
||||||
articleAccess := &ArticleAccess{ Groups: []string{set.A.B.GroupId} }
|
articleAccess := &ArticleAccess{ Groups: []string{set.A.B.GroupId} }
|
||||||
assert.NoError(t, SendEndpointTest(AddArticle, "POST", "/content/articles", nil, articleAccess, set.A.Token, &articleEntry))
|
assert.NoError(t, SendEndpointTest(AddArticle, "POST", "/content/articles", nil, articleAccess, set.A.Token, &article))
|
||||||
PrintMsg(articleEntry);
|
PrintMsg(article);
|
||||||
|
|
||||||
// check revisions
|
// check revisions
|
||||||
rev = GetTestRevision(set.A.Revisions)
|
rev = GetTestRevision(set.A.Revisions)
|
||||||
assert.Greater(t, rev.Content, contentRevision)
|
|
||||||
|
|
||||||
// view article blocks
|
|
||||||
assert.NoError(t, SendEndpointTest(GetArticleBlocks, "GET", "/content/articleBlocks", nil, nil, set.A.Token, &ids))
|
|
||||||
PrintMsg(ids)
|
|
||||||
|
|
||||||
// view article
|
// view article
|
||||||
|
|
||||||
|
@ -138,6 +138,8 @@ func TestGroupContact(t *testing.T) {
|
|||||||
vars["groupId"] = group.GroupId
|
vars["groupId"] = group.GroupId
|
||||||
r = mux.SetURLVars(r, vars)
|
r = mux.SetURLVars(r, vars)
|
||||||
SetBearerAuth(r, a)
|
SetBearerAuth(r, a)
|
||||||
|
PrintMsg(group.GroupId)
|
||||||
|
PrintMsg("REMOVED")
|
||||||
RemoveGroup(w, r)
|
RemoveGroup(w, r)
|
||||||
assert.NoError(t, ReadResponse(w, &group))
|
assert.NoError(t, ReadResponse(w, &group))
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user