This page displays a list of available reports, a report is a set of returned lettters that have been reported on the same day.
Each line of the page is a link that can download the report.
I'm not sure the format of the csv is right. The data might be confusing especially if the service has a mix of precompiled templates and jobs.
Units tests are still to come.
New units tests have not been written for this page because it is very like this will be refactor and probably a new template created for the page. Some design needs to go into this page.
But we needed something ready for user research.
Because it means you often have to cast to string in your application
code just to get your tests passing.
The method being monkey patched is originally defined here: b81aa0f18c/src/werkzeug/routing.py (L1272)
Show valdiation failed messages on letter notifications in red text,
not in the banner like we do on Uploads and Validation checker pages.
This is because it is a different step in the journey: the user
has already sent the notification and styling needs to be in line
with other places where user is checking the notification she already
has sent.
We store our audit history in two ways:
1. A list of versions of a service
2. A list of events to do with API keys
In the future there could be auditing data which we want to display that
is stored in other formats (for example the event table).
This commit adds some objects which wrap around the different types of
auditing data, and expose a consistent interface to them. This
architecture will let us:
- write clean code in the presentation layer to display these events on
a page
- add more types of events in the future by subclassing the `Event` data
type, without having to rewrite anything in the presentation layer
We hardcode this as second class for the moment but eventually
will let the user pick.
Currently the API appears to do no validation, e.g. a json
schema, that rejects API calls with the extra key for postage.
Next steps will be to put a PR into the API that will expect a
postage value in the request and save it with the rest of the
notification. Then when that is done we can add the user interface
to the admin app to let the user pick the postage.
Updating an organisation’s branding might now also update the branding
of services associated to that organisation. This is similar to how
updating an organisation’s type can update the organisation type for its
services.
In the latter case we already make sure to clear the cached version of
these services which is held in Redis.
This commit does the same clearing of the caches when updating an
organisation’s branding (and does a bit of refactoring to do so without
duplication of code.)
Added a send button which only appears on the page if the query string
indicates that the PDF is valid. Before actually sending, we check that
the service has the right permissions and that the metadata for the
letter confirms the letter is valid (because the query string can be
changed).
Before, the delete decorator would delete the keys from Redis and then
we made the request to api to change the data. However, it is possible
that the cache could get re-populated in between these two things
happening, and so would cache outdated data.
This changes the order to send the api request first. We then always
delete the specified keys from Redis. Changing the order of the code in
the decorator changes the order in which the cache keys get deleted, so
the tests have been updated.
This report will be used by the engagement team. There is a form to give
a start and end date for the report, and the form is then downloaded
as a CSV file when the form is submitted.
If we change our mind and decide whether a service should/should not be
counted in the list of live services then we should also drop the cache
which stores the count of how many live services there are.
This should make the ‘All organisations’ page load a lil’ bit quicker.
Still worth caching the domains separately so the response is smaller
when we only care about domains. This is because the code that uses the
domains is part of the sign up flow, so it’s really important that it’s
snappy.
Users can only be archived by Platform Admin from the user page
(/users/<user_id>). This removes them from all services and orgs and
updates their details.
The data flow of other bits of our application looks like this:
```
API (returns JSON)
⬇
API client (returns a built in type, usually `dict`)
⬇
Model (returns an instance, eg of type `Service`)
⬇
View (returns HTML)
```
The user API client was architected weirdly, in that it returned a model
directly, like this:
```
API (returns JSON)
⬇
API client (returns a model, of type `User`, `InvitedUser`, etc)
⬇
View (returns HTML)
```
This mixing of different layers of the application is bad because it
makes it hard to write model code that doesn’t have circular
dependencies. As our application gets more complicated we will be
relying more on models to manage this complexity, so we should make it
easy, not hard to write them.
It also means that most of our mocking was of the User model, not just
the underlying JSON. So it would have been easy to introduce subtle bugs
to the user model, because it wasn’t being comprehensively tested. A lot
of the changed lines of code in this commit mean changing the tests to
mock only the JSON, which means that the model layer gets implicitly
tested.
For those reasons this commit changes the user API client to return
JSON, not an instance of `User` or other models.
The domains lookup is a bit slow because it’s serialising all the
organisations in the database. Since we’re putting this in the sign up
flow it should feel snappy, so lets cache just the domain bit of it in
Redis.
At the moment we have to update a YAML file and deploy the change to get
a new domain whitelisted.
We already have a thing for adding new domains – the organisation stuff.
This commit extends the validation to look in the `domains` table on the
API if it can’t find anything in the YAML whitelist.
This has the advantage of:
- not having to deploy code to whitelist a new domain
- forcing us to create new organisations as they come along, so that
users’ services automatically get allocated to the organisation once
their domain is whitelisted
At the moment you have to wait for whoever you’ve invited to accept the
invitation before you can go live. Since this check is mainly for the
benefit of the service, not us, we should trust that people’s intentions
are good when they invite someone.
So this commit also checks the invited users when counting how many team
members a service has.
We’re deprecating storing the domain as text on a branding in favour of
a database relationship between branding and organisation.
We need to do this now in order to remove the validation on these fields
(which depends on the data in `domains.yml`)
This is the first step of replacing the `domains.yml` file.
In order to replicate the same functionality we get from the
`domains.yml` file and its associated code this commit adds a
`Organisation` model. This model copies a lot of methods from the
`AgreementInfo` class which wrapped the `domains.yml` file.
It factors out some stuff that would otherwise be duplicated between the
`Organisation` and `Service` model, in such a way that could be reused
for making other models in the future.
This commit doesn’t change other parts of the code to make use of this
new model yet – that will come in subsequent commits.
Returns the data calculated by the API. Stored in Redis against a
hardcoded key so that no-one hammering the home page is directly hitting
the database.