public documentation · no login

You buy the source.
We can put it on your server.

Flowuri is four packages for a small company: Leads, TimeTrack, Billing and Calendar. Each module is $50. You get the code, you host it, you own the data. If you want us to install it, that's $20.

Buy the code

This is not a subscription. You pay once, you receive the source for that module, and you run it on your own machine or VPS. Same accounts work across every module you add later.

one module

Any single package

$50 once

Leads, TimeTrack, Billing or Calendar. Source + the shared login/server pieces it needs to run.

we do the server

Install help

$20 once

We put the code on your host, create the database, start the realtime process, and leave you a working login.

PackageLives atWhat it isPrice
Flowuri Leads/app/Realtime conversation canvas per lead$50
Flowuri TimeTrack/timetrack/Clock in, breaks, approvals, CSV reports$50
Flowuri Billing/billing/Estimates, invoices, customer share links$50
Flowuri Calendar/calendar/Week view, booking link, .ics$50
All four/Same login, four apps$200
Install help—We set it up on your server$20

To buy, say which modules you want on the contact form. You get a zip of the source (or a repo copy) and these docs. No account is required to read this page.

What you get

  • The source for the modules you paid for — PHP backend, SQL, and the Vue/React frontends.
  • A shared identity: one users / sessions table. Add a person once.
  • A WebSocket server with no Composer dependencies. Reverse-proxy it at /ws.
  • Each extra module is its own tables (tt_*, bill_*, cal_*) and its own folder. Buying Calendar does not require Billing.
  • You host it. Nothing phones home.

Stack

LayerWhat
HTTPApache or Nginx + PHP 8.3 (FPM). Document root is public_html/.
DatabaseMySQL / MariaDB. Fresh install: sql/schema.sql. Upgrades: sql/migrations/.
Realtimephp server/ws_server.php — RFC 6455, no Ratchet. Proxy /ws to it.
Leads UIVue 3 + Vite in leads/ → builds to public_html/app/.
TimeTrack UIReact in timetracker/frontend/ → public_html/timetrack/.
Billing UIVue 3 + Vite in billing/ → public_html/billing/.
Calendar UIVue 3 + Vite in calendar/ → public_html/calendar/.
MarketingPlain HTML: /, /contact.html, this page.

Frontends live outside the document root so Apache never serves node_modules. Only the built folders under public_html/ are public.

Directory layout

