# Features — magalies-pharma-heisenberg-serverless

Evidence date: 2026-10-09. Source: `git@bitbucket.org:overdrive/magalies-pharma-heisenberg-serverless.git`, `master` at `7d003d5` (2023-05-03).

No features file existed in the repository or in Silicon Ark. "Current" means the function is declared in a Serverless template on `master` and has a handler in `src/`. It does not mean the route succeeds against a live stage.

Authorizer shorthand:

| Name | Header | Who passes |
|---|---|---|
| Cognito | `idtoken` | Any user in the admin user pool. No group check |
| SuperAdmin | `accesstoken` | Group `SuperAdmin` |
| Prescription | `accesstoken` | `SuperAdmin` or `Prescription` |
| Fulfilment | `accesstoken` | `SuperAdmin` or `Fulfilment` |
| Packaging | `accesstoken` | `SuperAdmin` or `Packaging` |
| Internal | `accesstoken` | `SuperAdmin`, `Fulfilment`, `Packaging`, or `Prescription` |
| API key | API Gateway `private: true` | Caller with a usage-plan key. No group check in this repo |
| None | — | No authorizer and not `private` |

## Current features

### Identity and access

| Feature | Where | Status |
|---|---|---|
| Admin user pool, email username, MFA off | `serverless/formations/03 - cognito.yml` | Implemented |
| Groups SuperAdmin, Prescription, Fulfilment, Packaging, Customer | Same file | Implemented |
| Lambda authorizers for those groups | `src/authorizers/`, `serverless.authorizers.yml` | Implemented |
| Customer authorizer attached to a route | `customerAuthorizer` is only declared in `serverless.presigned-url.yml` | Not routed |
| Create user with a generated temporary password and add to `role` | `POST user`, `src/user/create/` | Implemented. SuperAdmin |
| List, view, edit user | `GET/PUT user`, `GET user/{username}` | Implemented. SuperAdmin |
| Disable user | `DELETE user/{username}`, `src/user/delete/disable.js` | Implemented. Does not delete the Cognito user |

### Prescription and orders

| Feature | Where | Status |
|---|---|---|
| Submit prescription, status AWR, lines AWF | `POST prescription` | Implemented. Cognito |
| List orders, page and limit required | `GET order` | Implemented. Cognito. Search column `name` is not on the table |
| View order with parties, shipping, tracking, lines, batch items, medicine | `GET order/{order_id}` | Implemented. Cognito |
| Edit order, parties, shipping, and lines | `POST order/{order_id}` | Implemented. Internal |
| Split into child orders | `POST order/{order_id}/split` | Implemented. Prescription |
| Move lines between parent and children | `POST order/{order_id}/move` | Implemented. Compares `parent_id`, which is not a column. See business rules |
| Order tracking read | `GET order/{order_id}/tracking` | Implemented. Cognito |

### Catalogue

| Feature | Where | Status |
|---|---|---|
| Medicine create, list, view, edit | `medicine` routes in `serverless.medicine.yml` | Implemented. Writes: Prescription. Reads: Cognito. Delete: SuperAdmin, soft delete |
| Dosage unit CRUD | `dosage-unit` | Same authorizer pattern |
| Dosage type CRUD | `dosage-type` | Same |
| Package type CRUD | `package-type` | Same |
| Medicine dosage type CRUD | `medicine/{medicine_id}/dosage-type` | Same. `medicine_number` is unique and required after migration `08_08_2022_0900` |
| Medicine dosage package CRUD | `.../package` | Same. `contained_quantity` is a float after `11_23_2022_0830`. List can attach `stock_on_hand` when `stock` is present |
| Lookup lists | `POST form-data` | Implemented. Cognito |
| Seeded medicines, dosage forms, package types | `database/seeds/medicine.sql` | Implemented as SQL. Seed still inserts dropped column `default_price` |

### Manufacture, stock, packaging

| Feature | Where | Status |
|---|---|---|
| List and view batches | `GET batch`, `GET batch/{batch_id}` | Implemented. Cognito. View sets `remaining_quantity` |
| Create batch and N blank batch items | `POST batch` | Implemented. Fulfilment. Timeout 30 s. `reserve` in the comment is unused |
| Edit and delete batch | `PUT/DELETE batch/{batch_id}` | Implemented. Fulfilment |
| List, view, create batch items | `batch-item` routes | Implemented. Create: Fulfilment. Reads: Cognito |
| Stock count of unassigned batch items | `POST stock/check` | Implemented. Fulfilment |
| List batch items on an order line | `GET fulfilment/{order_item_id}` | Implemented. Packaging |
| Scan barcode onto a free batch item | `POST fulfilment/{order_item_id}/scan` | Implemented. Packaging |
| Mark line packed | `GET fulfilment/{order_item_id}/fulfill` | Implemented. Packaging |

