0.2.6 • Published 1 year ago

@govflow/govflow v0.2.6

Weekly downloads
-
License
MIT
Repository
github
Last release
1 year ago

Gov Flow

codecov

An open, modular work order and workflow management system for local governments and resident satisfaction.

What we are building

Our aim is to build an open source solution that address the following aspects of government service delivery:

  • 311 request management ("there is a pothole in my street")
  • general questions and comments from the public ("what time does the library open")
  • "internal" request management ("there is a water leak on the 4th floor of town hall")
  • centralized views of request management status and analytics ("what is our work volume at present and how do we perform over time?")

For smaller cities, we'd like to be able to meet all their work management needs with Gov Flow. For larger cities, we intend to build out integrations with existing CRMs and ticket management software.

We have a focus on expanding "input channels" for requests. The API server currently supports API calls for new requests (used by our web form), and an endpoint for inbound emails. We plan to expand to SMS, chatbots, and potentially other entry points such as audio messages, and social media apps. If you have specific interest or use cases in this area, please talk to us by starting a discussion.

How we are building it

We are currently a small team within Zencity. We have a high-level roadmap, and we prioritize features based on real use cases with our early adopter users.

The API server (this codebase) is open source. We have some UI components that we have not yet open sourced. If you are interested in Gov Flow and need some pointers on building UI please open a ticket or a discussion and talk to us about your needs.

Get involved

  • Discussions: We discuss new features, architecture and so on in our Discussions forum. Feel free to take part in existing discussions or start a new one.
  • Issues: If you find a bug, or have some input on the codebase, feel free to open an issue.

Getting started

Using Gov Flow

Install Gov Flow from npm:

npm install @govflow/govflow

If you are not modifying Gov Flow with plugins, or embedding Gov Flow into an existing application, you can run the default server. First, you'll need to have a database to connect to and run migrations against:

Ensure database:

createdb govflow

Ensure your new database is declated in an environment variable:

# similar to the following
DATABASE_URL=postgres://<YOUR_USER>@localhost:5432/govflow

Ensure object storage:

GovFlow stores file on an S3-compatible object storage backend. Install minio and set the STORAGE_ environment variables appropriately.

Run migrations:

npx govflow-migrate up

# migrate backwards with npx govflow-migrate down
# govflow-migrate is a wrapper around Umzug so see:
# https://github.com/sequelize/umzug

Run the default server:

npx govflow-start

You can then visit localhost:3000/ in your browser to see the base API endpoint.

Other CLI commands:

There are some other CLI commands available when Gov Flow is installed. The API for the CLI will change, but for now the following are available:

npx govflow-start
npx govflow-migrate
npx govflow-generate-fake-data
npx govflow-send-test-email
npx govflow-send-test-sms
npx govflow-send-test-dispatch

Create a custom entrypoint:

If you plan to modify Gov Flow with plugins or any custom configuration or integrations, create your own entrypoint based on the following:

// my-govflow-extension/config.ts
import { MyServiceRepositoryPlugin } from './repositories';

export const plugins = []; // your plugins here.
export const config = {}; // your config here.

// my-govflow-extension/index.ts
import type { Server } from 'http';
import { createApp } from '../index';
import logger from '../logging';

async function defaultServer(): Promise<Server> {
    process.env.CONFIG_MODULE_PATH = './my-govflow-extension/config.ts';
    const app = await createApp();
    const port = app.config.appPort;
    return app.listen(port, () => {
        logger.info(`application listening on ${port}.`)
    });
}

export default defaultServer;

Note: See src/servers for examples of ready-to-go server configurations.

Note: createApp is a factory function that takes custom configuration, and returns an Express.js app instance. See Customization for further information on this and other configuration entry points.

Developing Gov Flow

Clone the codebase:

git clone https://github.com/govflow/govflow.git

View the primary runnable tasks:

make

Install dependencies:

make install

Also ensure that you have Postgres running, and create a database called govflow for use.

Lint code:

make lint

Run tests:

make test

Customization

Configuration

Provide a path to your custom configuration module via process.env.CONFIG_MODULE_PATH. See src/config for how this is read. You can provide new config and overwrite existing config.

Entry point

The primary entry point is the createApp factory function defined in src/index.ts.

createApp calls initConfig which initializes the system correctly. All tools, such as the migration and fake data generator scripts, need to call initConfig as part of their initialization flow.

createApp returns an Express.js Applicationinstance app. app is provisioned with easy access to configuration at app.config, registered plugins at app.plugins, and repositories at app.repositories (repositories are used for all data access). The database is also configured via createApp, and is usable after createApp has been called by exporting databaseEngine from src/db.

Extensibility

Gov Flow is designed to be shaped for specific use cases and system integrations. Existing behavior can be modified or extended via plugins. Over time, such customizations will be available as extensions, downloadable via npm, contributed by the core maintainers and the wider community of users.

Plugins

