mirror of
https://github.com/Hestia-Homes/assessment-model.git
synced 2026-07-27 22:45:03 +00:00
devcontainer.json's forwardPorts is a VS Code feature; the devcontainer CLI (which devcontainer.sh drives) doesn't implement it. Compose only published 3000, so a container started via `./devcontainer.sh up|rebuild` left the impeccable live helper on 8400 unreachable from the host — and the failure is silent: the page loads, the injected script 404s, the element picker just never appears. Publish 8400:8400 explicitly. The mapping is fixed rather than dynamic because the injected script hard-codes http://localhost:8400, which also means only one container at a time can run live mode. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
197 lines
8.4 KiB
Markdown
197 lines
8.4 KiB
Markdown
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
|
|
|
|
### Getting Started
|
|
|
|
When first getting set up you'll firstly want to install the existing dependencies. To do this, simply run
|
|
|
|
```bash
|
|
npm install
|
|
# or
|
|
yarn install
|
|
```
|
|
|
|
First, run the development server:
|
|
|
|
```bash
|
|
npm run dev
|
|
# or
|
|
yarn dev
|
|
# or
|
|
pnpm dev
|
|
```
|
|
|
|
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
|
|
|
|
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
|
|
|
|
This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
|
|
|
|
## Learn More
|
|
|
|
To learn more about Next.js, take a look at the following resources:
|
|
|
|
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
|
|
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
|
|
|
|
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
|
|
|
|
## Deploy on Vercel
|
|
|
|
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
|
|
|
|
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
|
|
|
|
We currently have a development version, found at https://assessment-model-dev.vercel.app, and a production version at https://assessment-model.vercel.app, however the production version is missing a significant number of environmental variables, which will need to be added.
|
|
|
|
# Drizzle ORM
|
|
|
|
We're using Drizzle ORM to interface with our AWS Postgres database. Documentation on getting set up can be found [here](https://orm.drizzle.team/docs/installation-and-db-connection/postgresql/node-postgres)
|
|
|
|
## Schemas
|
|
|
|
In order to get started with Drizzle, a schema needs to be created. Schemas can be added src/app/db/schema as typescript files. See the documentation on how to set
|
|
up schemas but effectively, Drizzle allows you to define schemas as typescript code, which allows for simple, type safe schema definitions.
|
|
|
|
## Creating Migrations
|
|
|
|
To create a migration, a command has been set up in package.json. Simply run
|
|
|
|
```bash
|
|
npm run migration:generate
|
|
```
|
|
|
|
Or with yarn/pnmp accordingly.
|
|
|
|
Note, there seems to be a bug with Drizzle which is documented [here](https://github.com/drizzle-team/drizzle-orm/issues/803).
|
|
|
|
The workaround is to open up `tsconfig.json` and comment out `"target": "es5"`, and replace it with `"target": "ESNext"`. This should hopefully only
|
|
be a temporary workaround required.
|
|
|
|
## Pushing migrations
|
|
|
|
To push migrations, another command has been set up in package.json, since drizzle-kit currently does not support pushing for Postgres out of the box.
|
|
|
|
Run
|
|
|
|
```base
|
|
npm run migration:push
|
|
```
|
|
|
|
Which will commit changes to the database. The database changes will be pushed to the **public** schema, whereas a meta record will be pushed to the **\_\_drizzle_migrations** schema.
|
|
|
|
## Inserting users into the database
|
|
|
|
In order to insert a user into the database, simply run
|
|
|
|
```
|
|
npm run create_users -- {email} {firstName}
|
|
```
|
|
|
|
Since we're using just the built in process arguments to read command line arguments, the ordering of arguments needs to be email address and then name
|
|
|
|
# Cypress Testing Documentation
|
|
|
|
This document provides an overview of how to perform end-to-end testing using Cypress for the login functionality of the application. The testing code is based on the provided code snippets.
|
|
|
|
## Prerequisites
|
|
|
|
Node.js installed on your machine
|
|
Cypress installed as a dev dependency in your project
|
|
|
|
## Test Execution
|
|
|
|
To execute the login tests, follow these steps:
|
|
|
|
1. Run
|
|
|
|
```bash
|
|
npm run test:e2e:open
|
|
```
|
|
|
|
Which will open Crypress test runner
|
|
|
|
2. Select the tests that you want to run. At the time of writing, only login tests have been completed
|
|
|
|
## Key files
|
|
|
|
The key files that are at play for testing are documented here. Because of some issues testing next-auth and setting cookies, a custom command to set
|
|
the JWT, and avoid the functionality defined in the signIn function as defined in `src/app/api/auth/[...nextauth]/route.ts`
|
|
|
|
**cypress/plugins/index.js** is a standard file, required by cypress to journey through the Google Oauth flow
|
|
|
|
**cypress/figtures/session.json** is a user fixture that is used to log in a user in the login tests
|
|
|
|
**cypress/support/commands.ts** creates a custom login user command which sets a JWT and allows us to actually authenticate. `cy.intercept` only mocks the client side behaviour of the apis and therefore does not set any cookies, do this function does this manually.
|
|
|
|
# impeccable live mode
|
|
|
|
[Live mode](https://impeccable.style/live-mode/) lets you pick an element in the
|
|
running app, drop a comment, and have variants swapped in via HMR. Start it from
|
|
Claude Code with:
|
|
|
|
```
|
|
/impeccable live
|
|
```
|
|
|
|
Then open the app on the forwarded port 3000 and use the picker.
|
|
|
|
The skill is **vendored** at `.claude/skills/impeccable/` rather than installed
|
|
per-container, so live mode's `scripts/` are on a stable path and everyone gets
|
|
the same version. Refresh it with `npx impeccable update`.
|
|
|
|
Two things are easy to get wrong in the devcontainer:
|
|
|
|
- **Port 8400 must reach the container on host port 8400 exactly.** The script
|
|
injected into the page hard-codes `http://localhost:8400` (only the port is
|
|
configurable, not the host), so if it lands anywhere else the picker just
|
|
never appears — no error, no mark on the page. Two paths, both covered:
|
|
`docker-compose.yml` publishes `8400:8400` (this is what `devcontainer.sh`
|
|
needs — the devcontainer **CLI does not implement `forwardPorts`**, that's a
|
|
VS Code-only feature), and `devcontainer.json` pins it with `requireLocalPort`
|
|
for the VS Code path. Because the mapping is fixed, only one container at a
|
|
time can run live mode.
|
|
- **Live mode edits `src/app/layout.tsx`** to inject its script tag, and strips
|
|
it again on exit. If a session is killed uncleanly, run
|
|
`node .claude/skills/impeccable/scripts/live-server.mjs stop` to remove the
|
|
tag — don't commit it.
|
|
|
|
`DESIGN.md` and `PRODUCT.md` are the context live mode generates variants
|
|
against (DESIGN.md wins on visual decisions, PRODUCT.md on strategic/voice
|
|
ones), so keep them honest.
|
|
|
|
# Playwright
|
|
|
|
Playwright sits alongside Cypress rather than replacing it. Specs live in `e2e/`
|
|
(Cypress keeps `cypress/e2e/`), and `playwright.config.ts` boots `next dev` for
|
|
you unless something is already serving http://localhost:3000.
|
|
|
|
```bash
|
|
npm run test:playwright
|
|
```
|
|
|
|
The devcontainer image bakes in chromium and its OS libraries, so there is
|
|
nothing to install on a fresh container. Chromium is the only browser baked in —
|
|
adding firefox or webkit to the config means adding them to
|
|
`.devcontainer/Dockerfile` too. The `@playwright/test` version in `package.json`
|
|
and `PLAYWRIGHT_VERSION` in that Dockerfile are pinned to the same number on
|
|
purpose: Playwright ties each browser build to a library version, so if they
|
|
drift, runs fail with "Executable doesn't exist".
|
|
|
|
## Watching the browser
|
|
|
|
Runs are headless by default. To watch one drive, start the virtual desktop
|
|
(Xvfb -> fluxbox -> x11vnc -> noVNC, mirroring the Model devcontainer), open the
|
|
forwarded port 6080 in your browser, then run headed against that display:
|
|
|
|
```bash
|
|
bash scripts/start_viewer.sh
|
|
DISPLAY=:99 npm run test:playwright:headed
|
|
bash scripts/start_viewer.sh stop
|
|
```
|
|
|
|
# Generating pre-signed urls
|
|
|
|
In our terraform stack, we have a module called `s3_presignable_bucket` which contains the definition for our bucket which we will use to store retrofit plan input csv's in.
|
|
|
|
We will generate a pre-signed url and then make a post request to that endpoint to store that data to s3. Part of that process is the creation of an AWS IAM role which contains
|
|
the permission set to access the bucket, `rerofit-plan-inputs-<stage>`. The name of this IAM role is `s3_presign_role_<stage>` and for our NextJS application, as it's hosted outside of AWS (for the moment), we need to generate a set of access credentials to give the application access to this bucket. The access key and secret key are automatically generated and stored in AWS secrets manager under `dev/presign_frontend/access_key` and `dev/presign_frontend/secret_key` and need to be set in the environment for the pre-sign api to store csv data to aws.
|