Skip to content

Commit

Permalink
Update develop (#2)
Browse files Browse the repository at this point in the history
* [ID-34]Remove user data (rokwire#35)

* set the core adapter in the application and set the delete logic file

* in progress

* set delete survey responses and delete surveys

* set the Changelog.md

* fix lint issues

* mocks

* remove unused code

* Revert "mocks"

This reverts commit 845dd92.

* storage mocks

* after go mod tidy

* mocks

* resolve comments

* resolve comments

---------

Co-authored-by: Stefan Vitanov <[email protected]>

* update the version to 1.4.0

* update the dockerfile

* [ID-38]Start/end date (rokwire#41)

* set the Changelog.md

* set start_date and end_date fields if they are missing

* set the docs

* remove unused code

* make start_date and end_date int in the model

* set start_date and end date

* add start_date and end_date to updateSurvey

* set the POST /surveys

* fix PUT admin/surveys

* time filter for survey

* set request as not required

* add filter for start_date and end_date filter for GET surveys

* mockery

* set request body as nullable

* fix filter

* fix app and org id filter

---------

Co-authored-by: Stefan Vitanov <[email protected]>

* update the version to 1.5.0

* [ID-43]Fix "start_date" and "end_date" (rokwire#44)

* set the response to start_date and end_date to be UNIX timestamp

* set the Changelog.md

* set start_date as nullable

---------

Co-authored-by: Stefan Vitanov <[email protected]>

* [ID-39]Add extras field to survey data (rokwire#45)

* set the Changelog.md

* add "extras" to the SurveyData doc

* add "extras" to the model and set it as nullable

---------

Co-authored-by: Stefan Vitanov <[email protected]>

* [ID-37]Public flag (rokwire#46)

* add public flag to the docs

* add public to the model and the conversion

* set the public field in the update filter and in the update conversion

* add public to the query

* fix

* set public

* add response to the admin get surveys API

* set the mocks

---------

Co-authored-by: Stefan Vitanov <[email protected]>

* [ID-40]Archived flag (rokwire#47)

* set the Changelog.md

* fix the Changelog.md

* set the docs

* add archived in progress

* set archived to the update filter

* add archived to the storage filter

* set the mocks

---------

Co-authored-by: Stefan Vitanov <[email protected]>

* update version to 1.6.0

* [ID-49]Add Estimated_completion_time (rokwire#50)

* set the Changelog.md

* set the docs

* add to the model

* fix var name in the model

* set estimated_completion_time for create survey

* set estimated_completion_time to the update

---------

Co-authored-by: Stefan Vitanov <[email protected]>

* update version to 1.7.0

* [ID-52]Fix "start_date" and "end_date" timestamp, "archived", "public" and set "complete" in the result (rokwire#53)

* set the Changelog.md

* fix the docs

* remove unused code

* Revert "remove unused code"

This reverts commit eaa904c.

* in progress

* fix update survey

* fix time filter for Get surveys

* archived fix

* fix the archived in admin API

* fix public

* set complete into the response

* fix the Changelog

* set the mocks

* fix

* fix the Changelog

---------

Co-authored-by: Stefan Vitanov <[email protected]>

* update version to 1.8.0

* [ID-55]Fix "public" and "archived" (rokwire#56)

* set the Changelog.md

* fix "public" and "archived" filter and query

* mocks

---------

Co-authored-by: Stefan Vitanov <[email protected]>

* update version to 1.8.1

* [ID-58]Fix Get /surveys (rokwire#59)

* fix the limit and remove claims.Subject

* set the Changelog.md

---------

Co-authored-by: Stefan Vitanov <[email protected]>

* update version to 1.8.2

* [ID-61]Add "complete" field to show if the survey is completed (rokwire#62)

* in progress

* fix conversion

* fix conversion and set the docs

* add completed

* add the Changelog.md

* mocks

---------

Co-authored-by: Stefan Vitanov <[email protected]>

* update version to1.9.0

---------

Co-authored-by: stefanvitanov <[email protected]>
Co-authored-by: Stefan Vitanov <[email protected]>
  • Loading branch information
3 people authored Jul 26, 2024
1 parent 4728744 commit 0d28682
Show file tree
Hide file tree
Showing 30 changed files with 1,268 additions and 124 deletions.
37 changes: 37 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,43 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
## [1.9.0] - 2024-007-26
### Added
- Add "complete" field to show if the survey is completed [#61](https://github.com/rokwire/surveys-building-block/issues/61)
## [1.8.2] - 2024-007-26
### Fixed
- Fix Get /surveys [#58](https://github.com/rokwire/surveys-building-block/issues/58)

## [1.8.1] - 2024-007-26
### Fixed
- Fix "public" and "archived" [#55](https://github.com/rokwire/surveys-building-block/issues/55)

## [1.8.0] - 2024-007-25
### Added
- Fix "start_date" and "end_date" timestamp, "archived", "public" and set "complete" in the result [#52](https://github.com/rokwire/surveys-building-block/issues/52)

## [1.7.0] - 2024-007-24
### Added
- Add Estimated_completion_time [#49](https://github.com/rokwire/surveys-building-block/issues/49)

## [1.6.0] - 2024-007-23
### Added
- Archived flag [#40](https://github.com/rokwire/surveys-building-block/issues/40)
### Added
- Public flag [#37](https://github.com/rokwire/surveys-building-block/issues/37)
### Added
- Add extras field to survey data [#39](https://github.com/rokwire/surveys-building-block/issues/39)
### Fixed
- Fix "start_date" and "end_date" [#43](https://github.com/rokwire/surveys-building-block/issues/43)

## [1.5.0] - 2024-007-22
### Added
- Start/end date [#38](https://github.com/rokwire/surveys-building-block/issues/38)

## [1.4.0] - 2024-007-11
### Added
- Remove user data [#34](https://github.com/rokwire/surveys-building-block/issues/34)

## [1.3.0] - 2023-09-20
### Added
- Reintroduce survey responses admin API [#27](https://github.com/rokwire/surveys-building-block/issues/27)
Expand Down
3 changes: 2 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ WORKDIR /app
COPY . .
RUN make

FROM alpine:3.17.2
FROM alpine:3.20


#we need timezone database
RUN apk add --no-cache --update tzdata
Expand Down
4 changes: 2 additions & 2 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ Patches for **Surveys Building Block** in this repository will only be applied t

| Version | Supported |
| ------- | ------------------ |
| 1.3.0 | :white_check_mark: |
| < 1.3.0 | :x: |
| 1.9.0 | :white_check_mark: |
| < 1.9.0 | :x: |

## Reporting a Bug or Vulnerability

Expand Down
4 changes: 2 additions & 2 deletions core/app_admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ func (a appAdmin) GetSurvey(id string, orgID string, appID string) (*model.Surve
}

// GetSurvey returns surveys matching the provided query
func (a appAdmin) GetSurveys(orgID string, appID string, creatorID *string, surveyIDs []string, surveyTypes []string, calendarEventID string, limit *int, offset *int) ([]model.Survey, error) {
return a.app.shared.getSurveys(orgID, appID, creatorID, surveyIDs, surveyTypes, calendarEventID, limit, offset)
func (a appAdmin) GetSurveys(orgID string, appID string, creatorID *string, surveyIDs []string, surveyTypes []string, calendarEventID string, limit *int, offset *int, filter *model.SurveyTimeFilter, public *bool, archived *bool, completed *bool) ([]model.Survey, []model.SurveyResponse, error) {
return a.app.shared.getSurveys(orgID, appID, creatorID, surveyIDs, surveyTypes, calendarEventID, limit, offset, filter, public, archived, completed)
}

// GetAllSurveyResponses returns survey responses matching the provided query
Expand Down
5 changes: 3 additions & 2 deletions core/app_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,9 @@ func (a appClient) GetSurvey(id string, orgID string, appID string) (*model.Surv
}

// GetSurvey returns surveys matching the provided query
func (a appClient) GetSurveys(orgID string, appID string, creatorID *string, surveyIDs []string, surveyTypes []string, calendarEventID string, limit *int, offset *int) ([]model.Survey, error) {
return a.app.shared.getSurveys(orgID, appID, creatorID, surveyIDs, surveyTypes, calendarEventID, limit, offset)
func (a appClient) GetSurveys(orgID string, appID string, creatorID *string, surveyIDs []string, surveyTypes []string, calendarEventID string,
limit *int, offset *int, filter *model.SurveyTimeFilter, public *bool, archived *bool, completed *bool) ([]model.Survey, []model.SurveyResponse, error) {
return a.app.shared.getSurveys(orgID, appID, creatorID, surveyIDs, surveyTypes, calendarEventID, limit, offset, filter, public, archived, completed)
}

// CreateSurvey creates a new survey
Expand Down
180 changes: 180 additions & 0 deletions core/app_delete_data_logic.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
/*
* Copyright (c) 2020 Board of Trustees of the University of Illinois.
* All rights reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package core

import (
"fmt"

"application/core/interfaces"
"application/core/model"
corebb "application/driven/core"
"time"

"github.com/rokwire/logging-library-go/v2/logs"
)

type deleteDataLogic struct {
logger logs.Logger

serviceID string
core *corebb.Adapter

storage interfaces.Storage

//delete data timer
dailyDeleteTimer *time.Timer
timerDone chan bool
}

func (d deleteDataLogic) start() error {

//2. set up web tools timer
go d.setupTimerForDelete()

return nil
}

func (d deleteDataLogic) setupTimerForDelete() {
d.logger.Info("Delete data timer")

//cancel if active
if d.dailyDeleteTimer != nil {
d.logger.Info("setupTimerForDelete -> there is active timer, so cancel it")

d.timerDone <- true
d.dailyDeleteTimer.Stop()
}

//wait until it is the correct moment from the day
location, err := time.LoadLocation("America/Chicago")
if err != nil {
d.logger.Errorf("Error getting location:%s\n", err.Error())
}
now := time.Now().In(location)
d.logger.Infof("setupTimerForDelete -> now - hours:%d minutes:%d seconds:%d\n", now.Hour(), now.Minute(), now.Second())

nowSecondsInDay := 60*60*now.Hour() + 60*now.Minute() + now.Second()
desiredMoment := 14400 //4 AM

var durationInSeconds int
d.logger.Infof("setupTimerForDelete -> nowSecondsInDay:%d desiredMoment:%d\n", nowSecondsInDay, desiredMoment)
if nowSecondsInDay <= desiredMoment {
d.logger.Infof("setupTimerForDelete -> not delete process today, so the first process will be today")
durationInSeconds = desiredMoment - nowSecondsInDay
} else {
d.logger.Infof("setupTimerForDelete -> the delete process has already been processed today, so the first process will be tomorrow")
leftToday := 86400 - nowSecondsInDay
durationInSeconds = leftToday + desiredMoment // the time which left today + desired moment from tomorrow
}
//log.Println(durationInSeconds)
//duration := time.Second * time.Duration(3)
duration := time.Second * time.Duration(durationInSeconds)
d.logger.Infof("setupTimerForDelete -> first call after %s", duration)

d.dailyDeleteTimer = time.NewTimer(duration)
select {
case <-d.dailyDeleteTimer.C:
d.logger.Info("setupTimerForDelete -> delete timer expired")
d.dailyDeleteTimer = nil

d.process()
case <-d.timerDone:
// timer aborted
d.logger.Info("setupTimerForDelete -> delete timer aborted")
d.dailyDeleteTimer = nil
}
}

func (d deleteDataLogic) process() {
d.logger.Info("Deleting data process")

//process work
d.processDelete()

//generate new processing after 24 hours
duration := time.Hour * 24
d.logger.Infof("Deleting data process -> next call after %s", duration)
d.dailyDeleteTimer = time.NewTimer(duration)
select {
case <-d.dailyDeleteTimer.C:
d.logger.Info("Deleting data process -> timer expired")
d.dailyDeleteTimer = nil

d.process()
case <-d.timerDone:
// timer aborted
d.logger.Info("Deleting data process -> timer aborted")
d.dailyDeleteTimer = nil
}
}

func (d deleteDataLogic) processDelete() {
//load deleted accounts
deletedMemberships, err := d.core.LoadDeletedMemberships()
if err != nil {
d.logger.Errorf("error on loading deleted accounts - %s", err)
return
}
fmt.Print(deletedMemberships)
//process by app org
for _, appOrgSection := range deletedMemberships {
d.logger.Infof("delete - [app-id:%s org-id:%s]", appOrgSection.AppID, appOrgSection.OrgID)

accountsIDs := d.getAccountsIDs(appOrgSection.Memberships)
if len(accountsIDs) == 0 {
d.logger.Info("no accounts for deletion")
continue
}

d.logger.Infof("accounts for deletion - %s", accountsIDs)

//delete the data
d.deleteAppOrgUsersData(appOrgSection.AppID, appOrgSection.OrgID, accountsIDs)
}
}

func (d deleteDataLogic) deleteAppOrgUsersData(appID string, orgID string, accountsIDs []string) {
// delete survey responses
err := d.storage.DeleteSurveyResponsesWithIDs(appID, orgID, accountsIDs)
if err != nil {
d.logger.Errorf("error deleting the survey responses - %s", err)
return
}

// delete surveys
err = d.storage.DeleteSurveysWithIDs(appID, orgID, accountsIDs)
if err != nil {
d.logger.Errorf("error deleting the surveys - %s", err)
return
}

}

func (d deleteDataLogic) getAccountsIDs(memberships []model.DeletedMembership) []string {
res := make([]string, len(memberships))
for i, item := range memberships {
res[i] = item.AccountID
}
return res
}

// deleteLogic creates new deleteLogic
func deleteLogic(coreAdapter corebb.Adapter, logger logs.Logger) deleteDataLogic {
timerDone := make(chan bool)
return deleteDataLogic{core: &coreAdapter, timerDone: timerDone, logger: logger}
}
14 changes: 12 additions & 2 deletions core/app_shared.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,18 @@ func (a appShared) getSurvey(id string, orgID string, appID string) (*model.Surv
return a.app.storage.GetSurvey(id, orgID, appID)
}

func (a appShared) getSurveys(orgID string, appID string, creatorID *string, surveyIDs []string, surveyTypes []string, calendarEventID string, limit *int, offset *int) ([]model.Survey, error) {
return a.app.storage.GetSurveys(orgID, appID, creatorID, surveyIDs, surveyTypes, calendarEventID, limit, offset)
func (a appShared) getSurveys(orgID string, appID string, creatorID *string, surveyIDs []string, surveyTypes []string, calendarEventID string, limit *int, offset *int, filter *model.SurveyTimeFilter, public *bool, archived *bool, completed *bool) ([]model.Survey, []model.SurveyResponse, error) {
surveys, err := a.app.storage.GetSurveys(orgID, appID, creatorID, surveyIDs, surveyTypes, calendarEventID, limit, offset, filter, public, archived, nil)
if err != nil {
return nil, nil, err
}

surveysResponse, err := a.app.storage.GetSurveyResponses(nil, nil, nil, surveyIDs, surveyTypes, nil, nil, nil, nil)
if err != nil {
return nil, nil, err
}

return surveys, surveysResponse, nil
}

func (a appShared) createSurvey(survey model.Survey, externalIDs map[string]string) (*model.Survey, error) {
Expand Down
18 changes: 13 additions & 5 deletions core/application.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package core
import (
"application/core/interfaces"
"application/core/model"
corebb "application/driven/core"

"github.com/rokwire/core-auth-library-go/v3/authutils"
"github.com/rokwire/logging-library-go/v2/errors"
Expand Down Expand Up @@ -52,16 +53,19 @@ type Application struct {

logger *logs.Logger

storage interfaces.Storage
notifications interfaces.Notifications
calendar interfaces.Calendar
storage interfaces.Storage
notifications interfaces.Notifications
calendar interfaces.Calendar
corebb *corebb.Adapter
deleteDataLogic deleteDataLogic
}

// Start starts the core part of the application
func (a *Application) Start() {
//set storage listener
storageListener := storageListener{app: a}
a.storage.RegisterStorageListener(&storageListener)
a.deleteDataLogic.start()
}

// GetEnvConfigs retrieves the cached database env configs
Expand All @@ -78,8 +82,12 @@ func (a *Application) GetEnvConfigs() (*model.EnvConfigData, error) {
}

// NewApplication creates new Application
func NewApplication(version string, build string, storage interfaces.Storage, notifications interfaces.Notifications, calendar interfaces.Calendar, logger *logs.Logger) *Application {
application := Application{version: version, build: build, storage: storage, notifications: notifications, calendar: calendar, logger: logger}
func NewApplication(version string, build string, storage interfaces.Storage, notifications interfaces.Notifications, calendar interfaces.Calendar,
coreBB *corebb.Adapter, serviceID string, logger *logs.Logger) *Application {
deleteDataLogic := deleteDataLogic{logger: *logger, core: coreBB, serviceID: serviceID, storage: storage}

application := Application{version: version, build: build, storage: storage, notifications: notifications,
calendar: calendar, deleteDataLogic: deleteDataLogic, logger: logger}

//add the drivers ports/interfaces
application.Default = newAppDefault(&application)
Expand Down
2 changes: 1 addition & 1 deletion core/application_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ const (
func buildTestApplication(storage interfaces.Storage) *core.Application {
loggerOpts := logs.LoggerOpts{SuppressRequests: logs.NewStandardHealthCheckHTTPRequestProperties(serviceID + "/version")}
logger := logs.NewLogger(serviceID, &loggerOpts)
return core.NewApplication("1.1.1", "build", storage, nil, nil, logger)
return core.NewApplication("1.1.1", "build", storage, nil, nil, nil, "", logger)
}

func TestApplication_Start(t *testing.T) {
Expand Down
7 changes: 6 additions & 1 deletion core/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,16 @@ import "application/core/model"
type Shared interface {
// Surveys
getSurvey(id string, orgID string, appID string) (*model.Survey, error)
getSurveys(orgID string, appID string, creatorID *string, surveyIDs []string, surveyTypes []string, calendarEventID string, limit *int, offset *int) ([]model.Survey, error)
getSurveys(orgID string, appID string, creatorID *string, surveyIDs []string, surveyTypes []string, calendarEventID string, limit *int, offset *int, filter *model.SurveyTimeFilter, public *bool, archived *bool, completed *bool) ([]model.Survey, []model.SurveyResponse, error)
createSurvey(survey model.Survey, externalIDs map[string]string) (*model.Survey, error)
updateSurvey(survey model.Survey, userID string, externalIDs map[string]string, admin bool) error
deleteSurvey(id string, orgID string, appID string, userID string, externalIDs map[string]string, admin bool) error

isEventAdmin(orgID string, appID string, eventID string, userID string, externalIDs map[string]string) (bool, error)
hasAttendedEvent(orgID string, appID string, eventID string, userID string, externalIDs map[string]string) (bool, error)
}

// Core exposes Core APIs for the driver adapters
type Core interface {
LoadDeletedMemberships() ([]model.DeletedUserData, error)
}
4 changes: 2 additions & 2 deletions core/interfaces/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ type Default interface {
type Client interface {
// Surveys
GetSurvey(id string, orgID string, appID string) (*model.Survey, error)
GetSurveys(orgID string, appID string, creatorID *string, surveyIDs []string, surveyTypes []string, calendarEventID string, limit *int, offset *int) ([]model.Survey, error)
GetSurveys(orgID string, appID string, creatorID *string, surveyIDs []string, surveyTypes []string, calendarEventID string, limit *int, offset *int, filter *model.SurveyTimeFilter, public *bool, archived *bool, completed *bool) ([]model.Survey, []model.SurveyResponse, error)
CreateSurvey(survey model.Survey, externalIDs map[string]string) (*model.Survey, error)
UpdateSurvey(survey model.Survey, userID string, externalIDs map[string]string) error
DeleteSurvey(id string, orgID string, appID string, userID string, externalIDs map[string]string) error
Expand Down Expand Up @@ -59,7 +59,7 @@ type Admin interface {

// Surveys
GetSurvey(id string, orgID string, appID string) (*model.Survey, error)
GetSurveys(orgID string, appID string, creatorID *string, surveyIDs []string, surveyTypes []string, calendarEventID string, limit *int, offset *int) ([]model.Survey, error)
GetSurveys(orgID string, appID string, creatorID *string, surveyIDs []string, surveyTypes []string, calendarEventID string, limit *int, offset *int, filter *model.SurveyTimeFilter, public *bool, archived *bool, completed *bool) ([]model.Survey, []model.SurveyResponse, error)
CreateSurvey(survey model.Survey, externalIDs map[string]string) (*model.Survey, error)
UpdateSurvey(survey model.Survey, userID string, externalIDs map[string]string) error
DeleteSurvey(id string, orgID string, appID string, userID string, externalIDs map[string]string) error
Expand Down
Loading

0 comments on commit 0d28682

Please sign in to comment.