From f79869625a4cdad3327da0c4dcff52a8780f437b Mon Sep 17 00:00:00 2001 From: Daniel Naab Date: Mon, 9 Sep 2024 10:09:56 -0500 Subject: [PATCH] Documentation updates for backend (#302) * Add ADR for database strategy * Add authentication ADR * Add ADR for our REST API * Update db ADR with test speed note * Actually add the REST API ADR * Clean wording in auth ADR * Update documents/adr/0012-database-strategy.md * Renumber new ADRs to match main --- documents/adr/0013-database-strategy.md | 37 +++++++++++++++++++++++++ documents/adr/0014-authentication.md | 25 +++++++++++++++++ documents/adr/0015-rest-api.md | 21 ++++++++++++++ 3 files changed, 83 insertions(+) create mode 100644 documents/adr/0013-database-strategy.md create mode 100644 documents/adr/0014-authentication.md create mode 100644 documents/adr/0015-rest-api.md diff --git a/documents/adr/0013-database-strategy.md b/documents/adr/0013-database-strategy.md new file mode 100644 index 00000000..e6644061 --- /dev/null +++ b/documents/adr/0013-database-strategy.md @@ -0,0 +1,37 @@ +# 13. Database strategy + +Date: 2024-09-04 + +## Status + +Approved + +## Context + +During the prototyping and demo phase, the Form Platform used browser-local storage in lieu of a database. This allowed the team to limit development efforts to a simple static site, avoiding the cost of building a backend system. + +As we prepare to support our first government use case, we require a database to persist users, forms, form sessions, form submissions, and other future data. + +It is important that the database approach is clean and testable. Test strategies should include service-level integration tests and system integration tests, including end-to-end tests. The database should also be easy to mock, but fast integration tests should be preferred, when appropriate. + +The database should be commonly used and easy to host in many varied deployment environments. Libraries utilized should also be well-supported by an active community, and leverage the strengths of Typescript. + +## Decision + +We will use PostgreSQL in our production deployments. We will use [Testcontainers](https://testcontainers.com/) to unit-test database gateway logic against a PostgreSQL container. Integration testing will be handled with an in-memory SQLite database. + +[Knex.js](https://knexjs.org/) is the most widely-used node.js query builder, and has backend adapters for most common relational databases. We will utilize Knex.js for its migration support. Knex.js may also be used for queries, as appropriate. + +[Kysely](https://kysely.dev/) is a query builder that offers Typescript niceties that Knex.js lacks. Its usage numbers are growing rapidly, but the library's maturity, particularly with its migrations, is a bit behind Knex.js. Due to the developer experience gains of type-safety, we will use Kysely for most database queries. + +Abstract adapters to the database will hide technical details from consuming code and minimize setup/teardown boilerplate in tests. + +## Consequences + +The platform will target Postgres, a safe and featureful database, which we can deploy to a wide array of cloud environments. + +Confidence in the correctness of code will be enhanced with the use of integration testing and the avoidance of mocking. + +Helpers will be created to facilitate easy testing of database gateway functions against a Testcontainers-managed Postgres database. Additional helpers will be created to enable integration testing against a fast, in-memory SQLite database. + +The test strategy is intended to be a pragmatic mix between speed and simplicity, but the reliance on integration tests may eventually lead to a slow test suite. The team should keep an eye on this and continually reevaluate. diff --git a/documents/adr/0014-authentication.md b/documents/adr/0014-authentication.md new file mode 100644 index 00000000..737faa33 --- /dev/null +++ b/documents/adr/0014-authentication.md @@ -0,0 +1,25 @@ +# 14. Authentication + +Date: 2024-09-04 + +## Status + +Approved + +## Context + +The Form Platform requires a method of authenticating users. We are inclined to default to [Login.gov](https://login.gov/), a government-wide federated service hosted by [TTS](https://www.gsa.gov/about-us/organization/federal-acquisition-service/technology-transformation-services), unless circumstances prevent its usage. + +When using Login.gov, we need to choose which library and other integration details we will leverage. + +## Decision + +Initially, we will use the [Lucia Auth](https://lucia-auth.com/) library. Lucia is recommended in the [Astro documentation](https://docs.astro.build/en/guides/authentication/), and its companion library [Arctic](https://github.com/pilcrowonpaper/arctic) supports the PKCE method of OpenID Connect authentication supported by Login.gov. + +## Consequences + +Lucia and Arctic will provide us will a solid workable solution, and provides us with a structure we could incrementally replace if the need arises. + +Lucia manages sessions, but in the future we may find it preferable to manage them ourselves. + +Additionally, Arctic does not support JWT-based auth. We may want to consider node-openid-client, or an alternative, for a simpler approach. This would require our own session management. diff --git a/documents/adr/0015-rest-api.md b/documents/adr/0015-rest-api.md new file mode 100644 index 00000000..72b37f57 --- /dev/null +++ b/documents/adr/0015-rest-api.md @@ -0,0 +1,21 @@ +# 15. REST API approach + +Date: 2024-09-04 + +## Status + +Approved + +## Context + +During the prototyping and demo phase, the Form Platform used client-side services that persisted to browser local storage. As we introduce a backend to support agency users, we need to structure an API for the content authoring operations of the platform. + +## Decision + +The Form Platform will initially implement an HTTP API in the Astro server. The API will aim to be an idiomatic REST API. A client-side service that proxies requests via HTTP calls will be injected into the form manager implementation. + +For the short term, we will maintain the existing client-side local storage service implementation. This will allow us to continue to test the form platform in static site mode, without a backend, as well as provide an implementation for in-browser integration testing. This will be reevaluated as we mature the form builder portion of the codebase. + +## Consequences + +The project will have a seamless transition to a backend, without disrupting the existing behavior of the system. We will reevaluate API needs as the platform evolves.