# PRD — siliconreact

Evidence date: 2026-10-03. Source: `git@bitbucket.org:overdrive/siliconreact.git`, `master` at `96fd3b0` (2023-03-24).

There is no prior PRD in the repository or in Silicon Ark. The README is the create-next-app template and does not describe this product. Requirements below were recovered from the code and from commit messages. Provenance is marked on each item.

The password literal in the credentials provider is not copied into this document.

## Product purpose

The UI calls the product "Silicon React" and credits Silicon Overdrive. The implemented behaviour is a sign-in shell: a person submits an email and password, a single hardcoded pair is accepted, and a JWT session unlocks two placeholder pages (`/home` and `/users`).

Provenance: **Implemented**. A written purpose, audience, or success measure was not found. **Unknown / Requires Confirmation.**

## Users and interactions

| Actor | What the code lets them do | Evidence | Provenance |
|---|---|---|---|
| Visitor | Opens `/` and sees the sign-in form. Can open `/signup`, `/forgotpassword`, `/landing`, and `/auth/login` without a session | `pages/index.tsx`, route files | Implemented |
| Person with the hardcoded credential pair | Signs in and is sent to `/home`. Can open `/users`. Can sign out from `/home` | `pages/api/auth/[...nextauth].ts`, `pages/home/index.tsx`, `pages/users/index.tsx` | Implemented |
| Signed-in session | The returned user object includes `role: "admin"`. No page reads `role` | `[...nextauth].ts` | Implemented data, unused |
| Anyone | Can call `GET /api/hello` and receive `{ "name": "John Doe" }` | `pages/api/hello.ts` | Implemented (template sample) |

No other roles, organisations, or permission sets are defined.

The accepted login email (`johndoe@gmail.com`) is not the email stored on the session (`test@gmail.com`). Provenance: **Implemented**. Whether that mismatch is intentional is **Unknown / Requires Confirmation**.

## Main workflows

### W1 — Sign in

Trigger: the person submits the form on `/` or `/auth/login`. Both routes render `pages/auth/login.tsx`. `/` stopped rendering the landing page in `96fd3b0`; the landing import is commented out.

Inputs:

- Email and password (Formik, validated by `lib/validate.ts`).
- "Remember me" checkbox (`isChecked`). It is stored in Formik state and is not sent to `signIn`.

Client validation (`login_validate`), before submit:

- Email is required. It must match `/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i`.
- Password is required. A password that contains a space is rejected with "Invalid Password". No minimum length is coded.

The form does not render the error strings. When a field is touched and invalid, the fieldset border is set to red.

On submit the page calls `signIn("credentials", { redirect: false, email, password, callbackUrl: "/home" })`. If `res.ok`, it runs `router.push(res.url)`. If sign-in fails, the result is only `console.log`'d. No error message is shown.

Server (`pages/api/auth/[...nextauth].ts`):

- Session strategy is `jwt`.
- The credentials provider throws `Error('Invalid Credentials')` unless the email and password equal the literals in that file.
- On success it returns a fixed object: `id: "123"`, `firstName: "John"`, `lastName: "Doe"`, `name: "John Doe"`, `email: "test@gmail.com"`, `role: "admin"`.
- NextAuth sign-in page is set to `/auth/login/`.

Provenance: **Implemented**.

### W2 — Stay on a signed-in page

Trigger: the person opens `/home` or `/users`.

`useSession()` supplies `status`. While `status` is `"authenticated"`, the page renders its welcome text. `/home` also renders a Sign Out button. Any other status, including `"loading"`, renders the text `loading`.

If `status` becomes `"unauthenticated"`, an effect calls `Router.replace("/")`.

Provenance: **Implemented**. There is no `middleware.ts`, so the gate runs in the browser after the page loads.

### W3 — Sign out

Trigger: Sign Out on `/home` calls `signOut()` with no arguments.

The home page then treats an unauthenticated session as in W2 and replaces the route with `/`.

Provenance: **Implemented** for the button. NextAuth's own post-sign-out redirect is not configured in this repo.

### W4 — Open the landing page

Trigger: the person opens `/landing` directly. Nothing in the current UI links there. The page shows the Silicon logo, "Welcome To Silicon React", and a Log In button that pushes `/auth/login`.

Provenance: **Implemented**, but not the entry route since `96fd3b0`.

### W5 — Sign up

Trigger: "Don't have an account? Sign Up" on the login form goes to `/signup`.

