# Vita Server — deployment without SSH / shell access

This guide is for shared hosting (cPanel / DirectAdmin / Plesk / FTP-only)
where you cannot run `composer install` or `php artisan` on the server.

Falcon (the tenant ERP at `vitatec.io`) and Vita Server live on the **same**
host, so Vita Server is served under the subdirectory:

```
https://vitatec.io/vita_server/...
```

Falcon then points at it via the `VITA_MARKETPLACE_BASE_URL` env value.

---

## What you upload

```
vitatec.io/
└── vita_server/                <-- upload contents of this folder
    ├── app/                    Laravel application code
    ├── bootstrap/              cache directory (must be writable)
    ├── config/                 all Laravel config files
    ├── database/
    │   ├── migrations/
    │   ├── seeders/
    │   └── dumps/
    │       └── vita_server_seed.sql   <-- ready-made schema + seed
    ├── public/                 web root for this subdirectory
    │   ├── index.php
    │   ├── install.php         <-- DELETE AFTER FIRST USE
    │   └── .htaccess
    ├── routes/                 api.php
    ├── storage/                writable tree
    ├── vendor/                 17 MB — pre-built locally
    ├── .env                    fill in production values before upload
    ├── .htaccess               redirects requests to public/
    └── artisan                 not used here (no shell), but harmless
```

`vendor/` is shipped pre-built because the production host has no
composer. It was generated locally with:

```
composer install --no-dev --optimize-autoloader
```

---

## Step 1 — Prepare the local `.env` for production

Edit `vita-server/.env` BEFORE uploading and set:

```
APP_NAME=Vita Server
APP_ENV=production
APP_DEBUG=false
APP_URL=https://vitatec.io/vita_server

LOG_LEVEL=warning

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=<your_cpanel_db_for_vita_server>
DB_USERNAME=<db_user>
DB_PASSWORD=<db_password>

VITA_SERVER_ALLOW_DEV_TOKEN=false
INSTALL_KEY=<paste a 32+ char random string here>

CACHE_DRIVER=file
SESSION_DRIVER=file
QUEUE_CONNECTION=sync
```

> **Leave `APP_KEY=` blank.** The web installer (Step 4) will generate
> and write it for you on the first run.

---

## Step 2 — Create the MySQL database via cPanel

1. cPanel → MySQL Databases → create database (e.g. `xxx_vita_server`).
2. Create a user, give it ALL PRIVILEGES on that database.
3. cPanel → phpMyAdmin → select the new database → **Import** tab →
   choose `database/dumps/vita_server_seed.sql` from your laptop.
4. Click **Go**. You should see 4 tables created and rows inserted:
   - `platform_tokens` (1 row — the dev token, **rotate after install**)
   - `modules` (21 rows — Vita catalog)
   - `module_versions` (variable)
   - `entitlements` (105 rows — 5 tenants × 21 modules)
   - `personal_access_tokens` (empty, Sanctum scaffold)
   - `migrations` (5 rows)

Update your `.env` `DB_*` values to match the database/user you just made.

---

## Step 3 — Upload via FTP / cPanel File Manager

Upload the **entire** `vita_server/` folder to your account such that
the URL `https://vitatec.io/vita_server/public/index.php` resolves to
the Laravel front controller.

Recommended setup with the root `.htaccess` shipped here:

```
public_html/                      <-- vitatec.io document root (Falcon)
└── vita_server/                  <-- upload the contents of this folder
    ├── .htaccess                 (rewrites /vita_server/* to /vita_server/public/*)
    └── ...
```

If your host disallows `.htaccess` URL rewrites at this level, simply
make `vitatec.io/vita_server` a subdomain or addon-domain pointing at
the `public/` directory directly. The shipped `public/.htaccess` is the
standard Laravel one.

After upload, set permissions:

```
storage/             0775  (recursive)
bootstrap/cache/     0775  (recursive)
.env                 0640
```

