Skip to content

Repository files navigation

Tenant Access

A tenant access application for the New Jersey Innovation Authority. This application provides secure access management and interfaces for tenants.

Table of Contents

  1. Architecture
  2. Installation
  3. Usage
  4. Testing
  5. Code Quality
  6. License
  7. Disclaimer

Architecture

This is a modern React application built with Vite and TypeScript, organized as an npm workspace monorepo. The project emphasizes type safety, testing, and code quality through automated tooling.

Built With

Project Structure

tenant-access/
├── app/              # Frontend application workspace (React + Vite)
│   ├── src/          # Application source code
│   ├── public/       # Static assets
│   └── package.json  # App-specific dependencies
├── api/              # Backend workspace (AWS Lambda, TypeScript)
│   ├── src/          # Lambda handler source code
│   └── package.json  # API-specific dependencies
├── .github/          # GitHub workflows and templates
├── .husky/           # Git hooks
└── package.json      # Root workspace configuration

The api workspace is a minimal skeleton for the planned backend: a Lambda that communicates with a PostgreSQL database. It is configured for a Node runtime (its own tsconfig.json, separate from the frontend) with a placeholder handler. Build tooling, database client, and deployment are not yet chosen. Build/typecheck it with npm run build:api.

Installation

Prerequisites

  • Node.js (version specified in .nvmrc)
  • npm (comes with Node.js)

Setup

# Clone this repository
git clone https://github.com/newjersey/tenant-access

# Go into the repository
cd tenant-access

# Install dependencies
npm install

Adding Dependencies

This is an npm workspace monorepo: the root package.json owns the workspace configuration and the single package-lock.json, and dependencies are hoisted to the root node_modules. Always install from the repository root, targeting the app workspace:

# Runtime dependency for the app
npm install <package> --workspace=app

# Dev-only dependency for the app
npm install --save-dev <package> --workspace=app

Commit the updated app/package.json and the root package-lock.json together in the same change. CI runs npm ci, which installs strictly from the committed lockfile and fails if it is out of sync with package.json.

Infrastructure

This project uses the AWS CDK to deploy its infrastructure. To make updates, edit api/infrastructure/lib/tenant-access-stack.ts and then run npx cdk deploy with the proper AWS credentials in your environment variables.

Database Migrations

Create Migration File

# Create a new migration file with the date prefix
bash api/scripts/create_migration.sh <description>

# Example:
# bash api/scripts/create_migration.sh create_listings_table

# This creates the file:
# api/migrations/20260804110544_create_listings_table.sql

# Then edit your new migration file with SQL

Execute Migration

  1. The Migration Lambda in the tenant-access-stack.ts CDK config file is bundled with the whole api/migrations directory. Even thought the Lambda's code itself will rarely change, we need to do a CDK deployment to include any new migration files.

  2. Run npx cdk deploy to package the Lambda with the updated directory of migrations.

  3. Note the MigrationLambdaName in the output of npx cdk deploy. For example, TenantAccessStack.MigrationLambdaName = TenantAccessStack-MigrationFunction1060F2E0-DfbZthsVWubo

  4. Run the lambda with its name and the filename for the new migration.

aws lambda invoke \
    --function-name INSERT_LAMBDA_NAME \
    --cli-binary-format raw-in-base64-out \
    --payload '{"migrationFile":"INSERT_SQL_FILENAME"}' \
    /tmp/out.json && cat /tmp/out.json

# For example:

aws lambda invoke \
    --function-name TenantAccessStack-MigrationFunction1060F2E0-DfbZthsVWubo \
    --cli-binary-format raw-in-base64-out \
    --payload '{"migrationFile":"20260804110544_create_listings_table.sql"}' \
    /tmp/out.json && cat /tmp/out.json

If you see a happy JSON like {"statusCode":200,"body":"{\"success\":true,\"migration\":\"20260804110544_create_listings_table.sql\",\"message\":\"Migration completed successfully\"}"}, it was a success. Otherwise, you can debug using CloudWatch.

Usage

Development

Start the development server with hot module replacement:

npm run dev

The application will be available at http://localhost:5173

Build

Create a production build:

npm run build

Preview

Preview the production build locally:

npm run preview

Testing

Run Tests

# Run tests in watch mode
npm test

# Run tests with UI
npm run test:ui

# Run tests with coverage report
npm run test:coverage

Code Quality

Linting and Formatting

# Check formatting
npm run format:check

# Fix formatting issues
npm run format

# Run linter
npm run lint

# Fix linting issues
npm run lint:fix

# Run both checks and fixes
npm run check:fix

Git hooks are configured via Husky to automatically run code quality checks on commit.

Development Principles

  • Test-driven development (TDD)
  • YAGNI - build only what's needed now
  • Accessibility (WCAG 2.2 AA compliance)
  • Simple, maintainable solutions over clever complexity

License

This project is licensed under the MIT license. For more information, see LICENSE.

Disclaimer

This project utilizes certain tools and technologies for development purposes. The inclusion of these tools does not imply endorsement or recommendation. Users are encouraged to evaluate the suitability of these tools for their own use.

Used by

Contributors

Languages