- Introduced a new `processor` service in the Docker Compose setup to handle face matching jobs. - Configured Redis as a job queue and state management system for processing searches. - Updated the backend to enqueue jobs and manage user locks using Redis. - Added environment variables for Redis configuration and runtime paths. - Created technical design documentation for the processor service outlining architecture, queue model, and search lifecycle. - Updated package.json and package-lock.json to include dependencies for BullMQ and ioredis in the processor workspace. - Added sample PKL files for local testing in the `test_pkl` directory.
238 lines
9.2 KiB
Markdown
238 lines
9.2 KiB
Markdown
# FaceAI Scaffold
|
|
|
|
This folder scaffolds the new FaceAI app described in the integration plan.
|
|
|
|
It includes:
|
|
|
|
- a Vue frontend for the FaceAI upload and polling flow
|
|
- a Node/Express backend for session exchange, mocked searches, and return handoff
|
|
- a local legacy simulator so the launch and return flow can be tested without the old Java site
|
|
- a Dockerized PHP Apache stack for exercising the real `www/faceai_handoff.php` and `www/faceai_return.php` bridge files
|
|
|
|
## Structure
|
|
|
|
```text
|
|
faceai/
|
|
apps/
|
|
backend/
|
|
frontend/
|
|
docker/
|
|
Dockerfile
|
|
```
|
|
|
|
## What The Local Test Covers
|
|
|
|
The local simulator exercises the exact flow the plan is aiming for:
|
|
|
|
1. a legacy-like race page shows a `Face ID` button instead of `tipoPuntoFoto`
|
|
2. clicking it hits a mock legacy handoff endpoint
|
|
3. the backend signs a short-lived handoff token and redirects to the Vue app
|
|
4. the Vue app exchanges the token for its own FaceAI session cookie
|
|
5. the user uploads a selfie and starts a mocked race-scoped search
|
|
6. the frontend polls until the job completes
|
|
7. FaceAI requests a signed return URL
|
|
8. the browser is redirected back to a legacy-like filtered race page showing only the matched photos
|
|
|
|
## Local Run
|
|
|
|
From this folder:
|
|
|
|
```bash
|
|
npm install
|
|
npm run dev
|
|
```
|
|
|
|
Then open:
|
|
|
|
```text
|
|
http://localhost:3001/dev/legacy/race?raceId=101&lang=it
|
|
```
|
|
|
|
That page simulates the old site and launches the FaceAI app at `http://localhost:5173`.
|
|
|
|
## Docker Run With PHP Simulator
|
|
|
|
If you do not have PHP locally, use Docker instead:
|
|
|
|
```bash
|
|
npm install
|
|
npm run build
|
|
docker compose up --build
|
|
```
|
|
|
|
The Docker stack reuses the local FaceAI workspace and only containerizes the runtime services. That means PHP is fully containerized, while the Node service runs inside Docker against the already-installed local workspace dependencies and the already-built frontend assets.
|
|
|
|
This starts:
|
|
|
|
- FaceAI app on `http://localhost:3001`
|
|
- PHP Apache serving `www` on `http://localhost:8080`
|
|
|
|
For the end-to-end test through the PHP bridge, open:
|
|
|
|
```text
|
|
http://localhost:8080/faceai_simulator.php?raceId=101&lang=it
|
|
```
|
|
|
|
That page loads the original race-page JavaScript from `www/_js/rus-ecom-240621.js`, lets the script replace the visible `tipoPuntoFoto` selector with the new `Face ID` button, and launches the real PHP handoff bridge at `www/faceai_handoff.php`.
|
|
|
|
If you change frontend code and want Docker to serve the updated UI, rebuild first with:
|
|
|
|
```bash
|
|
npm run build
|
|
```
|
|
|
|
## Production Deployment From Registry
|
|
|
|
The published container is the user-facing FaceAI site only. It already contains:
|
|
|
|
- the Node/Express backend
|
|
- the built Vue frontend assets served by that backend
|
|
|
|
It does not include:
|
|
|
|
- the legacy PHP simulator
|
|
- the existing `www` site
|
|
- the future queue/processor worker
|
|
|
|
In production, deploy a single FaceAI container behind HTTPS on its own host name, for example `faceai.regalamiunsorriso.it`, and keep the legacy site on its existing stack.
|
|
|
|
### What The Production Container Exposes
|
|
|
|
- HTTP service on port `3001` inside the container
|
|
- health endpoint at `/health`
|
|
- frontend and API from the same process
|
|
|
|
The image should be run with a reverse proxy or ingress that terminates TLS and forwards traffic to the container.
|
|
|
|
### Required Runtime Configuration
|
|
|
|
Set these environment variables for production:
|
|
|
|
| Variable | Required | Example | Purpose |
|
|
| --- | --- | --- | --- |
|
|
| `NODE_ENV` | yes | `production` | disables development defaults |
|
|
| `PORT` | optional | `3001` | internal listen port |
|
|
| `FACEAI_FRONTEND_URL` | yes | `https://faceai.regalamiunsorriso.it` | URL used when the legacy bridge redirects into the app |
|
|
| `FACEAI_PUBLIC_BASE_URL` | yes | `https://faceai.regalamiunsorriso.it` | public base URL used for local links and return flow generation |
|
|
| `FACEAI_LEGACY_RETURN_URL` | yes | `https://www.regalamiunsorriso.it/faceai_return.php` | legacy endpoint that receives the signed FaceAI result handoff |
|
|
| `FACEAI_SHARED_SECRET` | yes | long random secret | shared signing secret between FaceAI and the legacy handoff/return bridge |
|
|
| `FACEAI_SESSION_COOKIE` | optional | `rus_faceai_session` | cookie name for the FaceAI session |
|
|
| `FACEAI_ENABLE_LOCAL_LEGACY_STATIC` | recommended | `0` | disables development-only static serving of local legacy assets |
|
|
|
|
Do not enable `FACEAI_ENABLE_LOCAL_LEGACY_STATIC` in production. That mode exists only for local simulator flows.
|
|
|
|
### Legacy-Side Configuration That Must Match
|
|
|
|
The container will not work correctly in production unless the legacy bridge is configured consistently.
|
|
|
|
The legacy site must:
|
|
|
|
- redirect users into `FACEAI_FRONTEND_URL` with a valid signed handoff token
|
|
- use the same `FACEAI_SHARED_SECRET` as the FaceAI container
|
|
- expose the configured `FACEAI_LEGACY_RETURN_URL`
|
|
- validate the signed return token and fetch the result payload from FaceAI
|
|
|
|
The shared secret is the trust boundary between the legacy site and FaceAI. Treat it like any other production secret and inject it through the platform secret store, not through source control.
|
|
|
|
### Example Docker Compose For Production
|
|
|
|
Replace the registry path and secret values with the real ones from Forgejo.
|
|
|
|
```yaml
|
|
services:
|
|
faceai:
|
|
image: registry.example.com/my-namespace/faceai:latest
|
|
container_name: regalami-faceai
|
|
restart: unless-stopped
|
|
environment:
|
|
NODE_ENV: production
|
|
PORT: 3001
|
|
FACEAI_FRONTEND_URL: https://faceai.regalamiunsorriso.it
|
|
FACEAI_PUBLIC_BASE_URL: https://faceai.regalamiunsorriso.it
|
|
FACEAI_LEGACY_RETURN_URL: https://www.regalamiunsorriso.it/faceai_return.php
|
|
FACEAI_SHARED_SECRET: change-this-to-a-long-random-secret
|
|
FACEAI_SESSION_COOKIE: rus_faceai_session
|
|
FACEAI_ENABLE_LOCAL_LEGACY_STATIC: 0
|
|
ports:
|
|
- "127.0.0.1:3001:3001"
|
|
```
|
|
|
|
This pattern assumes a reverse proxy on the host publishes `https://faceai.regalamiunsorriso.it` and forwards to `127.0.0.1:3001`.
|
|
|
|
### Example Docker Run
|
|
|
|
```bash
|
|
docker run -d \
|
|
--name regalami-faceai \
|
|
--restart unless-stopped \
|
|
-p 127.0.0.1:3001:3001 \
|
|
-e NODE_ENV=production \
|
|
-e PORT=3001 \
|
|
-e FACEAI_FRONTEND_URL=https://faceai.regalamiunsorriso.it \
|
|
-e FACEAI_PUBLIC_BASE_URL=https://faceai.regalamiunsorriso.it \
|
|
-e FACEAI_LEGACY_RETURN_URL=https://www.regalamiunsorriso.it/faceai_return.php \
|
|
-e FACEAI_SHARED_SECRET=change-this-to-a-long-random-secret \
|
|
-e FACEAI_SESSION_COOKIE=rus_faceai_session \
|
|
-e FACEAI_ENABLE_LOCAL_LEGACY_STATIC=0 \
|
|
registry.example.com/my-namespace/faceai:latest
|
|
```
|
|
|
|
### Reverse Proxy Expectations
|
|
|
|
The app should sit behind HTTPS. In practice that means:
|
|
|
|
- publish only the public FaceAI host name externally
|
|
- forward the original host and scheme headers from the proxy
|
|
- keep the container bound to localhost or a private network if possible
|
|
- allow normal browser redirects between the legacy site and the FaceAI host
|
|
|
|
### Post-Deploy Validation
|
|
|
|
After the container is up, validate at least the following:
|
|
|
|
1. `GET /health` returns `{"ok":true}` through the public FaceAI host.
|
|
2. The legacy handoff endpoint redirects to `https://faceai.../auth/callback?token=...`.
|
|
3. FaceAI can exchange the token and establish a session.
|
|
4. Completing a search produces a redirect URL that points to `FACEAI_LEGACY_RETURN_URL`.
|
|
5. The legacy return endpoint can resolve the signed result and render the filtered race page.
|
|
|
|
### Current Production Limitations
|
|
|
|
This image can be published and deployed, but the current scaffold still has important limitations:
|
|
|
|
- sessions and search results are stored only in memory, so container restarts lose state
|
|
- there is no real queue or processor yet
|
|
- there is no persistent storage layer yet
|
|
- the backend currently sets the FaceAI session cookie with `secure: false`, which should be hardened before final public rollout
|
|
- the local simulator endpoints under `/dev/*` are still present in the app and should be treated as non-production scaffolding
|
|
|
|
So the registry deployment is appropriate for early hosted integration and controlled production-like rollout, but not yet for the final hardened architecture described in the integration plan
|
|
|
|
## Environment
|
|
|
|
Defaults are already set for local development, but these can be overridden:
|
|
|
|
```text
|
|
PORT=3001
|
|
FACEAI_FRONTEND_URL=http://localhost:5173
|
|
FACEAI_PUBLIC_BASE_URL=http://localhost:3001
|
|
FACEAI_LEGACY_RETURN_URL=http://localhost:3001/dev/legacy/return
|
|
FACEAI_SHARED_SECRET=change-me
|
|
FACEAI_SESSION_COOKIE=rus_faceai_session
|
|
```
|
|
|
|
If you want FaceAI to return through the new PHP bridge prepared under `www`, point `FACEAI_LEGACY_RETURN_URL` to that endpoint instead, for example `http://localhost/faceai_return.php` or the equivalent URL in your local PHP setup.
|
|
|
|
In the provided Docker Compose stack, that wiring is already done with:
|
|
|
|
```text
|
|
FACEAI_LEGACY_RETURN_URL=http://localhost:8080/faceai_return.php
|
|
```
|
|
|
|
## Notes
|
|
|
|
- The backend currently uses in-memory stores and mocked search results.
|
|
- No database or real queue is wired yet.
|
|
- The local legacy simulator is intentionally backend-driven so the handoff can be tested without compiling the existing Java application.
|
|
- `www/faceai_simulator.php` exists only for local testing. It does not replace the actual JSP race page.
|
|
- The final legacy integration still needs a real signed identity source and a real return-filter implementation on the old site.
|