# Simulacro (MSRS) — MariaDB Support Repro Project

Local Git repository for planning documents and the Phase 1 POC app for Simulacro, the codename of the MariaDB Support Repro project.

## Documents

- `docs/MSRS-spec-v0.4.md` — Main product/technical specification (run-by-exception policy, Zendesk+Jira feed, hybrid execution strategy).
- `docs/MSRS-executive-one-pager.md` — Management-facing one-page summary.
- `docs/MSRS-technical-appendix.md` — Technical appendix for architecture, lifecycle, security, and delivery phases.
- `docs/MSRS-app-functional-spec.md` — Detailed app requirements for the control-plane POC (without provisioning executor).
- `docs/MSRS-POC-technical-design.md` — Build-ready technical design for implementing the POC app.
- `docs/MSRS-preset-catalog-v1.md` — Initial topology and capacity preset catalog from team inputs.
- `docs/MSRS-alpha-status-and-decisions.md` — Current alpha status, key decisions, and product philosophy.
- `docs/MSRS-support-org-presentation-slides.md` — Slide draft for support-organization presentation.
- `docs/MSRS-spec-v0.2.md` — Archived previous spec version.

## Confluence docs sync automation

Script: `ops/docs/sync_confluence.py`

Credentials file format (default path: `confulence-key.txt`):
1. Atlassian account email
2. Atlassian API token
3. Confluence base URL including `/wiki` (optional if passed via `--base-url`)

Whitelist behavior:
- Only documents listed in `ALLOWED_DOCS` inside `ops/docs/sync_confluence.py` can be synced.
- Any `--doc` value outside that whitelist fails fast.
- To publish a new document, first add it to `ALLOWED_DOCS` in the script.

Dry-run example:

```bash
python3 ops/docs/sync_confluence.py --space-key YOURSPACE --dry-run
```

Publish example:

```bash
python3 ops/docs/sync_confluence.py --space-key YOURSPACE --parent-id 123456
```

## Alpha release marker and README download in web app

- Current UI marker: **Alpha · v0.2.0-alpha.1** (shown in the top bar).
- Web app README download endpoint: `/downloads/readme` (available from Home and Technical Design pages).
- Docs area visual diagrams: `/docs/typical-workflow.svg` and `/docs/control-plane-visual-map.svg` (embedded in Technical Design page).

## Notes

- Phase 1 POC is UI/API + simulated lifecycle only (no real infrastructure provisioning).
- Current workflow is setup-centric: create/edit setup -> explicit **Provision** -> **Pause** or **Decommission**.
- Phase 2 integrates Terraform/OpenTofu execution hooks and provider adapters.

## MariaDB package install strategy for real provisioning (Phase 2)

For reliable CS/ES provisioning, use MariaDB repository setup scripts as the source of truth, but always through a controlled installer wrapper.

### 1. Target resolution and validation

Every provisioning request must resolve this tuple before any install step:

- `edition`: `CS` or `ES`
- `version`: exact MariaDB target version (free text from UI, normalized by backend)
- `distro`: e.g. `ubuntu`, `debian`, `rhel`, `rocky`, `almalinux`, `amazonlinux`, `sles`
- `distroVersion`: curated supported version for that distro

If a tuple is not in the supported matrix, fail fast with an explicit message.

### 2. Repository bootstrap (official script, wrapped)

1. Start from a clean VM/container image for the selected distro.
2. Run MariaDB repo setup script non-interactively for the selected edition and version.
3. Enforce signed repository + key verification before install.
4. Do not continue on warnings related to key/repo validity.

### 3. Deterministic package install

1. Install pinned package versions (not floating `latest`).
2. Keep the package list explicit (server/client and optional MaxScale where required).
3. Verify installation with both:
   - binary version check (e.g. `mariadb --version`)
   - SQL check (`SELECT VERSION()`)
4. Persist install metadata to repro logs (edition, requested version, installed version, distro tuple).

### 4. ES credential handling

1. Read enterprise repository credentials at runtime from secret storage (e.g. AWS Secrets Manager / Parameter Store).
2. Inject credentials only for the provisioning step.
3. Never bake credentials into AMIs/images, repository files committed to source, or long-lived logs.
4. Remove temporary credential material during teardown.

### 5. Reliability controls

- Retry network/package operations with bounded retries and exponential backoff.
- Categorize errors clearly: unsupported tuple vs repo auth failure vs package unavailable vs transient network.
- Add package caching in VPC (APT/YUM proxy or mirror) to reduce failure rate, time, and cost.
- Keep provisioning idempotent (safe to re-run on partial failure).

