# MicroBank Floci starter v1

A backend-only teaching overlay for a fresh MicroBank checkout at **f75da680251eebeb38bf17bce3e49b2fea8385c0**. MicroBank owns application code. Ship Boring Lab is the operating home for adopted IaC, configuration, GitOps and Backstage. This overlay is an isolated course fixture, not a second production infrastructure repository.

## Start with the smallest environment

| Activity | Environment | Verification status |
| --- | --- | --- |
| First MicroBank observation | Any current browser; no install/account | Prepared JSON exercise; no live deposit |
| Systems terminal labs | Disposable Linux guest, shell and Git | Use each lesson's VM instructions; this starter does not create a VM |
| This backend starter | macOS arm64 with Linux Docker containers, Python 3.11+, Git, Bash, Compose 2.20+ (or later major), Terraform 1.12–1.x, Ansible | Executed on macOS arm64; see exact versions below |
| Linux / Windows WSL2 | Linux shell plus the same tools and Linux containers | Intended compatible route; not executed on those hosts |
| Native Windows PowerShell | Use WSL2 instead | Launcher and guide require a Unix shell |
| Frontend, Kubernetes, real AWS, hosted CI | Separate extensions in later lessons | Outside this starter's execution claim |

Allow at least 6 GiB free disk for initial checks; image downloads/builds can require more. The observed host had 16 GB RAM. Stop your own other lab tracks if necessary. Database ports stay private. Only 127.0.0.1 ports **24666** (Floci), **28080** (Accounts), **28081** (Ledger) are published. Do not reuse an existing emulator on another port.

## Prepare a fresh checkout

Download `microbank-floci-starter-v1.zip` and its `.sha256` file from LearnWithSK. Verify the archive with `shasum -a 256` (macOS) or `sha256sum` (Linux), comparing it to the supplied digest. Keep the archive outside the checkout. Then:

```bash
git clone https://github.com/santoshkatageri/MicroBank.git microbank-study-v1
cd microbank-study-v1
git checkout --detach f75da680251eebeb38bf17bce3e49b2fea8385c0
unzip ../microbank-floci-starter-v1.zip
python3 scripts/study/starter.py prepare
python3 scripts/study/starter.py doctor
```

The ZIP contains only teaching files. `prepare` refuses another source revision or unrelated edits to either patched application file. It adds an explicit Accounts publisher lifecycle and injects Spring's configured ObjectMapper into Ledger's EventPublisher. The second fix is necessary because a bare mapper cannot serialize the settlement LocalDateTime and rolls back processing. Review both diffs. This does not add API authorization, settlement consumption, or new business guarantees.

Expected: preparation reports no cloud resources created, and doctor reports every MicroBank check PASS. It checks tools, daemon, Compose/Terraform versions, disk and free ports. It does not install tools, print credentials, or stop services. Do not continue with a BLOCKED result. For missing tools, install Python/Git from your OS package manager and follow the official Docker/OrbStack, Terraform and Ansible installation guides; rerun doctor afterward.

## Run one verified case

Predict first: does an accepted Accounts request establish Ledger completion?

```bash
python3 -m unittest discover -s tests/study -v
python3 scripts/study/starter.py start
python3 scripts/study/starter.py create-case
python3 scripts/study/starter.py verify
```

The launcher starts only project `learnwithsk-microbank-v1`, verifies Floci 2.1.0 identity before Terraform, creates nine local resources, generates a private runtime file through Ansible, builds the two applications sequentially, and waits for health. Initial image downloads can take several minutes. The source's legacy LocalStack initializer is bypassed. No LocalStack token or real AWS account is used.

Expected first apply: `9 added, 0 changed, 0 destroyed`. An unchanged second Ansible run should report `changed=0`. A successful case prints JSON containing:

```json
{"expected_cents":1000,"ledger_entries_for_tx":1,"ledger_verified":true}
```

The real output also contains generated `account_id` and `tx_id`; do not compare UUIDs to an example. The case is saved at `evidence/starter-case.json` before verification, so a failure can be investigated without creating a replacement. Reusing an existing case filename is refused. To create another, use `--case-file evidence/another-case.json`.

