mirror of
https://github.com/balzack/databag.git
synced 2025-02-12 03:29:16 +00:00
adding addArticle endpoint
This commit is contained in:
parent
4298bd5b31
commit
1dc2ddcf39
82
doc/api.oa3
82
doc/api.oa3
@ -1635,15 +1635,7 @@ paths:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
blockId:
|
||||
type: string
|
||||
blockRevision:
|
||||
type: integer
|
||||
format: int64
|
||||
article:
|
||||
$ref: '#/components/schemas/Article'
|
||||
$ref: '#/components/schemas/ArticleEntry'
|
||||
'401':
|
||||
description: permission denied
|
||||
'410':
|
||||
@ -1654,19 +1646,7 @@ paths:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required:
|
||||
- labels
|
||||
- groups
|
||||
properties:
|
||||
labels:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
groups:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
$ref: '#/components/schemas/ArticleAccess'
|
||||
|
||||
/content/articles/{articleId}:
|
||||
get:
|
||||
@ -4025,6 +4005,36 @@ components:
|
||||
data:
|
||||
type: string
|
||||
|
||||
ArticleAccess:
|
||||
type: object
|
||||
required:
|
||||
- labels
|
||||
- groups
|
||||
properties:
|
||||
labels:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
groups:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
|
||||
ArticleEntry:
|
||||
type: object
|
||||
required:
|
||||
- blockId
|
||||
- blockRevision
|
||||
- article
|
||||
properties:
|
||||
blockId:
|
||||
type: string
|
||||
blockRevision:
|
||||
type: integer
|
||||
format: int64
|
||||
article:
|
||||
$ref: '#/components/schemas/Article'
|
||||
|
||||
Account:
|
||||
type: object
|
||||
required:
|
||||
@ -4251,19 +4261,6 @@ components:
|
||||
type: string
|
||||
enum: [ active, offsync, inactive, dismissed ]
|
||||
|
||||
Tunnel:
|
||||
type: object
|
||||
required:
|
||||
- cardId
|
||||
- type
|
||||
properties:
|
||||
cardId:
|
||||
type: string
|
||||
type:
|
||||
type: string
|
||||
data:
|
||||
type: string
|
||||
|
||||
Topic:
|
||||
type: object
|
||||
required:
|
||||
@ -4310,11 +4307,11 @@ components:
|
||||
type: object
|
||||
required:
|
||||
- articleId
|
||||
- articleRevision
|
||||
- type
|
||||
- revision
|
||||
- dataType
|
||||
- data
|
||||
- created
|
||||
- modified
|
||||
- updated
|
||||
- status
|
||||
- labels
|
||||
- tagCount
|
||||
@ -4323,22 +4320,22 @@ components:
|
||||
properties:
|
||||
articleId:
|
||||
type: string
|
||||
articleRevision:
|
||||
revision:
|
||||
type: integer
|
||||
format: int64
|
||||
type:
|
||||
dataType:
|
||||
type: string
|
||||
data:
|
||||
type: string
|
||||
created:
|
||||
type: integer
|
||||
format: int64
|
||||
modified:
|
||||
updated:
|
||||
type: integer
|
||||
format: int64
|
||||
status:
|
||||
type: string
|
||||
enum: [ unconfirmed, confirmed, complete, error ]
|
||||
enum: [ unconfirmed, confirmed, incomplete, error ]
|
||||
labels:
|
||||
type: array
|
||||
items:
|
||||
@ -4555,3 +4552,4 @@ components:
|
||||
bearerAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
|
||||
|
64
net/server/internal/api_addArticle.go
Normal file
64
net/server/internal/api_addArticle.go
Normal file
@ -0,0 +1,64 @@
|
||||
package databag
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"gorm.io/gorm"
|
||||
"github.com/google/uuid"
|
||||
"databag/internal/store"
|
||||
)
|
||||
|
||||
func AddArticle(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
account, code, err := BearerAppToken(r, false)
|
||||
if err != nil {
|
||||
ErrResponse(w, code, err)
|
||||
return
|
||||
}
|
||||
|
||||
var articleAccess ArticleAccess
|
||||
if err := ParseRequest(r, w, &articleAccess); err != nil {
|
||||
ErrResponse(w, http.StatusBadRequest, err)
|
||||
return
|
||||
}
|
||||
|
||||
var groups []store.Group
|
||||
if err := store.DB.Where("group_id IN ?", articleAccess.Groups).Find(&groups).Error; err != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
var labels []store.Label
|
||||
if err := store.DB.Where("label_id IN ?", articleAccess.Labels).Find(&labels).Error; err != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
article := &store.Article{
|
||||
ArticleId: uuid.New().String(),
|
||||
AccountID: account.ID,
|
||||
Revision: 1,
|
||||
Status: APP_ARTICLEUNCONFIRMED,
|
||||
Expires: 0,
|
||||
TagUpdated: 0,
|
||||
TagRevision: 0,
|
||||
Groups: groups,
|
||||
Labels: labels,
|
||||
}
|
||||
err = store.DB.Transaction(func(tx *gorm.DB) error {
|
||||
if res := store.DB.Save(article).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
if res := store.DB.Model(&account).Update("content_revision", account.ContentRevision + 1).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
SetStatus(account)
|
||||
SetContentNotification(account)
|
||||
WriteResponse(w, getArticleModel(article, 0))
|
||||
}
|
@ -13,11 +13,6 @@ import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func AddArticle(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func AddArticleAsset(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
|
@ -25,6 +25,10 @@ const APP_MODULECONTENT = "content"
|
||||
const APP_TOKENAPP = "app"
|
||||
const APP_TOKENCONTACT = "contact"
|
||||
const APP_NOTIFYBUFFER = 4096
|
||||
const APP_ARTICLEUNCONFIRMED = "unconfirmed"
|
||||
const APP_ARTICLECONFIRMED = "confirmed"
|
||||
const APP_ARTICLEINCOMPLETE = "incomplete"
|
||||
const APP_ARTICLEERROR = "error"
|
||||
|
||||
func AppCardStatus(status string) bool {
|
||||
if status == APP_CARDPENDING {
|
||||
|
@ -47,3 +47,34 @@ func getGroupModel(group *store.Group) *Group {
|
||||
Updated: group.Updated,
|
||||
}
|
||||
}
|
||||
|
||||
func getArticleModel(article *store.Article, tagCount int32) *Article {
|
||||
|
||||
// populate group id list
|
||||
var groups []string;
|
||||
for _, group := range article.Groups {
|
||||
groups = append(groups, group.GroupId)
|
||||
}
|
||||
|
||||
// populate label id list
|
||||
var labels []string;
|
||||
for _, label := range article.Labels {
|
||||
labels = append(labels, label.LabelId)
|
||||
}
|
||||
|
||||
return &Article{
|
||||
ArticleId: article.ArticleId,
|
||||
Revision: article.Revision,
|
||||
DataType: article.DataType,
|
||||
Data: article.Data,
|
||||
Created: article.Created,
|
||||
Updated: article.Updated,
|
||||
Status: article.Status,
|
||||
Labels: labels,
|
||||
Groups: groups,
|
||||
TagCount: tagCount,
|
||||
TagUpdated: article.TagUpdated,
|
||||
TagRevision: article.TagRevision,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,6 +38,17 @@ type AppData struct {
|
||||
Image string `json:"image,omitempty"`
|
||||
}
|
||||
|
||||
type ArticleAccess struct {
|
||||
Labels []string `json:"labels"`
|
||||
Groups []string `json:"groups"`
|
||||
}
|
||||
|
||||
type ArticleEntry struct {
|
||||
BlockId string `json:"blockId"`
|
||||
BlockRevision int64 `json:"blockRevision"`
|
||||
Article *Article `json:"article"`
|
||||
}
|
||||
|
||||
type Subject struct {
|
||||
DataType string `json:"dataType"`
|
||||
Data string `json:"data"`
|
||||
@ -45,16 +56,16 @@ type Subject struct {
|
||||
|
||||
type Article struct {
|
||||
ArticleId string `json:"articleId"`
|
||||
ArticleRevision int64 `json:"articleRevision"`
|
||||
Type_ string `json:"type"`
|
||||
Revision int64 `json:"revision"`
|
||||
DataType string `json:"type"`
|
||||
Data string `json:"data"`
|
||||
Created int64 `json:"created"`
|
||||
Modified int64 `json:"modified"`
|
||||
Updated int64 `json:"updated"`
|
||||
Status string `json:"status"`
|
||||
Labels []string `json:"labels"`
|
||||
Groups []string `json:"groups,omitempty"`
|
||||
TagCount int32 `json:"tagCount"`
|
||||
TagUpdate int64 `json:"tagUpdate,omitempty"`
|
||||
TagUpdated int64 `json:"tagUpdated,omitempty"`
|
||||
TagRevision int64 `json:"tagRevision"`
|
||||
}
|
||||
|
||||
|
@ -174,7 +174,7 @@ type Article struct {
|
||||
Created int64 `gorm:"autoCreateTime"`
|
||||
Updated int64 `gorm:"autoUpdateTime"`
|
||||
TagUpdated int64 `gorm:"not null"`
|
||||
TagRevision uint64 `gorm:"not null"`
|
||||
TagRevision int64 `gorm:"not null"`
|
||||
Groups []Group `gorm:"many2many:article_groups;"`
|
||||
Labels []Label `gorm:"many2many:article_labels;"`
|
||||
Account Account
|
||||
|
@ -13,7 +13,7 @@ import (
|
||||
)
|
||||
|
||||
const TEST_READDEADLINE = 2
|
||||
const TEST_REVISIONWAIT = 250
|
||||
const TEST_REVISIONWAIT = 100
|
||||
|
||||
type TestCard struct {
|
||||
Guid string
|
||||
@ -91,11 +91,11 @@ func SendEndpointTest(
|
||||
// | \ /|
|
||||
// | requested,nogroup confirmed,group |
|
||||
// | |
|
||||
// requested,group ,
|
||||
// connected,group ,
|
||||
// |
|
||||
// --x--
|
||||
// |
|
||||
// confirmed,group ,
|
||||
// connected,group ,
|
||||
// | |
|
||||
// | confirmed,nogroup pending,nogroup |
|
||||
// |/ \|
|
||||
@ -177,6 +177,9 @@ func AddTestGroup(prefix string) (*TestGroup, error) {
|
||||
if g.C.A.CardId, err = AddTestCard(g.C.Token, g.A.Token); err != nil {
|
||||
return g, err
|
||||
}
|
||||
if err = OpenTestCard(g.C.Token, g.C.A.CardId); err != nil {
|
||||
return g, err
|
||||
}
|
||||
if g.C.A.GroupId, err = GroupTestCard(g.C.Token, g.C.A.CardId); err != nil {
|
||||
return g, err
|
||||
}
|
||||
@ -202,6 +205,9 @@ func AddTestGroup(prefix string) (*TestGroup, error) {
|
||||
if g.B.A.Token, err = GetCardToken(g.B.Token, g.B.A.CardId); err != nil {
|
||||
return g, err
|
||||
}
|
||||
if g.C.A.Token, err = GetCardToken(g.C.Token, g.C.A.CardId); err != nil {
|
||||
return g, err
|
||||
}
|
||||
if g.C.D.Token, err = GetCardToken(g.C.Token, g.C.D.CardId); err != nil {
|
||||
return g, err
|
||||
}
|
||||
@ -217,18 +223,21 @@ func AddTestGroup(prefix string) (*TestGroup, error) {
|
||||
g.A.Revisions = make(chan *Revision, 64)
|
||||
g.A.Revisions <- rev
|
||||
go MonitorStatus(ws, &g.A);
|
||||
rev = &Revision{}
|
||||
if ws, err = StatusConnection(g.B.Token, rev); err != nil {
|
||||
return g, err
|
||||
}
|
||||
g.B.Revisions = make(chan *Revision, 64)
|
||||
g.B.Revisions <- rev
|
||||
go MonitorStatus(ws, &g.B);
|
||||
rev = &Revision{}
|
||||
if ws, err = StatusConnection(g.C.Token, rev); err != nil {
|
||||
return g, err
|
||||
}
|
||||
g.C.Revisions = make(chan *Revision, 64)
|
||||
g.C.Revisions <- rev
|
||||
go MonitorStatus(ws, &g.C);
|
||||
rev = &Revision{}
|
||||
if ws, err = StatusConnection(g.D.Token, rev); err != nil {
|
||||
return g, err
|
||||
}
|
||||
|
@ -9,24 +9,26 @@ func TestAddArticle(t *testing.T) {
|
||||
var set *TestGroup
|
||||
var err error
|
||||
var rev *Revision
|
||||
var article Article
|
||||
var contentRevision int64
|
||||
|
||||
// setup testing group
|
||||
set, err = AddTestGroup("addarticle1")
|
||||
set, err = AddTestGroup("addarticle")
|
||||
assert.NoError(t, err)
|
||||
|
||||
// initial revision
|
||||
rev = GetTestRevision(set.A.Revisions)
|
||||
assert.NotNil(t, rev)
|
||||
|
||||
|
||||
// EXAMPLE
|
||||
subject := &Subject{
|
||||
}
|
||||
var group Group
|
||||
assert.NoError(t, SendEndpointTest(AddGroup, nil, subject, set.A.Token, &group))
|
||||
PrintMsg(group)
|
||||
contentRevision = rev.Content
|
||||
|
||||
// create article
|
||||
articleAccess := &ArticleAccess{ Groups: []string{set.A.B.GroupId} }
|
||||
assert.NoError(t, SendEndpointTest(AddArticle, nil, articleAccess, set.A.Token, &article))
|
||||
|
||||
// check content revision
|
||||
// check revisions
|
||||
rev = GetTestRevision(set.A.Revisions)
|
||||
assert.Greater(t, rev.Content, contentRevision)
|
||||
|
||||
// check contact revisions
|
||||
// view article
|
||||
|
||||
PrintMsg(rev)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user