### Courier

| Feature | Where | Status |
|---|---|---|
| Shipping contact and address for an order | `GET courier/{order_id}` | Implemented. API key. Company contact fields do not match the `company` table |
| Save waybill on an order | `POST courier/{order_id}/waybill` | Implemented. API key |
| Save tracking text | `POST courier/tracking` | Implemented. API key |
| Dawn Wing token | `POST waybill/auth` | Implemented. No authorizer |
| Forward waybill, parcel, and complete | `POST waybill/capture`, `POST parcel/capture`, `POST waybill/complete` | Implemented. No authorizer |
| Track and trace | `GET waybill/trackandtrace` | Present. Call shape does not match `dpd()` and the path is hardcoded to UAT |

### Reporting and documents

| Feature | Where | Status |
|---|---|---|
| Dashboard counts by status | `POST dashboard` | Implemented. Cognito |
| Medicine time-series report | `POST report/medicine` | Implemented. Cognito. `type` daily or weekly, `format` default or xls |
| Batch report with `stock_remaining` | `POST report/batch` | Implemented. Cognito |
| Order report | `POST report/order` | Implemented. Cognito |
| Presigned S3 upload and download URLs | `POST presigned-url/generate-upload`, `generate-download` | Implemented. Cognito. Bucket is caller-supplied |
| Order-summary image or PDF | `POST prescription-pack`, template `order_summary.hbs` | Implemented. Cognito. Timeout 30 s |
| Audit log list | `GET log` | Implemented. SuperAdmin |

## Changed features visible in migrations and commits

These are already on `master`. They are not an open changelog.

| Change | Evidence | Date |
|---|---|---|
| Individual email and alternate email | `05_10_2022_0813_individual_email.sql` | 2022-05-10 |
| `tracking_details` table | `05_10_2022_0920_tracking_table.sql` | 2022-05-10 |
| Unique `medicine_number` on dosage type | `08_08_2022_0900_add_medicine_number.sql` | 2022-08-08 |
| Company `distributor_id` self-reference | `08_08_2022_1010_distributor_id.sql` | 2022-08-08 |
| Package label, price, `is_active`; dosage `is_active`; drop `default_price` | `08_08_2022_1230_package_type_updates.sql` | 2022-08-08 |
| `prescriber_id` added, first as a company FK | `08_16_2022_0840_prescriber_id.sql` | 2022-08-16 |
| Batch expiry date | `09_30_2022_0900_batch_expiry_date.sql` | 2022-09-30 |
| `shipping_details.waybill_data` JSON | `10_10_2022_waybill_data.sql` | 2022-10-10 |
| `batch_item.medicine_number` for the scanned value | `10_31_2022_store_scanned_med_number.sql` | 2022-10-31 |
| `contained_quantity` becomes FLOAT | `11_23_2022_0830_medicine_dosage_package_type_quantity.sql` | 2022-11-23 |
| Prescriber FK retargeted from `company` to `individual` | `11_23_2022_1309_change_prescriber_to_individual.sql` | 2022-11-23 |
| Internal authorizer added | commit `1eb8102` | In history before the 2023 tip |
| Courier timeout 19 seconds | `7d003d5` | 2023-05-03 |
| Live versus staging Dawn Wing path via env | commit `130338a` message | In history |

## Planned

No TODO, roadmap, or ticket file in the repository describes unfinished work.

Candidates that look unfinished, marked **Inferred** and **Requires Confirmation**:

- Customer group and Customer authorizer with no route.
- Email layer (SES and Handlebars templates) with no `src/` caller, and bucket name `heisenberg-emails-${stage}` not created by the buckets stack.
- Batch create comment describes a `reserve` array the handler ignores.
- `GET medicine?sellable=true` reads the flag and never filters on it.

## Deprecated or removed

Nothing in Git history on this clone was identified as a removed product feature with a replacement note. `default_price` was removed from `medicine_dosage_type` by migration and is still inserted by `database/seeds/medicine.sql`.

`README.md` install steps still `cd re-mind-serverless/`. That path is not this repository.

## Not features of this repository

- A web or mobile UI. Bucket `heisenberg-frontend-${stage}` is only a name in CloudFormation.
- SonarQube project files named in the onboarding task. They are not on `master`.
- Automated tests or a pipeline file.
