GithubHelp home page GithubHelp logo

nditech / apollo Goto Github PK

View Code? Open in Web Editor NEW
13.0 13.0 9.0 23.89 MB

A robust data collection and analysis tool to document political processes

Home Page: https://dem.tools/elections

License: Other

Python 23.26% HTML 13.22% CSS 6.91% JavaScript 56.24% Dockerfile 0.01% Makefile 0.03% Shell 0.17% Mako 0.01% Smarty 0.01% SCSS 0.15% Procfile 0.01%
election-analysis election-data election-quick-count elections elections-toolkit political-parties pvt

apollo's People

Contributors

blynchndi avatar delegbede avatar dependabot[bot] avatar dodumosu avatar jamesmura avatar stigsfoot avatar takinbo avatar transifex-integration[bot] avatar turnerd avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

apollo's Issues

change import workflow to do field mapping in reverse of what currently exists

When doing an import (e.g. participants or locations), we have internal data fields that are then mapped to columns in the import document. This isn't flexible and resorts to using things like column prefixes for fields that have multiple columns in the import document. This is a proposal to switch the import workflow to map column fields to internal data fields; this will allow us to do the following:

phone 1 -> phone number
phone 2 -> phone number
national -> sample
state -> sample

And this way we can tell that phone1 and phone 2 are columns of phone number type. We would also be able to import special data fields like this as well.

improve test coverage to 80%

Current test coverage sits around 33%. This issue is to track improvements to the coverage and to get to at least 80% of the code base (where reasonable).

TypeError: storage must be a werkzeug.FileStorage on file upload

Uploading any file to the system now returns a TypeError

127.0.0.1 - - [30/May/2018 06:44:39] "POST /locations/set/1/import HTTP/1.1" 500 -
Traceback (most recent call last):
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/flask/app.py", line 1997, in __call__
    return self.wsgi_app(environ, start_response)
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/werkzeug/contrib/fixers.py", line 152, in __call__
    return self.app(environ, start_response)
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/whitenoise/base.py", line 66, in __call__
    return self.application(environ, start_response)
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/flask/app.py", line 1985, in wsgi_app
    response = self.handle_exception(e)
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/flask_restful/__init__.py", line 273, in error_router
    return original_handler(e)
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/flask_restful/__init__.py", line 273, in error_router
    return original_handler(e)
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/flask/app.py", line 1540, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/flask/_compat.py", line 33, in reraise
    raise value
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/flask/app.py", line 1982, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/flask/app.py", line 1614, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/flask_restful/__init__.py", line 273, in error_router
    return original_handler(e)
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/flask_restful/__init__.py", line 273, in error_router
    return original_handler(e)
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/flask/app.py", line 1517, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/flask/_compat.py", line 33, in reraise
    raise value
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/flask/app.py", line 1612, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/flask_debugtoolbar/__init__.py", line 125, in dispatch_request
    return view_func(**req.view_args)
  File "/home/takinbo/p/apollo/apollo/frontend/__init__.py", line 10, in wrapper
    return f(*args, **kwargs)
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/flask_principal.py", line 199, in _decorated
    rv = f(*args, **kw)
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/flask_login/utils.py", line 261, in decorated_view
    return func(*args, **kwargs)
  File "/home/takinbo/p/apollo/apollo/locations/views_locations.py", line 141, in locations_import
    filename = uploads.save(upload_file)
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/flask_uploads.py", line 402, in save
    raise TypeError("storage must be a werkzeug.FileStorage")
TypeError: storage must be a werkzeug.FileStorage

creating a critical incident from the web interface throws an error

after filling the participant and location and then filling out the critical incident form, on saving; the application crashes.

sqlalchemy.exc.InvalidRequestError: This Session's transaction has been rolled back due to a previous exception during flush. To begin a new transaction with this Session, first issue Session.rollback(). Original exception was: (psycopg2.IntegrityError) null value
in column "location_id" violates not-null constraint
DETAIL:  Failing row contains (75, 1, 1, 2, 1, null, {"A": 1, "B": 1}, null, O, 2018-03-30 17:16:09.436356, null, t, , , null, null, {}, {}, {}).
 [SQL: "INSERT INTO submission (id, deployment_id, event_id, form_id, participant_id, location_id, data, submission_type, created, updated, sender_verified, quarantine_status, verification_status, incident_description, incident_status, confidence, quality_assurance_status, overridden_fields) VALUES (nextval('submission_id_seq'), %(deployment_id)s, %(event_id)s, %(form_id)s, %(participant_id)s, %(location_id)s, %(data)s, %(submission_type)s, %(created)s, %(updated)s, %(sender_verified)s, %(quarantine_status)s, %(verification_status)s, %(incident_description)s, %(incident_status)s, %(confidence)s, %(quality_assurance_status)s, %(overridden_fields)s) RETURNING submission.id"] [parameters: {'deployment_id': 1, 'event_id': 1, 'form_id': 2, 'participant_id': 1, 'location_id': None, 'data':
'{"A": 1, "B": 1}', 'submission_type': 'O', 'created': datetime.datetime(2018, 3, 30, 17, 16, 9, 436356, tzinfo=<UTC>), 'updated': None, 'sender_verified': True, 'quarantine_status': '', 'verification_status': '', 'incident_description': None, 'incident_status': None, 'confidence': '{}', 'quality_assurance_status': '{}', 'overridden_fields': []}]

