# Features — click-learner-portal-platform

Evidence date: 2026-10-18.

Source: `master` at `99bde51` unless a row says **Production branch** (`origin/Production` at `131cc59`). There is no features list in the source repository. "Current" means present on `master`, which is `origin/HEAD`.

## Current (on `master`)

| Feature | Behaviour | Evidence |
|---|---|---|
| TAO quiz launch | `GET /default/{learnerId}/{quizId}/{quizEndDate}` returns an LTI 1.3 resource-link HTML redirect form. | `src/Controller/DefaultController.php` route `default_list` |
| TAO tool target | Launch URL is `https://testrunner-ignite.prod.gcp-eu.taocloud.org/api/v1/auth/launch-lti-1p3/{quizId}`. | `DefaultController.php` |
| Learner role and deployment | Login hint is the learner id. Role is the IMS Learner membership URI. Deployment id is `1`. | `DefaultController.php`, registration `tao` in `config/packages/lti1p3.yaml` |
| Return URL | `https://portaltest.clicklearning.org/click-home-learning` with `learner_id` and `quiz_id`. | `DefaultController.php` on `master` |
| Delivery close claim | Custom claim `deliverySettings.closeOn` is the quiz end date plus `T00:00:00+00:00`. | `DefaultController.php` |
| Click Learning platform registration | Platform name `Click Learner Portal Platform`, audience `https://clms.clicklearning.org/platform`, client id `click-learning`. | `config/packages/lti1p3.yaml` registration `tao` |
| Local platform registration | Audience `http://127.0.0.1:8000/platform`, tool on port 8001, client id `common_client_id_value`. | `lti1p3.yaml` registration `local` |
| API Platform learner link | `GET /api/ltiresourcelink/{learnerid}` builds a localhost launch and returns a JSON-encoded URL. Comment says testing. Learner id is not used in the hint. | `src/Entity/ltirequest.php`, `src/Controller/LtiRequestController.php` |
| Stub user authenticator | Always succeeds. Named user id is the login hint and the name is `Maanie`, unless the caller forces anonymous. | `src/Controller/UserAuthenticator.php`, `config/services.yaml` |
| OIDC, token, and JWKS URLs | Configured on `clms.clicklearning.org` and on `127.0.0.1:8000`. | `lti1p3.yaml` |
| Committed dev keys | Platform and tool key chains all read `config/secrets/dev/public.key` and `private.key`. | `lti1p3.yaml`, `config/secrets/dev/` |
| CORS for localhost | Browser CORS origin limited to localhost and `127.0.0.1`. | `config/packages/nelmio_cors.yaml`, `.env` `CORS_ALLOW_ORIGIN` |
| QA deploy | Branch `master` zips the repo and CodeDeploys with `QA_*` variables. | `bitbucket-pipelines.yml` |
| Apache install layout | Files land in `/var/www/html/clms.clicklearning.org/` as `apache`. Start hook runs `service httpd start`. | `appspec.yml`, `scripts/start_server` |
| Recipe PostgreSQL | Compose service `database` uses Postgres 13. Application code does not query it. | `docker-compose.yml`, `config/packages/doctrine.yaml` |
| OpenAPI switch | API Platform swagger versions `[3]` is set. One resource is declared. | `config/packages/api_platform.yaml`, `ltirequest.php` |

## Present on `Production`, not on `master`

| Feature | Behaviour | Evidence |
|---|---|---|
| Home label | `GET /` returns HTML text `clms.clicklearning.org`. | `DefaultController::home` added in `131cc59` |
| Learn return URL | `return_url` host is `learn.clicklearning.org` instead of `portaltest.clicklearning.org`. | `91d9530` |
| Production deploy | Branch name `Production` CodeDeploys with `PROD_*` variables. The pipeline key was `production` for one commit, then renamed. | `50ba7e3`, `1fcda4a` |
| Compiled prod env file | `.env.local.php` is tracked and sets `APP_ENV` and `SYMFONY_ENV` to `prod`. `.env` on the same branch still says `APP_ENV=dev`. | `origin/Production:.env.local.php`, `.env` |
| PHP platform pin | Constraint `php: >=8.0`, Composer platform PHP `8.2`, plus `laminas/laminas-code`. | `composer.json` on `origin/Production` |
| Start-hook export | `scripts/start_server` exports `SYMFONY_ENV=prod` after `service httpd start`. Symfony 5.4 reads `APP_ENV`. The export is in the hook shell, not in an Apache env file. | `scripts/start_server` on `origin/Production` |
| Committed dev cache | `var/cache/dev/` is tracked on this branch. | `git diff --name-only master origin/Production` |

## Planned

No TODO, ticket, or roadmap file describes a future feature.

In-code notes that describe work not done:

| Note | Where | Status |
|---|---|---|
| `//TODO:` inside `authenticate`, with no lookup | `UserAuthenticator.php` | **Unknown** whether anyone still intends to implement it |
| `TESTING ONLY, 2nd param needs to be false` | `LtiRequestController.php` | **Implemented** test arguments. Not switched off |
| `needs to be unique` on the resource-link id | Both controllers | **Implemented** as a constant. Not made unique |
| Commented HTML redirect | `LtiRequestController.php` | Present as a comment. The live return is the JSON URL |

## Completed

Git does not label a release. The history that landed on `master` and is still visible in the current launch is:

| When | What remains |
|---|---|
| 2022-06-03 to 2022-06-08 | Symfony app, API Platform resource, CodeDeploy, TAO launch URL |
| 2022-06-09 to 2022-06-15 | Learner id and quiz id on the route; return URL moved off localhost onto a domain |
| 2022-08-03 to 2022-08-04 | Quiz end date and `deliverySettings.closeOn` |
| 2022-09-25 to 2022-10-20 | TAO endpoint and platform URL updates that match `lti1p3.yaml` and `DefaultController` on `99bde51` |

August commits also mention a delivery TTL custom claim (`8abb811`, `c07031e`). The current `DefaultController` does not set a TTL claim. Provenance: those commits are **history**. The TTL claim is not a current feature.

## Deprecated / removed

Nothing in git deletes a controller after it was added. The following are off the `master` path without a removal commit that says "deprecated":

| Item | What the tree shows |
|---|---|
| Delivery TTL claim | Introduced in August 2022 commit messages. Absent from `DefaultController.php` at `99bde51`. |
| `APP_ENV=prod` in `.env` | Set in `535f550` and again on `Production` in `4c10c2e`, then reverted to `dev` (`4f6cc87`, `325e804`). |
| HTML redirect from `LtiRequestController` | The return statement is commented. The method returns a JSON string. |
| Pipeline branch key `production` | Renamed to `Production` in `1fcda4a` so the key matches the branch name. |

## Not in this repository

- A page named `click-home-learning`.
- The TAO Ignite application.
- A learner profile, class, school, or quiz catalogue.
- Login, roles, or an admin UI.
- Tests (`composer.json` has no `require-dev`; `git ls-files` has no `tests/` path).
- README or Sonar project files in git.
- A PHP or Apache service in Docker Compose.
- Background workers, queues, or a monitoring config.
