glm9637/fractal-arch-demo

Rust

0

1 commits

updated Sep 22, 2026

See the code

See what people are saying

SourceMessageScoreDate

My homebrewed architecture (r/webdev)

As probably no one of you still knows, I wrote a post about rpc style apis a while back. And as a follow up today I published a new one about a few month of refinement over this. This time I hope I caught most of the things you guys asked and criticized about the last one. But in short: \- The…

4

Sep 23, 2026

README

Zahlbob

A shared-expense tracker for people who already trust each other. Put a group together, log what everyone spent, and Zahlbob works out who owes what — netted down to the fewest transfers that square the group up, or left un-netted if you'd rather the payments match the debts people actually remember.

See docs/project.md for the motivation and design decisions behind it.

Stack

  • Frontend: Angular (standalone components, signals), organized as domain-scoped libraries. See docs/frontend.md.
  • Backend: Rust (Axum + ConnectRPC, sqlx/Postgres), organized as a Cargo workspace of domain crates. See docs/backend.md.
  • Auth: Zitadel (OIDC).

Getting started

Prerequisites are managed via mise.

just setup           # install required tools via mise
just start infra     # start local infra (Postgres, Zitadel, Caddy) via podman compose
just start migrations  # apply database migrations

Infra takes a bit to become healthy (Zitadel in particular) — wait and retry if the next step fails immediately.

Zitadel one-time setup

Fresh infra needs a Project + OIDC Application (for a client_id) and at least one login account before the app is actually usable - none of that exists until you run:

just setup zitadel                 # or: just setup zitadel 192.168.50.82 for infra-devbox

This creates the app registration (writing client_id to app/client/public/env.js, gitignored, picked up automatically by app.config.ts - see index.html's env.js comment) and self-registers dev@md.local / _Password1 (for you).

Run the backend and frontend in separate terminals:

just start backend    # cargo run -p zahlbob, raw HTTP on 0.0.0.0:5421
just start frontend   # ng serve, raw HTTP on 0.0.0.0:5431

Both run as plain native processes with no TLS of their own - Caddy is what terminates HTTPS and proxies to them (host.containers.internal:5421/:5431, see config/infra/caddy/Caddyfile), so the app itself is browsed at https://localhost:5430, not :5431. The raw ports still work directly over http://localhost:5421/:5431 for local-only debugging (e.g. the "ng serve" launch config in .vscode/launch.json) - that's fine since localhost is a secure context on its own, but don't use the raw ports from another machine, since that's exactly the insecure-context case Caddy exists to avoid.

Testing

just test        # see config/scripts/test.just for available targets

Repository layout

  • app/ — application entry points (e.g. the backend server binary)
  • domain/ — vertical slices (auth, group, landing, shared, tracing), each with its own frontend/, backend/, and api/ as applicable
  • docs/ — architecture and design documentation
  • config/ — local dev tooling (just recipes, infra compose files)

Contributors

glm9637

1 commits

glm9637/fractal-arch-demo

Rust

0

1 commits

updated Sep 22, 2026

See the code

See what people are saying

SourceMessageScoreDate

My homebrewed architecture (r/webdev)

As probably no one of you still knows, I wrote a post about rpc style apis a while back. And as a follow up today I published a new one about a few month of refinement over this. This time I hope I caught most of the things you guys asked and criticized about the last one. But in short: \- The…

4

Sep 23, 2026

README

Zahlbob

A shared-expense tracker for people who already trust each other. Put a group together, log what everyone spent, and Zahlbob works out who owes what — netted down to the fewest transfers that square the group up, or left un-netted if you'd rather the payments match the debts people actually remember.

See docs/project.md for the motivation and design decisions behind it.

Stack

  • Frontend: Angular (standalone components, signals), organized as domain-scoped libraries. See docs/frontend.md.
  • Backend: Rust (Axum + ConnectRPC, sqlx/Postgres), organized as a Cargo workspace of domain crates. See docs/backend.md.
  • Auth: Zitadel (OIDC).

Getting started

Prerequisites are managed via mise.

just setup           # install required tools via mise
just start infra     # start local infra (Postgres, Zitadel, Caddy) via podman compose
just start migrations  # apply database migrations

Infra takes a bit to become healthy (Zitadel in particular) — wait and retry if the next step fails immediately.

Zitadel one-time setup

Fresh infra needs a Project + OIDC Application (for a client_id) and at least one login account before the app is actually usable - none of that exists until you run:

just setup zitadel                 # or: just setup zitadel 192.168.50.82 for infra-devbox

This creates the app registration (writing client_id to app/client/public/env.js, gitignored, picked up automatically by app.config.ts - see index.html's env.js comment) and self-registers dev@md.local / _Password1 (for you).

Run the backend and frontend in separate terminals:

just start backend    # cargo run -p zahlbob, raw HTTP on 0.0.0.0:5421
just start frontend   # ng serve, raw HTTP on 0.0.0.0:5431

Both run as plain native processes with no TLS of their own - Caddy is what terminates HTTPS and proxies to them (host.containers.internal:5421/:5431, see config/infra/caddy/Caddyfile), so the app itself is browsed at https://localhost:5430, not :5431. The raw ports still work directly over http://localhost:5421/:5431 for local-only debugging (e.g. the "ng serve" launch config in .vscode/launch.json) - that's fine since localhost is a secure context on its own, but don't use the raw ports from another machine, since that's exactly the insecure-context case Caddy exists to avoid.

Testing

just test        # see config/scripts/test.just for available targets

Repository layout

  • app/ — application entry points (e.g. the backend server binary)
  • domain/ — vertical slices (auth, group, landing, shared, tracing), each with its own frontend/, backend/, and api/ as applicable
  • docs/ — architecture and design documentation
  • config/ — local dev tooling (just recipes, infra compose files)

Contributors

glm9637

1 commits

Languages

Rust

83.5%

TypeScript

12.7%

SCSS

1.9%

HTML

1.2%