# Features — unity-api

Evidence date: 2026-09-30.

Source: `git@bitbucket.org:overdrive/unity-api.git`, `master` at `eeafec9` (2019-08-30).

There is no features list in the source repository. Status below is taken from routes, controllers, models, migrations, and `db/unity.sql`. "Current" means present on `master` at that revision. Git has no commits after 2019-08-30, so "recently changed" means the last change inside this three-commit history.

Personal data and secrets in the SQL dump are not listed here.

## Current features

### API registration — envelope

- **Status:** Current. Added in `23fc561` (2019-08-14).
- **Behaviour:** `POST /api/register`. Validates `name`, `email`, `password`, `c_password`. Returns HTTP 200 `{ success, data: { token, name }, message }` or HTTP 404 on validation failure. Token name `MyApp`.
- **Code:** `app/Http/Controllers/API/RegisterController.php`, `app/Http/Controllers/API/BaseController.php`, `routes/api.php`.

### API registration — token only

- **Status:** Current. Same commit.
- **Behaviour:** `POST /api/v1/register`. Same fields. Returns HTTP 200 `{ success: { token } }` or HTTP 401 on validation failure. Token name `AppName`. Custom CORS middleware.
- **Code:** `app/Http/Controllers/API/AuthController.php` (namespace `App\Http\Controllers\Api`), `routes/api.php`.

### Login

- **Status:** Current. Same commit.
- **Behaviour:** `POST /api/v1/login`. `Auth::attempt` on email and password. Token name `AppName`. Failure HTTP 401 `{ error: "Unauthorised" }`.
- **Code:** `AuthController::login`.

### Current user

- **Status:** Current.
- **Behaviour:** `POST /api/v1/getUser` returns `{ success: user }`. `GET /api/user` returns the authenticated user. Both require `auth:api`. Password and remember token are hidden.
- **Code:** `AuthController::getUser`, `routes/api.php`, `app/User.php`.

### Product catalogue CRUD

- **Status:** Current. The `products` table is not the dump's `crmproduct` table.
- **Behaviour:** Authenticated resource at `/api/products`. Fields `name` and `detail`. List is unfiltered. No pagination, no owner.
- **Code:** `app/Http/Controllers/API/ProductController.php`, `app/Product.php`, `database/migrations/2019_07_13_213211_create_products_table.php`.

### Passport API authentication

- **Status:** Current.
- **Behaviour:** Guard `api` uses driver `passport`. `User` uses `HasApiTokens`. `Passport::routes()` is called with no arguments. Personal access tokens are created with `createToken`.
- **Code:** `config/auth.php`, `app/Providers/AuthServiceProvider.php`, `app/User.php`.
- **Dump evidence:** `migrations` rows for the five Passport 2016_06_01 oauth migrations, batch 2. PHP files for those migrations are not in `database/migrations`.

### API rate limit

- **Status:** Current.
- **Behaviour:** `api` middleware group is `throttle:60,1` plus route-model bindings.
- **Code:** `app/Http/Kernel.php`.

### CORS

- **Status:** Current. Three layers, see the PRD FR-006.
- **Code:** `config/cors.php`, `app/Http/Middleware/Cors.php`, `app/Http/Kernel.php` (global `Spatie\Cors\Cors`), `.htaccess`.

### Welcome page

- **Status:** Current. Stock Laravel page.
- **Code:** `routes/web.php`, `resources/views/welcome.blade.php`.

### Front-end scaffold

- **Status:** Current as generated assets, not as a product UI.
- **Behaviour:** Laravel Mix compiles `resources/js/app.js` and `resources/sass/app.scss` to `public/js` and `public/css`. One Vue component, `example-component`. The compiled JS bundle is committed.
- **Code:** `webpack.mix.js`, `package.json`, `resources/js/components/ExampleComponent.vue`, `public/js/app.js`, `public/css/app.css`.

### SQL dump of database `unity`

- **Status:** Current. Added in `eeafec9` (2019-08-30).
- **Behaviour:** File only. The PHP application does not load it. phpMyAdmin 4.8.4, MySQL 5.7.24, PHP 7.3.1, host `127.0.0.1:3306`, generated 2019-08-30 09:53, database name `unity`.
- **Code:** `db/unity.sql`.

## Completed features

Nothing in the repository is marked finished, released, or removed after shipping. The three commits are the whole history. The Bitbucket starter README (`bed847e`) was replaced and is no longer the file at `HEAD`.

## In development

No branch, TODO register, or unfinished controller indicates work in progress. `master` is the only branch.

## Planned

No issue list, roadmap, or commented future route describes a planned feature. Commented-out lines that exist are framework samples, not a backlog:

- `DatabaseSeeder` calls no seeder (`database/seeds/DatabaseSeeder.php`).
- `app/Console/Kernel.php` has the sample `inspire` schedule commented out.
- `routes/console.php` still defines the `inspire` Artisan command.
- `config/app.php` has `BroadcastServiceProvider` commented out, so `routes/channels.php` is not loaded.
- Custom CORS `Access-Control-Allow-Headers` is commented out in `app/Http/Middleware/Cors.php`.

## Changed across the three commits

| Change | Commit | Notes |
|---|---|---|
| Repository created with Bitbucket starter README | `bed847e` | No application code |
| Laravel 5.8 API tree added; starter README replaced | `23fc561` | Auth, products, Passport, CORS, Mix scaffold |
| `db/unity.sql` added; README set back to the stock Laravel README | `eeafec9` | Dump is not referenced by PHP |