Inspect Accounts acceptance, message route, Ledger entries and balance as separate observations. The check repeats one idempotency key sequentially; it does not establish concurrent exactly-once delivery. Accounts may remain `pending` because this source has no settlement consumer. The S3 bucket is practice infrastructure; the deposit does not exercise an S3 receipt writer.

## Check persistence and recovery

```bash
bash scripts/study/compose.sh restart
bash scripts/study/compose.sh up -d --wait
python3 scripts/study/starter.py verify
```

Verify the **same saved case**. Do not create a new deposit to hide missing data. The Floci profile explicitly enables persistent storage, and each database has a named volume. This demonstrates a local restart; it does not prove backup recovery.

For a small challenge, stop only this profile's Ledger, create a case with a new filename, retain the expected failed verification, restore Ledger, and verify that exact file. A refused Ledger connection while it is stopped is an expected unavailable result, not proof of data loss.

```bash
bash scripts/study/compose.sh stop ledger
python3 scripts/study/starter.py create-case --case-file evidence/recovery-case.json
# Expected nonzero verification while Ledger is unavailable. Keep the saved case.
bash scripts/study/compose.sh up -d --wait ledger
python3 scripts/study/starter.py verify --case-file evidence/recovery-case.json
```

## Common errors

| Observation | What it means / next action |
| --- | --- |
| Port check BLOCKED | Inspect its owner. If it is this starter, stop it before `start`; leave unrelated workloads alone. Never provision against an endpoint whose identity is unknown. |
| Unexpected emulator identity | Stop before Terraform. Check the exact loopback port and named Compose project; do not destroy resources in the other emulator. |
| Docker unavailable | Start your container engine and verify its context. Doctor does not change contexts. |
| Provider or image download fails | Check network/registry access, then retry the failed step. Do not remove endpoint settings or use real cloud credentials. |
| Image exits 137 | Inspect memory pressure and this project's logs; stop your own optional lab workloads and retry. |
| Missing runtime JSON / assertion fails | Terraform did not complete or output came from another instance. Inspect local state and endpoint; do not weaken the assertion. |
| Health passes, deposit fails | Trace the saved ID from Accounts/outbox to SNS/SQS to Ledger. Health is a process check. Keep the same case file. |
| LocalDateTime serialization error | Ensure `prepare` applied the guarded Ledger mapper fix, rebuild Ledger and recreate that service. |
| Existing case filename | Use `verify` for the existing case, or choose a new filename for a new operation. |
| Doctor reports busy after a successful run | Expected: your stack owns the ports. Use `verify`; stop before another full `start`. |

Use `bash scripts/study/compose.sh logs --tail 100 accounts ledger floci` for this project's logs. Keep runtime files, local state and unredacted logs out of public commits. Preserve sanitized Markdown evidence with prediction, actual observation, scope, recovery check and remaining unknowns.

## Stop or reset deliberately

```bash
python3 scripts/study/starter.py stop
```

Stop removes only this project's containers/network and retains volumes. Run `start` to reconcile and resume, then `verify` the same saved case.

Only when discarding **this starter's synthetic runtime**:

```bash
python3 scripts/study/starter.py reset --confirm-project learnwithsk-microbank-v1
```

Reset removes only the named project's volumes and this checkout's local Terraform runtime/state files. It preserves evidence and `.study.env`; old case files describe the discarded runtime. After restarting, create a fresh filename. It does not prune Docker globally, delete the source checkout, or clean an existing external emulator.

## Version and evidence record

Executed 27 October 2026 on macOS arm64 with OrbStack Linux containers, Docker 29.8.2 / Compose 5.5.0, Python 3.14.7, Terraform 1.16.4, Ansible core 2.21.4. Provider `hashicorp/aws` is pinned to 6.66.0 with a lock file. Floci 2.1.0 and PostgreSQL images are pinned by digest in `infra/study/versions.env`. The app build base tags can move; retain actual image IDs when repeating the lab. Record your own versions/results instead of assuming this record verifies your environment.

References: [Floci Terraform](https://floci.io/floci/getting-started/terraform/), [Floci configuration](https://floci.io/floci/configuration/environment-variables/), [Docker Compose](https://docs.docker.com/compose/install/), [Terraform installation](https://developer.hashicorp.com/terraform/install), [Ansible installation](https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html), [OrbStack](https://docs.orbstack.dev/quick-start).
