# Studio Readiness Audit

_A domain-by-domain gap analysis of the FlowFabric codebase against enterprise no-code platform expectations (Mendix/OutSystems/Appian/Power Platform-class), produced 2026-09-10. See the companion artifact for the visual version: https://claude.ai/code/artifact/2240870e-9403-4c81-8467-7da3316b33be_

## Where the platform is solid

**Data Model & App Builder — Built.** Masters, Forms, and Pages form a genuinely deep no-code triangle: reference fields cascade off one another, formulas compute server-side, and a Data Grid gives inline CRUD without leaving the page — all gated by row-level scope, enforced twice (app layer and Postgres RLS).

- No internal reader view for a Page — only the Designer, so an internal "landing page" opens in edit mode.
- Form submissions are append-only; there's no first-class "edit an existing record via a Form" flow.

_Refs: `backend/app/schemas/{master,workflow,navigation}.py`, `db/schema.sql` RLS policies_

That foundation is what the rest of this audit is measured against — everything below is real, working code with specific, named gaps, not a from-scratch list.

## The eight domains

### 1. Workflow Engine — Partial

**What exists:** start/task/approval/decision/end steps, a full append-only step-history audit trail, and SLA hours with a business-days mode. Parent→child instance spawning emulates fan-out to multiple offices (fork-join for one use case, not a generic construct).

**Gaps:**
- No real parallel gateway, loop, or callable sub-workflow — only single-path transitions plus fire-and-forget spawn.
- Instance status has an `escalated` state that's declared but never actually set anywhere.
- No mid-instance reassignment or delegation of an approver.
- Advance/start run synchronously inside the HTTP request — no durable job queue behind it.

_Refs: `backend/app/routers/workflow_instances.py`, `core/scheduler.py`_

### 2. Automation & Integrations — Partial

**What exists:** seventeen Task node types — email, SMS, Excel, PDF, REST, SOAP, MQTT, payment initiation, custom code — each backed by a real library, not a stub.

**Gaps:**
- No retry or backoff policy on any node — one failed call fails the task.
- No OAuth2 flow for a connector, and no inbound webhook _trigger_ — only outbound calls.
- Connector credentials sit in plain JSONB — no secrets vault or masking.
- `custom_code` runs via a bare subprocess with a 15s timeout, not a real sandbox.

_Refs: `backend/app/crud/tasks.py`, `models/connector.py`_

### 3. Analytics & Reporting — Partial

**What exists:** five widget types on a two-column dashboard grid, a Data Explorer with filter/sort and one aggregate function, Excel export.

**Gaps:**
- `refresh_interval` is stored on every widget but nothing ever polls — "real-time" is a label.
- No drill-down or cross-filtering between widgets on the same dashboard.
- PDF export and scheduled report delivery both have schema fields but no code path that fires them.
- Datasets are single-source — no real cross-Master join, no pivot/OLAP view.

_Refs: `frontend/src/pages/DashboardDetail.tsx`, `crud/dataset_query.py`_

### 4. App Lifecycle & Governance — Partial

**What exists:** App Bundle export/import genuinely works cross-tenant, with id remapping and credential stripping. Every write already lands in an append-only audit log.

**Gaps:**
- No frontend page reads the audit log — it's real data nobody can currently see.
- Releases are a snapshot for history, explicitly not a rollback mechanism.
- No dev→staging→prod pipeline — "promotion" means export a file, import it elsewhere by hand.
- Nothing tests a Form or Workflow before publish, and no approval gate sits in front of publishing.

_Refs: `backend/app/crud/{audit,app_bundle,release}.py`_

### 5. Security & Identity — Partial

**What exists:** JWT + bcrypt auth, and Postgres Row-Level Security scoping every tenant-owned table — a real, DB-enforced isolation layer, not just an app-side filter.

**Gaps:**
- No SSO — no SAML or OIDC federation anywhere in the codebase.
- No MFA, no password complexity/expiry policy.
- Tokens can't be revoked server-side — no refresh tokens, no logout-everywhere.
- No API keys for machine-to-machine integration, no IP allowlisting.

_Refs: `backend/app/core/{auth,security}.py`, `db/schema.sql:713-756`_

### 6. Scalability & Platform Ops — Missing

**What exists:** scheduling runs on a single in-process asyncio loop, documented in its own header as having no distributed-lock story for more than one worker.

**Gaps:**
- No background job queue (Celery/RQ) and no cache layer (Redis) anywhere in the stack.
- No containerization — no Dockerfile, no docker-compose, no CI pipeline.
- `/health` returns a bare OK with no dependency checks; no metrics endpoint, no error tracking.
- Search is `ILIKE` only — no full-text index.

_Refs: `backend/app/core/scheduler.py`, repo root (no Dockerfile found)_

### 7. i18n & Accessibility — Missing

**What exists:** i18next is wired, but by its own header comment scoped deliberately to the Portal's chrome only.

**Gaps:**
- Two locales, roughly sixteen translated strings total — the internal Studio is 100% English-only.
- No RTL support anywhere in the CSS.
- Four `aria-label` occurrences across the entire frontend — no accessibility pass has happened.
- No mechanism for a tenant to localize their own form labels or page copy.

_Refs: `frontend/src/lib/i18n.ts`, `locales/{en,hi}.json`_

## Where to spend the next quarter

1. **Stand up a real job queue.** Celery or RQ behind Redis, replacing the in-process scheduler. Nearly every other gap — SLA escalation, report delivery, node retries, horizontal scaling — needs durable background execution to sit underneath it first.
2. **Add SSO and MFA.** SAML or OIDC federation plus TOTP. For an enterprise buyer's security review, this is usually the single line item that decides whether the conversation continues at all.
3. **Containerize and wire up CI.** A Dockerfile, docker-compose for local/staging parity, and a GitHub Actions pipeline running the existing seven-module test suite. Nothing else here can be deployed credibly without this.
4. **Put a face on the audit log, and gate publishing behind it.** The data already exists and is already correct — this is a frontend page plus one approval step in front of "Publish," not new backend work.
5. **Give the Workflow engine real parallel branches and retries.** A fork/join gateway, a loop construct, and a retry policy on Task nodes close the largest functional gap against Appian- or Mendix-class competitors, and finally give the dormant `escalated` status somewhere to go.

---

_8 domains reviewed · 1 built · 5 partial · 2 missing_
