server

package module
v0.0.0-...-f2e39e4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 10, 2021 License: MIT Imports: 6 Imported by: 0

README

Impactasaurus Server Build Status Go Report Card GoDoc

Impactasaurus is changing the way charities measure and report on social impact. We are building a free, open source, easy to use, configurable impact measure tool, which is compatible with any CRM. Read more about Impactasaurus at https://impactasaurus.org.

This project is the backend for Impactasaurus. It is composed of a single golang application which uses a mongo database. A graphql API is exposed for the web app to consume.

Getting Started

Currently impactasaurus is an invite only application. To get access please email admin@impactasaurus.org or visit our gitter chat room and ask for an invite.

A docker compose file is available which will start the server locally with a linked mongodb. Ensure you have docker and docker compose installed, then run the following command:

docker-compose build && docker-compose up

This will start the golang application, a mongodb database and an in browser IDE for interacting with the graphql API.

The following URLs are of interest:

To use the graphql IDE, you must first obtain a JWT. This can be achieved by logging into the web app and running the following javascript in the developer console:

localStorage.getItem("token")

Enter the gathered token into the token input field and put http://localhost:8081/v1 into the URL input field.

You can configure the web app to communicate to your locally hosted server instance. This is detailed more in the app project's readme.

API Documentation

GraphQL APIs include documentation, to view this, please navigate to the graphql IDE listed above. The API documentation will be visible on the right hand side of the web site.

Configuration

The golang application is configured using environmental variables. The details of the available env vars can be found at cmd/config.go. Environmental variables can be added or adjusted, when using docker-compose, by editing server.environment within the docker-compose.yml file.

Third Party Dependencies
Auth0

Impactasaurus uses Auth0 as its identify platform. Auth0 manages authentication and user metadata storage. If Auth0 is being used, a non interactive client should be created for the server application. The details of which should be defined against the configuration values starting with USERS. If this is not available, the server application will return 'Unknown' for asked for user information.

Sentry

The server application can track errors to Sentry. To configure this, set a SENTRY_DSN configuration value. If not available, it will just log errors to stdout.

Contributing

Please read the contribution guidelines to find out how to contribute.

Thanks goes to these wonderful people:

drimpactthemakshteranatolyyyyyy

Contributions of any kind are welcome!

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Aggregate

func Aggregate(in []float32, aggregation Aggregation) (float32, error)

func Mean

func Mean(in []float32) float32

func Sum

func Sum(in []float32) float32

Types

type Aggregates

type Aggregates struct {
	Category []CategoryAggregate `json:"category"`
}

Aggregates stores aggregations associated with a meeting

type Aggregation

type Aggregation string
const (
	MEAN Aggregation = "mean"
	SUM  Aggregation = "sum"
)

type Answer

type Answer struct {
	QuestionID string      `json:"questionID" bson:"questionID"`
	Answer     interface{} `json:"answer"`
	Type       AnswerType  `json:"type"`
	Notes      *string     `json:"notes"`
}

func (Answer) IsNumeric

func (a Answer) IsNumeric() bool

func (Answer) ToFloat

func (a Answer) ToFloat() (float32, error)

type AnswerAggregation

type AnswerAggregation struct {
	ID      string  `json:"id"`
	Initial float32 `json:"initial"`
	Latest  float32 `json:"latest"`
	Stats   Stats   `json:"stats"`
}

AnswerAggregation aggregates answers for a question or category over multiple beneficiaries

type AnswerSummary

type AnswerSummary struct {
	ID              string        `json:"id"`
	Initial         DateTimeValue `json:"initial"`
	Latest          DateTimeValue `json:"latest"`
	NumberOfRecords int           `json:"noRecords"`
	ReportCoverage  float32       `json:"reportCoverage"`
	Stats           Stats         `json:"stats"`
}

AnswerSummary summarises a beneficiary's results for a question or category

type AnswerType

type AnswerType string
const INT AnswerType = "int"

type BenSummary

type BenSummary struct {
	ID         string          `json:"id"`
	Questions  []AnswerSummary `json:"questions"`
	Categories []AnswerSummary `json:"categories"`
}

BenSummary summarises a beneficiary's results

type Beneficiary

