KatoCall — install instructions
===============================

The short version. README.md in the same directory is the full one, and
covers configuration, operation and the security posture.


WHAT YOU NEED
-------------

  A server            Debian 12 (Bookworm), 64-bit. Nothing else is
                      tested. A fresh VPS is the expected starting
                      point — the installer configures the firewall,
                      nginx and fail2ban, and will not fight an
                      existing web server for you.
  2 CPU cores         minimum.
  4 GB RAM            recommended; 2 GB is the floor. Building Asterisk
                      from source is the peak, and below 2 GB it is
                      killed by the kernel part-way through.
  20 GB free disk     The Asterisk source build needs ~1.5 GB on its
                      own, and CDRs grow with your traffic.
  A public IPv4       address.
  root                or an account with sudo.

  A DNS name          Only if you want HTTPS. Let's Encrypt will not
                      issue a certificate for a bare IP address, so
                      without a name the panel stays on plain HTTP.

  Ports open to the   80/tcp      the panel (443 once TLS is set up)
  internet            5060/udp    SIP signalling
                      5060/tcp    SIP signalling
                      10000-20000/udp  RTP media
                      your SSH port — detected and kept open for you

                      The installer configures ufw itself. If your
                      provider has its own firewall in front of the
                      box (OVH, Hetzner, AWS security groups), open
                      these there too.

  From your carrier   A SIP trunk: their host, and either an IP they
                      will accept you from or a username and password.
                      Numbers (DIDs) if you want to receive calls.

`install/00-preflight.sh` checks the server side of all of this and
tells you what is wrong before anything is installed. It changes
nothing.

Installed for you: Asterisk 20 (built from source), PostgreSQL, Redis,
Python 3, Node.js 20, nginx, ufw, fail2ban, certbot.


INSTALLING
----------

The quick way — one command runs the whole thing:

    sudo bash install/install.sh

It runs preflight, then 01-09 and backups (11), in order, and stops with
a clear message if anything fails — fix it and run the same command
again; the steps that already finished skip themselves. Add --with-dialer
for the outbound dialer, and --tls <domain> <email> for HTTPS. Installing
against a domain? Export KATOCALL_HOSTNAME first (see below).

To do it by hand instead — or just to see what each step does — run them
yourself, as root, on a fresh box, in this order. Each script is
idempotent, and each checks its own prerequisites and refuses with an
explanation rather than half-applying.

    sudo bash install/00-preflight.sh            # checks the box, changes nothing
    sudo bash install/01-install-asterisk.sh     # Asterisk 20 from source, 10-20 min
    sudo bash install/02-install-base-stack.sh   # PostgreSQL, Redis, Python, Node
    sudo bash install/03-setup-admin-panel.sh    # backend, frontend, database, admin user
    sudo bash install/04-configure-ami.sh        # connects Asterisk to the billing engine
    sudo bash install/05-production-hardening.sh # nginx + daphne + firewall
    sudo bash install/06-configure-did-forwarding.sh   # inbound numbers
    sudo bash install/07-configure-fail2ban.sh   # SIP and panel brute-force protection
    sudo bash install/08-configure-nat.sh        # PJSIP provisioning (and NAT if needed)
    sudo bash install/09-configure-outbound.sh   # outbound routing
    sudo bash install/11-configure-backups.sh    # nightly backups, log rotation
    sudo bash install/12-configure-dialer.sh     # predictive/power dialer (optional)

ALL OF 01-09 ARE REQUIRED. 06, 08 and 09 are what make the switch carry
calls: without them you have a billing panel that cannot dial.

12 is only needed if you will use the outbound dialer (campaigns and the
IVR menu). It installs the dialer's dialplan and the katocall-dialer
service; skip it and everything else works exactly the same.

Then, if you have a domain pointing at this box:

    sudo bash install/10-configure-tls.sh panel.example.com you@example.com

Installing against a domain rather than a bare IP? Set it BEFORE 03, so
the panel is configured for the name you will actually use:

    export KATOCALL_HOSTNAME=panel.example.com

Finally, confirm it:

    sudo bash install/verify.sh

That checks around fifty things — every service, the firewall, the
migrations, the fail2ban filters, the file permissions that keep the
telephony user away from the panel's secrets — and names the script to
re-run for anything that failed. Run it after an install, after an
upgrade, and any time something is wrong.