Gov Flow exposes a number of interfaces that can have their behaviour customized via plugins. All interfaces abstractions that can be customized in this way are prefixed with I and are bound to a concrete implementation via IoC containers instantiated in the registry module. The default concrete implementations are part of the src/core module - see the Module overview below for further information on the organization of the codebase.

In the current release, repository interfaces can be customized via plugins. Repositories are a data access abstraction layer - see the tests for examples of how they are used, and how custom implementations can be provided.

Future releases may see interfaces that can be customised via plugins for routes, models, and so on.

Providing a plugin

Provide a path to your custom configuration module via process.env.CONFIG_MODULE_PATH, and from that module export a member plugins which is an array of Plugin types. See examples in the test suite, and see where implementations are bound in src/registry.

Models

Providing a model

See the tests for examples of modifying a core model and/or providing an additional model.

Note: It is likely that the Plugin concept will be expanded in the future to encapsulate the provision of custom models, and other aspects of the system like routers, so this current API is likely to change.

Modules

This is a short overview of the modules under src in the codebase to help you get oriented, especially while documentation is sparse. Please also review tests, and all functionality of the codebase is on display in the test suite.

config

Provides a configuration object to store various config for the system. The configuration object is backed by nconf.

core

This provides the core functionality of the system. Here you will find a submodule for each core entity, with its routes, repositories, models, and any business logic.

db

Provides a database engine object, with verification of the connection, syncing of tables, migration of schema changes, and registration of custom models. Sequelize is used.

logging

Provides a logger. Winston is used.

migrations

Stores migration directives for Umzug, Sequelize's tool for programmatic migrations.

registry

Provides registration and implementation of custom components for the system. Implementation is managed via Inversify IoC containers.

servers

Provides server configurations for the app.

types

Provides all types that the system declares.

default

Provides the default server configuration to run the system with no customization.

index

The entry point for the system, providing the createApp factory function to initialize and configure an app.

Communications

An important part of any workflow management ot 311 system is communication with public users who submit requests, and staff users who handle requests. Gov Flow currently supports email and SMS for such transactional messaging.

SendGrid is used as the email backend, and Twilio is used as the SMS backend. You will need to setup accounts and credentials at both providers to send messages from GovFlow.

Configuration

The following configuration variables need to be set on the environment:

  • SENDGRID_API_KEY
  • SENDGRID_FROM_EMAIL
  • TWILIO_ACCOUNT_SID
  • TWILIO_AUTH_TOKEN
  • TWILIO_FROM_PHONE

The following configuration variables are not required for messaging to work, but are required for message templates to be meaningful:

  • APP_CLIENT_URL
  • APP_PUBLIC_EMAIL

An additional configuration variable allows bypassing the backends and sending messages to console for testing and development (see below):

  • COMMUNICATIONS_TO_CONSOLE

Manual messaging to verify the backends

make send-email, make send-sms, and make send-dispatch can be used to send test messages. You will need to set TEST_TO_EMAIL and TEST_TO_PHONE environment variables to receive these messages. All credentials will need to be properly set for these manual tests to work. make send-dispatch sets COMMUNICATIONS_TO_CONSOLE to undefined to force usage of the backend provider, and, it uses the higher-level dispatchMessage function that us used by the dispatch handler in the app, rather than the low-level sendSms and sendEmail functions.

Messages to console

Important: if the COMMUNICATIONS_TO_CONSOLE environment variable is set to any truthy value, then SMS and email messages will be logged to the console and will not be sent to the backend service providers. We highly recommend setting this environment variable for local development, and in particular for running tests. Even if all backend provider credentials are set, if COMMUNICATIONS_TO_CONSOLE is truthy, then they will not be used to send messages.

File support

Gov Flow supports files (usually images) being added to service requests. File support is a client/server architecture where the actual file storage is on an S3-compatible object storage (for object storage solutions that are not S3 compatible, namely, Azure Blog Storage, Minio can be used as a gateway to provide the required API).

The flow

  • A client (such as a service request submission form, or an administration dashboard for 311 work management) provides functionality to allow users to (i) upload, or (ii) view, a file.
  • The client submits the file name to the appropriate Gov Flow storage endpoint to either (i) get a presigned PUT url, or (ii) get a presigned GET url.
  • The server responds with a URL, time limited in usage, to perform the appropriate PUT or GET request from the client.
  • The client performs the appropriate action with the new url.
  • In the case of allowing users to upload URLs, for example for a new service request, the client submits the service request payload with an array of image URLs, not actual images.

Configuration

The following environment variables are required:

STORAGE_BUCKET // default 'govflow_uploads' STORAGE_REGION // default 'us-east-1' STORAGE_SSL // default 1 which is cast to true STORAGE_PORT STORAGE_ENDPOINT STORAGE_ACCESS_KEY STORAGE_SECRET_KEY STORAGE_SIGNED_GET_EXPIRY // minutes for get urls to expiry

Testing and development