The form shows first name, last name, email, and password. Formik initial values also include `confirmPassword`, and there is no confirm-password field and no `validate` function. The inputs are not bound to Formik (`getFieldProps` is not used). `onSubmit` only `console.log`s the Formik values, which stay at the initial empty strings.

"Already have an account? Sign in" links to `/` (changed from `/auth/login` in `96fd3b0`).

Provenance: **Implemented** as a screen. Account creation is not implemented. The commit history does not describe a planned API.

### W6 — Forgot password

Trigger: "Forgot password?" on the login form goes to `/forgotpassword`.

The page shows an email field and a Reset Password button. The button calls `handleResetPassword`, which `console.log`s `"sent email"`. The email field is not controlled and is not validated. "Return to Login Page" links to `/`.

Provenance: **Implemented** as a screen. Sending mail or changing a password is not implemented.

### W7 — Users page

Trigger: a signed-in person opens `/users`. No navigation link points at this route.

The page shows "Welcome to the User Page!" when authenticated, and otherwise follows W2.

The commit that added the file (`dc7d03c`, message "forgot password page, additional validation, users page (still to populate)") states that the page was not finished.

Provenance: **Implemented** placeholder. Population of user data is **Planned** only in that commit message, with no further specification.

## Functional requirements

### FR-001 — Application entry is the sign-in form

`/` renders the login component.

- Trigger: request to `/`.
- Evidence: `pages/index.tsx`.
- Implementation: Implemented.
- Confidence: High.

### FR-002 — Login form validates email and password

Email is required and must match the expression in `lib/validate.ts`. Password is required and must not contain a space. Invalid touched fields show a red border. Error text is not displayed.

- Evidence: `lib/validate.ts`, `pages/auth/login.tsx`.
- Implementation: Implemented.
- Confidence: High.

### FR-003 — Sign-in uses NextAuth credentials and a JWT session

The only provider is Credentials. Session strategy is `jwt`. The NextAuth sign-in page option is `/auth/login/`.

- Evidence: `pages/api/auth/[...nextauth].ts`, `pages/_app.tsx` (`SessionProvider`).
- Implementation: Implemented.
- Confidence: High.

### FR-004 — One hardcoded identity is accepted

`authorize` accepts only the email and password literals in source. Success returns the fixed John Doe object, not the submitted email. Failure throws `Invalid Credentials`. The login page does not show that error.

- Evidence: `pages/api/auth/[...nextauth].ts`, `pages/auth/login.tsx`.
- Implementation: Implemented.
- Confidence: High.
- The password is not recorded in this PRD. Whether these literals were meant as a temporary stub is **Unknown / Requires Confirmation**.

### FR-005 — Successful sign-in navigates to the callback URL

`signIn` is called with `redirect: false` and `callbackUrl: "/home"`. When `res.ok` is true, the client pushes `res.url`.

- Evidence: `pages/auth/login.tsx`.
- Implementation: Implemented.
- Confidence: High.

### FR-006 — Remember me is displayed and not applied

The checkbox updates Formik `isChecked`. It is not passed to `signIn`. No `maxAge` or `updateAge` is set on the session config.

- Evidence: `pages/auth/login.tsx`, `pages/api/auth/[...nextauth].ts`.
- Implementation: Implemented as UI only.
- Confidence: High.

### FR-007 — Home and users require a client session

Unauthenticated status replaces the route with `/`. Authenticated status shows the welcome line. Loading and other statuses show the text `loading`.

- Evidence: `pages/home/index.tsx`, `pages/users/index.tsx`.
- Implementation: Implemented.
- Confidence: High.

### FR-008 — Home can sign the session out

The Sign Out button calls `signOut()` with no arguments.

- Evidence: `pages/home/index.tsx`.
- Implementation: Implemented.
- Confidence: High.

### FR-009 — Signup and forgot-password are non-persistent screens

Neither screen calls an API, writes storage, or sends email. Signup submit logs Formik's initial values. Reset logs the string `sent email`.

- Evidence: `pages/signup/index.tsx`, `pages/forgotpassword/index.tsx`.
- Implementation: Implemented (incomplete relative to the button labels).
- Confidence: High.

### FR-010 — Landing page remains reachable by URL

`/landing` shows the logo, the welcome heading, and a button to `/auth/login`. It is not linked from the other pages, and it is not `/`.

- Evidence: `pages/landing/index.tsx`, `pages/index.tsx`.
- Implementation: Implemented.
- Confidence: High.