YOUR FIRST LOGIN
----------------

    http://<your-server>/

    username: admin
    password: Katocall

It will immediately require a new password, and NOTHING ELSE WORKS until
you set one — not the API, not the Django admin, not the live-call feed.
A predictable first login that cannot survive first contact is safer in
practice than a generated one you have to go and find.

For an unattended install, set KATOCALL_ADMIN_PASSWORD before running
03. It is still forced to change on first use.


THEN
----

In the panel, in this order:

  1. Suppliers      who you buy minutes from
  2. Rate Cards     one for what they charge you (provider), one for
                    what you charge (customer). Import the carrier's
                    CSV deck rather than typing prefixes.
  3. Trunks         the SIP connection to each supplier
  4. Routing Groups which trunks to try for which prefixes, in order
  5. Accounts       your customers: their rate card, routing group,
                    balance, and how they authenticate
  6. DIDs           inbound numbers, and where each one forwards to

Every field in the panel has a "?" beside it that explains what it is
for, in all ten interface languages. Settings > Network is where you
push your configuration to Asterisk.


OPERATING IT
------------

    sudo bash install/verify.sh                  # is everything healthy?
    sudo bash install/upgrade.sh                 # apply a newer version
    sudo /usr/local/sbin/katocall-backup         # take a backup now
    sudo bash install/uninstall.sh               # remove it (keeps the data)

Backups run nightly to /var/backups/katocall and hold the database and
the secrets together, because either alone cannot be restored. THEY ARE
ON THE SAME DISK AS THE THING THEY BACK UP — copy them elsewhere.


WHAT IS NOT IN THIS RELEASE
---------------------------

Read this before you promise any of it to a customer.

  * THE DIALER IS A POWER DIALER, NOT A PREDICTIVE ONE. A running
    campaign DOES place calls now (install step 12 and the
    katocall-dialer service), through the same routing AGI as every
    other outbound call, so they are rated and billed identically. But
    it has NO ANSWERING-MACHINE DETECTION — a voicemail that answers
    counts as answered and is handed to the IVR menu — and NO PREDICTIVE
    PACING: concurrency is a fixed ceiling you set per campaign (also
    capped by the account's channel limit and balance), not a rate it
    adjusts against a live-agent pool or an abandon-rate target. One
    engine runs at a time, so the dialer does not scale across multiple
    boxes. If you did NOT run install step 12, a campaign set to
    "Running" stores that status and dials nothing.

  * NO CURRENCY CONVERSION. Every account and every supplier carries its
    own currency and nothing converts between them, because there is no
    exchange rate anywhere in this platform. A call whose sell and cost
    currencies differ therefore shows NO margin — in the panel and in
    the CSV export both — and a revenue total spanning more than one
    currency is shown without a unit. If you bill in one currency and
    buy in another, per-call margin and the dashboard totals are yours
    to compute outside this system.

  * SUPPLIER CREDIT LIMIT IS A NOTE, NOT A CONTROL. A PREPAID supplier
    stops receiving calls when its balance reaches zero. A POSTPAID
    supplier's balance runs negative without limit; the "credit limit"
    field records what you believe the real limit is and does not stop
    routing. The same is true of a postpaid customer account with no
    limit set.

  * CONCURRENT-CALL EXPOSURE IS BOUNDED BY THE BALANCE, NOT BY ZERO. A
    prepaid account's calls are each capped against its balance minus
    what its other live calls are about to charge, and the billing loop
    re-checks every increment — so a fan-out cannot spend several times
    the balance. It can still end a call slightly past zero, by at most
    one billing increment on the last call standing.


BEFORE YOU GO LIVE
------------------

  * Run install/10-configure-tls.sh. Until you do, the panel is plain
    HTTP and the session cookie of an account that can move money
    crosses the network in the clear.
  * Copy the backups off the box.
  * Read "WHAT IS NOT IN THIS RELEASE" above, and the "Security posture"
    section of README.md. That one lists what is protected and, just as
    importantly, what is not.
  * Check the ledger reconciles before you trust a report:
        sudo -u softswitch admin/backend/venv/bin/python              admin/backend/manage.py verify_ledger
