# PRD — laravelReactjs

Evidence date: 2026-10-10.

Source: `git@bitbucket.org:overdrive/laravelreactjs.git`, `master` at `7e1ef64` (2019-04-05).

There is no prior PRD in the source repository or in Silicon Ark. Requirements below are recovered from the implementation and from the current `README.md`. Provenance is labelled. The committed application key is not reproduced.

## Product purpose

**Documented.** `README.md` titles the repository **Laravel React Tut** and links to `https://blog.pusher.com/react-laravel-application/`.

**Implemented.** A browser that requests `/` receives the Laravel 5.8 welcome page. The page does not mention projects, tasks, or React. `Project` and `Task` exist as empty models and as tables with only `id` and timestamps.

**Unknown / Requires Confirmation:** what product the README link was meant to become. The article is not stored in the repository.

## Users and roles

| Actor | Evidence | Status |
|---|---|---|
| Anonymous visitor | `GET /` returns `welcome.blade.php` with no auth check | **Implemented** |
| User who could log in | `LoginController`, session guard `web` | **Implemented** as a class. No login route is registered |
| User who could register | `RegisterController` validation and `User::create` | **Implemented** as a class. No register route is registered |
| API caller | `GET /api/user` with `auth:api` | **Implemented** as a route. The `users` table has no `api_token` column |
| Verified-email user | `VerificationController`, `MustVerifyEmail` import | **Implemented** as unused scaffolding. `User` does not implement `MustVerifyEmail` |
| Project or task owner | No role, policy, or foreign key | **Unknown**. Not implemented |

`config/auth.php` defines two guards and one user provider. No second role exists.

| Guard | Driver | Provider | Notes |
|---|---|---|---|
| `web` (default) | `session` | `users` → `App\User` | Used by auth controllers if those routes were registered |
| `api` | `token`, `hash` => `false` | `users` | Used by `GET /api/user` |

No policies are registered. `AuthServiceProvider::$policies` contains only a commented example.

## Systems the product talks to

At product level, from code that actually runs for a request:

1. The visitor's browser, loading `welcome.blade.php`.
2. Google Fonts, requested by the welcome page (`fonts.googleapis.com`, family Nunito).
3. MySQL, if a database-backed feature is invoked. The welcome page does not query it.

Configured in `.env.example`, and matched by the committed `.env` except for `APP_KEY`:

| System | Setting | Used by application code? |
|---|---|---|
| MySQL `127.0.0.1:3306`, database `homestead` | `DB_*` | Only if migrations or Eloquent run. No route does that |
| File cache, file session, sync queue | `CACHE_DRIVER`, `SESSION_DRIVER`, `QUEUE_CONNECTION` | Framework defaults for any request that starts a session |
| Log broadcaster | `BROADCAST_DRIVER=log` | No broadcast is sent. App `BroadcastServiceProvider` is commented out in `config/app.php` |
| Redis `127.0.0.1:6379` | `REDIS_*` | No application call |
| Mailtrap SMTP port 2525 | `MAIL_*`, username and password `null` | No mailable. Password-reset mail cannot be sent because those routes are not registered |
| AWS keys empty, region `us-east-1` | `AWS_*` | S3 disk is defined. Nothing stores a file |
| Pusher keys empty, cluster `mt1` | `PUSHER_*`, `MIX_PUSHER_*` | Echo setup in `resources/js/bootstrap.js` is commented out |

Mailgun, Postmark, SES, SparkPost, and Stripe appear in `config/services.php` as Laravel skeleton entries. No matching keys are in `.env.example`. Nothing in `app/` calls them.

## Major workflows

### WF-1 — Open the welcome page

`routes/web.php` registers `GET /`. The closure returns `view('welcome')`.

`resources/views/welcome.blade.php`:

- Title and heading text are "Laravel".
- Locale comes from `app()->getLocale()`, which `config/app.php` sets to `en`.
- Styles are inline. The page does not include `public/css/app.css` or `public/js/app.js`.
- There is no element with id `example`, so the React example cannot mount on this page.
- Login and register links render only when `Route::has('login')` is true. `Auth::routes()` is not called, so those links are omitted.
- Footer links point at Laravel Docs, Laracasts, Laravel News, the Laravel Blog, Nova, Forge, and the laravel/laravel GitHub repository.

Provenance: **Implemented**.

`tests/Feature/ExampleTest.php` requests `GET /` and asserts HTTP 200. It imports `RefreshDatabase` and does not apply that trait.

### WF-2 — Ask the API for the current user

