chore(api): update to allow CRUD progress and activity in v1
This commit is contained in:
@@ -2,7 +2,9 @@ package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"reichard.io/antholume/database"
|
||||
)
|
||||
|
||||
@@ -72,3 +74,78 @@ func (s *Server) GetActivity(ctx context.Context, request GetActivityRequestObje
|
||||
}
|
||||
return GetActivity200JSONResponse(response), nil
|
||||
}
|
||||
|
||||
// POST /activity
|
||||
func (s *Server) CreateActivity(ctx context.Context, request CreateActivityRequestObject) (CreateActivityResponseObject, error) {
|
||||
auth, ok := s.getSessionFromContext(ctx)
|
||||
if !ok {
|
||||
return CreateActivity401JSONResponse{Code: 401, Message: "Unauthorized"}, nil
|
||||
}
|
||||
|
||||
if request.Body == nil {
|
||||
return CreateActivity400JSONResponse{Code: 400, Message: "Request body is required"}, nil
|
||||
}
|
||||
|
||||
tx, err := s.db.DB.Begin()
|
||||
if err != nil {
|
||||
log.Error("Transaction Begin DB Error:", err)
|
||||
return CreateActivity500JSONResponse{Code: 500, Message: "Database error"}, nil
|
||||
}
|
||||
committed := false
|
||||
defer func() {
|
||||
if committed {
|
||||
return
|
||||
}
|
||||
if rollbackErr := tx.Rollback(); rollbackErr != nil {
|
||||
log.Debug("Transaction Rollback DB Error:", rollbackErr)
|
||||
}
|
||||
}()
|
||||
|
||||
qtx := s.db.Queries.WithTx(tx)
|
||||
|
||||
allDocumentsMap := make(map[string]struct{})
|
||||
for _, item := range request.Body.Activity {
|
||||
allDocumentsMap[item.DocumentId] = struct{}{}
|
||||
}
|
||||
|
||||
for documentID := range allDocumentsMap {
|
||||
if _, err := qtx.UpsertDocument(ctx, database.UpsertDocumentParams{ID: documentID}); err != nil {
|
||||
log.Error("UpsertDocument DB Error:", err)
|
||||
return CreateActivity400JSONResponse{Code: 400, Message: "Invalid document"}, nil
|
||||
}
|
||||
}
|
||||
|
||||
if _, err := qtx.UpsertDevice(ctx, database.UpsertDeviceParams{
|
||||
ID: request.Body.DeviceId,
|
||||
UserID: auth.UserName,
|
||||
DeviceName: request.Body.DeviceName,
|
||||
LastSynced: time.Now().UTC().Format(time.RFC3339),
|
||||
}); err != nil {
|
||||
log.Error("UpsertDevice DB Error:", err)
|
||||
return CreateActivity400JSONResponse{Code: 400, Message: "Invalid device"}, nil
|
||||
}
|
||||
|
||||
for _, item := range request.Body.Activity {
|
||||
if _, err := qtx.AddActivity(ctx, database.AddActivityParams{
|
||||
UserID: auth.UserName,
|
||||
DocumentID: item.DocumentId,
|
||||
DeviceID: request.Body.DeviceId,
|
||||
StartTime: time.Unix(item.StartTime, 0).UTC().Format(time.RFC3339),
|
||||
Duration: item.Duration,
|
||||
StartPercentage: float64(item.Page) / float64(item.Pages),
|
||||
EndPercentage: float64(item.Page+1) / float64(item.Pages),
|
||||
}); err != nil {
|
||||
log.Error("AddActivity DB Error:", err)
|
||||
return CreateActivity400JSONResponse{Code: 400, Message: "Invalid activity"}, nil
|
||||
}
|
||||
}
|
||||
|
||||
if err := tx.Commit(); err != nil {
|
||||
log.Error("Transaction Commit DB Error:", err)
|
||||
return CreateActivity500JSONResponse{Code: 500, Message: "Database error"}, nil
|
||||
}
|
||||
committed = true
|
||||
|
||||
response := CreateActivityResponse{Added: int64(len(request.Body.Activity))}
|
||||
return CreateActivity200JSONResponse(response), nil
|
||||
}
|
||||
|
||||
@@ -164,6 +164,27 @@ type ActivityResponse struct {
|
||||
// BackupType defines model for BackupType.
|
||||
type BackupType string
|
||||
|
||||
// CreateActivityItem defines model for CreateActivityItem.
|
||||
type CreateActivityItem struct {
|
||||
DocumentId string `json:"document_id"`
|
||||
Duration int64 `json:"duration"`
|
||||
Page int64 `json:"page"`
|
||||
Pages int64 `json:"pages"`
|
||||
StartTime int64 `json:"start_time"`
|
||||
}
|
||||
|
||||
// CreateActivityRequest defines model for CreateActivityRequest.
|
||||
type CreateActivityRequest struct {
|
||||
Activity []CreateActivityItem `json:"activity"`
|
||||
DeviceId string `json:"device_id"`
|
||||
DeviceName string `json:"device_name"`
|
||||
}
|
||||
|
||||
// CreateActivityResponse defines model for CreateActivityResponse.
|
||||
type CreateActivityResponse struct {
|
||||
Added int64 `json:"added"`
|
||||
}
|
||||
|
||||
// DatabaseInfo defines model for DatabaseInfo.
|
||||
type DatabaseInfo struct {
|
||||
ActivitySize int64 `json:"activity_size"`
|
||||
@@ -335,9 +356,11 @@ type OperationType string
|
||||
type Progress struct {
|
||||
Author *string `json:"author,omitempty"`
|
||||
CreatedAt *time.Time `json:"created_at,omitempty"`
|
||||
DeviceId *string `json:"device_id,omitempty"`
|
||||
DeviceName *string `json:"device_name,omitempty"`
|
||||
DocumentId *string `json:"document_id,omitempty"`
|
||||
Percentage *float64 `json:"percentage,omitempty"`
|
||||
Progress *string `json:"progress,omitempty"`
|
||||
Title *string `json:"title,omitempty"`
|
||||
UserId *string `json:"user_id,omitempty"`
|
||||
}
|
||||
@@ -388,6 +411,21 @@ type StreaksResponse struct {
|
||||
Streaks []UserStreak `json:"streaks"`
|
||||
}
|
||||
|
||||
// UpdateProgressRequest defines model for UpdateProgressRequest.
|
||||
type UpdateProgressRequest struct {
|
||||
DeviceId string `json:"device_id"`
|
||||
DeviceName string `json:"device_name"`
|
||||
DocumentId string `json:"document_id"`
|
||||
Percentage float64 `json:"percentage"`
|
||||
Progress string `json:"progress"`
|
||||
}
|
||||
|
||||
// UpdateProgressResponse defines model for UpdateProgressResponse.
|
||||
type UpdateProgressResponse struct {
|
||||
DocumentId string `json:"document_id"`
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
}
|
||||
|
||||
// UpdateSettingsRequest defines model for UpdateSettingsRequest.
|
||||
type UpdateSettingsRequest struct {
|
||||
NewPassword *string `json:"new_password,omitempty"`
|
||||
@@ -533,6 +571,9 @@ type PostSearchFormdataBody struct {
|
||||
Title string `form:"title" json:"title"`
|
||||
}
|
||||
|
||||
// CreateActivityJSONRequestBody defines body for CreateActivity for application/json ContentType.
|
||||
type CreateActivityJSONRequestBody = CreateActivityRequest
|
||||
|
||||
// PostAdminActionMultipartRequestBody defines body for PostAdminAction for multipart/form-data ContentType.
|
||||
type PostAdminActionMultipartRequestBody PostAdminActionMultipartBody
|
||||
|
||||
@@ -557,6 +598,9 @@ type EditDocumentJSONRequestBody EditDocumentJSONBody
|
||||
// UploadDocumentCoverMultipartRequestBody defines body for UploadDocumentCover for multipart/form-data ContentType.
|
||||
type UploadDocumentCoverMultipartRequestBody UploadDocumentCoverMultipartBody
|
||||
|
||||
// UpdateProgressJSONRequestBody defines body for UpdateProgress for application/json ContentType.
|
||||
type UpdateProgressJSONRequestBody = UpdateProgressRequest
|
||||
|
||||
// PostSearchFormdataRequestBody defines body for PostSearch for application/x-www-form-urlencoded ContentType.
|
||||
type PostSearchFormdataRequestBody PostSearchFormdataBody
|
||||
|
||||
@@ -568,6 +612,9 @@ type ServerInterface interface {
|
||||
// Get activity data
|
||||
// (GET /activity)
|
||||
GetActivity(w http.ResponseWriter, r *http.Request, params GetActivityParams)
|
||||
// Create activity records
|
||||
// (POST /activity)
|
||||
CreateActivity(w http.ResponseWriter, r *http.Request)
|
||||
// Get admin page data
|
||||
// (GET /admin)
|
||||
GetAdmin(w http.ResponseWriter, r *http.Request)
|
||||
@@ -643,6 +690,9 @@ type ServerInterface interface {
|
||||
// List progress records
|
||||
// (GET /progress)
|
||||
GetProgressList(w http.ResponseWriter, r *http.Request, params GetProgressListParams)
|
||||
// Update document progress
|
||||
// (PUT /progress)
|
||||
UpdateProgress(w http.ResponseWriter, r *http.Request)
|
||||
// Get document progress
|
||||
// (GET /progress/{id})
|
||||
GetProgress(w http.ResponseWriter, r *http.Request, id string)
|
||||
@@ -726,6 +776,26 @@ func (siw *ServerInterfaceWrapper) GetActivity(w http.ResponseWriter, r *http.Re
|
||||
handler.ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
// CreateActivity operation middleware
|
||||
func (siw *ServerInterfaceWrapper) CreateActivity(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
ctx := r.Context()
|
||||
|
||||
ctx = context.WithValue(ctx, BearerAuthScopes, []string{})
|
||||
|
||||
r = r.WithContext(ctx)
|
||||
|
||||
handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
siw.Handler.CreateActivity(w, r)
|
||||
}))
|
||||
|
||||
for _, middleware := range siw.HandlerMiddlewares {
|
||||
handler = middleware(handler)
|
||||
}
|
||||
|
||||
handler.ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
// GetAdmin operation middleware
|
||||
func (siw *ServerInterfaceWrapper) GetAdmin(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
@@ -1371,6 +1441,26 @@ func (siw *ServerInterfaceWrapper) GetProgressList(w http.ResponseWriter, r *htt
|
||||
handler.ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
// UpdateProgress operation middleware
|
||||
func (siw *ServerInterfaceWrapper) UpdateProgress(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
ctx := r.Context()
|
||||
|
||||
ctx = context.WithValue(ctx, BearerAuthScopes, []string{})
|
||||
|
||||
r = r.WithContext(ctx)
|
||||
|
||||
handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
siw.Handler.UpdateProgress(w, r)
|
||||
}))
|
||||
|
||||
for _, middleware := range siw.HandlerMiddlewares {
|
||||
handler = middleware(handler)
|
||||
}
|
||||
|
||||
handler.ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
// GetProgress operation middleware
|
||||
func (siw *ServerInterfaceWrapper) GetProgress(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
@@ -1638,6 +1728,7 @@ func HandlerWithOptions(si ServerInterface, options StdHTTPServerOptions) http.H
|
||||
}
|
||||
|
||||
m.HandleFunc("GET "+options.BaseURL+"/activity", wrapper.GetActivity)
|
||||
m.HandleFunc("POST "+options.BaseURL+"/activity", wrapper.CreateActivity)
|
||||
m.HandleFunc("GET "+options.BaseURL+"/admin", wrapper.GetAdmin)
|
||||
m.HandleFunc("POST "+options.BaseURL+"/admin", wrapper.PostAdminAction)
|
||||
m.HandleFunc("GET "+options.BaseURL+"/admin/import", wrapper.GetImportDirectory)
|
||||
@@ -1663,6 +1754,7 @@ func HandlerWithOptions(si ServerInterface, options StdHTTPServerOptions) http.H
|
||||
m.HandleFunc("GET "+options.BaseURL+"/home/streaks", wrapper.GetStreaks)
|
||||
m.HandleFunc("GET "+options.BaseURL+"/info", wrapper.GetInfo)
|
||||
m.HandleFunc("GET "+options.BaseURL+"/progress", wrapper.GetProgressList)
|
||||
m.HandleFunc("PUT "+options.BaseURL+"/progress", wrapper.UpdateProgress)
|
||||
m.HandleFunc("GET "+options.BaseURL+"/progress/{id}", wrapper.GetProgress)
|
||||
m.HandleFunc("GET "+options.BaseURL+"/search", wrapper.GetSearch)
|
||||
m.HandleFunc("POST "+options.BaseURL+"/search", wrapper.PostSearch)
|
||||
@@ -1707,6 +1799,50 @@ func (response GetActivity500JSONResponse) VisitGetActivityResponse(w http.Respo
|
||||
return json.NewEncoder(w).Encode(response)
|
||||
}
|
||||
|
||||
type CreateActivityRequestObject struct {
|
||||
Body *CreateActivityJSONRequestBody
|
||||
}
|
||||
|
||||
type CreateActivityResponseObject interface {
|
||||
VisitCreateActivityResponse(w http.ResponseWriter) error
|
||||
}
|
||||
|
||||
type CreateActivity200JSONResponse CreateActivityResponse
|
||||
|
||||
func (response CreateActivity200JSONResponse) VisitCreateActivityResponse(w http.ResponseWriter) error {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(200)
|
||||
|
||||
return json.NewEncoder(w).Encode(response)
|
||||
}
|
||||
|
||||
type CreateActivity400JSONResponse ErrorResponse
|
||||
|
||||
func (response CreateActivity400JSONResponse) VisitCreateActivityResponse(w http.ResponseWriter) error {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(400)
|
||||
|
||||
return json.NewEncoder(w).Encode(response)
|
||||
}
|
||||
|
||||
type CreateActivity401JSONResponse ErrorResponse
|
||||
|
||||
func (response CreateActivity401JSONResponse) VisitCreateActivityResponse(w http.ResponseWriter) error {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(401)
|
||||
|
||||
return json.NewEncoder(w).Encode(response)
|
||||
}
|
||||
|
||||
type CreateActivity500JSONResponse ErrorResponse
|
||||
|
||||
func (response CreateActivity500JSONResponse) VisitCreateActivityResponse(w http.ResponseWriter) error {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(500)
|
||||
|
||||
return json.NewEncoder(w).Encode(response)
|
||||
}
|
||||
|
||||
type GetAdminRequestObject struct {
|
||||
}
|
||||
|
||||
@@ -2730,6 +2866,50 @@ func (response GetProgressList500JSONResponse) VisitGetProgressListResponse(w ht
|
||||
return json.NewEncoder(w).Encode(response)
|
||||
}
|
||||
|
||||
type UpdateProgressRequestObject struct {
|
||||
Body *UpdateProgressJSONRequestBody
|
||||
}
|
||||
|
||||
type UpdateProgressResponseObject interface {
|
||||
VisitUpdateProgressResponse(w http.ResponseWriter) error
|
||||
}
|
||||
|
||||
type UpdateProgress200JSONResponse UpdateProgressResponse
|
||||
|
||||
func (response UpdateProgress200JSONResponse) VisitUpdateProgressResponse(w http.ResponseWriter) error {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(200)
|
||||
|
||||
return json.NewEncoder(w).Encode(response)
|
||||
}
|
||||
|
||||
type UpdateProgress400JSONResponse ErrorResponse
|
||||
|
||||
func (response UpdateProgress400JSONResponse) VisitUpdateProgressResponse(w http.ResponseWriter) error {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(400)
|
||||
|
||||
return json.NewEncoder(w).Encode(response)
|
||||
}
|
||||
|
||||
type UpdateProgress401JSONResponse ErrorResponse
|
||||
|
||||
func (response UpdateProgress401JSONResponse) VisitUpdateProgressResponse(w http.ResponseWriter) error {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(401)
|
||||
|
||||
return json.NewEncoder(w).Encode(response)
|
||||
}
|
||||
|
||||
type UpdateProgress500JSONResponse ErrorResponse
|
||||
|
||||
func (response UpdateProgress500JSONResponse) VisitUpdateProgressResponse(w http.ResponseWriter) error {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(500)
|
||||
|
||||
return json.NewEncoder(w).Encode(response)
|
||||
}
|
||||
|
||||
type GetProgressRequestObject struct {
|
||||
Id string `json:"id"`
|
||||
}
|
||||
@@ -2935,6 +3115,9 @@ type StrictServerInterface interface {
|
||||
// Get activity data
|
||||
// (GET /activity)
|
||||
GetActivity(ctx context.Context, request GetActivityRequestObject) (GetActivityResponseObject, error)
|
||||
// Create activity records
|
||||
// (POST /activity)
|
||||
CreateActivity(ctx context.Context, request CreateActivityRequestObject) (CreateActivityResponseObject, error)
|
||||
// Get admin page data
|
||||
// (GET /admin)
|
||||
GetAdmin(ctx context.Context, request GetAdminRequestObject) (GetAdminResponseObject, error)
|
||||
@@ -3010,6 +3193,9 @@ type StrictServerInterface interface {
|
||||
// List progress records
|
||||
// (GET /progress)
|
||||
GetProgressList(ctx context.Context, request GetProgressListRequestObject) (GetProgressListResponseObject, error)
|
||||
// Update document progress
|
||||
// (PUT /progress)
|
||||
UpdateProgress(ctx context.Context, request UpdateProgressRequestObject) (UpdateProgressResponseObject, error)
|
||||
// Get document progress
|
||||
// (GET /progress/{id})
|
||||
GetProgress(ctx context.Context, request GetProgressRequestObject) (GetProgressResponseObject, error)
|
||||
@@ -3082,6 +3268,37 @@ func (sh *strictHandler) GetActivity(w http.ResponseWriter, r *http.Request, par
|
||||
}
|
||||
}
|
||||
|
||||
// CreateActivity operation middleware
|
||||
func (sh *strictHandler) CreateActivity(w http.ResponseWriter, r *http.Request) {
|
||||
var request CreateActivityRequestObject
|
||||
|
||||
var body CreateActivityJSONRequestBody
|
||||
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
|
||||
sh.options.RequestErrorHandlerFunc(w, r, fmt.Errorf("can't decode JSON body: %w", err))
|
||||
return
|
||||
}
|
||||
request.Body = &body
|
||||
|
||||
handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) {
|
||||
return sh.ssi.CreateActivity(ctx, request.(CreateActivityRequestObject))
|
||||
}
|
||||
for _, middleware := range sh.middlewares {
|
||||
handler = middleware(handler, "CreateActivity")
|
||||
}
|
||||
|
||||
response, err := handler(r.Context(), w, r, request)
|
||||
|
||||
if err != nil {
|
||||
sh.options.ResponseErrorHandlerFunc(w, r, err)
|
||||
} else if validResponse, ok := response.(CreateActivityResponseObject); ok {
|
||||
if err := validResponse.VisitCreateActivityResponse(w); err != nil {
|
||||
sh.options.ResponseErrorHandlerFunc(w, r, err)
|
||||
}
|
||||
} else if response != nil {
|
||||
sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response))
|
||||
}
|
||||
}
|
||||
|
||||
// GetAdmin operation middleware
|
||||
func (sh *strictHandler) GetAdmin(w http.ResponseWriter, r *http.Request) {
|
||||
var request GetAdminRequestObject
|
||||
@@ -3764,6 +3981,37 @@ func (sh *strictHandler) GetProgressList(w http.ResponseWriter, r *http.Request,
|
||||
}
|
||||
}
|
||||
|
||||
// UpdateProgress operation middleware
|
||||
func (sh *strictHandler) UpdateProgress(w http.ResponseWriter, r *http.Request) {
|
||||
var request UpdateProgressRequestObject
|
||||
|
||||
var body UpdateProgressJSONRequestBody
|
||||
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
|
||||
sh.options.RequestErrorHandlerFunc(w, r, fmt.Errorf("can't decode JSON body: %w", err))
|
||||
return
|
||||
}
|
||||
request.Body = &body
|
||||
|
||||
handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) {
|
||||
return sh.ssi.UpdateProgress(ctx, request.(UpdateProgressRequestObject))
|
||||
}
|
||||
for _, middleware := range sh.middlewares {
|
||||
handler = middleware(handler, "UpdateProgress")
|
||||
}
|
||||
|
||||
response, err := handler(r.Context(), w, r, request)
|
||||
|
||||
if err != nil {
|
||||
sh.options.ResponseErrorHandlerFunc(w, r, err)
|
||||
} else if validResponse, ok := response.(UpdateProgressResponseObject); ok {
|
||||
if err := validResponse.VisitUpdateProgressResponse(w); err != nil {
|
||||
sh.options.ResponseErrorHandlerFunc(w, r, err)
|
||||
}
|
||||
} else if response != nil {
|
||||
sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response))
|
||||
}
|
||||
}
|
||||
|
||||
// GetProgress operation middleware
|
||||
func (sh *strictHandler) GetProgress(w http.ResponseWriter, r *http.Request, id string) {
|
||||
var request GetProgressRequestObject
|
||||
|
||||
@@ -92,9 +92,13 @@ components:
|
||||
type: string
|
||||
device_name:
|
||||
type: string
|
||||
device_id:
|
||||
type: string
|
||||
percentage:
|
||||
type: number
|
||||
format: double
|
||||
progress:
|
||||
type: string
|
||||
document_id:
|
||||
type: string
|
||||
user_id:
|
||||
@@ -103,6 +107,88 @@ components:
|
||||
type: string
|
||||
format: date-time
|
||||
|
||||
UpdateProgressRequest:
|
||||
type: object
|
||||
properties:
|
||||
document_id:
|
||||
type: string
|
||||
percentage:
|
||||
type: number
|
||||
format: double
|
||||
progress:
|
||||
type: string
|
||||
device_id:
|
||||
type: string
|
||||
device_name:
|
||||
type: string
|
||||
required:
|
||||
- document_id
|
||||
- percentage
|
||||
- progress
|
||||
- device_id
|
||||
- device_name
|
||||
|
||||
UpdateProgressResponse:
|
||||
type: object
|
||||
properties:
|
||||
document_id:
|
||||
type: string
|
||||
timestamp:
|
||||
type: string
|
||||
format: date-time
|
||||
required:
|
||||
- document_id
|
||||
- timestamp
|
||||
|
||||
CreateActivityItem:
|
||||
type: object
|
||||
properties:
|
||||
document_id:
|
||||
type: string
|
||||
start_time:
|
||||
type: integer
|
||||
format: int64
|
||||
duration:
|
||||
type: integer
|
||||
format: int64
|
||||
page:
|
||||
type: integer
|
||||
format: int64
|
||||
pages:
|
||||
type: integer
|
||||
format: int64
|
||||
required:
|
||||
- document_id
|
||||
- start_time
|
||||
- duration
|
||||
- page
|
||||
- pages
|
||||
|
||||
CreateActivityRequest:
|
||||
type: object
|
||||
properties:
|
||||
device_id:
|
||||
type: string
|
||||
device_name:
|
||||
type: string
|
||||
activity:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/CreateActivityItem'
|
||||
required:
|
||||
- device_id
|
||||
- device_name
|
||||
- activity
|
||||
|
||||
CreateActivityResponse:
|
||||
type: object
|
||||
properties:
|
||||
added:
|
||||
type: integer
|
||||
format: int64
|
||||
required:
|
||||
- added
|
||||
|
||||
Activity:
|
||||
type: object
|
||||
properties:
|
||||
@@ -1003,6 +1089,44 @@ paths:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
put:
|
||||
summary: Update document progress
|
||||
operationId: updateProgress
|
||||
tags:
|
||||
- Progress
|
||||
security:
|
||||
- BearerAuth: []
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/UpdateProgressRequest'
|
||||
responses:
|
||||
200:
|
||||
description: Progress updated successfully
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/UpdateProgressResponse'
|
||||
400:
|
||||
description: Bad request
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
401:
|
||||
description: Unauthorized
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
500:
|
||||
description: Internal server error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
|
||||
/progress/{id}:
|
||||
get:
|
||||
@@ -1093,6 +1217,44 @@ paths:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
post:
|
||||
summary: Create activity records
|
||||
operationId: createActivity
|
||||
tags:
|
||||
- Activity
|
||||
security:
|
||||
- BearerAuth: []
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/CreateActivityRequest'
|
||||
responses:
|
||||
200:
|
||||
description: Activity created successfully
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/CreateActivityResponse'
|
||||
400:
|
||||
description: Bad request
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
401:
|
||||
description: Unauthorized
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
500:
|
||||
description: Internal server error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
|
||||
/settings:
|
||||
get:
|
||||
|
||||
@@ -3,9 +3,10 @@ package v1
|
||||
import (
|
||||
"context"
|
||||
"math"
|
||||
"time"
|
||||
|
||||
"reichard.io/antholume/database"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"reichard.io/antholume/database"
|
||||
)
|
||||
|
||||
// GET /progress
|
||||
@@ -26,9 +27,9 @@ func (s *Server) GetProgressList(ctx context.Context, request GetProgressListReq
|
||||
}
|
||||
|
||||
filter := database.GetProgressParams{
|
||||
UserID: auth.UserName,
|
||||
Offset: (page - 1) * limit,
|
||||
Limit: limit,
|
||||
UserID: auth.UserName,
|
||||
Offset: (page - 1) * limit,
|
||||
Limit: limit,
|
||||
}
|
||||
|
||||
if request.Params.Document != nil && *request.Params.Document != "" {
|
||||
@@ -45,7 +46,7 @@ func (s *Server) GetProgressList(ctx context.Context, request GetProgressListReq
|
||||
total := int64(len(progress))
|
||||
var nextPage *int64
|
||||
var previousPage *int64
|
||||
|
||||
|
||||
// Calculate total pages
|
||||
totalPages := int64(math.Ceil(float64(total) / float64(limit)))
|
||||
if page < totalPages {
|
||||
@@ -58,13 +59,13 @@ func (s *Server) GetProgressList(ctx context.Context, request GetProgressListReq
|
||||
apiProgress := make([]Progress, len(progress))
|
||||
for i, row := range progress {
|
||||
apiProgress[i] = Progress{
|
||||
Title: row.Title,
|
||||
Author: row.Author,
|
||||
DeviceName: &row.DeviceName,
|
||||
Percentage: &row.Percentage,
|
||||
DocumentId: &row.DocumentID,
|
||||
UserId: &row.UserID,
|
||||
CreatedAt: parseTimePtr(row.CreatedAt),
|
||||
Title: row.Title,
|
||||
Author: row.Author,
|
||||
DeviceName: &row.DeviceName,
|
||||
Percentage: &row.Percentage,
|
||||
DocumentId: &row.DocumentID,
|
||||
UserId: &row.UserID,
|
||||
CreatedAt: parseTimePtr(row.CreatedAt),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,33 +88,23 @@ func (s *Server) GetProgress(ctx context.Context, request GetProgressRequestObje
|
||||
return GetProgress401JSONResponse{Code: 401, Message: "Unauthorized"}, nil
|
||||
}
|
||||
|
||||
filter := database.GetProgressParams{
|
||||
UserID: auth.UserName,
|
||||
DocFilter: true,
|
||||
DocumentID: request.Id,
|
||||
Offset: 0,
|
||||
Limit: 1,
|
||||
}
|
||||
|
||||
progress, err := s.db.Queries.GetProgress(ctx, filter)
|
||||
row, err := s.db.Queries.GetDocumentProgress(ctx, database.GetDocumentProgressParams{
|
||||
UserID: auth.UserName,
|
||||
DocumentID: request.Id,
|
||||
})
|
||||
if err != nil {
|
||||
log.Error("GetProgress DB Error:", err)
|
||||
log.Error("GetDocumentProgress DB Error:", err)
|
||||
return GetProgress404JSONResponse{Code: 404, Message: "Progress not found"}, nil
|
||||
}
|
||||
|
||||
if len(progress) == 0 {
|
||||
return GetProgress404JSONResponse{Code: 404, Message: "Progress not found"}, nil
|
||||
}
|
||||
|
||||
row := progress[0]
|
||||
apiProgress := Progress{
|
||||
Title: row.Title,
|
||||
Author: row.Author,
|
||||
DeviceName: &row.DeviceName,
|
||||
Percentage: &row.Percentage,
|
||||
DocumentId: &row.DocumentID,
|
||||
UserId: &row.UserID,
|
||||
CreatedAt: parseTimePtr(row.CreatedAt),
|
||||
DeviceName: &row.DeviceName,
|
||||
DeviceId: &row.DeviceID,
|
||||
Percentage: &row.Percentage,
|
||||
Progress: &row.Progress,
|
||||
DocumentId: &row.DocumentID,
|
||||
UserId: &row.UserID,
|
||||
CreatedAt: parseTimePtr(row.CreatedAt),
|
||||
}
|
||||
|
||||
response := ProgressResponse{
|
||||
@@ -121,4 +112,52 @@ func (s *Server) GetProgress(ctx context.Context, request GetProgressRequestObje
|
||||
}
|
||||
|
||||
return GetProgress200JSONResponse(response), nil
|
||||
}
|
||||
}
|
||||
|
||||
// PUT /progress
|
||||
func (s *Server) UpdateProgress(ctx context.Context, request UpdateProgressRequestObject) (UpdateProgressResponseObject, error) {
|
||||
auth, ok := s.getSessionFromContext(ctx)
|
||||
if !ok {
|
||||
return UpdateProgress401JSONResponse{Code: 401, Message: "Unauthorized"}, nil
|
||||
}
|
||||
|
||||
if request.Body == nil {
|
||||
return UpdateProgress400JSONResponse{Code: 400, Message: "Request body is required"}, nil
|
||||
}
|
||||
|
||||
if _, err := s.db.Queries.UpsertDevice(ctx, database.UpsertDeviceParams{
|
||||
ID: request.Body.DeviceId,
|
||||
UserID: auth.UserName,
|
||||
DeviceName: request.Body.DeviceName,
|
||||
LastSynced: time.Now().UTC().Format(time.RFC3339),
|
||||
}); err != nil {
|
||||
log.Error("UpsertDevice DB Error:", err)
|
||||
return UpdateProgress500JSONResponse{Code: 500, Message: "Database error"}, nil
|
||||
}
|
||||
|
||||
if _, err := s.db.Queries.UpsertDocument(ctx, database.UpsertDocumentParams{
|
||||
ID: request.Body.DocumentId,
|
||||
}); err != nil {
|
||||
log.Error("UpsertDocument DB Error:", err)
|
||||
return UpdateProgress500JSONResponse{Code: 500, Message: "Database error"}, nil
|
||||
}
|
||||
|
||||
progress, err := s.db.Queries.UpdateProgress(ctx, database.UpdateProgressParams{
|
||||
Percentage: request.Body.Percentage,
|
||||
DocumentID: request.Body.DocumentId,
|
||||
DeviceID: request.Body.DeviceId,
|
||||
UserID: auth.UserName,
|
||||
Progress: request.Body.Progress,
|
||||
})
|
||||
if err != nil {
|
||||
log.Error("UpdateProgress DB Error:", err)
|
||||
return UpdateProgress400JSONResponse{Code: 400, Message: "Invalid request"}, nil
|
||||
}
|
||||
|
||||
response := UpdateProgressResponse{
|
||||
DocumentId: progress.DocumentID,
|
||||
Timestamp: parseTime(progress.CreatedAt),
|
||||
}
|
||||
|
||||
return UpdateProgress200JSONResponse(response), nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user