Tracking user interactions for Apollo Instances

@takinbo,

For the main branch of Apollo 3, we'll be selecting a few instances to learn user behavior in order to provide guidance for what we functionality we build, user experience we implement.

As part of this initiative to be better informed on how users are using Apollo, kindly:

Paste the Google Tag ManagerCopy the code below and paste it onto our main template to affect every Apollo page.

Paste this code as high in the of the page as possible:

<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-W8V7PJF');</script>
<!-- End Google Tag Manager -->

EDIT: Wrong key ^^

Additionally, paste this code immediately after the opening tag:

<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-W8V7PJF"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
<!-- End Google Tag Manager (noscript) -->

Changing user

When editing a user within the admin menu, the default is that all fields for a user are empty, including roles. Thus if you change the password for a user and click save without touching any other field, the user's roles are erased, removing the ability for the user to access most of the site. The fix would be to default the roles and permissions fields to be filled in with whatever ones the user currently has, so that if only the password is changed, the roles and permissions will stay the same and not be taken away.

fields don't map correctly to specified columns in participant upload

@dodumosu when attempting to do a participant upload, I noticed that the following fields don't map correctly: Participant ID, Phone and extra data fields. In this particular upload, the Participant ID was mapping to the phone number, Phone number did not map to the correct field (in my example it was blank) and for National ID (which was an extra data field), it was mapping to the phone number also.

include forms in the user menu

in order to reduce the number of clicks required to make modifications to the forms accessible in a particular event, the forms feature should be included in the user menu.

filtering by QA parameter that does a lookup on an extra data field throws an exception

Attempting to filter by a QA condition that does a lookup against an extra data field, throws an exception.

screenshot-1527834351

Exception