### 6. Failure policy

- If exact requested version cannot be installed, fail the environment as `FAILED` with precise reason.
- Do not silently downgrade/upgrade to nearby versions unless explicitly requested by user workflow.
- Surface actionable remediation hints in run output.

## POC applications

- `apps/api` — NestJS API with in-memory environments, catalog, lifecycle actions, audit events, and policy simulation.
- `apps/web` — Next.js intranet-style UI with landing page, dashboard, create wizard, environment detail, lifecycle actions, management console (filters + quick/bulk controls), preset management, custom multi-cluster topology builder, and per-environment access instructions page (stub).
- `apps/worker` — mock worker scaffold for policy/executor hooks (no provisioning calls).
- `packages/shared` — shared types package for cross-app contracts.

## Run locally

1. `npm install`
2. `npm run dev:api`
3. in another terminal: `npm run dev:web`
4. open `http://localhost:3001`

Optional request headers for role simulation:
- `x-msrs-user-email`
- `x-msrs-role` (`support_engineer`, `repro_admin`, `sre_auditor`)

## Simulacro deployment package (nginx + systemd)

For the presentation host (`simulacro.spum.app`) the repository now includes:

- `ops/deploy/simulacro/nginx/simulacro.spum.app.conf`
- `ops/deploy/simulacro/systemd/simulacro-api.service`
- `ops/deploy/simulacro/systemd/simulacro-web.service`
- `ops/deploy/simulacro/simulacro.env.example`
- `ops/deploy/simulacro/scripts/deploy_on_host.sh`
- `ops/deploy/simulacro/scripts/sync_and_deploy.sh`

Expected server layout:
- `/var/www/simulacro/current` (application files)
- `/etc/simulacro/simulacro.env` (runtime environment)
- `/var/lib/simulacro/presets-store.json` (persistent preset storage)
- `/var/lib/simulacro/msrs-state.db` (SQLite persistent runtime state: environments + events)

Quick deployment (SSH key-based):

```bash
SERVER_HOST=<host> SERVER_USER=<user> SERVER_PATH=/var/www/simulacro/current \
  bash ops/deploy/simulacro/scripts/sync_and_deploy.sh
```

Password-based deployment (if no SSH key is configured yet):

```bash
SERVER_HOST=<host> SERVER_USER=<user> SERVER_PASS='<password>' \
SERVER_PATH=/var/www/simulacro/current \
  bash ops/deploy/simulacro/scripts/sync_and_deploy.sh
```

`SERVER_PASS` is optional and consumed only at runtime (not stored in files).
Password mode requires `sshpass` on the local machine.
Remote deployment steps require passwordless `sudo` for the SSH user.
The deploy script auto-detects nginx layouts (`sites-available` or `conf.d`).
Runtime persistence is configured by:
- `MSRS_PRESETS_STORE_FILE` for preset catalog storage
- `MSRS_STATE_DB_FILE` for SQLite environment/event history

Optional service runtime override (useful on hosts with `nginx` user):

```bash
RUNTIME_USER=nginx RUNTIME_GROUP=nginx \
SERVER_HOST=<host> SERVER_USER=<user> SERVER_PASS='<password>' \
SERVER_PATH=/var/www/simulacro/current \
  bash ops/deploy/simulacro/scripts/sync_and_deploy.sh
```

Porta web custom (se `3001` è già usata da un altro vhost/app):

```bash
RUNTIME_USER=nginx RUNTIME_GROUP=nginx \
WEB_PORT=3101 API_PORT=3000 \
SERVER_HOST=<host> SERVER_USER=<user> SERVER_PASS='<password>' \
SERVER_PATH=/var/www/simulacro/current \
  bash ops/deploy/simulacro/scripts/sync_and_deploy.sh
```

Enable SSL certificate provisioning (Let’s Encrypt via certbot):

```bash
RUNTIME_USER=nginx RUNTIME_GROUP=nginx \
ENABLE_SSL=1 SSL_EMAIL=<you@example.com> DOMAIN=simulacro.spum.app \
SERVER_HOST=<host> SERVER_USER=<user> SERVER_PASS='<password>' \
SERVER_PATH=/var/www/simulacro/current \
  bash ops/deploy/simulacro/scripts/sync_and_deploy.sh
```

DNS requirement:
- Create an **A record**: `simulacro.spum.app -> <server public IPv4>`
- (Optional) Add AAAA only if your server has working IPv6 for nginx.

You do **not** map subdomain to a folder manually. Nginx `server_name` routes the host header to the Node services.