## Present but not a working feature

| Item | Why it is not a feature a caller can use | Code |
|---|---|---|
| Web login, register, forgot password, reset, email verification | Controllers exist. No route registers them. Redirect target `/home` has no route | `app/Http/Controllers/Auth/` |
| Email verification | `User` implements `MustVerifyEmail`. `verified` middleware is unused. API register does not dispatch `Registered`, so `SendEmailVerificationNotification` does not run | `app/User.php`, `app/Providers/EventServiceProvider.php`, `app/Http/Kernel.php` |
| Password reset expiry of 60 minutes | Config only | `config/auth.php` |
| Product `create` and `edit` routes | Registered by `Route::resource`. Methods are not on `ProductController` | `routes/api.php` |
| Authorisation policies | Map points at `App\Policies\ModelPolicy`, which is not in the tree | `app/Providers/AuthServiceProvider.php` |
| Broadcasting | Provider commented out. Channel closure exists but is not booted | `config/app.php`, `routes/channels.php` |
| Queues, Redis, mail, S3, Pusher, Stripe | Env and config stubs. No job class, no mail class, `app/Console/Commands` is absent | `.env.example`, `config/` |
| Scheduled work | Schedule method is empty | `app/Console/Kernel.php` |

## In the SQL dump, not exposed by this API

These tables and triggers are in `db/unity.sql`. No Eloquent model or query in `app/` names them. Treating them as API features would be wrong. They are data that was committed beside the API.

Grouped by table-name prefix:

| Prefix | Tables (names only) | What the names indicate |
|---|---|---|
| `crm` | `crmclient`, `crmclientsite`, `crmcontact`, `crmdepartment`, `crmdepartmentstatus`, `crminvoiceitem`, `crmpaymentterms`, `crmproduct`, `crmproductbundle`, `crmproductbundleitem`, `crmproductcategory`, `crmproposal`, `crmproposalgroup`, `crmproposalitem`, `crmsalesperson`, `crmserviceboard`, `crmsupplier`, `crmtask`, `crmtaskfault`, `crmtaskfix`, `crmticket`, `crmticketowner`, `crmtime` | Clients, catalogue, proposals, tasks, tickets, time |
| `hr` | `hrcorevalue`, `hrdevelopmentplan`, `hrkpa`, `hrkpi`, `hrleaveapplication`, `hrleavetype`, `hrlog`, `hrperformancereview`, `hrprobjective`, `hrpublicholiday`, `hrreview`, `hrrole`, `hrrolekpa`, `hrstaff`, `hrstaffaux`, `hrsurvey` | Leave, roles, performance review |
| `sys` | `sysauditcriticalfields`, `sysauditlog`, `sysaudit_lamp`, `sysaudit_master`, `syscommslog`, `syscompany`, `syscronjob`, `sysfaq`, `syslog`, `syslogin`, `sysmenulevel1`, `sysmenulevel2`, `syspassword`, `syssecurity`, `syssecuritygroup`, `syssettings`, `sysuser`, `sysvat`, `syswidget` | Users, security groups, settings, audit, cron queue |
| `sla` | `slaschedule`, `slatask`, `slaticket` | SLA schedules and tasks |
| `so` | `soserver`, `soserverupdate`, `soupdate` | Server / update records |
| `dwf` | `dwfperformancereview_base`, `dwfproposal`, `dwfproposalgroup`, `dwfproposalitem`, `dwftask`, `dwfticket`, `dwftime` | Summary tables used by at least one trigger |
| `edu` | `edutrainingcertificate`, `edutrainingcourse`, `edutrainingmaterial`, `edutrainingmaterialbooking` | Training |
| `tbl` / `tmp` / other | `tblemail`, `tblemailtemplate`, `tblicon`, `tmpleaveapplication`, `tmptask_7052`, `tmptask_x`, `tmpticket_7052`, `tmpticket_x`, `en_viefaq`, `` `table 61` `` | Mail templates, scratch tables, one table whose name is `table 61` |
| `vie*` | `viebillingrate`, `vieclient`, `viedepartmentstatus`, `vieedutrainingmaterialbookinglast`, `viefaq`, `vielinemanagers`, `vieproductbundle`, `vieproposallatest`, `vieuserlastlogin` | Dumped under `CREATE TABLE`. Some matching `CREATE VIEW` text is also stored as `syssettings` values. Whether every `vie*` object was a view on the source server is **Unknown / Requires Confirmation** |

Laravel tables that do match the PHP app, and that are also inside the same dump: `users`, `password_resets`, `products`, `migrations`, `oauth_access_tokens`, `oauth_auth_codes`, `oauth_clients`, `oauth_personal_access_clients`, `oauth_refresh_tokens`.

`products` has a `CREATE TABLE` and no `INSERT` in the dump. `users` has four rows.

## Deprecated or removed

No removed route or migration `down()` that was applied as a removal is visible. The Bitbucket starter README is gone from `HEAD`. That is a file replacement, not a product feature removal.

## Tests that describe features

| Test | Asserts | File |
|---|---|---|
| Feature example | `GET /` returns 200 | `tests/Feature/ExampleTest.php` |
| Unit example | `assertTrue(true)` | `tests/Unit/ExampleTest.php` |

No test covers register, login, products, or Passport.
