From f40eb4e5e4c9164a496a351c99d5cdc04c4313a8 Mon Sep 17 00:00:00 2001 From: Emily Jablonski <65367387+emilyjablonski@users.noreply.github.com> Date: Thu, 24 Oct 2024 12:37:08 -0600 Subject: [PATCH] docs: update readmes (#4410) --- README.md | 90 +++++++++--------- api/.env.template | 2 +- api/README.md | 183 +++++++++++++++++++++---------------- shared-helpers/README.md | 14 +-- sites/partners/README.md | 32 +++---- sites/public/.env.template | 2 +- sites/public/README.md | 31 +++---- 7 files changed, 175 insertions(+), 179 deletions(-) diff --git a/README.md b/README.md index 0214fc6741..1470a5d278 100644 --- a/README.md +++ b/README.md @@ -1,96 +1,96 @@ -# Bloom Affordable Housing System +# Bloom Affordable Housing Platform -This is the repository for the Bloom affordable housing system. +Bloom is [Exygy](https://www.exygy.com/)’s affordable housing platform. Bloom's goal is to be a single entry point for affordable housing seekers and application management for developers. You can read more about the platform on [bloomhousing.com](https://bloomhousing.com/). -## System Overview +## Overview -Bloom consists of a client/server architecture using [Next.js](https://nextjs.org) (a React-based site framework) for the frontend applications and [NestJS](https://nestjs.com) for the backend API. +![TypeScript](https://img.shields.io/badge/typescript-%23007ACC.svg?style=for-the-badge&logo=typescript&logoColor=white) ![Next JS](https://img.shields.io/badge/Next-black?style=for-the-badge&logo=next.js&logoColor=white) ![NestJS](https://img.shields.io/badge/nestjs-%23E0234E.svg?style=for-the-badge&logo=nestjs&logoColor=white) ![Prisma](https://img.shields.io/badge/Prisma-3982CE?style=for-the-badge&logo=Prisma&logoColor=white) ![Postgres](https://img.shields.io/badge/postgres-%23316192.svg?style=for-the-badge&logo=postgresql&logoColor=white) ![SASS](https://img.shields.io/badge/SASS-hotpink.svg?style=for-the-badge&logo=SASS&logoColor=white) ![Jest](https://img.shields.io/badge/-jest-%23C21325?style=for-the-badge&logo=jest&logoColor=white) ![cypress](https://img.shields.io/badge/-cypress-%23E5E5E5?style=for-the-badge&logo=cypress&logoColor=058a5e) ![Testing-Library](https://img.shields.io/badge/-TestingLibrary-%23E33332?style=for-the-badge&logo=testing-library&logoColor=white) -The frontend apps can easily be deployed to any Jamstack-friendly web host such as [Netlify](https://www.netlify.com/) or Vercel. The frontend build process performs a static rendering of as much of the React page component trees as possible based on API data available at the time of the build. Additional real-time interactivity is made possible by React components at run-time. - -The backend can be simultaenously deployed to PaaS-style hosts such as Heroku. Its primary architectural dependency is a PostgreSQL database. +Bloom consists of a client/server architecture using [Next.js](https://nextjs.org) for the frontend applications and [NestJS](https://nestjs.com), [Prisma](https://www.prisma.io/), and [Postgres](https://www.postgresql.org/) on the backend. ### Structure -Bloom uses a monorepo-style repository containing multiple user-facing applications and backend services. The three main high-level packages are `api`, `sites`, and `shared-helpers`. Additionally, Bloom's UI leverages the in-house npm package `@bloom-housing/ui-components`. +Bloom uses a monorepo-style repository containing multiple user-facing applications and backend services. The three main high-level packages are `api`, `sites`, and `shared-helpers`. Additionally, Bloom's UI leverages the in-house packages `@bloom-housing/ui-seeds` and `@bloom-housing/ui-components`. -The `sites` package contains reference implementations for the two user-facing applications in the system: +The `sites` folder contains reference implementations for both the public and partner applications: --- -- `sites/public` is the applicant-facing site available to the general public. It provides the ability to browse available listings and to apply for listings either using the Common Application (which we build and maintain) or an external link to a third-party online or paper application. +- `sites/public` is the applicant-facing site available to the general public. It provides the ability to browse and apply for available listings either using the Common Application (which we build and maintain) or an external link to a third-party online or paper application. - Visit [sites/public/README](https://github.com/bloom-housing/bloom/blob/main/sites/public/README.md) for more details. - `sites/partners` is the site designed for housing developers, property managers, and city/county (jurisdiction) employees. For application management, it offers the ability to view, edit, and export applications for listings and other administrative tasks. For listing management, it offers the ability to create, edit, and publish listings. A login is required to use the Partners Portal. - Visit [sites/partners/README](https://github.com/bloom-housing/bloom/blob/main/sites/partners/README.md) for more details. -In some cases the sites diverge slightly to accomodate jurisdictional customizations. The [housingbayarea Bloom fork](https://github.com/housingbayarea/bloom) is a fork of Bloom core for Bay Area jurisdictions which is loosely customized for that location. In this fork, our jurisdictions are each a separate branch. - --- -- `api` is the container for the key backend services (e.g. listings, applications, users). Information is stored in a Postgres database and served over HTTPS to the front-end (either at build time for things that can be server-rendered, or at run time). Most services are part of a NestJS application which allows for consolidated operation in one runtime environment. Services expose a REST API, and aren't expected to have any UI other than for debugging. +- `api` is the container for the key backend services (e.g. listings, applications, users). Information is stored in a Postgres database and served over HTTPS to the front-end (either at build time for things that can be server-rendered, or at run time). Services expose a REST API. - Visit [api/README](https://github.com/bloom-housing/bloom/blob/main/api/README.md) for more details. --- -- `shared-helpers` contains types and functions intended for shared use between the public and partners sites. +- `shared-helpers` contains types, functions, and components that are shared between the public and partners sites. - Visit [shared-helpers/README](https://github.com/bloom-housing/bloom/blob/main/shared-helpers/README.md) for more details. --- -- `@bloom-housing/ui-components` is our component library based on our internal design system. It is comprised of React components that we consume as an npm package and also build to be configurable for outside consumers. We use [Storybook](https://storybook.js.org/), an environment to provide documentation and display iterations. Our published storybook can be found[here](https://storybook.bloom.exygy.dev/) and for further details visit the [ui-components repository](https://github.com/bloom-housing/ui-components). +- `@bloom-housing/ui-seeds` (Seeds) is our component library based on our internal design system. It is comprised of React components and design system tokens. The published ui-seeds [Storybook](https://storybook.js.org/) can be found [here](https://storybook-ui-seeds.netlify.app/?path=/story/tokens-introduction--page). For further details visit the [ui-seeds repository](https://github.com/bloom-housing/ui-seeds) and our [external design documentation](https://zeroheight.com/5e69dd4e1/p/938cb5-seeds-design-system) on Zeroheight. -## Getting Started for Developers +- `@bloom-housing/ui-components` (UIC) is also an internal component library - but it is being slowly replaced with `ui-seeds` which is the next iteration. The published ui-components storybook can be found [here](https://storybook.bloom.exygy.dev/). For further details visit the [ui-components repository](https://github.com/bloom-housing/ui-components). -If this is your first time working with Bloom, please be sure to check out the `sites/public`, `sites/partners` and `api` README files for important configuration information specific to those pieces. +## Getting started for developers -## General Local Setup +If this is your first time working with Bloom, please be sure to check out the `sites/public`, `sites/partners`, and `api` README files for important and specific configuration information. After doing so, you can proceed with the below setup instructions. + +## Starting locally ### Dependencies -``` -yarn install -``` +Run `yarn install` at root and from within the api directory. + +If you don't have yarn installed, you can install homebrew with [these instructions](https://brew.sh/) and then do so with `brew install yarn`. ### Local environment variables -Configuration of each app and service is read from environment variables. There is an `.env.template` file in each app or service directory that must be copied to `.env` (or equivalent). Some keys are purposefully missing for security concerns and are internally available. +Configuration of each app and service is read from environment variables. There is an `.env.template` file in `sites/public`, `sites/partners`, and `api` that must be copied to an `.env` at the same level. Some keys are secret and are internally available. The template files include default values and descriptions of each variable. -### Running a local test server +### VSCode Extensions + +If you use VSCode, these are some recommended extensions. + +With the [Prettier plugin](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) installed, ⌘⇧P Open User Settings, search for and enable `Format on Save`, and then ⌘⇧P Reload Window. When you save a file locally, it should automatically format according to our configuration. -``` -yarn dev:all -``` +The [Postgres explorer plugin](https://marketplace.visualstudio.com/items?itemName=ckolkman.vscode-postgres) will let you inspect your local database (more setup instructions in the [api README](https://github.com/bloom-housing/bloom/blob/main/api/README.md)). -This runs 3 processes for both apps and the backend services on 3 different ports: +The [Code Spell Checker plugin](https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker) will flag spelling errors. + +### Running a local test server + +Running `yarn dev:all` from root runs 3 processes for both apps and the backend services on 3 different ports: - 3000 for the public app - 3001 for the partners app -- 3100 for api +- 3100 for the api -There is a chance that this won't work on your machine. If that is the case you can run each individually on separate terminals with the following command in each directory. +You can also run each process individually from separate terminals with the following command in each directory: `yarn dev`. -``` -yarn dev -``` +### Bloom UIC development -### Bloom's UI-Component Development +Because Bloom's ui-components package is a separate open source repository, developing in Bloom while concurrently iterating in ui-components requires linking the folders with the following steps: -- Because Bloom's ui-components package is a separate open source repository, developing within both repos locally requires linking the folders with the following steps: - -### Directory Setup +### Directory setup 1. Clone both Bloom and the [ui-components repository](https://github.com/bloom-housing/ui-components) on the same directory level. -### Symlinking UI-C +### Symlinking UIC 1. In the Bloom directory, run `yarn link:uic`. 2. Open the next.config.js file in the public and partner's directory. 3. Uncomment the experimental property at the bottom of each file. 4. Follow the directions above to run Bloom locally. - These steps allow for two development patterns. You can edit ui-components within the node_modules of Bloom and the changes will be reflected in your local version of ui-components. Alternatively, you can edit the local version of ui-components and the changes will be reflected in the node_modules in Bloom. Both patterns will display up-to-date changes on the local server. + These steps allow you to edit your local version of ui-components and the changes will be reflected in the node_modules in Bloom. -### Unlinking UI-C +### Unlinking UIC 1. In the Bloom directory, run `yarn unlink:uic`. 2. Open the next.config.js file in the public and partner's directory. @@ -104,22 +104,18 @@ Contributions to the core Bloom applications and services are welcomed. To help ### Issue tracking -Our development tasks are managed through GitHub issues and development in the vast majority of cases should be tied to an issue. Please feel free to submit issues even if you don't plan on implementing it yourself. Before creating an issue, check first to see if one already exists. When creating an issue, give it a descriptive title and include screenshots if relevant. Please don't start work on an issue without checking in with the Bloom team first as it may already be in development! You can tag us (@seanmalbert, @emilyjablonski, @yazeedloonat) to get started on an issue or ask any questions. +Our development tasks are managed through GitHub issues and development in the vast majority of cases should be tied to an issue. Please feel free to submit issues even if you don't plan on implementing them yourself. Before creating an issue, check first to see if one already exists. When creating an issue, give it a descriptive title and include screenshots if relevant. Please don't start work on an issue without checking in with the Bloom team first as it may already be in development! You can tag us (@ludtkemorgan, @emilyjablonski, @yazeedloonat) to get started on an issue or ask any questions. ### Committing We are also using [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/), a specification for commit messages that indicates what type and level of change each commit is. -On commit, two steps automatically run: (1) linting and (2) a verification of the conventional commit standard. You can either, instead of running `git commit`, globally install commitizen (`npm install -g commitizen`) and then commit with `git cz` which will run a commit message CLI. The CLI asks a series of questions about your changeset and builds the commit message for you in the conventional commit format. You can alternatively run `git commit` with your own message if you are confident it follows the conventional standard, and it will fail if it does not. - -On every merge to `main`, our Netlify and Heroku environment automatically deploys. +On commit, two steps automatically run: (1) linting and (2) a verification of the conventional commit standard. You can either, instead of running `git commit`, globally install commitizen (`npm install -g commitizen`) and then commit with `git cz` which will run a commit message CLI (the CLI asks a series of questions about your changeset and builds the commit message for you in the conventional commit format), or alternatively run `git commit` with your own message if you are confident it follows the conventional standard, and the linter will fail if it does not. ### Pull Requests -Pull requests are opened to the main branch. When opening a pull request please fill out the entire pull request template which includes tagging the issue your PR is related to, a description of your PR, indicating the type of change, including details for the reviewer about how to test your PR, and a testing checklist. Additionally, officially link the issue to the PR using GitHub's linking UI. - -When your PR is ready for review, add the `needs review(s)` label to help surface it to our internal team. You can assign people as reviewers to surface the work further. If you put up a PR that is not yet ready for eyes, add the `wip` label. +Pull requests are opened to the main branch. When opening a pull request please fill out the entire pull request template which includes tagging the issue your PR is related to, a description of your PR, including details for the reviewer about how to test your PR, and a testing checklist. -Once the PR has been approved, you either (1) squash and merge the commits if your changes are just in one package, or (2) rebase and merge your commits if your commits are cleanly separated across multiple packages to allow the versions to propagate appropriately. +When your PR is ready for review, add the `needs review(s)` label to surface it to our internal team. If you put up a PR that is not yet ready for eyes, add the `wip` label. As a reviewer on a PR, try not to leave only comments, but a clear next step action. If the PR requires further discussion or changes, mark it with Requested Changes. If a PR looks good to you (or even if there are small changes requested that won't require an additional review), please mark it with Approved and comment on the last few changes needed. This helps other reviewers better understand the state of PRs at the list view and prevents an additional unnecessary review cycle. diff --git a/api/.env.template b/api/.env.template index e6517a0dff..8120547feb 100644 --- a/api/.env.template +++ b/api/.env.template @@ -11,7 +11,7 @@ GOOGLE_API_KEY= # cloudinary secret CLOUDINARY_SECRET= # app secret -APP_SECRET= +APP_SECRET="some-long-secret-key" # url for the proxy PROXY_URL= # the node env the app should be running as diff --git a/api/README.md b/api/README.md index 459a60f5cd..07d90e591f 100644 --- a/api/README.md +++ b/api/README.md @@ -1,36 +1,59 @@ -# Setup +# Bloom Backend + +![TypeScript](https://img.shields.io/badge/typescript-%23007ACC.svg?style=for-the-badge&logo=typescript&logoColor=white) ![NestJS](https://img.shields.io/badge/nestjs-%23E0234E.svg?style=for-the-badge&logo=nestjs&logoColor=white) ![Prisma](https://img.shields.io/badge/Prisma-3982CE?style=for-the-badge&logo=Prisma&logoColor=white) ![Postgres](https://img.shields.io/badge/postgres-%23316192.svg?style=for-the-badge&logo=postgresql&logoColor=white) + +## Overview + +This is the backend services container. Data is stored in a [Postgres](https://www.postgresql.org/) database and served over HTTPS to the frontend (either at build time for things that can be server-rendered, otherwise at run time). Most services are part of a [NestJS](https://nestjs.com/) application. [Prisma](https://www.prisma.io/) is the application's ORM. [OpenAPI Swagger](https://swagger.io/tools/swagger-ui/) documentation is automatically generated by the server at http://localhost:3100/api/ in local development environments, or in any other environment by adding `/api` to the api URL. This can be helpful to get a more visual overview of all available endpoints. + ## Installation -Make sure the .env file's db placement is what works for your set up, Then run the following: -```bash -$ yarn install -$ yarn prisma generate -$ yarn build -$ yarn db:setup:staging -``` +The following commands are for macOS / Linux, but you can find equivalent instructions for Windows machines online. + +### Environment Variables + +Configuration of the backend is pulled from environment variables defined in an `.env` file in the api directory. Copy the `.env.template` file in api into a `.env` file. Some keys are secret and are internally available. The template file includes default values and descriptions of each variable. + +### Dependencies + +If you don't have yarn installed, you can install homebrew with [these instructions](https://brew.sh/) and then do so with `brew install yarn`. + +#### Installing Node + +We are currently using Node version 18. You can install Node using homebrew with the following command: `brew install node@18`. + +If you have multiple versions of Node installed, you can use [nvm](https://github.com/nvm-sh/nvm) (node version manager), or other similar tools, to switch between them. Ensure you're on the right version by checking with `node -v`. + +If along the way you get `env: node: No such file or directory`, inspect the output from installing node for instructions on if you might need to add node to certain terminal paths. + +#### Installing Postgresql + +You can install Postgres using homebrew with the following command: `brew install postgresql@15`. You then start it with `brew services start postgresql@15`. + +#### Project dependencies + +Install project dependencies with `yarn install` from within the api directory. + +## Starting locally -These commands are also encapsulated in: -```bash -$ yarn setup -``` +The following command will generate and build the Prisma schema and setup the database with seeded data: `yarn setup:dev`. +If you would prefer to have it setup with more realistic data you can instead run: `yarn setup`. -If you would prefer to have it setup with more realistic data you can run `yarn db:setup:staging` instead of `yarn db:setup`. +If this is your first time running this command and you see `psql: error: FATAL: database "" does not exist` you may need to run `createdb ` first. -## Starting the application -In order to run the application you can run : -```bash -$ yarn start -``` +You will also need to update the `DATABASE_URL` environment variable to include your username. -or to run in watch mode run: -```bash -$ yarn dev -``` +If you're using VSCode, you can install [the Postgres explorer extension](https://marketplace.visualstudio.com/items?itemName=ckolkman.vscode-postgres) to inspect your local database. When you click on the + to create a new connection, you can use the following inputs to each question to create a connection to the newly created database: `localhost`, ``, hit enter for password, `5432`, standard, `bloom_prisma`, and a descriptive name like `local-bloom`. Once the connection is established, you can inspect the database. -# Modifying the Schema +To start the application run: `yarn dev`. + +## Modifying the Schema + +If you're using VSCode, you can install the [Prisma extension](https://marketplace.visualstudio.com/items?itemName=Prisma.prisma) to add syntax highlighting and formatting to Prisma schema files. + +To modify the Prisma schema you will need to work with the schema.prisma file. This file controls the following: -We use [Prisma](https://www.prisma.io/) as the ORM. To modify the schema you will need to work with the schema.prisma file. This file controls the following:
  1. The Structure of each model (entity if you are more familiar with TypeORM)
  2. The Relationships between models
  3. @@ -39,131 +62,129 @@ We use [Prisma](https://www.prisma.io/) as the ORM. To modify the schema you wil
You will need to: + 1. Add the field in the DTO 2. Run `yarn generate:client` to add the type to the swagger file 3. Manually add the field to `schema.prisma` 4. Run `yarn prisma migrate dev --name ` to create the migration file +### Conventions -## Conventions We use the following conventions: +
    -
  • model and enum names are capitalized camelcased (e.g. HelloWorld)
  • -
  • model and enum names are @@map()ed to lowercase snakecased (e.g. hello_world)
  • -
  • a model's fields are lowercase camelcased (e.g. helloWorld)
  • -
  • a model's fields are @map()ed to lowercase snackcased (e.g. hello_world)
  • +
  • model and enum names are capitalized camel case (e.g. HelloWorld)
  • +
  • model and enum names are @@map()ed to lowercase snake case (e.g. hello_world)
  • +
  • a model's fields are lowercase camel case (e.g. helloWorld)
  • +
  • a model's fields are @map()ed to lowercase snake case (e.g. hello_world)
This is to make the api easier to work with, and to respect postgres's name space conventions.

-# Controllers -Controllers are where backend endpoints are housed. They follow the [Nestjs standards](https://docs.nestjs.com/controllers) +## Controllers -They are housed under `/src/controllers`. +Backend endpoints live in controllers under `src/controllers`. They follow the [NestJs standards](https://docs.nestjs.com/controllers) -## Conventions -Controllers are given the extension `.contoller.ts` and the model name (listing, application, etc) is singular. So for example `listing.controller.ts`. +### Conventions -The exported class should be in capitalized camelcase (e.g. `ListingController`). +Controllers are given the extension `.controller.ts` and the model name (listing, application, etc) is singular. So for example `listing.controller.ts`. -# DTOs -Data Transfer Objects. These are how we flag what fields endpoints will take in, and what the form of the response from the backend will be. +The exported class should be in capitalized camel case (e.g. `ListingController`). + +## DTOs + +DTOs (Data Transfer Objects) are how we flag what fields endpoints will take in, and what the form of the response from the backend will be. We use the packages [class-transformer](https://www.npmjs.com/package/class-transformer) & [class-validator](https://www.npmjs.com/package/class-validator) for this. -They are housed under `src/dtos`, and are broken up by what model they are related too. There are also shared DTOs which are housed under the shared sub-directory. +DTOs are stored under `src/dtos`, and are broken up by what model they are related to. There are also shared DTOs which are stored under the shared sub-directory. -## Conventions -DTOs are given the extension `.dto.ts` and the file name is lowercase kebabcase. +### Conventions -So for example `listings-filter-params.dto.ts`. +DTOs are given the extension `.dto.ts` and the file name is lowercase kebab case (e.g. `listings-filter-params.dto.ts`). -The exported class should be in capitalized camelcase (e.g. `ListingFilterParams`) and does not include the DTO as a suffix. +The exported class should be in capitalized camel case (e.g. `ListingFilterParams`) and does not include the DTO as a suffix. -# Enums -These are enums used by NestJs primarily for either taking in a request or sending out a response. Database enums (enums from Prisma) are part of the primsa schema and are not housed here. +## Enums -They are housed under `src/enums` and the file name is lowercase kebabcase and end with `-enum.ts`. +These are enums used by NestJs primarily for either taking in a request or sending out a response. Database enums (enums from Prisma) are part of the Prisma schema and are not housed here. + +They are housed under `src/enums` and the file name is lowercase kebab case and end with `-enum.ts`. So for example `filter-key-enum.ts`. -## Conventions -The exported enum should be in capitalized camelcase (e.g. `ListingFilterKeys`). +### Conventions + +The exported enum should be in capitalized camel case (e.g. `ListingFilterKeys`). + +## Modules -# Modules Modules connect the controllers to services and follow [NestJS standards](https://docs.nestjs.com/modules). -## Conventions +### Conventions + Modules are housed under `src/modules` and are given the extension `.module.ts`. The model name (listing, application, etc) is singular. So for example `listing.module.ts`. -The exported class should be in capitalized camelcase (e.g. `ListingModule`). +The exported class should be in capitalized camel case (e.g. `ListingModule`). -# Services -Services are where business logic is performed as well as interfacing with the database. +## Services + +Services are where business logic is performed as well as interfacing with the database. Controllers should be calling functions in services in order to do their work. The follow the [NestJS standards](https://docs.nestjs.com/providers). -## Conventions +### Conventions + Services are housed under `src/services` and are given the extension `.services.ts`. The model name (listing, application, etc) is singular. So for example `listing.service.ts`. -The exported class should be in capitalized camelcase (e.g. `ListingService`). +The exported class should be in capitalized camel case (e.g. `ListingService`). + +## Guards & Passport Strategies -# Guards & Passport Strategies We currently use guards for 2 purposes. Passport guards and Permissioning guards. Passport guards (jwt.guard.ts, mfa.guard.ts, and optional.guard.ts) verify that the request is from a legitimate user. JwtAuthGuard does this by verifying the incoming jwt token (off the request's cookies) matches a user. MfaAuthGuard does this by verifying the incoming login information (email, password, mfaCode) matches a user's information. OptionalAuthGuard is used to allow requests from users not logged in through. It will still verify the user through the JwtAuthGuard if a user was logged in. -Passport guards are paired with a passport strategy (jwt.strategy.ts, and mfa.strategy.ts), this is where the code to actually verify the requester lives. +Passport guards are paired with a passport strategy (jwt.strategy.ts, and mfa.strategy.ts), this is where the code to actually verify the requester lives. -Hopefully that makes sense, if not think of guards as customs agents, and the passport strategy is what the guards look for in a request to allow entry to a requester. Allowing them access the endpoint that the guard protects. +Hopefully that makes sense, if not think of guards as customs agents, and the passport strategy is what the guards look for in a request to allow entry to a requester. Allowing them access the endpoint that the guard protects. [NestJS passport docs](https://docs.nestjs.com/recipes/passport) [NestJS guards docs](https://docs.nestjs.com/guards) -Permissioning guards (permission.guard.ts, and user-profile-permission-guard.ts) verify that the requester has access to the resource and action they are trying to perform. For example a user that is not logged in (anonymous user) can submit applications, but cannot create listings. We leverage [Casbin](https://www.npmjs.com/package/casbin) to do user verification. +Permissioning guards (permission.guard.ts, and user-profile-permission-guard.ts) verify that the requester has access to the resource and action they are trying to perform. For example a user that is not logged in (anonymous user) can submit applications, but cannot create listings. We leverage [Casbin](https://www.npmjs.com/package/casbin) to do user verification. +## Testing -# Testing There are 2 different kinds of tests that the backend supports: Integration tests and Unit tests. -Integration Tests are tests that DO interface with the database, reading/writing/updating/deleting data from that database. +Integration Tests are tests that DO interface with the database, reading/writing/updating/deleting data from that database. Unit Tests are tests that MOCK interaction with the database, or test functionality directly that does not interact with the database. +### Integration Testing -## Integration Testing Integration Tests are housed under `test/integration`, and files are given the extension `.e2e-spec.ts`. These tests will generally test going through the controller's endpoints and will mock as little as possible. When testing the database should start off as empty and should be reset to empty once tests are completed (i.e. data is cleaned up). -## How to run integration tests -Running the following will run all integration tests: -```bash -$ yarn test:e2e -``` +#### How to run integration tests + +Running the following will run all integration tests `yarn test:e2e`. + +### Unit Testing -## Unit Testing Unit Tests are housed under `test/unit`, and files are given the extension `.spec.ts`. These tests will generally test the functions of a service, or helper functions. These tests will mock Prisma and therefore will not interface directly with the database. This allows for verifying the correct business logic is performed without having to set up the database. -## How to run unit tests -Running the following will run all unit tests: -```bash -$ yarn test -``` - +#### How to run unit tests -## Testing with code coverage -We have set up both code coverage and code coverage benchmarks. These benchmarks must be met for your PR to pass CI checks. Test coverage is calculated against both the integration and unit test runs. You can run test coverage with the followig: -```bash -$ yarn test:cov -``` +Running the following will run all unit tests: `yarn test` +### Testing with code coverage -# Considerations For Detroit -As it stands right now `core` uses the AmiChart items column and `detroit` uses the AmiChartItem table. -As we move through converting detroit over to prisma we will unify those and choose one of the two approaches. \ No newline at end of file +We have set up both code coverage and code coverage benchmarks. These benchmarks must be met for your PR to pass CI checks. Test coverage is calculated against both the integration and unit test runs. You can run test coverage with the following: `yarn test:cov` diff --git a/shared-helpers/README.md b/shared-helpers/README.md index 9051ad9192..c31989a3ec 100644 --- a/shared-helpers/README.md +++ b/shared-helpers/README.md @@ -1,15 +1,9 @@ # Bloom Shared Helpers -This package is the home of types and functions intended for shared use between the Next.js sites within the Bloom monorepo. In certain instances there is also some commonality between the frontend plus the backend (not implemented currently). +![TypeScript](https://img.shields.io/badge/typescript-%23007ACC.svg?style=for-the-badge&logo=typescript&logoColor=white) ![React](https://img.shields.io/badge/react-%2320232a.svg?style=for-the-badge&logo=react&logoColor=%2361DAFB) ![SASS](https://img.shields.io/badge/SASS-hotpink.svg?style=for-the-badge&logo=SASS&logoColor=white) ![Testing-Library](https://img.shields.io/badge/-TestingLibrary-%23E33332?style=for-the-badge&logo=testing-library&logoColor=white) ![Jest](https://img.shields.io/badge/-jest-%23C21325?style=for-the-badge&logo=jest&logoColor=white) -## CLI +This package includes types, functions, and components shared between the public and partners sites within Bloom. -To run the test suite which is built with Jest run: +## Tests -``` -yarn test - -# or - -yarn test:coverage # generates local coverage reports, useful as you are writing tests -``` +You can run the unit test suite with `yarn test`, or with `yarn test:coverage` to generate coverage reports. diff --git a/sites/partners/README.md b/sites/partners/README.md index 881e1ede46..28cc3eda06 100644 --- a/sites/partners/README.md +++ b/sites/partners/README.md @@ -1,31 +1,23 @@ # Bloom Partners Application -This is the reference implementation of our partners web app, providing the UI for all of the administrative functions for affordable housing partners using Bloom-based systems (managing applications, and soon publishing listings). Partners include housing developers, property managers, cities, and counties. +![TypeScript](https://img.shields.io/badge/typescript-%23007ACC.svg?style=for-the-badge&logo=typescript&logoColor=white) ![Next JS](https://img.shields.io/badge/Next-black?style=for-the-badge&logo=next.js&logoColor=white) ![SASS](https://img.shields.io/badge/SASS-hotpink.svg?style=for-the-badge&logo=SASS&logoColor=white) ![cypress](https://img.shields.io/badge/-cypress-%23E5E5E5?style=for-the-badge&logo=cypress&logoColor=058a5e) ![Testing-Library](https://img.shields.io/badge/-TestingLibrary-%23E33332?style=for-the-badge&logo=testing-library&logoColor=white) ![Jest](https://img.shields.io/badge/-jest-%23C21325?style=for-the-badge&logo=jest&logoColor=white) + +This is the reference implementation of our partners web app, providing the UI for all of the administrative functions for affordable housing partners including managing applications and listings. Partners include housing developers, property managers, cities, and counties. You can read more about the product at [bloomhousing.com](https://bloomhousing.com/). ## Getting Started -All from within `sites/partners`: +The following commands are for macOS / Linux, but you can find equivalent instructions for Windows machines online. -- `yarn install` to install dependencies -- Copy the `.env.template` to `.env` and edit variables appropriate to your local environment -- `yarn dev:all` will start up the backend at port 3100 and the partners app at port 3001 +If you don't have yarn installed, you can install homebrew with [these instructions](https://brew.sh/) and then do so with `brew install yarn`. -## Tests +- `yarn install` at root to install dependencies +- From within `sites/partners` copy the `.env.template` to `.env` and edit variables appropriate to your local environment - some keys are secret and are internally available - the template file includes default values and descriptions of each variable +- `yarn dev:all` at root will start up the backend at port 3100 and the partners app at port 3001 -For our partnres application, our tests currently consistent of a Cypress integration test suite. We are looking to add React Testing Library unit tests soon. +## Tests -To run the Cypress suite, with the application running, run `yarn test` from within `sites/partners` and when the test runner in a Chrome browser opens, click on whichever suite you want to run. +For our partners application, our tests currently consist of both a Cypress end to end suite and a jest unit/integration suite. -## Environment Variables +To run the Cypress suite, with the application already running, run `yarn test` from within `sites/partners`. -| Name | Description | Default | Type | -| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------- | --------------------- | ------- | -| BACKEND_API_BASE | URL pointing to a working NestJS bloom server (no trailing slash) | http://localhost:3100 | string | -| NEXTJS_PORT | Defines port number the server will listen to for incoming connections | 3001 | number | -| LISTINGS_QUERY | Value specifying what path to use to fetch listings at build time for static serving (?) | /listings | string | -| SHOW_DUPLICATES | Toggles the duplicate application feature on/off | false | boolean | -| SHOW_LM_LINKS | Toggles the listings management button on/off | true | boolean | -| MAPBOX_TOKEN | Access token used for interacting with maps. See more documentation [here](https://docs.mapbox.com/help/getting-started/access-tokens/) | Available internally | string | -| CLOUDINARY_CLOUD_NAME | Used for features that upload files/images | exygy | string | -| CLOUDINARY_KEY | Used for features that upload files/images, access token | Available internally | string | -| CLOUDINARY_SIGNED_PRESET | Used for features that upload files/images, access token | Available internally | string | +To run the unit/integration suite, run `yarn test:unit` from within `sites/partners`, or `yarn test:unit:coverage` to run with coverage reports. diff --git a/sites/public/.env.template b/sites/public/.env.template index aabc5984d6..2be26a494b 100644 --- a/sites/public/.env.template +++ b/sites/public/.env.template @@ -8,7 +8,7 @@ NEXTJS_PORT=3000 MAPBOX_TOKEN= LANGUAGES=en,es,zh,vi,tl IDLE_TIMEOUT=5 -JURISDICTION_NAME=Alameda +JURISDICTION_NAME=Bloomington CLOUDINARY_CLOUD_NAME=exygy # next js cache revalidate CACHE_REVALIDATE=60 diff --git a/sites/public/README.md b/sites/public/README.md index 5459815d0e..09c277666e 100644 --- a/sites/public/README.md +++ b/sites/public/README.md @@ -1,30 +1,23 @@ # Bloom Public Application -This is the reference implementation of our public-facing web app. It displays listings and allows users to apply for those listings. Users are also able to create accounts with which they can view the applications they have submitted. +![TypeScript](https://img.shields.io/badge/typescript-%23007ACC.svg?style=for-the-badge&logo=typescript&logoColor=white) ![Next JS](https://img.shields.io/badge/Next-black?style=for-the-badge&logo=next.js&logoColor=white) ![SASS](https://img.shields.io/badge/SASS-hotpink.svg?style=for-the-badge&logo=SASS&logoColor=white) ![cypress](https://img.shields.io/badge/-cypress-%23E5E5E5?style=for-the-badge&logo=cypress&logoColor=058a5e) ![Testing-Library](https://img.shields.io/badge/-TestingLibrary-%23E33332?style=for-the-badge&logo=testing-library&logoColor=white) ![Jest](https://img.shields.io/badge/-jest-%23C21325?style=for-the-badge&logo=jest&logoColor=white) + +This is the reference implementation of our public-facing portal. It displays listings and allows users to apply for those listings. Users are also able to create accounts they can use to view submitted applications. You can read more about the product at [bloomhousing.com](https://bloomhousing.com/). ## Getting Started -All from within `sites/public`: +The following commands are for macOS / Linux, but you can find equivalent instructions for Windows machines online. -- `yarn install`to install dependencies -- Copy the `.env.template` to `.env` and edit variables appropriate to your local environment -- `yarn dev:all` will start up the backend at port 3100 and the public app at port 3000 +If you don't have yarn installed, you can install homebrew with [these instructions](https://brew.sh/) and then do so with `brew install yarn`. -## Tests +- `yarn install` at root to install dependencies +- From within `sites/public` copy the `.env.template` to `.env` and edit variables appropriate to your local environment - some keys are secret and are internally available - the template file includes default values and descriptions of each variable +- `yarn dev:all` at root will start up the backend at port 3100 and the public app at port 3000 -For our public application, our tests currently consistent of a Cypress integration test suite. We are looking to add React Testing Library unit tests soon. +## Tests -To run the Cypress suite, with the application running, run `yarn test` from within `sites/public` and when the test runner in a Chrome browser opens, click on whichever suite you want to run. +For our public application, our tests currently consist of both a Cypress end to end suite and a jest unit/integration suite. -## Environment Variables +To run the Cypress suite, with the application already running, run `yarn test` from within `sites/public`. -| Name | Description | Default | Type | -| ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | -------------------------------------- | -| BACKEND_API_BASE | URL pointing to a working NestJS bloom server (no trailing slash) | http://localhost:3100 | string | -| LISTINGS_QUERY | Value specifying what path to use to fetch listings at build time for static serving | /listings | string | -| HOUSING_COUNSELOR_SERVICE_URL | If this is set, we show a link to this URL in the site header labelled "Get Assistance" | https://housing.sfgov.org/assets/housing_counselors-7b0f260dac22dfa20871edd36135b62f1a25a9dad78faf2cf8e8e2514b80cf61.json | string | -| NEXTJS_PORT | Defines port number the server will listen to for incoming connections | 3000 | number | -| MAPBOX_TOKEN | Mapbox access token used for interacting with maps. See more documentation [here](https://docs.mapbox.com/help/getting-started/access-tokens/) | Available internally | string | -| LANGUAGES | Controls what languages Next will try to render on the page | en,es,zh,vi | string | | number | -| JURISDICTION_NAME | Defines an identifier sent along with XHR requests for the backend to identify the current jurisdiction | Alameda | "Alameda" \| "San Jose" \| "San Mateo" | -| GTM_KEY | Refer to [analytics docs](https://github.com/bloom-housing/bloom/blob/master/docs/Analytics.md) | GTM-KF22FJP | string | +To run the unit/integration suite, run `yarn test:unit` from within `sites/public`, or `yarn test:unit:coverage` to run with coverage reports.