### FR-011 — Sample hello API

`pages/api/hello.ts` responds `200` with `{ name: "John Doe" }` for any method. It does not check a session.

- Evidence: `pages/api/hello.ts`. README still documents `http://localhost:3000/api/hello`.
- Implementation: Implemented (template).
- Confidence: High.

### FR-012 — Shared chrome

Pages that include the copyright block link "Silicon Overdrive" to `https://www.overdrive.co.za/` and append the current calendar year. Document language is `en`. A shortcut icon is requested from `/favicon.ico`. Roboto is loaded from Google Fonts. MUI `CssBaseline` is applied around every page.

- Evidence: copyright function in the three auth-related pages, `pages/_document.tsx`, `pages/_app.tsx`.
- Implementation: Implemented.
- Confidence: High.

## Integrations

| System | Direction | Trigger | Data | Failure behaviour |
|---|---|---|---|---|
| NextAuth (in-process) | In-app | Sign-in and `useSession` / `signOut` | Email, password, JWT session, fixed user object | Provider throws `Invalid Credentials`. The login UI does not display it |
| Google Fonts | Outbound browser request | Every document | Stylesheet URL for Roboto weights 300, 400, 500, 700 | Not handled in code |
| SonarQube | CI outbound | Pipeline on `master` | Scan of the clone. `SONAR_HOST_URL`, `SONAR_TOKEN` from Bitbucket variables | Not described beyond the pipe definition |
| overdrive.co.za | Browser navigation | Copyright link | None | Ordinary external link |

No database, email provider, OAuth identity provider, queue, or payment integration is present.

`NEXTAUTH_SECRET`, `NEXTAUTH_URL`, and any other environment variables are not referenced in the source. How NextAuth is configured outside the repo is **Unknown / Requires Confirmation**.

## Constraints

- Single branch `master`. Last change 2023-03-24.
- `package.json` marks the package `"private": true`, version `0.1.0`.
- No server-side authorisation middleware.
- `reactStrictMode: true` in `next.config.js`. No other Next config.
- TypeScript `strict` is on. Path alias `@/*` maps to the repo root (`tsconfig.json`).
- Client validation does not accept email domains whose public suffix is longer than four letters (the expression requires a 2–4 character TLD). Provenance: **Implemented** in the regular expression.
- The users page was left unfinished on purpose, according to the commit message. Provenance: **Documented** in that message only.

## Removed behaviour

`pages/login/index.tsx` existed from `4018f2b` and was deleted in `dc7d03c`. The route `/login` is not in the current tree. Login lives at `/auth/login` and, since `96fd3b0`, also at `/`.

## Discrepancies

| Topic | What one source says | What another source does |
|---|---|---|
| Entry page | README says edit `pages/index.tsx` and describes the create-next-app starter | `pages/index.tsx` renders the login form. The landing page is a separate route |
| Fonts | README says the project uses `next/font` to load Inter | No `next/font` usage. `_document.tsx` links the Roboto Google Fonts stylesheet |
| Signup | Button label "Sign Up" and required fields | Submit does not create an account. Fields are not bound to Formik, which also holds an unused `confirmPassword` |
| Forgot password | Button label "Reset Password" | Handler logs `sent email` |
| Users | Page title implies a user area | Commit `dc7d03c` says "still to populate". The page renders one welcome line |
| Remember me | Checkbox is on the form | Value is ignored at sign-in |
| Session identity | Login email must be `johndoe@gmail.com` | Session email is `test@gmail.com` |
| Role | User object includes `role: "admin"` | No screen checks the role |
| Favicon comment vs file | `_document` comment says "PWA primary color" and links `/favicon.ico` | `public/favicon.ico` is in git. No web-app manifest was found |
| Scan listing | Task creation listed `sonarqube_scan.bat` | File is not in git |

## Unknown / requires confirmation

- Intended product, users, and whether this repository is still in use.
- Whether the hardcoded credential pair was a temporary stub and must be removed.
- Where, if anywhere, the app is deployed, and which environment variables are set.
- Whether a build from a clean install is expected to succeed. `src/Link.tsx` imports `clsx`, which is not in `package.json`. Nothing imports `src/Link.tsx`. This investigation did not run `npm install` or `next build`.
- Whether SonarQube still has project `overdrive_siliconreact_AYbC8sOS_7nCiPvwlqwc`.
- What "additional validation" in commit `dc7d03c` referred to beyond the files that commit touched.