sqlalchemy.exc.ProgrammingError
sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) operator does not exist: integer = jsonb
LINE 3: ... AND (CAST((submission.data ->> 'BB') AS INTEGER) = (partici...
                                                             ^
HINT:  No operator matches the given name and argument type(s). You might need to add explicit type casts.
 [SQL: 'SELECT submission.id AS submission_id, submission.deployment_id AS submission_deployment_id, submission.event_id AS submission_event_id, submission.form_id AS submission_form_id, submission.participant_id AS submission_participant_id, submission.location_id AS submission_location_id, submission.data AS submission_data, submission.extra_data AS submission_extra_data, submission.submission_type AS submission_submission_type, submission.created AS submission_created, submission.updated AS submission_updated, submission.sender_verified AS submission_sender_verified, submission.quarantine_status AS submission_quarantine_status, submission.verification_status AS submission_verification_status, submission.incident_description AS submission_incident_description, submission.incident_status AS submission_incident_status, submission.overridden_fields AS submission_overridden_fields, submission.conflicts AS submission_conflicts \nFROM submission JOIN participant ON submission.participant_id = participant.id \nWHERE %(param_1)s = submission.form_id AND submission.submission_type = %(submission_type_1)s AND (CAST((submission.data ->> %(data_1)s) AS INTEGER) = (participant.extra_data -> %(extra_data_1)s)) = true \n LIMIT %(param_2)s OFFSET %(param_3)s'] [parameters: {'param_1': 1, 'submission_type_1': 'O', 'data_1': 'BB', 'extra_data_1': 'national', 'param_2': 25, 'param_3': 0}] (Background on this error at: http://sqlalche.me/e/f405)

arpeggio does not understand "=" as an option

The QA builder currently only allows one to use the "=" operator for equality matching but the arpeggio library is not configured to use that for equality matching, instead it uses "==". Either change the QA builder to use "==" or change arpeggio to use "=" for equality.

screenshot-1527833470

Not all models cascade deletes

@blynchNDI reported an error deleting a participant set. On examination, the cause is that the participant set table delete does not cascade. The different models (particularly those which can be deleted via the admin) should be modified to cascade deletes when it makes sense.

Upstream issues with MongoEngine cause random errors when logging messages

The recurrent ValidationError exception that says that we can only reference documents after they have been saved always occurs at the same point: logging a message and attaching participants and/or submissions. For some reason, MongoEngine won't update the document with an ObjectID, so trying to update the document will fail.

Apparent bug relating to data being lost

Validate transactions don't run into conflicts for Apollo 3.x

In the second round of the Mali elections, data was submitted to Apollo and stayed there for a period of time, but later on was no longer in the database. This problem only occurred for approximately 30-50 observers and happened exclusively for responses to sections D and E of the checklist.

Created from Aha! https://nditech.aha.io/features/APOLLO-82

creating administrative divisions throws an exception

When attempting to create an administrative division, I get the following exception:

TypeError: 'has_political_code' is an invalid keyword argument for LocationType

Here's the entire traceback

Traceback (most recent call last):
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/gunicorn/workers/async.py", line 56, in handle
    self.handle_request(listener_name, req, client, addr)
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/gunicorn/workers/ggevent.py", line 152, in handle_request
    super(GeventWorker, self).handle_request(*args)
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/gunicorn/workers/async.py", line 107, in handle_request
    respiter = self.wsgi(environ, resp.start_response)
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/flask/app.py", line 1997, in __call__
    return self.wsgi_app(environ, start_response)
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/werkzeug/contrib/fixers.py", line 152, in __call__
    return self.app(environ, start_response)
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/whitenoise/base.py", line 66, in __call__
    return self.application(environ, start_response)
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/flask/app.py", line 1985, in wsgi_app
    response = self.handle_exception(e)
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/flask_restful/__init__.py", line 273, in error_router
    return original_handler(e)
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/flask_restful/__init__.py", line 273, in error_router
    return original_handler(e)
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/flask/app.py", line 1540, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/flask/_compat.py", line 33, in reraise
    raise value
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/flask/app.py", line 1982, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/flask/app.py", line 1614, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/flask_restful/__init__.py", line 273, in error_router
    return original_handler(e)
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/flask_restful/__init__.py", line 273, in error_router
    return original_handler(e)
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/flask/app.py", line 1517, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/flask/_compat.py", line 33, in reraise
    raise value
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/flask/app.py", line 1612, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/flask_debugtoolbar/__init__.py", line 125, in dispatch_request
    return view_func(**req.view_args)
  File "/home/takinbo/p/apollo/apollo/frontend/__init__.py", line 10, in wrapper
    return f(*args, **kwargs)
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/flask_principal.py", line 199, in _decorated
    rv = f(*args, **kw)
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/flask_login/utils.py", line 261, in decorated_view
    return func(*args, **kwargs)
  File "/home/takinbo/p/apollo/apollo/locations/views_locations.py", line 248, in locations_builder
    import_graph(divisions_graph, location_set)
  File "/home/takinbo/p/apollo/apollo/locations/utils.py", line 50, in import_graph
    location_set_id=location_set.id
  File "/home/takinbo/p/apollo/apollo/dal/service.py", line 58, in create
    return self.save(self.new(**kwargs))
  File "/home/takinbo/p/apollo/apollo/dal/service.py", line 55, in new
    return self.__model__(**kwargs)
  File "<string>", line 4, in __init__
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/sqlalchemy/orm/state.py", line 417, in _initialize_instance
    manager.dispatch.init_failure(self, args, kwargs)
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/sqlalchemy/util/langhelpers.py", line 66, in __exit__
    compat.reraise(exc_type, exc_value, exc_tb)
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/sqlalchemy/util/compat.py", line 187, in reraise
    raise value
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/sqlalchemy/orm/state.py", line 414, in _initialize_instance
    return manager.original_init(*mixed[1:], **kwargs)
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/sqlalchemy/ext/declarative/base.py", line 699, in _declarative_constructor
    (k, cls_.__name__))
TypeError: 'has_political_code' is an invalid keyword argument for LocationType

change sample imports and exports to be derived from participant imports and exports

this is dependent on #13 been done to allow mapping of those sample fields. this will then allow samples to be defined during imports of participants. The column name will represent the name of the sample. The samples management interface will then just be for deletion of samples or sample locations. Sample exports will also be included in the participants export.

When I want to create an event, I want to enable forms, participant, and location lists to be created independently of events, so that I can drag-drop into an event.

  • Be able to attach arbitrary additional pre-loaded fields to locations, such as EMB PS ID, or Registered Voters
  • Permit certain levels of user to see these pre-loaded fields
  • Permit quality assurance checks to access these pre-loaded fields
  • Be able to add or delete participants and locations directly
  • Be able to add or delete administrative divisions after the system is built
  • Be able to export and import administrative structure
  • Be able to export and import participants
  • Be able to export and import locations
  • Be able to export and import samples
  • Be able to export and import forms
  • Locations should have XY coordinate fields

Created from Aha! https://nditech.aha.io/features/APOLLO-19

forms should fail gracefully when no groups or fields are defined

Traceback (most recent call last):
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/flask/app.py", line 1997, in __call__
    return self.wsgi_app(environ, start_response)
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/werkzeug/contrib/fixers.py", line 152, in __call__
    return self.app(environ, start_response)
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/whitenoise/base.py", line 66, in __call__
    return self.application(environ, start_response)
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/flask/app.py", line 1985, in wsgi_app
    response = self.handle_exception(e)
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/flask_restful/__init__.py", line 273, in error_router
    return original_handler(e)
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/flask_restful/__init__.py", line 273, in error_router
    return original_handler(e)
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/flask/app.py", line 1540, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/flask/_compat.py", line 33, in reraise
    raise value
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/flask/app.py", line 1982, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/flask/app.py", line 1614, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/flask_restful/__init__.py", line 273, in error_router
    return original_handler(e)
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/flask_restful/__init__.py", line 273, in error_router
    return original_handler(e)
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/flask/app.py", line 1517, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/flask/_compat.py", line 33, in reraise
    raise value
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/flask/app.py", line 1612, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/flask_debugtoolbar/__init__.py", line 125, in dispatch_request
    return view_func(**req.view_args)
  File "/home/takinbo/p/apollo/apollo/frontend/__init__.py", line 10, in wrapper
    return f(*args, **kwargs)
  File "/home/takinbo/.virtualenvs/apollo-nrEiZ9Wj/lib/python3.6/site-packages/flask_login/utils.py", line 261, in decorated_view
    return func(*args, **kwargs)
  File "/home/takinbo/p/apollo/apollo/submissions/views_submissions.py", line 89, in submission_list
    filter_class = filters.make_submission_list_filter(event, form)
  File "/home/takinbo/p/apollo/apollo/submissions/filters.py", line 239, in make_submission_list_filter
    form._populate_field_cache()
  File "/home/takinbo/p/apollo/apollo/formsframework/models.py", line 98, in _populate_field_cache
    f['tag']: f for g in self.data['groups'] for f in g['fields']
TypeError: 'NoneType' object is not subscriptable

Edit submission view does not load comments

Comments are not saved with a deployment, so when the submission edit view is loaded, the associated comments are not.

Possible fixes:

  • set deployment on saving comments;
  • instead of loading submission comments through their service, load directly from the submission object (i.e: use submission.comments instead of services.submission_comments.find(submission=submission)

Aha! Link: https://nditech.aha.io/features/APOLLO-201

implement permissions for resources

Resources are objects in the database that have been so defined as to allow for fine-grained permissions; resources include forms and extra data fields in participants and locations.

This issue is to track progress on the implementation of permissions to allow or disallow access to these resources.

do we need to split the repository into two?

We're coming up against an issue where the code for Apollo 2 and 3 have diverged. Putting up everything on one branch makes it difficult to manage changes.

We have two options:

  1. Maintain different release branches for both versions
  2. Split the project into two repositories and manage them independently

Any suggestions on what might be a better strategy for managing the project going forward?

@cdoten @stigsfoot @dodumosu

Participant page for Apollo 3.1 crashes on our instance

When trying to upload participants to the Apollo 3.1 demo site (https://elections.demcloud.org) the Participants feature crashes (permanently).

Steps to reproduce:

  1. Login
  2. Nav to Participants tab
  3. Click import participants
  4. Upload CSV
  5. Map CSV

Actual results:

  • After mapping submitting participants leads to an error page with a 500
  • I have since been unable to access the Participants page.

Currently, we are re-installing Apollo and will provide you the CSV and give you access to the server to check any logs. Kindly provide Carlos with any findings you see, assuming this is related to a bad install.

Created from Aha! https://nditech.aha.io/features/APOLLO-83

docker images fail to build

There is a current issue with building docker images for Apollo (currently affects 2.7.10.1 and possibly 3.x). This is likely due to some changes that may have been introduced in the base alpine linux images. An urgent fix is required.

add extra data fields for locations

just like we had in participants, we should also have something similar but for locations. this should resolve

Be able to attach arbitrary additional pre-loaded fields to locations, such as EMB PS ID, or Registered Voters

in #3 although we need to have a conversation about how this will be handled by permissions as specified

Permit certain levels of user to see these pre-loaded fields

integrate prometheus to gather metrics

The prometheus platform allows for external applications to provide endpoints for extracting metric data; by integrating an exporter in Apollo, administrators will be able to identify problems before they become critical and also have better insight into the performance of the Apollo application

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.