`RouteServiceProvider` loads `routes/api.php` with prefix `api` and middleware group `api`.

The only route is:

```text
GET /api/user
middleware: auth:api
behaviour: return $request->user()
```

The `api` middleware group is `throttle:60,1` and `bindings`. It does not start a session.

The `api` guard is the token driver with `hash` => `false`. Laravel's token guard reads a plain `api_token` on the user. The `users` migration has no `api_token` column.

Provenance: route and guard are **Implemented**. The conclusion that a caller cannot authenticate against this schema is **Inferred** from that guard plus the migration.

There is no other API route. There is no project or task API.

### WF-3 — Register, log in, reset a password, verify email

These controller classes exist and are not routed:

| Class | Trait / behaviour in the class | Redirect constant | Middleware in constructor |
|---|---|---|---|
| `LoginController` | `AuthenticatesUsers` | `/home` | `guest` except `logout` |
| `RegisterController` | `RegistersUsers` | `/home` | `guest` |
| `ForgotPasswordController` | `SendsPasswordResetEmails` | (trait default) | `guest` |
| `ResetPasswordController` | `ResetsPasswords` | `/home` | `guest` |
| `VerificationController` | `VerifiesEmails` | `/home` | `auth`; `signed` on `verify`; `throttle:6,1` on `verify` and `resend` |

`RedirectIfAuthenticated` sends an already authenticated guest-route user to `/home`. No route returns a view named home. `resources/views/` contains only `welcome.blade.php`.

Registration rules, if that controller were reached:

| Field | Rules |
|---|---|
| `name` | required, string, max 255 |
| `email` | required, string, email, max 255, unique on `users` |
| `password` | required, string, min 8, confirmed |

`create()` stores `name`, `email`, and `Hash::make($data['password'])`. Hash driver in `config/hashing.php` is `bcrypt`, rounds `env('BCRYPT_ROUNDS', 10)`.

`User` mass-assignable fields are `name`, `email`, `password`. Hidden from arrays: `password`, `remember_token`. `email_verified_at` is cast to datetime.

`EventServiceProvider` listens for `Registered` and queues `SendEmailVerificationNotification`. `User` imports `MustVerifyEmail` and does not implement it. **Inferred** from the framework contract: that listener does not send mail unless the user model implements the interface.

Password reset config: table `password_resets`, expire 60 minutes (`config/auth.php`).

Provenance: the classes, rules, and config are **Implemented**. They are not reachable over HTTP. Treating them as product behaviour would overstate the running application.

### WF-4 — Store a project or a task

`projects` and `tasks` migrations create a table with `id` (`bigIncrements`) and `timestamps` only. Models `App\Project` and `App\Task` extend `Model` and declare nothing else: no `$fillable`, no `$guarded` override, no relationship, no factory, no seeder.

No controller, route, form, or React component reads or writes these models.

Provenance: schema and models are **Implemented**. A user workflow is **not implemented**.

### WF-5 — Show the React example

`resources/js/app.js` requires `./bootstrap` and `./components/Example`.

`Example.js` renders a Bootstrap card titled "Example Component" with the body "I'm an example component!". If `document.getElementById('example')` exists, it mounts there with `ReactDOM.render`.

`webpack.mix.js` compiles that file with `mix.react` to `public/js/app.js`, and compiles `resources/sass/app.scss` to `public/css/app.css`. Both compiled files are in git. The JavaScript bundle contains the example strings.

`resources/js/bootstrap.js` loads Lodash, jQuery, Popper, Bootstrap, and Axios. Axios sets `X-Requested-With` and, when a `csrf-token` meta tag exists, `X-CSRF-TOKEN`. The Echo / Pusher block is commented out.

No Blade file loads these assets or renders `<div id="example">`.

Provenance: **Implemented** as a build artefact. **Not implemented** as a page.

## Functional requirements

### FR-001 — Welcome page

The application responds to `GET /` with the Laravel welcome view and HTTP 200 when the view renders.

| | |
|---|---|
| Who | Anonymous visitor |
| Trigger | HTTP GET `/` |
| Input | None |
| Behaviour | Return `welcome` |
| Output | HTML titled Laravel |
| Validation | None |
| Errors | View or framework exceptions use Laravel's handler. `APP_DEBUG` in the committed env files is `true`, so debug pages are enabled for `APP_ENV=local` |
| Dependencies | `routes/web.php`, `resources/views/welcome.blade.php` |

Implementation: **Implemented**. Confidence: **High**.

