mirror of
https://github.com/balzack/databag.git
synced 2025-02-11 19:19:16 +00:00
added revision filter for groups and cards
This commit is contained in:
parent
5932f177aa
commit
67ffe43c8c
142
doc/api.oa3
142
doc/api.oa3
@ -835,6 +835,13 @@ paths:
|
||||
operationId: get-groups
|
||||
security:
|
||||
- bearerAuth: []
|
||||
parameters:
|
||||
- name: groupRevision
|
||||
in: query
|
||||
description: only return updated groups since specified revision
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: successful operation
|
||||
@ -1524,6 +1531,30 @@ paths:
|
||||
type: integer
|
||||
format: int64
|
||||
|
||||
/contact/label/revision:
|
||||
put:
|
||||
tags:
|
||||
- contact
|
||||
description: Set label revision for contact. This is intend to be invoked automatically anytime a contact updates their label or sharing. Access granted to contact tokens.
|
||||
operationId: set-label-revision
|
||||
security:
|
||||
- bearerAuth: []
|
||||
responses:
|
||||
'200':
|
||||
description: revision set
|
||||
'401':
|
||||
description: not authorized
|
||||
'410':
|
||||
description: account disabled
|
||||
'500':
|
||||
description: internal server error
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
|
||||
/contact/view/revision:
|
||||
put:
|
||||
tags:
|
||||
@ -2404,6 +2435,19 @@ paths:
|
||||
operationId: get-labels
|
||||
security:
|
||||
- bearerAuth: []
|
||||
parameters:
|
||||
- name: viewRevision
|
||||
in: query
|
||||
description: only return updated if view matches
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
- name: labelRevision
|
||||
in: query
|
||||
description: only return updated if view matches
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: successful operation
|
||||
@ -4068,30 +4112,21 @@ components:
|
||||
node:
|
||||
type: string
|
||||
|
||||
CardData:
|
||||
type: object
|
||||
required:
|
||||
- status
|
||||
properties:
|
||||
revision:
|
||||
type: integer
|
||||
format: int64
|
||||
status:
|
||||
type: string
|
||||
enum: [ pending, confirmed, requested, connecting, connected ]
|
||||
notes:
|
||||
type: string
|
||||
token:
|
||||
type: string
|
||||
groups:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
|
||||
Card:
|
||||
type: object
|
||||
required:
|
||||
- cardId
|
||||
- cardData
|
||||
properties:
|
||||
cardId:
|
||||
type: string
|
||||
cardData:
|
||||
$ref: '#/components/schemas/CardData'
|
||||
|
||||
CardData:
|
||||
type: object
|
||||
required:
|
||||
- status
|
||||
- cardProfile
|
||||
- cardData
|
||||
- notifiedProfile
|
||||
@ -4110,9 +4145,23 @@ components:
|
||||
notifiedContent:
|
||||
type: integer
|
||||
format: int64
|
||||
notifiedLabel:
|
||||
type: integer
|
||||
format: int64
|
||||
notifiedView:
|
||||
type: integer
|
||||
format: int64
|
||||
status:
|
||||
type: string
|
||||
enum: [ pending, confirmed, requested, connecting, connected ]
|
||||
notes:
|
||||
type: string
|
||||
token:
|
||||
type: string
|
||||
groups:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
|
||||
Asset:
|
||||
type: object
|
||||
@ -4326,37 +4375,25 @@ components:
|
||||
type: integer
|
||||
format: int64
|
||||
|
||||
ArticleView:
|
||||
type: object
|
||||
required:
|
||||
- articleId
|
||||
- revision
|
||||
- tagRevision
|
||||
properties:
|
||||
articleId:
|
||||
type: string
|
||||
revision:
|
||||
type: integer
|
||||
format: int64
|
||||
tagRevision:
|
||||
type: integer
|
||||
format: int64
|
||||
|
||||
Group:
|
||||
type: object
|
||||
required:
|
||||
- groupId
|
||||
- revision
|
||||
- groupData
|
||||
properties:
|
||||
groupId:
|
||||
type: string
|
||||
groupData:
|
||||
$ref: '#/components/schemas/GroupData'
|
||||
|
||||
GroupData:
|
||||
type: object
|
||||
required:
|
||||
- dataType
|
||||
- data
|
||||
- created
|
||||
- updated
|
||||
properties:
|
||||
groupId:
|
||||
type: string
|
||||
revision:
|
||||
type: integer
|
||||
format: int64
|
||||
dataType:
|
||||
type: string
|
||||
data:
|
||||
@ -4372,18 +4409,22 @@ components:
|
||||
type: object
|
||||
required:
|
||||
- labelId
|
||||
- labelRevision
|
||||
- type
|
||||
- labelData
|
||||
properties:
|
||||
labelId:
|
||||
type: string
|
||||
labelData:
|
||||
$ref: '#/components/schemas/LabelData'
|
||||
|
||||
LabelData:
|
||||
type: object
|
||||
required:
|
||||
- dataType
|
||||
- data
|
||||
- created
|
||||
- modified
|
||||
properties:
|
||||
labelId:
|
||||
type: string
|
||||
labelRevision:
|
||||
type: integer
|
||||
format: int64
|
||||
type:
|
||||
dataType:
|
||||
type: string
|
||||
data:
|
||||
type: string
|
||||
@ -4544,4 +4585,3 @@ components:
|
||||
scheme: bearer
|
||||
|
||||
|
||||
|
||||
|
@ -1,11 +1,22 @@
|
||||
package databag
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"net/http"
|
||||
"databag/internal/store"
|
||||
)
|
||||
|
||||
func GetCards(w http.ResponseWriter, r *http.Request) {
|
||||
var res error
|
||||
var cardRevision int64
|
||||
|
||||
card := r.FormValue("cardRevision")
|
||||
if card != "" {
|
||||
if cardRevision, res = strconv.ParseInt(card, 10, 64); res != nil {
|
||||
ErrResponse(w, http.StatusBadRequest, res)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
account, code, err := BearerAppToken(r, false);
|
||||
if err != nil {
|
||||
@ -14,7 +25,7 @@ func GetCards(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
var slots []store.CardSlot
|
||||
if err := store.DB.Preload("Card.Groups.GroupSlot").Where("account_id = ?", account.ID).Find(&slots).Error; err != nil {
|
||||
if err := store.DB.Preload("Card.Groups.GroupSlot").Where("account_id = ? AND revision > ?", account.ID, cardRevision).Find(&slots).Error; err != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
@ -1,11 +1,22 @@
|
||||
package databag
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"net/http"
|
||||
"databag/internal/store"
|
||||
)
|
||||
|
||||
func GetGroups(w http.ResponseWriter, r *http.Request) {
|
||||
var res error
|
||||
var groupRevision int64
|
||||
|
||||
group := r.FormValue("groupRevision")
|
||||
if group != "" {
|
||||
if groupRevision, res = strconv.ParseInt(group, 10, 64); res != nil {
|
||||
ErrResponse(w, http.StatusBadRequest, res)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
account, code, err := BearerAppToken(r, false)
|
||||
if err != nil {
|
||||
@ -14,7 +25,7 @@ func GetGroups(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
var slots []store.GroupSlot
|
||||
if err := store.DB.Where("account_id = ?", account.ID).Find(&slots).Error; err != nil {
|
||||
if err := store.DB.Preload("Group").Where("account_id = ? AND revision > ?", account.ID, groupRevision).Find(&slots).Error; err != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
49
net/server/internal/api_setLabelRevision.go
Normal file
49
net/server/internal/api_setLabelRevision.go
Normal file
@ -0,0 +1,49 @@
|
||||
package databag
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"gorm.io/gorm"
|
||||
"databag/internal/store"
|
||||
)
|
||||
|
||||
func SetLabelRevision(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
card, code, err := BearerContactToken(r)
|
||||
if err != nil {
|
||||
ErrResponse(w, code, err)
|
||||
return
|
||||
}
|
||||
|
||||
var revision int64
|
||||
if err := ParseRequest(r, w, &revision); err != nil {
|
||||
ErrResponse(w, http.StatusBadRequest, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := NotifyProfileRevision(card, revision); err != nil {
|
||||
ErrResponse(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
WriteResponse(w, nil)
|
||||
}
|
||||
|
||||
func NotifyLabelRevision(card *store.Card, revision int64) error {
|
||||
|
||||
act := &card.Account
|
||||
err := store.DB.Transaction(func(tx *gorm.DB) error {
|
||||
if res := tx.Model(card).Where("id = ?", card.ID).Update("notified_label", revision).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
if res := tx.Model(act).Where("id = ?", act.ID).Update("card_revision", act.CardRevision + 1).Error; res != nil {
|
||||
return res
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
SetStatus(act)
|
||||
return nil
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ const APP_CARDCONNECTING = "connecting"
|
||||
const APP_CARDCONNECTED = "connected"
|
||||
const APP_NOTIFYPROFILE = "profile"
|
||||
const APP_NOTIFYCONTENT = "content"
|
||||
const APP_NOTIFYLABEL = "label"
|
||||
const APP_NOTIFYVIEW = "view"
|
||||
const APP_TOKENAPP = "app"
|
||||
const APP_TOKENCONTACT = "contact"
|
||||
|
@ -64,6 +64,10 @@ func SendLocalNotification(notification *store.Notification) {
|
||||
if err := NotifyContentRevision(&card, notification.Revision); err != nil {
|
||||
ErrMsg(err)
|
||||
}
|
||||
} else if notification.Module == APP_NOTIFYLABEL {
|
||||
if err := NotifyLabelRevision(&card, notification.Revision); err != nil {
|
||||
ErrMsg(err)
|
||||
}
|
||||
} else if notification.Module == APP_NOTIFYVIEW {
|
||||
if err := NotifyViewRevision(&card, notification.Revision); err != nil {
|
||||
ErrMsg(err)
|
||||
@ -220,4 +224,59 @@ func SetContactViewNotification(account *store.Account, card *store.Card) {
|
||||
}
|
||||
|
||||
|
||||
// notify all cards of label change
|
||||
// account.Label incremented by adding, updating, removing a label & setting or clearning group from article
|
||||
func SetLabelNotification(account *store.Account) {
|
||||
|
||||
// select all connected cards
|
||||
var cards []store.Card
|
||||
if err := store.DB.Where("account_id = ? AND status = ?", account.Guid, APP_CARDCONNECTED).Find(&cards).Error; err != nil {
|
||||
ErrMsg(err)
|
||||
return
|
||||
}
|
||||
|
||||
// add new notification for each card
|
||||
err := store.DB.Transaction(func(tx *gorm.DB) error {
|
||||
for _, card := range cards {
|
||||
notification := &store.Notification{
|
||||
Node: card.Node,
|
||||
Module: APP_NOTIFYLABEL,
|
||||
Token: card.OutToken,
|
||||
Revision: account.LabelRevision,
|
||||
}
|
||||
if err := tx.Save(notification).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
notify <- notification
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
ErrMsg(err)
|
||||
}
|
||||
}
|
||||
|
||||
// notify single card of label change
|
||||
// card.Label incremented by adding or removing group from label
|
||||
func SetContactLabelNotification(account *store.Account, card *store.Card) {
|
||||
|
||||
if card.Status != APP_CARDCONNECTED {
|
||||
return
|
||||
}
|
||||
|
||||
// add new notification for card
|
||||
notification := &store.Notification{
|
||||
Node: card.Node,
|
||||
Module: APP_NOTIFYLABEL,
|
||||
Token: card.OutToken,
|
||||
Revision: account.LabelRevision,
|
||||
}
|
||||
|
||||
if res := store.DB.Save(notification).Error; res != nil {
|
||||
ErrMsg(res)
|
||||
} else {
|
||||
notify <- notification
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -390,6 +390,13 @@ var routes = Routes{
|
||||
SetContentRevision,
|
||||
},
|
||||
|
||||
Route{
|
||||
"SetLabelRevision",
|
||||
strings.ToUpper("Put"),
|
||||
"/contact/label/revision",
|
||||
SetLabelRevision,
|
||||
},
|
||||
|
||||
Route{
|
||||
"SetOpenMessage",
|
||||
strings.ToUpper("Put"),
|
||||
|
@ -185,6 +185,7 @@ type Card struct {
|
||||
ViewRevision int64 `gorm:"not null"`
|
||||
NotifiedView int64
|
||||
NotifiedContent int64
|
||||
NotifiedLabel int64
|
||||
NotifiedProfile int64
|
||||
Account Account `gorm:"references:Guid"`
|
||||
Groups []Group `gorm:"many2many:card_groups"`
|
||||
|
@ -17,8 +17,6 @@ func TestAddArticle(t *testing.T) {
|
||||
set, err = AddTestGroup("addarticle")
|
||||
assert.NoError(t, err)
|
||||
|
||||
PrintMsg(set)
|
||||
|
||||
// initial revision
|
||||
rev = GetTestRevision(set.B.Revisions)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user