type Beneficiary struct {
	ID             string   `json:"id" bson:"beneficiary"`
	OrganisationID string   `json:"organisationID" bson:"organisationID"`
	Tags           []string `json:"tags"`
}

type CatalogueOutcomeSet

type CatalogueOutcomeSet struct {
	OutcomeSet  `json:"outcomeset"`
	License     string  `json:"license"`
	Attribution *string `json:"attribution"`
}

type Category

type Category struct {
	ID          string      `json:"id"`
	Name        string      `json:"name"`
	Description string      `json:"description"`
	Aggregation Aggregation `json:"aggregation"`
}

type CategoryAggregate

type CategoryAggregate struct {
	CategoryID string  `json:"categoryID"`
	Value      float32 `json:"value"`
}

CategoryAggregate aggregates multiple questions belonging to the same category to a question category level

type DateTimeValue

type DateTimeValue struct {
	Value     float32   `json:"value"`
	Timestamp time.Time `json:"timestamp"`
}

DateTimeValue combines a time.Time with a float32

type Exclusion

type Exclusion struct {
	Beneficiary *string `json:"beneficiary,omitempty"`
	Question    *string `json:"question,omitempty"`
	Category    *string `json:"category,omitempty"`
	Reason      string  `json:"reason"`
}

Exclusion details what has been excluded from the report and why. The structure can explain entire exclusion of a particular beneficiary, question or category or can explain why a particular question has been excluded on a single beneficiary

func (Exclusion) String

func (e Exclusion) String() string

type Export

type Export struct {
	Filename string
	Mime     string
	Data     []byte
}

type Label

type Label struct {
	Value int    `json:"value"`
	Label string `json:"label"`
}

type Meeting

type Meeting struct {
	ID             string    `json:"id" bson:"_id"`
	Beneficiary    string    `json:"beneficiary"`
	User           string    `json:"user"`
	OutcomeSetID   string    `json:"outcomeSetID" bson:"outcomeSetID"`
	OrganisationID string    `json:"organisationID" bson:"organisationID"`
	Answers        []Answer  `json:"answers"`
	Conducted      time.Time `json:"conducted"`
	Created        time.Time `json:"created"`
	Modified       time.Time `json:"modified"`
	Incomplete     bool      `json:"incomplete"`
	Completed      time.Time `json:"completed,omitempty"`
	Notes          *string   `json:"notes"`
	// Tags contains all the tags associated with the meeting.
	// This could be both meeting specific tags and tags inherited from the beneficiary
	Tags []string `json:"tags"`
	// BenTags details the tags inherited from the beneficiary
	BenTags []string `json:"benTags"  bson:"benTags"`
}

func (*Meeting) GetAnswer

func (m *Meeting) GetAnswer(questionID string) *Answer

func (*Meeting) GetCategoryAggregate

func (m *Meeting) GetCategoryAggregate(categoryID string, os OutcomeSet) (*CategoryAggregate, error)

GetCategoryAggregate aggregates multiple answers into a single value. If the returned CategoryAggregate is nil, there were either no answers available for the category or not all the questions belonging to the category were answered

func (*Meeting) GetCategoryAggregates

func (m *Meeting) GetCategoryAggregates(os OutcomeSet) ([]CategoryAggregate, error)

func (*Meeting) GetMeetingSpecificTags

func (m *Meeting) GetMeetingSpecificTags() []string

GetMeetingSpecificTags gathers the tags specifically assigned to the meeting i.e. removing all tags which are inherited from the beneficiary

type Meetings

type Meetings []Meeting

func (Meetings) FilterDeletedQuestionnaires

func (ms Meetings) FilterDeletedQuestionnaires(qf QuestionnaireFetcher, u auth.User) Meetings

func (Meetings) KeyedByBeneficiary

func (ms Meetings) KeyedByBeneficiary() map[string][]Meeting

type Organisation

type Organisation struct {
	Name     string                 `json:"name"`
	ID       string                 `json:"id" bson:"_id"`
	Settings map[string]interface{} `json:"_" bson:"settings"`
	Created  time.Time              `json:"_" bson:"created"`
	DonID    string                 `json:"_" bson:"donID"`
}

type OutcomeSet