Some shared hosts require `0777` on writable directories. Try `0775`
first and only escalate if you see "permission denied" in the installer.

---

## Step 4 — Run the web installer (replaces artisan)

Visit:

```
https://vitatec.io/vita_server/install.php?token=<INSTALL_KEY>
```

The installer:

1. Verifies the secret token matches `.env`.
2. Generates `APP_KEY` and writes it to `.env` (if blank).
3. Checks that `storage/` and `bootstrap/cache/` are writable.
4. Loads the autoloader and boots Laravel.
5. Verifies the DB is reachable and counts rows in key tables.
6. Runs `config:cache` and `route:cache` for production speed.
7. Prints **All checks passed.** when done.

If you see any red entries, fix them and refresh the page. Common fixes:

| Error                            | Fix                                                   |
|----------------------------------|-------------------------------------------------------|
| `not writable: storage/...`      | chmod 0775 (or 0777) on the listed path via FTP       |
| `DB query failed`                | Fix `DB_*` values in `.env` and re-run                |
| `vendor/autoload.php missing`    | Re-upload the entire `vendor/` folder via FTP         |

---

## Step 5 — DELETE the installer

As soon as you see **All checks passed**, delete:

```
public/install.php
```

via FTP / File Manager. Leaving it there is a credential-exfiltration
risk even with the token guard.

You may also delete `database/dumps/vita_server_seed.sql` from the
server to avoid leaking the dev bearer token; the production database
already contains everything it needs.

---

## Step 6 — Rotate the dev bearer token

The shipped dump contains a development bearer token so that local
Falcon installations work out of the box. **You must rotate it on
production** before exposing Vita Server to the internet.

Use phpMyAdmin to update the `platform_tokens` row, OR run this from
your local machine pointed at production DB:

```
php artisan tinker
> $plain = 'vita_'.bin2hex(random_bytes(28));
> echo $plain;                              // <-- keep this safe
> DB::table('platform_tokens')
>   ->where('label','dev')
>   ->update([
>      'token_hash' => hash('sha256', $plain),
>      'label'      => 'production',
>      'updated_at' => now(),
>   ]);
```

Then update Falcon's setting:

```
php artisan vita:token:set <new_plain_token>
```

---

## Step 7 — Point Falcon at production Vita Server

In Falcon's `.env`:

```
VITA_MARKETPLACE_DRIVER=vita
VITA_MARKETPLACE_BASE_URL=https://vitatec.io/vita_server
```

Then in Falcon:

```
php artisan config:clear
php artisan vita:doctor
```

You should see:

```
driver           : vita
base URI         : https://vitatec.io/vita_server/
resolved class   : App\Vita\Marketplace\Drivers\VitaMarketplaceClient
source           : setting:vita.platform_token
has token        : yes
Summary: 0 error(s), 0 warning(s).
```

That confirms Falcon is now talking to your own Vita Server, not to
`api.akaunting.com`.

---

## Troubleshooting

- **HTTP 500 on every URL under `/vita_server/`** — check Laravel logs
  at `storage/logs/laravel.log` via FTP. The most common causes are
  missing config files in `config/` or a missing `APP_KEY`.
- **HTTP 403 on `install.php`** — your `INSTALL_KEY` does not match the
  `?token=...` you used in the URL. Look at the `.env` you uploaded.
- **HTTP 429 on every API call** — the rate limiter is rejecting you.
  This is keyed off the bearer token; if Falcon is sharing a single
  token across many tenants, raise the limit in
  `app/Providers/RouteServiceProvider.php`.
- **`Auth guard [] is not defined.`** — you forgot to upload
  `config/auth.php`. Re-upload the entire `config/` directory.

---

## Rollback story

If Vita Server goes down or behaves badly, flip Falcon's `.env` back
to the legacy Akaunting marketplace:

```
VITA_MARKETPLACE_DRIVER=akaunting
```

`php artisan config:clear` and Falcon is back to `api.akaunting.com`.
No code change required.
