Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<p align="center">
<img src="docs/assets/larafly-banner.svg" alt="LaraFly — Firefly Framework for PHP" width="100%">
<img src="docs/assets/larafly-banner.svg" alt="larafly — Firefly Framework for PHP" width="100%">
</p>

<h1 align="center">LaraFly</h1>
<h1 align="center">larafly</h1>

<p align="center">
<strong>Spring Boot's cohesion, native to Laravel 13.</strong>
Expand Down Expand Up @@ -40,7 +40,7 @@
<details>
<summary><b>Table of contents</b></summary>

- [📘 The Book — *LaraFly by Example*](#-the-book--larafly-by-example)
- [📘 The Book — *larafly by example*](#-the-book--larafly-by-example)
- [Why LaraFly?](#why-larafly)
- [Quickstart](#quickstart)
- [Philosophy](#philosophy)
Expand All @@ -60,10 +60,10 @@

---

## 📘 The Book — *LaraFly by Example*
## 📘 The Book — *larafly by example*

**LaraFly by Example** is the official, project-driven book for the framework — a PHP sibling to
[*PyFly by Example*](https://github.com/fireflyframework/fireflyframework-pyfly). It builds **Lumen**, the
**larafly by example** is the official, project-driven book for the framework — a PHP sibling to
[*pyfly by example*](https://github.com/fireflyframework/fireflyframework-pyfly). It builds **Lumen**, the
wallet-and-ledger service in [`samples/lumen/`](samples/lumen/), from an empty directory into a secured,
event-driven, actuator-observed microservice, chapter by chapter — every listing drawn from that real project
(its boot and test suite are verified in CI against the same framework source).
Expand Down Expand Up @@ -1122,7 +1122,7 @@ Start at the **[documentation table of contents](docs/README.md)** — it groups
- [Laravel ↔ Spring Boot Comparison](docs/laravel-comparison.md) — concept-by-concept mapping for both audiences.
- [Versioning](docs/versioning.md) · [Contributing](docs/contributing.md) · [Publishing](docs/publishing.md).
- Every [module guide](#modules) above.
- [*LaraFly by Example*](book/README.md) — the complete bilingual book (16 chapters + appendices, PDF + EPUB).
- [*larafly by example*](book/README.md) — the complete bilingual book (16 chapters + appendices, PDF + EPUB).
- [`samples/lumen/`](samples/lumen/) — the wallet-and-ledger sample this README's showcases are drawn from;
run its own test suite with `vendor/bin/pest samples/lumen/tests`.

Expand Down Expand Up @@ -1161,7 +1161,7 @@ still ahead, accurately:
- **Read models / projections as a first-class concept.** The sample's `LedgerProjector` shows the pattern
today via a plain `#[EventListener]`; a dedicated `firefly/eventsourcing`-style package for event
sourcing/snapshots/projections is future work, as it is in PyFly.
- **Documentation.** The end-to-end [tutorial](docs/tutorial.md) (EN + ES), the *LaraFly by Example*
- **Documentation.** The end-to-end [tutorial](docs/tutorial.md) (EN + ES), the *larafly by example*
[book](book/README.md) (16 chapters + appendices, EN + ES, PDF + EPUB), and a
[docs table of contents](docs/README.md) all shipped with the documentation-parity milestone.
Deeper guides (more recipes, more diagrams) continue to grow from here.
Expand Down
31 changes: 27 additions & 4 deletions book/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# LaraFly by Example — the book build system
# larafly by example — the book build system

This directory builds *LaraFly by Example*, a bilingual (EN + ES) book teaching
This directory builds *larafly by example*, a bilingual (EN + ES) book teaching
LaraFly by walking through the `samples/lumen` project chapter by chapter. It
mirrors `fireflyframework-pyfly/book/`'s architecture (WeasyPrint -> PDF, a
hand-rolled EPUB3 assembler, python-markdown with custom directives), renamed
Expand Down Expand Up @@ -95,7 +95,7 @@ book/
# note/tip/warning/laravel admonitions, codehilite
epub.py # stdlib-only EPUB3 (OCF) zip assembler
pdf.py # WeasyPrint HTML -> PDF
gen_cover.py # regenerates art/cover.{svg,png} (firefly/spark motif)
gen_cover.py # validates canonical art; --render rasterizes outlined SVGs
verify_code.py # fenced ```php listings: `php -l`, except `source:` ones
run.sh # sets DYLD_FALLBACK_LIBRARY_PATH, execs build.py
requirements.txt # pinned: weasyprint, markdown, pygments, pyyaml, pytest, cairosvg
Expand All @@ -105,7 +105,9 @@ book/
print.css # @page rules, running heads, page-break control (PDF only)
pygments.css # syntax-highlighting token colors
art/
cover.svg, cover.png # generated by gen_cover.py
cover{,-es}.{svg,png} # canonical localized front covers
back-cover{,-es}.{svg,png} # canonical localized back covers
PROVENANCE.md # source and delivered artwork hashes
figures/ # inline-SVG diagrams referenced by ::: figure
openers/ # reserved for future per-chapter opener art (empty)
src/ # EN manuscript (Markdown)
Expand Down Expand Up @@ -168,3 +170,24 @@ code they run, and no `php` or `source:` block carries one. The repository's own
prose guard derives both halves of that parity — the per-chapter sizes, and the
blocks themselves, byte for byte — and fails the build the moment one edition
stops matching the other.

## Branded front and back covers

The English and Spanish manifests select their own front/back SVG and PNG files
under `art/`. See [artwork provenance](art/PROVENANCE.md) for the canonical brand
kit source and delivered asset hashes. The SVG typography is outlined; the build
needs no author-machine fonts for the covers.

```bash
book/.venv/bin/python book/build/gen_cover.py
```

This validates all four SVG/PNG pairs without modifying them. Use an explicit
`--render` only to rasterize the checked-in SVGs again. The book build fails if a
configured PNG is missing. Covers fill the PDF trim without running text; EPUB
editions include accessible front/back documents and localized navigation.

Book-only editions can be published separately under `books-*` tags and must not
be marked as the latest framework release. Keep the book source commit and asset
checksums with the edition. A book-only edition does not change framework package
versions or replace the assets attached to an existing framework version.
80 changes: 80 additions & 0 deletions book/art/PROVENANCE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Book artwork provenance

The front and back covers belong to the shared Firefly Framework book collection,
prepared on 2026-10-08. Canonical delivery: `Framework-Brand-Kit/11-Books/php/`.
They use the official Firefly Framework identity (A2 treatment) and Manrope
letterforms converted to vector paths. They contain no live font dependency.

The source SVGs and delivered PNGs are 1500 × 1850 pixels, matching the book's
7.5 × 9.25 inch trim. English uses `cover` and `back-cover`; Spanish uses
`cover-es` and `back-cover-es`. Both are full pages in PDF and explicit bookends
in the EPUB reading order. Edition manifests supply accessible alternative text.

`book/build/gen_cover.py` validates this canonical set without changing it.
An explicit `--render` recreates the PNGs from these SVGs with CairoSVG; it never
recreates the retired cover design or substitutes machine-local fonts. Raster
bytes can vary between renderers, so refresh the hashes below if replacing the
delivered PNGs. Publication checksums identify the actual PDF/EPUB bytes.

## Delivered asset SHA-256

| Asset | SHA-256 |
|---|---|
| `cover.svg` | `d8faa683578c0297f57f8d1230daff157cf22d4d8c1cae3d4d33ccd55c800f04` |
| `cover.png` | `6b9dd580be852e410a7c76ff8dbbc01104390780f1b731477059b8860216eab2` |
| `cover-es.svg` | `d4a63f98680517a1fe68511b76f1125f72ad2d1e393def3c875c3117e706142e` |
| `cover-es.png` | `de603dcb41f1ae8ce2881012ffa3e5fed4e6e5871569eff247bca833467402d9` |
| `back-cover.svg` | `64a6b78c9ec4c23354ab0420579e9087a9b742b105617482cdbad96080ff290b` |
| `back-cover.png` | `da2e633783f90d47a18152d917271fa44e38ef5ba62a9e8ebd6beac2405b8c16` |
| `back-cover-es.svg` | `4fb65c27c3c586eba36374c54a6c664b9b780b5e9c6e16d5f9fbaefc9a7ee192` |
| `back-cover-es.png` | `2c2b9db429bbba63e9f30a6197167574cf022b50b00cca0ae04e2ab06f89c4cb` |

## Documentation and interior diagram identity

The 2026-10-08 identity pass applies shared ink (`#10110f`), warm neutral
(`#f3f1eb` / `#dedbd2`) and amber (`#ffb34a`) surfaces. Dark amber (`#8a5714`)
is reserved for readable lines and text on white. Existing blue, green and rust
status/callout colors and third-party marks retain their semantic distinction.

`diagram-branding.json` inventories the diagrams and records SHA-256 fingerprints
of their original non-paint structure. These fingerprints cover every technical
label, path, arrow and layout attribute. Only paint, the old decorative raster
mark and the added footer are excluded. The original viewBox is recorded too.
The footer adds 7.8% of the original width below the content; its outlined family
lockup is embedded with unique SVG IDs and does not cover or scale any original
shape. Screen readers retain the diagram's original title/description.

The canonical lockup is `docs/assets/larafly-logo-light.svg`,
from `Framework-Brand-Kit/12-Frameworks/php/`.
The documentation favicon and small diagram marks use the official kit's
`02-Icons/favicon.svg`. No legacy snake/insect raster is regenerated.

Run `book/.venv/bin/python book/build/brand_diagrams.py --check` to validate
identity, geometry, text and mirrors without writing. Omit `--check` to apply
the idempotent palette/footer pass to a reviewed original source. An intentional
technical diagram edit requires review and updating its fingerprint; never reset
fingerprints merely to make a failing check pass.

Book interiors use the same ink, paper and amber theme. Blue informational,
green tip, rust warning and native Spring/Laravel callout colors remain semantic.

All nine hand-authored diagrams under `docs/assets/diagrams/` are mirrored
byte-for-byte into `book/art/figures/`. There is no Mermaid/PlantUML export step.

For PDF only, `book/build/pdf.py` rasterizes the small canonical footer lockup
at 800 pixels wide before WeasyPrint renders it. This preserves the approved
gradient-y and clipped paths that WeasyPrint otherwise simplifies. Diagram
labels and technical shapes remain selectable text and vectors. Public SVGs
and EPUBs keep the outlined vector logo. Gradients whose stops are the same
color use identical solid paint so WeasyPrint does not drop header backgrounds.

### Outbox layout correction

The `outbox-flow.svg` commit bar previously covered the final pre-commit labels.
Its bar and atomic-commit caption now sit below both branches and `pg_notify`.
The transaction frame grows downward by 70 SVG units; the separate-consumer
section moves down by the same amount into existing bottom whitespace. All
text, arrow connections, width and overall viewBox remain unchanged. Both
mirrors match. The manifest retains the previous structure hash and explains
the intentional layout revision; a geometry guard keeps the commit bar clear
of labels and the consumer frame inside the original canvas.
Binary file added book/art/back-cover-es.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions book/art/back-cover-es.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added book/art/back-cover.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions book/art/back-cover.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added book/art/cover-es.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions book/art/cover-es.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified book/art/cover.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
115 changes: 1 addition & 114 deletions book/art/cover.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
87 changes: 87 additions & 0 deletions book/art/diagram-branding.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
{
"version": "2026-10-08",
"logo": "docs/assets/larafly-logo-light.svg",
"mark": "docs/assets/larafly-favicon.svg",
"palette": {
"#4b5563": "#62645b",
"#1f2937": "#10110f",
"#374151": "#46483f",
"#6b7280": "#62645b",
"#9ca3af": "#a6a295",
"#d1d5db": "#dedbd2",
"#f3f4f6": "#f3f1eb",
"#f8fafc": "#faf9f6",
"#eef2ff": "#fff0d8",
"#ecfdf5": "#edf1e8"
},
"diagrams": {
"docs/assets/diagrams/boot-pipeline.svg": {
"structure": "77a2180ee41aa084e582f8cbc1bc8ddbc18024c55eb9e37ac5fb6e1aea06919b",
"originalViewBox": "0 0 1120 1000",
"mirrors": [
"book/art/figures/boot-pipeline.svg"
]
},
"docs/assets/diagrams/cqrs-eda-bridge.svg": {
"structure": "679ecd3e23e10c0dd19c97d6000e0bc927bc68f655645538ae9572d396452079",
"originalViewBox": "0 0 1200 820",
"mirrors": [
"book/art/figures/cqrs-eda-bridge.svg"
]
},
"docs/assets/diagrams/di-autoconfig.svg": {
"structure": "61e54779e19b086c6fb735e45b2d8f84eab4766159d58e18e5b4974b8590cb3e",
"originalViewBox": "0 0 1120 970",
"mirrors": [
"book/art/figures/di-autoconfig.svg"
]
},
"docs/assets/diagrams/method-interceptor-chain.svg": {
"structure": "44bab250ce3d89df314405594787ffaf4fe701f3ed7df342c5df9daabccc8017",
"originalViewBox": "0 0 1240 920",
"mirrors": [
"book/art/figures/method-interceptor-chain.svg"
]
},
"docs/assets/diagrams/oauth2-authorization-code.svg": {
"structure": "68be371c70f2779811347000a211902cb2d4d000dddedfcf214f008ab7343651",
"originalViewBox": "0 0 1240 1070",
"mirrors": [
"book/art/figures/oauth2-authorization-code.svg"
]
},
"docs/assets/diagrams/outbox-flow.svg": {
"structure": "56c906d58240aa387b8a663e6ecdae9ffe067e4a6f0d0c14e97044f9dae07a03",
"originalViewBox": "0 0 1200 1080",
"mirrors": [
"book/art/figures/outbox-flow.svg"
],
"previousStructure": "a5ae1cf023bf1d432a6038abcc4348e3d030938859098316469a4792c4af1d77",
"layoutRevision": {
"date": "2026-10-08",
"reason": "Move commit bar below both pre-commit branches and pg_notify label; extend transaction frame 70 units, shift consumer section 70 units into existing bottom whitespace. No text, topology, width or overall viewBox changes."
}
},
"docs/assets/diagrams/request-lifecycle.svg": {
"structure": "a8dbb676a409939f39e9fc76b0828304b4d5f400de870f304c755402cf637db0",
"originalViewBox": "0 0 1300 900",
"mirrors": [
"book/art/figures/request-lifecycle.svg"
]
},
"docs/assets/diagrams/security-filter-chain.svg": {
"structure": "7eee7837fdc8566d9718653cd3b97ed10ca41f4eaf9cc61f90ae781edb0d6a72",
"originalViewBox": "0 0 1240 900",
"mirrors": [
"book/art/figures/security-filter-chain.svg"
]
},
"docs/assets/diagrams/tracing-propagation.svg": {
"structure": "8ac1bb2eefe84685714c9ecbcd402f72aed4f6fa20a5b9659c1612f0997ec5ed",
"originalViewBox": "0 0 1400 940",
"mirrors": [
"book/art/figures/tracing-propagation.svg"
]
}
}
}
Loading
Loading