type OutcomeSet struct {
	ID             string     `json:"id" bson:"_id"`
	OrganisationID string     `json:"organisationID" bson:"organisationID"`
	Name           string     `json:"name"`
	Description    string     `json:"description"`
	Instructions   string     `json:"instructions"`
	Questions      []Question `json:"questions"`
	Categories     []Category `json:"categories"`
	Deleted        bool       `json:"deleted"`
	Skippable      bool       `json:"skippable"`
	Source         *Source    `json:"source,omitempty" bson:"source,omitempty"`
	Created        time.Time  `json:"_" bson:"created"`
}

func (*OutcomeSet) ActiveQuestions

func (os *OutcomeSet) ActiveQuestions() []Question

ActiveQuestions returns only the currently active questions (i.e. not deleted)

func (*OutcomeSet) GetArchivedCategoryQuestions

func (os *OutcomeSet) GetArchivedCategoryQuestions(catID string) []Question

GetArchivedCategoryQuestions gets archived questions belonging to the provided category ID

func (*OutcomeSet) GetCategory

func (os *OutcomeSet) GetCategory(catID string) *Category

func (*OutcomeSet) GetCategoryQuestions

func (os *OutcomeSet) GetCategoryQuestions(catID string) []Question

GetCategoryQuestions gets questions belonging to the provided category ID Does not return archived questions

func (*OutcomeSet) GetQuestion

func (os *OutcomeSet) GetQuestion(qID string) *Question

GetQuestion returns the question with the provided qID or nil

type Question

type Question struct {
	ID          string                 `json:"id"`
	Question    string                 `json:"question"`
	Description string                 `json:"description"`
	Short       string                 `json:"short"`
	Type        QuestionType           `json:"type"`
	Deleted     bool                   `json:"deleted"`
	Options     map[string]interface{} `json:"options"`
	CategoryID  string                 `json:"categoryID,omitempty"  bson:"categoryID"`
}

func (Question) GetExtremeLabels

func (q Question) GetExtremeLabels() (left, right *string)

func (Question) GetName

func (q Question) GetName() string

func (Question) GetScale

func (q Question) GetScale() (left, right *int)

func (Question) Labels

func (q Question) Labels() []Label

type QuestionType

type QuestionType string
const LIKERT QuestionType = "likert"

type QuestionnaireFetcher

type QuestionnaireFetcher interface {
	GetOutcomeSet(id string, u auth.User) (OutcomeSet, error)
}

type Report

type Report struct {
	Beneficiaries []BenSummary        `json:"beneficiaries"`
	Questions     []AnswerAggregation `json:"questions"`
	Categories    []AnswerAggregation `json:"categories"`
	Excluded      []Exclusion         `json:"excluded"`
	Records       []Meeting           `json:"-"`
}

Report aggregates records over multiple beneficiaries

type ReportArgs

type ReportArgs struct {
	Start              time.Time
	End                time.Time
	QID                string
	Tags               []string
	OrTags             bool
	Open               bool
	MinRequiredRecords int
}

ReportArgs defines the arguments required to generate a report

type Source

type Source struct {
	ID      string    `json:"id"`
	Service string    `json:"service"`
	Version string    `json:"version"`
	Sourced time.Time `json:"sourced"`
}

type Stats

type Stats struct {
	Delta     float32 `json:"delta"`
	LOBFDelta float32 `json:"lobfDelta"`
	ROC       float32 `json:"roc"`
}

Stats are values calculated as part of report generation

type Summon

type Summon struct {
	ID            string    `bson:"_id"`
	Organisation  string    `bson:"organisation"`
	Questionnaire string    `bson:"questionnaireID"`
	User          string    `bson:"user"`
	Created       time.Time `bson:"created"`
	Expires       time.Time `bson:"expires"`
	Generated     uint      `bson:"generated"`
}

Summon are questionnaire links which can be given to multiple beneficiaries. They differ to remote meetings as they are not tied to an individual beneficiary. When clicked, the summon information is used to create a remote meeting for the beneficiary.

Directories

Path Synopsis
cmd
mock
auth
Package mock_auth is a generated GoMock package.
Package mock_auth is a generated GoMock package.
data
Package mock_data is a generated GoMock package.
Package mock_data is a generated GoMock package.
softoutcomes provides methods for interacting with softoutcomes.org which is a database of soft outcome questionnaires
softoutcomes provides methods for interacting with softoutcomes.org which is a database of soft outcome questionnaires

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL