# PRD — formulys_simpleflow_backend

Evidence date: 2026-10-14.

Source: `git@bitbucket.org:overdrive/formulys_simpleflow_backend.git`, `master` at `c30ed2b` (2024-06-05).

There is no prior PRD in the source repository or in Silicon Ark. Requirements below are recovered from `package.json`, `server.js`, `models/User.js`, `socket_handlers/index.js`, `.env`, and `.gitignore`. Provenance is labelled. The value of `MONGO_URI` is not reproduced.

## Product purpose

**Unknown** as a written product statement. Nothing in the repository states what Formulys or Simpleflow is, who pays for it, or which workflows the backend must support.

**Implemented.** A Node.js package that intends to:

1. Serve HTTP with Express, including a `GET /` smoke response.
2. Attach Socket.io to the same HTTP server and broadcast chat-style `message` events.
3. Connect to MongoDB with Mongoose.
4. Define a `User` document with username, password, optional tenant, and role.

**Inferred** from the slug and the `User` role enum: a multi-tenant backend for something named Formulys / Simpleflow, with platform and tenant administrator roles. That inference is not confirmed by any product document.

**Unknown / Requires Confirmation:** product owner, production URL, client applications, and relationship to other Simpleflow repositories documented elsewhere in Silicon Ark.

## Users and roles

| Actor | Evidence | Status |
|---|---|---|
| HTTP client | `GET /` in `server.js` | **Implemented** as anonymous caller. No auth middleware |
| Socket.io client | `io.on('connection', ...)` | **Implemented** as anonymous connection. No auth handshake |
| `tenantUser` | `role` enum in `models/User.js` | **Implemented** as schema value only. No route assigns or checks it |
| `tenantAdmin` | Same enum | Same |
| `platformAdmin` | Same enum | Same |
| Tenant (document) | `tenantId` ref `'Tenant'` | **Implemented** as ObjectId reference. No `Tenant` model file exists |
| Repository authors | Git history: Abdurahmaan Ismail / maanie | **Implemented** as history only |

No login, session, permission check, or role guard exists in source.

## Systems the product talks to

1. **MongoDB** — `mongoose.connect(process.env.MONGO_URI, { useNewUrlParser: true, useUnifiedTopology: true })`. Connection events log errors and a success message. Provenance: **Implemented**.
2. **Socket.io clients** — same process as the HTTP server. Provenance: **Implemented**.
3. **axios HTTP clients** — dependency present; no source file imports it. Provenance of intended use: **Unknown**.

There is no identity provider, mail sender, queue, object storage, or CI integration in this repository.

## Major workflows

### WF-1 — Start the server

**Implemented** as intended behaviour in `server.js` and `package.json`. **Not runnable as committed** (see defects in technical documentation).

Trigger: `npm start` → `node server.js`, or `npm run dev` → `nodemon server.js`.

Expected steps from the source text:

1. Load environment via `dotenv.config()`.
2. Create Express app, HTTP server, and Socket.io.
3. Parse JSON bodies.
4. Connect Mongoose to `MONGO_URI`.
5. Register `GET /` and Socket.io handlers.
6. Listen on `PORT` or `3000`.

Failure behaviour: Mongo connection errors are bound to `console.error`. No retry policy, health check beyond `GET /`, or process exit on DB failure is defined.

### WF-2 — Smoke HTTP check

**Implemented** in `server.js`.

Trigger: `GET /`.

Output: plain text body `Hello World`. No status override (Express default 200). No JSON envelope.

### WF-3 — Broadcast a socket message

**Implemented** in both `server.js` and `socket_handlers/index.js` with the same shape.

Trigger: a connected socket emits `message` with payload `msg`.

Behaviour: `io.emit('message', msg)` — every connected client receives the payload. No validation, room, tenant filter, or persistence.

On connect / disconnect the server logs `User connected` / `User disconnected`.

### WF-4 — Persist a user (schema only)

**Implemented** as a Mongoose model. **Not implemented** as an API or socket command.

A caller that used the model (none does in this repo) would need:

| Field | Rule |
|---|---|
| `username` | String, required, unique |
| `password` | String, required (no hashing in schema) |
| `tenantId` | Optional ObjectId referencing `Tenant` |
| `role` | Required; one of `tenantUser`, `tenantAdmin`, `platformAdmin` |

## Functional requirements

### FR-001 — Keep a Bitbucket repository named formulys_simpleflow_backend

**Implemented.**

Remote observed: `https://jacooverdrive@bitbucket.org/overdrive/formulys_simpleflow_backend.git` (SSH form in task metadata: `git@bitbucket.org:overdrive/formulys_simpleflow_backend.git`). Default branch: `master`. Tip: `c30ed2b`.

Evidence: `git remote`, `origin/HEAD`, `git log`.

### FR-002 — Run as an npm package with start and dev scripts

**Implemented** in `package.json`.

- `name`: `formulys_simpleflow_backend`
- `version`: `1.0.0`
- `scripts.start`: `node server.js`
- `scripts.dev`: `nodemon server.js`
- `main`: `index.js` — **no `index.js` file exists**. Provenance of the `main` field: **Implemented** as a mismatched field. Provenance of intended entry: **Inferred** as `server.js` from the scripts.

### FR-003 — Expose `GET /` that returns Hello World

**Implemented** in `server.js`.

### FR-004 — Connect to MongoDB using `MONGO_URI`

**Implemented** in `server.js` and `.env` (key present). Whether a live database matches the committed URI is **Unknown / Requires Confirmation**.

### FR-005 — Accept Socket.io connections and relay `message` events

**Implemented** in source. Wiring is broken by the missing `./socket` module and premature `socketSetup(io)` call, so the process does not reach a listening state as written.

### FR-006 — Model users with multi-tenant roles

**Implemented** in `models/User.js` as schema only.

### FR-007 — Load configuration from environment variables

**Implemented** via `dotenv` and use of `process.env.MONGO_URI` and `process.env.PORT`.

### FR-008 — Ignore common generated artifacts

**Implemented** as Bitbucket's unmodified example `.gitignore` (Node, Java, Python, Maven, JetBrains, OS junk, media). It does **not** ignore `.env`, and `.env` is tracked.

## Constraints

| Constraint | Provenance |
|---|---|
| Role values limited to three strings | **Implemented** (`enum` on `role`) |
| Username unique | **Implemented** (`unique: true`) |
| Password required as String | **Implemented**; hashing **not** implemented |
| Default listen port 3000 if `PORT` unset | **Implemented** |
| No authentication on HTTP or sockets | **Implemented** (absence) |
| No tests or CI gate | **Implemented** (absence) |

## Edge cases and defects visible in source

| Case | Observation | Provenance |
|---|---|---|
| Missing `./socket` | `require('./socket')` fails; only `socket_handlers/index.js` exists | **Implemented** defect |
| `socketSetup(io)` before `io` is created | Temporal dead zone / ReferenceError if require succeeded | **Implemented** defect |
| Duplicate socket handlers | Inline in `server.js` and in `socket_handlers/index.js` | **Implemented** |
| `Tenant` model missing | `ref: 'Tenant'` with no model file | **Implemented** gap |
| Deprecated Mongoose options | `useNewUrlParser`, `useUnifiedTopology` with mongoose `^8.4.1` | **Inferred** from Mongoose 8 docs vs package range |
| Secrets in git | `.env` tracked | **Implemented** |

## Requirements that could not be established

- Business purpose of Formulys / Simpleflow for this backend.
- Auth method (JWT, sessions, API keys).
- Password storage policy (hashing algorithm, complexity).
- Tenant lifecycle and platform admin workflows.
- Deployment target, Node version, and MongoDB hosting.
- Whether SonarQube was meant for this repo (scan-host files not in git).
- Whether `axios` was intended for a specific upstream API.

Mark all of the above **Unknown / Requires Confirmation**.