The simplest solution is to run an instance of minio locally. See the GitHub workflow, which runs a minio instance for the test suite, and see the Minio documentation at https://min.io

0.2.6

1 year ago

0.2.5

1 year ago

0.2.3

1 year ago

0.0.124-alpha

1 year ago

0.0.119-alpha

2 years ago

0.0.123-alpha

1 year ago

0.0.121-alpha

1 year ago

0.0.127-alpha

1 year ago

0.1.1

1 year ago

0.1.7

1 year ago

0.1.9

1 year ago

0.1.4

1 year ago

0.0.126-alpha

1 year ago

0.1.3

1 year ago

0.1.6

1 year ago

0.1.5

1 year ago

0.0.122-alpha

1 year ago

0.0.125-alpha

1 year ago

0.0.130-alpha

1 year ago

0.0.128-alpha

1 year ago

0.2.1

1 year ago

0.2.0

1 year ago

0.0.118-alpha

2 years ago

0.0.112-alpha

2 years ago

0.0.113-alpha

2 years ago

0.0.109-alpha

2 years ago

0.0.114-alpha

2 years ago

0.0.111-alpha

2 years ago

0.0.115-alpha

2 years ago

0.0.108-alpha

2 years ago

0.0.104-alpha

2 years ago

0.0.95-alpha

2 years ago

0.0.100-alpha

2 years ago

0.0.107-alpha

2 years ago

0.0.98-alpha

2 years ago

0.0.99-alpha

2 years ago

0.0.103-alpha

2 years ago

0.0.96-alpha

2 years ago

0.0.106-alpha

2 years ago

0.0.90-alpha

2 years ago

0.0.85-alpha

2 years ago

0.0.93-alpha

2 years ago

0.0.88-alpha

2 years ago

0.0.102-alpha

2 years ago

0.0.94-alpha

2 years ago

0.0.84-alpha

2 years ago

0.0.87-alpha

2 years ago

0.0.101-alpha

2 years ago

0.0.80-alpha

2 years ago

0.0.75-alpha

2 years ago

0.0.78-alpha

2 years ago

0.0.83-alpha

2 years ago

0.0.63-alpha

2 years ago

0.0.69-alpha

2 years ago

0.0.76-alpha

2 years ago

0.0.66-alpha

2 years ago

0.0.72-alpha

2 years ago

0.0.82-alpha

2 years ago

0.0.79-alpha

2 years ago

0.0.65-alpha

2 years ago

0.0.70-alpha

2 years ago

0.0.68-alpha

2 years ago

0.0.73-alpha

2 years ago

0.0.74-alpha

2 years ago

0.0.81-alpha

2 years ago

0.0.77-alpha

2 years ago

0.0.67-alpha

2 years ago

0.0.64-alpha

2 years ago

0.0.55-alpha

2 years ago

0.0.58-alpha

2 years ago

0.0.60-alpha

2 years ago

0.0.43-alpha

2 years ago

0.0.49-alpha

2 years ago

0.0.59-alpha

2 years ago

0.0.42-alpha

2 years ago

0.0.62-alpha

2 years ago

0.0.50-alpha

2 years ago

0.0.45-alpha

2 years ago

0.0.53-alpha

2 years ago

0.0.61-alpha

2 years ago

0.0.57-alpha

2 years ago

0.0.54-alpha

2 years ago

0.0.44-alpha

2 years ago

0.0.40-alpha

2 years ago

0.0.38-alpha

2 years ago

0.0.37-alpha

2 years ago

0.0.41-alpha

2 years ago

0.0.35-alpha

2 years ago

0.0.20-alpha

2 years ago

0.0.30-alpha

2 years ago

0.0.18-alpha

2 years ago

0.0.32-alpha

2 years ago

0.0.22-alpha

2 years ago

0.0.28-alpha

2 years ago

0.0.27-alpha

2 years ago

0.0.17-alpha

2 years ago

0.0.23-alpha

2 years ago

0.0.33-alpha

2 years ago

0.0.25-alpha

2 years ago

0.0.29-alpha

2 years ago

0.0.19-alpha

2 years ago

0.0.21-alpha

2 years ago

0.0.31-alpha

2 years ago

0.0.36-alpha

2 years ago

0.0.26-alpha

2 years ago

0.0.24-alpha

2 years ago

0.0.34-alpha

2 years ago

0.0.15-alpha

2 years ago

0.0.11-alpha

2 years ago

0.0.14-alpha

2 years ago

0.0.12-alpha

2 years ago

0.0.16-alpha

2 years ago

0.0.4-alpha

2 years ago

0.0.2-alpha

2 years ago

0.0.10-alpha

2 years ago

0.0.9-alpha

2 years ago

0.0.6-alpha

2 years ago

0.0.3-alpha

2 years ago

0.0.5-alpha

2 years ago

0.0.7-alpha

2 years ago

0.0.1-alpha

3 years ago