public_html/
  index.html              Homepage
  contact.html            Contact form
  docs.html               This page
  PROTOCOL.md             WebSocket message reference
  app/                    Leads build  → /app/
  timetrack/              TimeTrack build → /timetrack/
  billing/                Billing build → /billing/
  calendar/               Calendar build → /calendar/
  sql/schema.sql          Fresh database
  sql/migrations/         002 … 008 (add modules)
  server/config.php       DB, WS, uploads, mail
  server/ws_server.php    Realtime daemon
  server/*Repository.php  One file per product
  api/login.php           Shared login (token)
  api/*_share.php         Public customer links
  bin/create_user.php     Make / reset accounts

leads/                    Vue source for Leads
billing/                  Vue source for Billing
calendar/                 Vue source for Calendar
timetracker/frontend/     React source for TimeTrack

Do not hand-edit public_html/app/, timetrack/, billing/ or calendar/ — the next npm run build empties them.

Modules

Each product is a folder, a SQL migration, a repository class, and a WebSocket *.request family. Identity stays in users.

Leads — $50

Path /app/. Tables: leads, nodes, attachments, audit, plus sharing. Messages are named actions (lead.create, node.update, …) on the same socket. owner sees every lead; salesrep sees only what they own or were shared.

cd leads && npm install && npm run build
# writes public_html/app/

TimeTrack — $50

Path /timetrack/. Migration 006_timetracker.sql (tt_* tables only). RPC: {"type":"tt.request","request_id":"…","action":"time.clock_in","payload":{}}. Includes a Chrome/Edge extension that clocks in from ClickUp or Jira.

cd timetracker/frontend && npm install && npm run build
# writes public_html/timetrack/

Billing — $50

Path /billing/. Migration 007_billing.sql (bill_*). RPC: bill.request. Customers open /billing/p/:shareId with no login via /api/billing_share.php. Can import approved hours from TimeTrack if that module is installed.

cd billing && npm install && npm run build
# writes public_html/billing/

Calendar — $50

Path /calendar/. Migration 008_calendar.sql (cal_*). RPC: cal.request. Public booking /calendar/p/:shareId and confirmation /calendar/m/:shareId use /api/calendar_share.php. Times stored UTC; company timezone defaults to Europe/Bucharest.

cd calendar && npm install && npm run build
# writes public_html/calendar/

Install it yourself

You need PHP 8.3, MySQL/MariaDB, Node (to build UIs), and Apache or Nginx. Point the web root at public_html/.

1. Database

New machine:

mysql -u root -p < public_html/sql/schema.sql

That seeds three demo accounts — change the passwords before anyone else can reach the server:

usernamepasswordrole
ownerowner123owner
salesrep1salesrep123salesrep
salesrep2salesrep123salesrep

Existing database: run migrations in order, only the ones for modules you bought:

mysql -u root -p leadflow < public_html/sql/migrations/006_timetracker.sql
mysql -u root -p leadflow < public_html/sql/migrations/007_billing.sql
mysql -u root -p leadflow < public_html/sql/migrations/008_calendar.sql

Create a non-root DB user and put the password in the environment, not in git:

LEADFLOW_DB_HOST, LEADFLOW_DB_NAME, LEADFLOW_DB_USER, LEADFLOW_DB_PASS
LEADFLOW_WS_HOST, LEADFLOW_WS_PORT, LEADFLOW_WS_SECRET

LEADFLOW_WS_SECRET must be a long random string. It lets upload.php and the share endpoints push live events into the socket. Anyone who knows it can inject broadcasts.

2. Realtime daemon

php public_html/server/ws_server.php

Keep it up with systemd or supervisor. After any PHP or migration change, restart it.

3. Reverse-proxy /ws

Terminate HTTPS on Apache/Nginx and proxy the WebSocket to 127.0.0.1:8080 (or whatever you set). The PHP process itself stays on plain TCP.

# Apache
ProxyPass /ws ws://127.0.0.1:8080
ProxyPassReverse /ws ws://127.0.0.1:8080

# Nginx
location /ws {
  proxy_pass http://127.0.0.1:8080;
  proxy_http_version 1.1;
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection "upgrade";
}

4. SPA fallbacks

TimeTrack, Billing and Calendar use client-side routes. Each build copies an .htaccess. If AllowOverride is off, add e.g.:

<Directory /var/www/flowuri/public_html/calendar>
    AllowOverride All
    FallbackResource /calendar/index.html
</Directory>

5. First user

php public_html/bin/create_user.php --reset-password owner 'your-new-password'

We install — $20

If you would rather not touch Apache, send the host login (or a temporary SSH user) and which modules you bought on the contact form. For $20 we:

  • Copy the source onto the server
  • Create the database and run the right migrations
  • Set environment variables and a real LEADFLOW_WS_SECRET
  • Start ws_server.php so it survives a reboot
  • Point /ws and the module folders at the right places
  • Leave you an owner login and tell you to change the password

The $20 is the setup, not a hosting fee. The machine stays yours.

Login and roles

Every app uses POST /api/login.php with {username, password}. The response is an opaque token. Store it as accessToken in localStorage. Open /ws, then send:

{"type":"hello","token":"…"}

The server replies welcome. After that, Leads uses named messages; the other three use correlated RPC.

  • owner — sees everything, company settings, void/convert in Billing, Calendar defaults, TimeTrack admin.
  • salesrep — Leads they own or were shared; they can draft and send bills; they see the team calendar and edit their own meetings.

Roles are checked in PHP on every write. Hiding a button is not the security model.

Realtime protocol

One JSON object per WebSocket text frame, always with a type. Full field list: /PROTOCOL.md (also public, no login).

AppRequestReplyPush
Leadslead.*, node.*, …broadcast + errorlead.updated, node.created, …
TimeTracktt.requesttt.responsett.event
Billingbill.requestbill.responsebill.event
Calendarcal.requestcal.responsecal.event
{"type":"cal.request","request_id":"d4b2","action":"meetings.list","payload":{}}
{"type":"cal.response","request_id":"d4b2","ok":true,"data":[]}

Customer pages (estimate accept, calendar book) are ordinary HTTP on /api/*_share.php. They may push an event so the logged-in team sees the change live.

Build the frontends

On a machine with Node:

cd leads && npm install && npm run build
cd ../timetracker/frontend && npm install && npm run build
cd ../../billing && npm install && npm run build
cd ../calendar && npm install && npm run build

Local work against a running backend:

FLOWURI_DEV_PROXY=http://localhost:8090 npm run dev

Ports: Leads 5173, TimeTrack per its README, Billing 5175, Calendar 5176.

Smoke the PHP side after deploy:

php public_html/bin/test_timetracker_backend.php --database
php public_html/bin/test_billing_backend.php --database
php public_html/bin/test_calendar_backend.php --database

Ready to buy, or want the $20 install? Contact us →