Evidence: `routes/web.php`, `welcome.blade.php`, `tests/Feature/ExampleTest.php`.

### FR-002 — Session web stack

Web routes receive the `web` middleware group: encrypt cookies, add queued cookies, start session, share errors, verify CSRF, substitute bindings. `AuthenticateSession` is commented out of the group.

| | |
|---|---|
| Who | Any caller of a web route |
| Trigger | Request enters `routes/web.php` |
| Input | Cookies, including the session cookie |
| Behaviour | Start a file session (`SESSION_DRIVER=file` in the committed env). Reject cross-site POSTs that fail CSRF. No URI is listed in `VerifyCsrfToken::$except` |
| Output | Response from the route, plus session cookie |
| Validation | CSRF token on state-changing web requests |
| Errors | CSRF mismatch is Laravel's token mismatch response. `GET /` does not require a token |
| Dependencies | `app/Http/Kernel.php`, `config/session.php`, `VerifyCsrfToken` |

Implementation: **Implemented**. Confidence: **High**.

The only web route is GET `/`, so CSRF is not exercised by a form in this tree.

### FR-003 — API current user

`GET /api/user` returns the token-authenticated user or rejects the caller.

| | |
|---|---|
| Who | API caller |
| Trigger | HTTP GET `/api/user` |
| Input | API token as required by Laravel's token guard |
| Behaviour | Middleware `auth:api`, then return the user model |
| Output | JSON user, with `password` and `remember_token` hidden by `User::$hidden` |
| Validation | Token must match a user. Rate limit 60 requests per minute (`throttle:60,1`) |
| Errors | Unauthenticated response from the `auth` middleware. **Inferred:** lookup cannot succeed because `users.api_token` does not exist |
| Dependencies | `routes/api.php`, `config/auth.php`, `users` migration |

Implementation: route **Implemented**; successful authentication **not possible** with the shipped schema. Confidence: **High** on the route, **Medium** on the schema conclusion (inferred from the token guard's usual column).

### FR-004 — User record shape

When migrations run, `users` has:

| Column | Definition |
|---|---|
| `id` | big increment |
| `name` | string |
| `email` | string, unique |
| `email_verified_at` | timestamp, nullable |
| `password` | string |
| `remember_token` | remember token |
| `created_at`, `updated_at` | timestamps |

`password_resets` has `email` (indexed), `token`, and nullable `created_at`.

Implementation: **Implemented** as migrations. Nothing in the repository shows that they have been applied to a database. Confidence: **High** on the files, **Unknown** on any live database.

### FR-005 — Project and task tables

When migrations run, `projects` and `tasks` each have `id` and timestamps only.

Implementation: **Implemented** as migrations and empty models. No product behaviour reads them. Confidence: **High**.

### FR-006 — Registration validation

Described under WF-3. The rules exist on `RegisterController`. No route invokes them.

Implementation: **Implemented** in a class that is not routed. Confidence: **High**.

### FR-007 — React example bundle

`npm` scripts `dev`, `development`, `watch`, `watch-poll`, `hot`, `prod`, and `production` run Laravel Mix 4. The React entry is `resources/js/app.js`.

Implementation: source, Mix config, lockfile, and compiled `public/js/app.js` / `public/css/app.css` are **Implemented**. The welcome page does not load them. Confidence: **High**.

## Important constraints

- PHP `^7.1.3` and Laravel `5.8.*` (`composer.json`).
- Timezone `UTC`. Locale and fallback locale `en`. Faker locale `en_US` (`config/app.php`).
- Cipher `AES-256-CBC`. Application key comes from `APP_KEY`.
- Default database connection `mysql` (`config/database.php`).
- Queue default `sync`. No job class and no `jobs` migration.
- Log channel `stack`, which writes the `daily` channel, 14 days, path `storage/logs/laravel.log`.
- Password reset tokens expire after 60 minutes, if that flow is ever routed.
- API throttle is 60 per minute. Web routes have no throttle middleware.
- `User` does not implement `MustVerifyEmail`, so the verification listener has no implementing model.

## Requirements that are not established

| Topic | Status |
|---|---|
| Who the users are beyond "visitor" and the unused auth classes | Unknown / Requires Confirmation |
| Whether projects belong to users or tasks belong to projects | Unknown. No foreign keys |
| Whether the Pusher article's screens are in scope | Unknown. Only the URL is in the README |
| Deployed URL, host, or environment other than the local example | Unknown |
| Whether migrations have been applied anywhere | Unknown |
| SonarQube project settings | Unknown. Not in git |
