1
0
mirror of git://f0xx.org/ac/ac-docs synced 2026-07-29 06:18:07 +03:00
This commit is contained in:
Anton Afanasyeu
2026-06-23 12:20:43 +02:00
commit 69a448f156
151 changed files with 33372 additions and 0 deletions

View File

@@ -0,0 +1,556 @@
Project repository and structure reorganization draft
milestone: R0-pre
severity: high
state: pre-implementation
author: Anton Afanasyeu
date: 2026-06-18
[AI comment]: Updated 2026-06-18 — PO chose org **`ac`**, **full microservice** end-state, separate **ac-scripts**, URL path migration (§L), optional **ac-workspace** (not build-all-in-one), VM-first cloud (§N). See §G master repo table.
The problem:
The project looks like monolith. For better and more atomic support we need to reorganize the whole project repo structure
[AI comment]: Agree on the problem, but **atomic** should mean: independent release cadence, CI, deploy, and rollback — not “one git repo per PHP class.” Todays real coupling is **one MariaDB**, **one PHP session** (`ac_crash_sess`, [BUILD_DEPLOY.md](../BUILD_DEPLOY.md)), and **one nginx vhost tree** on BE. Split repos before extracting shared platform code will multiply broken deploys.
──────────────────────────────────────────────────────────────────────────────
A. Current codebase map (monolith → draft names)
──────────────────────────────────────────────────────────────────────────────
| Draft name / intent | Actual path today | Coupling notes |
|---------------------|-------------------|----------------|
| ac-mobile | `app/`, `ndk/`, `gradle/`, `build.gradle`, `settings.gradle` | WireGuard tunnel module; `third-party/*` submodules |
| ac-session-studio | `desktop/session-studio/` | Standalone; low coupling — **easy first extract** |
| ac-docs | `docs/` (+ `docs/_pdf_build/`) | No runtime deps — **easy extract** |
| ac-scripts | `scripts/` (pdf, native codecs, OTA, CI helpers) | Used by mobile + orchestration; keep with **ac-deploy** or meta until split clear |
| ac-be-console (crashes/issues/tickets/graphs/rbac/ra) | `examples/crash_reporter/backend/` | **32 PHP classes**, 24 `public/api/*.php`, shared `Auth.php`, `Database.php`, `Rbac.php` — **one modular monolith** |
| ac-be-builder | `examples/build_console/backend/` | Separate app; shares auth pattern via `examples/platform/shared_session.php` + same DB users table |
| ac-be-landing | `examples/app_hub/` | Static hub + deploy nginx snippets |
| ac-be-ota (artifacts) | `examples/ota/v0/...` | Files on disk + nginx; logic also in builder + `scripts/generate-ota-v0.sh` |
| ac-ms-url-shortener | `backend/url-shortener/` | **Only live submodule today** — `git://f0xx.org/androidcast_project/url-shortener` |
| ac-deploy / orchestration | `orchestration/` (docker, cluster0, nginx, runtime) | Local stack + **cast0103** lab ([orchestration/sim/cluster0/ARCHITECTURE.md](../../orchestration/sim/cluster0/ARCHITECTURE.md)) |
| ac-ms-vpn / WG / RSSH | Mobile: `app/.../remoteaccess/`; BE: `RemoteAccessRepository.php`, `WireGuard*`, `Rssh*` provisioners | **Split by plane**: client in mobile, control API in BE console — not two deployables yet |
| ac-ms-vcs (gitea) | `examples/crash_reporter/backend/scripts/gitea/` | **Ops scripts only** — Gitea is external service on BE, not app source |
| ac-ms-tracker / analytics | `Ticket*`, `Graph*` repos in crash_reporter | Same DB + session — **logical modules**, not separate services today |
| SFU stub | `examples/sfu/`, `api/sfu_health.php` | Post-alpha; stay in console until F1 SPEC |
| Experimental / lab | Nested `.git` under `examples/` (not `third-party/` or `backend/url-shortener`) | **Out of scope** — omit from migration docs and manifests |
| third-party codecs | `third-party/libvpx|opus|speex|wireguard-android` | Stay **submodules of ac-mobile** (upstream URLs unchanged); Gitea mirrors per existing migrate script |
[AI comment]: **Correction for draft “how” section:** `be-console` is **not** `./examples/build_console` — that is **builder**. Primary operator console is **`examples/crash_reporter/backend`** (crashes + tickets + graphs + RBAC + remote access APIs). Builder is separate product surface under `/build/`.
──────────────────────────────────────────────────────────────────────────────
B. Infrastructure & cloud fit (combine lab + prod + future cloud)
──────────────────────────────────────────────────────────────────────────────
Principles (from [specs/20100612_1_scaling.md](../specs/20100612_1_scaling.md), [INFRA.md](../INFRA.md), cluster0):
1. **Deploy unit = VM role or container image**, not git repo count. Phase A prod: `be-web-1` runs nginx + PHP-FPM for hub + console + graphs UI; `be-data-1` MariaDB; `be-ops-1` url-shortener + Gitea; `be-build-1` builder.
2. **cluster0 pattern** (NFS config only, app on local disk, GTID MariaDB) maps to cloud as:
- NFS `/shared/cluster/` → **ConfigMaps / object storage** for nginx + SQL seeds + scripts
- Per-node `/var/www/...` → **container image** or **git pull on VM** per service
- Managed DB → **connection string in secret** (PO: “pay for DB service”) — must **not** live in `ms-common` git
3. **PHP session + RBAC**: Shared cookie path `/app/androidcast_project` across hub/crashes/build ([BUILD_DEPLOY.md](../BUILD_DEPLOY.md)). Until true SSO/service tokens exist, **splitting BE UI repos is fine**; splitting **API auth** into N repos without `ac-platform-php` Composer package is painful.
4. **OpenAPI**: PO wants MS OpenAPI-compatible — today APIs are PHP files, not generated spec. Recommend **`ac-platform-openapi`** (or `ac-docs/openapi/`) as **contract-first** artifacts; implement in console first, extract services later.
5. **CI**: `build.config.yml` + CircleCI shape assume **monorepo checkout**. Meta-repo needs **per-repo pipelines** + `ac-deploy` triggering builds with `git_ref` across submodules (builder already does this for `android_cast`).
6. **URL / paths:** Under **discussion** — PO wants path-per-service (§M), not frozen `?view=` under `/crashes/`. nginx + mobile `BackendEndpoints` must migrate with redirects.
[AI comment]: Shared cookie path may become `/app/androidcast_project/` at **edge** only while backends move to `/issues/`, `/tickets/`, etc.
──────────────────────────────────────────────────────────────────────────────
C. Target structure — **full microservice** (PO decision 2026-06-18)
──────────────────────────────────────────────────────────────────────────────
PO chose **full microservice** end-state (§K comparison). Delivery remains **phased** (§D).
```text
Platform (libraries — Composer, not runtime MS)
ac-platform-php, ac-platform-db, ac-platform-web, ac-scripts, ac-docs
Infrastructure
ac-deploy submodules ac-scripts; cluster0/docker/nginx
ac-workspace optional clone manifest only (§N) — NOT unified build
Clients
ac-mobile-android (+ future ac-mobile-ios)
ac-session-studio
Microservices (OpenAPI APIs / workers)
ac-ms-identity, ac-ms-rbac, ac-ms-devices, ac-ms-issues, ac-ms-tickets,
ac-ms-graphs, ac-ms-remote-access, ac-ms-url-shortener, ac-ms-build,
ac-ms-ota, ac-ms-notifications (later)
Backend UI (thin)
ac-be-hub, ac-be-issues, ac-be-tickets, ac-be-graphs, ac-be-remote-access,
ac-be-access, ac-be-builder, ac-be-auth (optional)
Edge
ac-platform-edge nginx BFF — recommended for cookie + URL migration (§M)
```
[AI]: Collapse POs **ms-vpn-rssh** + **ms-vpn-wireguard** → **ac-ms-remote-access**. Drop **ac-ms-vcs** as code repo (Gitea = infra). Drop **ac-ms-tracker** as separate MS — split into **ac-ms-issues** + **ac-ms-tickets** (different URLs PO wants).
**Risk mitigation:** Composer semver for platform libs (avoid @common submodule diamond in 20+ repos).
──────────────────────────────────────────────────────────────────────────────
D. Phased migration (safe order — no big-bang)
──────────────────────────────────────────────────────────────────────────────
| Phase | Action | Alpha blocker? | Rollback |
|-------|--------|----------------|----------|
| **P0** | Create Gitea org **`ac`**; mirror legacy → **ac-workspace** (optional) | No | Keep `android_cast` mirror |
| **P1** | Extract **ac-docs**, **ac-session-studio** submodules; meta points SHAs | No | Revert submodule |
| **P2** | Extract **ac-ms-url-shortener** path to `ac/ac-ms-url-shortener` (already submodule — change URL only) | No | Old URL works via mirror |
| **P3** | **ac-platform-php** + **ac-platform-web** + **ac-ms-identity** first (everything depends on auth) | **Yes** for MS split | Shim monolith |
| **P4** | Extract **ac-ms-issues**, **ac-ms-tickets**, **ac-ms-rbac**, **ac-ms-devices** + matching **ac-be-*** UI repos | Medium | Edge proxy to monolith |
| **P5** | **ac-mobile-android**, **ac-deploy** (+ submodule **ac-scripts**), **ac-ms-build**, **ac-ms-ota** | Medium | Per-repo CI |
| **P6** | **ac-platform-edge** nginx routes (§M); retire `/crashes/?view=` | Medium | 301 redirects |
| **P7** | cluster0 + cloud VMs (§O); optional **ac-ms-graphs**, **ac-ms-remote-access** | No | Per scaling SPEC |
[AI comment]: Do **not** start P4 until P3 — otherwise Auth/Database duplicates diverge in days.
**ms-common sensitive data:** Split into:
- `ac-platform-php` — code (session helpers, RBAC classes, DB adapter interfaces)
- **Runtime config** — `config.php` / env / K8s secrets per deploy (never in git)
- Optional `ac-platform-db` — **SQL migrations only** (shared schema), consumed by console + shortener + builder
──────────────────────────────────────────────────────────────────────────────
E. The what (original table — annotated)
──────────────────────────────────────────────────────────────────────────────
Current project structure
Project | Placement | Repo | State | Description
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
AndroidCast all in one | repo root | git://f0xx.org/android_cast | monolithic | all-in-one project, needs to be splitted
[AI]: → becomes **ac-meta** umbrella; keep **read-only mirror** at old URL ≥ 1 release
libvpx | third-party/libvpx | https://chromium.googlesource.com/webm/libvpx | 3rdparty exported submodule | VPx video codecs
[AI]: stays upstream URL in .gitmodules; Gitea mirror `AndroidCast/libvpx` unchanged
opus | third-party/opus | https://github.com/xiph/opus | 3rdparty exported submodule | Opus voice codec
speex | third-party/speex | https://github.com/xiph/speex/ | 3rdparty exported submodule | Speex voice codec
wireguard | third-party/wireguard-android | https://git.zx2c4.com/wireguard-android | 3rdparty exported submodule | wireguard for android
url-shortener | backend/url-shortener | git://f0xx.org/androidcast_project/url-shortener | part of AndroidCast backend | url shortener standalone backend
[AI]: migrate to **git://f0xx.org/ac/ac-ms-url-shortener**; alias old URL
──────────────────────────────────────────────────────────────────────────────
F. The how (original target — annotated + fixes)
──────────────────────────────────────────────────────────────────────────────
Next hope project structure
AndroidCast project - all in one | git://f0xx.org/ac/ac-meta
|-- AndroidCast - common | @ac-platform-php [AI: Composer, not submodule diamond]
|-- AndroidCast - mobile | @ac-mobile
|-- AndroidCast - BE | @ac-be-console (+ builder, hub as siblings)
... TBD
AndroidCast project | Placement (@ - submodule) | Description | Repo
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
AndroidCast - common | @common | project all common | git://f0xx.org/ac/ac-common
[AI]: **Rename → ac-platform-php** (Composer). Reserve **ac-common** for non-PHP only: LICENSE templates, OpenAPI, semver constants — or drop repo and fold into ac-docs.
|-- AndroidCast - docs | @docs | project docs, BE, MS, mobile, web, everything | git://f0xx.org/ac/ac-docs
|-- AndroidCast - scripts | @scripts | common project scripts | git://f0xx.org/ac/ac-scripts
[AI]: merge ac-scripts into **ac-deploy** unless mobile-only scripts dominate
AndroidCast - mobile | @mobile | mobile app sources | git://f0xx.org/ac/ac-mobile
|-- AndroidCast - common | @common | | git://f0xx.org/ac/ac-common
[AI]: mobile should NOT submodule ac-common PHP — only third-party natives
AndroidCast - Session Studio | @session-studio | offline analytic tools | git://f0xx.org/ac/ac-session-studio
|-- AndroidCast - common | @common | | git://f0xx.org/ac/ac-common
[AI]: session-studio has no PHP dep — drop @common edge
AndroidCast - BE - MS | @backend | backend microservices common base (UI) | git://f0xx.org/ac/ac-be-microservice
[AI]: **Overloaded name.** Split: **ac-be-console** (main UI+API), **ac-platform-php** (lib). “ac-be-microservice” as umbrella meta for BE apps optional.
|-- AndroidCast - common | @common | | git://f0xx.org/ac/ac-common
AndroidCast - MS | @microservices | microservice commons | git://f0xx.org/ac/ac-microservice
[AI]: defer **ac-microservice** meta-repo until ≥3 independently deployed APIs exist (today: 1 = url-shortener)
|-- AndroidCast - common | @common | | git://f0xx.org/ac/ac-common
... TBD
AndroidCast BE microservices and their derivatives (OpenAPI providers, any REST API services for web and mobile apps)
AndroidCast - MS - template <- AndroidCast - MS (@ means suibmodule) |git://f0xx.org/ac/ac-microservice/ac-ms-template
[AI]: good template for **future** services; seed from url-shortener layout (public/, src/, sql/, tests/)
| -- AndroidCast - common | @common | project all common | git://f0xx.org/ac/ac-common
| -- AndroidCast - MS - common | @ms-common | microservices common | git://f0xx.org/ac/ac-microservice/ac-ms-common
[AI]: **ms-common = ac-platform-php + openapi + migration runner** — NOT DB passwords. Fix typo **@ms-commmon** in remote-access row below.
|-- AndroidCast - MS - builder | @ms-builder | builder microservice | git://f0xx.org/ac/ac-microservice/ac-ms-builder
[AI]: today = **ac-be-builder** (UI+worker in one); split worker when be-build-1 is isolated CI agent only
|-- AndroidCast - MS - VPN | @ms-vpn | VPN microservice | git://f0xx.org/ac/ac-microservice/ac-ms-vpn
[AI]: **Phase 6+** — API surface = `remote_access.php` + provisioners; client stays in ac-mobile
|-- AndroidCast - MS - VPN - RSSH | @ms-vpn-rssh | VPN RSSH microservice | git://f0xx.org/ac/ac-microservice/ac-ms-vpn-rssh
|-- AndroidCast - MS - VPN - WireGuard | @ms-vpn-wireguard | VPN WG microservice | git://f0xx.org/ac/ac-microservice/ac-ms-vpn-wireguard
[AI]: package by directory inside console first: `src/RemoteAccess/Rssh/`, `src/RemoteAccess/WireGuard/`
|-- AndroidCast - MS - VCS | @ms-vcs | VCS microservice (gitea) | git://f0xx.org/ac/ac-microservice/ac-ms-vcs
[AI]: **Not a code repo** — Gitea is infra; keep **ac-deploy** scripts + docs for Gitea ops
|-- AndroidCast - MS - URL shortener | @ms-url-shortener | URL shortener microservice | git://f0xx.org/ac/ac-microservice/ac-ms-url-shortener
[AI]: **P2** — flatten path to `git://f0xx.org/ac/ac-ms-url-shortener` (no nested ac-microservice parent)
|-- AndroidCast - MS - analytics | @ms-analytics | analytics microservice | git://f0xx.org/ac/ac-microservice/ac-ms-analytics
[AI]: graphs ingest + GA config — module in console until read load warrants split
|-- AndroidCast - MS - orchestration | @ms-orchestration | orchestration microservice | git://f0xx.org/ac/ac-microservice/ac-ms-orchestration
[AI]: today = **ac-deploy** + builder API; name collision with folder `orchestration/`
|-- AndroidCast - MS - tracker | @ms-tracker | issues & tickets tracker microservice | git://f0xx.org/ac/ac-microservice/ac-ms-tracker
|-- AndroidCast - MS - RBAC | @ms-rbac | RBAC microservice | git://f0xx.org/ac/ac-microservice/ac-ms-rbac
... TBD
Sub-project of AndroidCast BE/MS, mostly Web UI stuff, but also should be OpenAPI-compatible and provide services to the mobile app (@ means suibmodule)
AndroidCast - BE - common <- AndroidCast - BE - MS | git://f0xx.org/ac/ac-backend
[AI]: prefer **per-app repos** (ac-be-console, ac-be-builder, …) over deep `ac-backend/*` tree — flatter Gitea permissions
|-- AndroidCast - BE - vcs (UI) | @be-vcs | VCS frontend, former gitea, backend UI | git://f0xx.org/ac/ac-backend/ac-be-vcs
[AI]: Gitea **is** the UI — link from hub only; optional thin PHP wrapper if needed
|-- AndroidCast - MS - vcs | @ms-vcs | VCS microservice (gitea) | git://f0xx.org/ac/ac-microservice/ac-ms-vcs
|-- AndroidCast - BE - console (UI) | @be-console | git://f0xx.org/ac/ac-backend/ac-be-console | primary console, ./examples/build_console ? check if it is
[AI]: **FIX:** primary console = **ac-be-console** ← `examples/crash_reporter/backend`. Builder = **ac-be-builder** ← `examples/build_console`.
|-- AndroidCast - MS - common | @ms-common | git://f0xx.org/ac/ac-microservice/ac-ms-common | microservice commons
|-- AndroidCast - BE - landing (UI) | @be-landing | git://f0xx.org/ac/ac-backend/ac-be-landing | landing page(s), now in ./examples/app_hub
|-- AndroidCast - MS - common | @ms-common | git://f0xx.org/ac/ac-microservice/ac-ms-common | microservice commons
|-- AndroidCast - BE - issues (UI) | @be-issues | git://f0xx.org/ac/ac-backend/ac-be-issues | issues tracker UI, now is in ./examples somewhere
[AI]: **same PHP app** as tickets — `?view=` routes in crash_reporter views, not separate deployable
|-- AndroidCast - MS - tracker | @ms-tracker | git://f0xx.org/ac/ac-microservice/ac-ms-tracker | issues tracker microservice shared base, now is in ./examples somewhere
|-- AndroidCast - BE - tickets (UI) | @be-tickets | git://f0xx.org/ac/ac-backend/ac-be-tickets | tickets UI, now is in ./examples somewhere
|-- AndroidCast - MS - tracker | @ms-tracker | git://f0xx.org/ac/ac-microservice/ac-ms-tracker | issues tracker microservice shared base, now is in ./examples somewhere
|-- AndroidCast - BE - graphs (UI) | @be-graphs | git://f0xx.org/ac/ac-backend/ac-be-graphs | graphs UI, now somewhere in ./examples
|-- AndroidCast - MS - analytics | @ms-analytics | git://f0xx.org/ac/ac-microservice/ac-ms-analytics | analytics base microservice
|-- AndroidCast - BE - analytics (UI) | @be-analytics | git://f0xx.org/ac/ac-backend/ac-be-analytics | analytics and statistics web UI
|-- AndroidCast - MS - analytics | @ms-analytics | git://f0xx.org/ac/ac-microservice/ac-ms-analytics | analytics base microservice
[AI]: graphs + analytics UI = views inside **ac-be-console** today (`GraphRepository`, `AnalyticsHead`)
|-- AndroidCast - BE - remote access (UI) | @be-remote-access | git://f0xx.org/ac/ac-backend/ac-be-remote-access | remote access (now for vpn, somewhere in ./examples now) UI
|-- AndroidCast - MS - common | @ms-commmon | git://f0xx.org/ac/ac-microservice/ac-ms-common | microservice commons
[AI]: typo **commmon** → common; RA UI = admin views in console + mobile app
|-- AndroidCast - MS - VPN | @ms-vpn | git://f0xx.org/ac/ac-microservice/ac-ms-vpn | VPN MS as a dependency
|-- AndroidCast - MS - RBAC | @ms-rbac | @ms-rbac | git://f0xx.org/ac/ac-microservice/ac-ms-rbac | RBAC MS as a dependency
|-- AndroidCast - BE - URL shortener (UI) | @be-url-shortener | git://f0xx.org/ac/ac-backend/ac-be-url-shortener | URL shortener UI, now is in separate submodule
[AI]: short-link **admin UI** is in crash console (`short_links.js`, hub tokens); **API** is submodule
|-- AndroidCast - MS - URL shortener | @ms-url-shortener | git://f0xx.org/ac/ac-microservice/ac-ms-url-shortener | URL shortener microservice, now is in separate submodule
|-- AndroidCast - BE - builder (UI) | @be-builder | git://f0xx.org/ac/ac-backend/ac-be-builder | orchestration builder UI, now in ./orchestration
[AI]: **FIX:** builder UI = `examples/build_console`; **orchestration/** = docker/cluster0 (**ac-deploy**)
|-- AndroidCast - MS - orchestration | @ms-orchestration | git://f0xx.org/ac/ac-microservice/ac-ms-orchestration | orchestration microservice, now in ./orchestration
|-- AndroidCast - BE - RBAC (UI) | @be-rbac | git://f0xx.org/ac/ac-backend/ac-be-rbac | RBAC backend, now mixed within ./examples somewhere
|-- AndroidCast - MS - common | @ms-common | git://f0xx.org/ac/ac-microservice/ac-ms-common | microservice commons
|-- AndroidCast - MS - RBAC | @ms-rbac | git://f0xx.org/ac/ac-microservice/ac-ms-rbac | RBAC microservice
|-- AndroidCast - BE - OTA | @be-ota | git://f0xx.org/ac/ac-backend/ac-be-ota | OTA BE UI
|-- AndroidCast - MS - OTA | @ms-ota | git://f0xx.org/ac/ac-microservice/ac-ms-ota | OTA microservice, now intermixed in examples/ota and other commons
[AI]: OTA = static tree + builder publish + nginx location; extract API when `5.1 OTA` nginx stable
... TBD
ms-common (microservices common) needs a sharp eye, it may share project sensitive parts, like common stuff such as shared web sessions, DB access (or should be separated to @be-db-service/@ac-db-service sort of)
[AI]: **Agree.** Recommended split:
- **ac-platform-php** — session *code*, Auth, Rbac, PDO factory (reads DSN from env)
- **ac-platform-db** — SQL migrations + schema version table (shared by console, builder, shortener)
- **ac-deploy/secrets** — example only; prod DSN in vault / Alpine `config.php` outside git
- **No ac-db-service runtime** until you run DB proxy (PlanetScale, RDS, etc.) — app VMs use driver + secret
──────────────────────────────────────────────────────────────────────────────
G. FULL REPO CATALOG — microservice end-state (Gitea org **ac**)
──────────────────────────────────────────────────────────────────────────────
Canonical clone: `git://f0xx.org/ac/<repo>`. HTTPS UI: `https://apps.f0xx.org/app/androidcast_project/git/ac/<repo>.git` (path TBD with edge migration). Legacy `git://f0xx.org/android_cast` → read-only mirror until retired.
| ID | Repo | Git URL | Role | From (monolith) | VM / cloud slot |
|----|------|---------|------|-----------------|-----------------|
| **Workspace** |
| W0 | ac-workspace | `git://f0xx.org/ac/ac-workspace` | Optional submodule manifest; **no unified build** | `.gitmodules` | dev laptops |
| **Platform** |
| P0 | ac-platform-php | `git://f0xx.org/ac/ac-platform-php` | Composer: HTTP, auth client, PDO factory | Auth*, bootstrap | baked into PHP images |
| P1 | ac-platform-db | `git://f0xx.org/ac/ac-platform-db` | SQL migrations + schema version | sql/, migrations | be-data-1 job |
| P2 | ac-platform-web | `git://f0xx.org/ac/ac-platform-web` | Shared CSS/JS/theme | crashes/assets, hub links | CDN / edge static |
| P3 | ac-platform-edge | `git://f0xx.org/ac/ac-platform-edge` | nginx routes, cookie domain, proxy | fe/apps.conf | be-web-1 / FE |
| P4 | ac-scripts | `git://f0xx.org/ac/ac-scripts` | CI, OTA, native codec, pdf scripts | `scripts/` | CI runners |
| P5 | ac-docs | `git://f0xx.org/ac/ac-docs` | Documentation | `docs/` | — |
| **Deploy** |
| D0 | ac-deploy | `git://f0xx.org/ac/ac-deploy` | docker, cluster0, env templates; **uses ac-scripts** | `orchestration/` | all VMs |
| **Clients** |
| C0 | ac-mobile-android | `git://f0xx.org/ac/ac-mobile-android` | Android app + ndk + third-party | `app/`, `ndk/` | CI → OTA |
| C1 | ac-mobile-ios | `git://f0xx.org/ac/ac-mobile-ios` | Future iOS client | — | CI → OTA |
| C2 | ac-session-studio | `git://f0xx.org/ac/ac-session-studio` | Desktop analyzer | `desktop/session-studio/` | releases |
| **Microservices** |
| S0 | ac-ms-template | `git://f0xx.org/ac/ac-ms-template` | Cookiecutter for new PHP MS | url-shortener layout | — |
| S1 | ac-ms-identity | `git://f0xx.org/ac/ac-ms-identity` | Users, login, register, 2FA, sessions | Auth*, UserRepository | be-web-1 |
| S2 | ac-ms-rbac | `git://f0xx.org/ac/ac-ms-rbac` | Companies, memberships, privileges | Rbac*, RbacAdmin* | be-web-1 |
| S3 | ac-ms-devices | `git://f0xx.org/ac/ac-ms-devices` | Device registry | DeviceRepository | be-web-1 |
| S4 | ac-ms-issues | `git://f0xx.org/ac/ac-ms-issues` | Crash/report ingest + reports API | upload, Report*, Tag* | be-web-1 |
| S5 | ac-ms-tickets | `git://f0xx.org/ac/ac-ms-tickets` | Tickets workflow, comments, attachments | Ticket* | be-web-1 |
| S6 | ac-ms-graphs | `git://f0xx.org/ac/ac-ms-graphs` | Graph ingest + query | GraphRepository, graph_*.php | be-web-1 |
| S7 | ac-ms-remote-access | `git://f0xx.org/ac/ac-ms-remote-access` | WG + RSSH control API | RemoteAccess*, WireGuard*, Rssh* | be-ops-1 |
| S8 | ac-ms-url-shortener | `git://f0xx.org/ac/ac-ms-url-shortener` | Short link API | `backend/url-shortener/` | be-ops-1 |
| S9 | ac-ms-build | `git://f0xx.org/ac/ac-ms-build` | Build queue + worker API | BuildRunner, build_console APIs | be-build-1 |
| S10 | ac-ms-ota | `git://f0xx.org/ac/ac-ms-ota` | Channel manifests; multi-client SHAs | OTA scripts + v0 tree | be-web-1 / OBJ |
| S11 | ac-ms-notifications | `git://f0xx.org/ac/ac-ms-notifications` | SMTP / auth mail (post-alpha) | AuthMailer | be-ops-1 |
| **Backend UI** |
| B0 | ac-be-hub | `git://f0xx.org/ac/ac-be-hub` | Landing | `examples/app_hub/` | be-web-1 |
| B1 | ac-be-issues | `git://f0xx.org/ac/ac-be-issues` | Issues UI → S4 | views reports/* | be-web-1 |
| B2 | ac-be-tickets | `git://f0xx.org/ac/ac-be-tickets` | Tickets UI → S5 | views tickets/* | be-web-1 |
| B3 | ac-be-graphs | `git://f0xx.org/ac/ac-be-graphs` | Graphs dashboard UI | graphs views | be-web-1 |
| B4 | ac-be-remote-access | `git://f0xx.org/ac/ac-be-remote-access` | RA admin UI → S7 | view remote_access | be-web-1 |
| B5 | ac-be-access | `git://f0xx.org/ac/ac-be-access` | RBAC admin UI → S2 | view rbac | be-web-1 |
| B6 | ac-be-builder | `git://f0xx.org/ac/ac-be-builder` | Builder UI → S9 | `examples/build_console/` | be-build-1 |
| B7 | ac-be-auth | `git://f0xx.org/ac/ac-be-auth` | Login/register chrome → S1 | login.php shared | be-web-1 |
| **Third-party (submodules of C0 only)** |
| — | libvpx, opus, speex, wireguard-android | upstream URLs + Gitea mirrors under `ac/` | Native deps | `third-party/*` | mobile CI |
| **Future** |
| F1 | ac-ms-sfu-signaling | `git://f0xx.org/ac/ac-ms-sfu-signaling` | WebRTC signaling | examples/sfu | be-media-N |
| F2 | ac-ms-media-transcode | `git://f0xx.org/ac/ac-ms-media-transcode` | VOD/ffmpeg | V.2x draft | be-media-N |
**PO draft mapping fixes:**
- `ac-be-console` (monolith) → **dissolved** into B1B5 + S4S7
- `ac-ms-tracker` → **S4 + S5** (issues ≠ tickets — PO URL split confirms)
- `ac-ms-analytics` → **S6** (graphs) + later BI; GA config in **P2 platform-web**
- `ac-ms-orchestration` → **S9 + D0** (worker vs deploy)
- `ac-ms-vcs` → **not a repo**; document in **D0**
- `ac-be-url-shortener` UI → admin panel in **B5** or **B0** calling **S8** (tokens already in crashes console)
**ac-deploy ↔ ac-scripts:** D0 submodules P4 at pinned SHA; deploy-local scripts only for image entrypoints.
──────────────────────────────────────────────────────────────────────────────
H. ac-workspace sketch (optional — PO §5)
──────────────────────────────────────────────────────────────────────────────
**Purpose:** “I only work on mobile” or “I only work on tickets UI” — clone workspace, init selected submodules. **Not** for building everything in one Gradle/PHP tree.
```ini
# ac-workspace — example partial checkout
[submodule "mobile-android"]
path = clients/android
url = git://f0xx.org/ac/ac-mobile-android
[submodule "ms-issues"]
path = services/issues
url = git://f0xx.org/ac/ac-ms-issues
[submodule "be-issues"]
path = ui/issues
url = git://f0xx.org/ac/ac-be-issues
[submodule "deploy"]
path = deploy
url = git://f0xx.org/ac/ac-deploy
```
Developers without workspace clone individual repos directly.
──────────────────────────────────────────────────────────────────────────────
I. PO decisions (2026-06-18) — recorded
──────────────────────────────────────────────────────────────────────────────
| # | Question | Decision |
|---|----------|----------|
| 1 | Gitea org | **`ac`** |
| 2 | Architecture | **Full microservice** end-state (phased delivery) — §K |
| 3 | ac-scripts | **Separate repo**; **ac-deploy submodules/invokes it** |
| 4 | Public URLs | **Change desired** — path-per-service (§M); not frozen under `/crashes/?view=` |
| 5 | Meta repo | **`ac-workspace` optional** — selective clone only; **not** build-all-in-one; §N OTA |
| 6 | Cloud | **No K8s requirement** — start VM lift-and-shift (§O); K8s later optional |
──────────────────────────────────────────────────────────────────────────────
J. Microservice vs modular monolith — comparison (PO requested)
──────────────────────────────────────────────────────────────────────────────
| Criterion | Full microservice (PO choice) | Modular monolith (single ac-be-console) |
|-----------|------------------------------|----------------------------------------|
| **Independent deploy** | Deploy tickets without touching issues | One PHP deploy for any UI fix |
| **Team scaling** | Different owners per repo/service | Single codebase, simpler grep |
| **Failure isolation** | Ticket MS down ≠ crash ingest | Shared FPM pool — blast radius larger |
| **CI speed** | Small repos, faster per-service tests | One `./gradlew`-scale PHP test suite |
| **Auth/session** | Needs **ac-ms-identity** + edge cookie early | Already works (`ac_crash_sess`) |
| **DB** | Shared MariaDB OK initially; schema ownership per MS | One migration stream today |
| **Operational cost** | More nginx routes, more images, more logs | One BE tree to sync ([INFRA.md](../INFRA.md)) |
| **PO microservice learning curve** | Higher — mitigated by **ac-ms-template**, **D0** | Lower short-term |
| **Cloud path** | Maps 1:1 to VM roles then containers | Lift whole monolith first |
| **URL clarity** | Natural `/issues/`, `/tickets/` per service | Stuck on `?view=` without refactor |
| **Rollback** | Revert one service SHA | Revert one monolith commit |
| **Risk for alpha** | **Higher** if done before identity split | Lower — current prod pattern |
[AI]: PO choice is valid **if P3 (identity + platform) is non-negotiable first**. Without it, full MS split repeats the build-console/bootstrap.php class of failures across N repos.
──────────────────────────────────────────────────────────────────────────────
K. Service dependency graph (logical + structural + repo)
──────────────────────────────────────────────────────────────────────────────
```mermaid
flowchart TB
subgraph clients [Clients]
AND[ac-mobile-android]
IOS[ac-mobile-ios future]
HUB[ac-be-hub]
SS[ac-session-studio]
end
subgraph edge [Edge]
EDGE[ac-platform-edge]
end
subgraph core [Core platform MS]
ID[ac-ms-identity]
RB[ac-ms-rbac]
DV[ac-ms-devices]
end
subgraph domain [Domain MS]
IS[ac-ms-issues]
TK[ac-ms-tickets]
GR[ac-ms-graphs]
RA[ac-ms-remote-access]
UL[ac-ms-url-shortener]
BL[ac-ms-build]
OT[ac-ms-ota]
end
subgraph ui [Backend UI]
UI_I[ac-be-issues]
UI_T[ac-be-tickets]
UI_G[ac-be-graphs]
UI_R[ac-be-remote-access]
UI_A[ac-be-access]
UI_B[ac-be-builder]
end
AND -->|upload API| EDGE
AND -->|RA API| EDGE
AND -->|graph upload| EDGE
HUB --> EDGE
UI_I & UI_T & UI_G & UI_R & UI_A & UI_B --> EDGE
EDGE --> ID & IS & TK & GR & RA & UL & BL & OT & RB
ID --> RB
RB --> DV
IS --> DV
IS --> RB
TK --> RB
TK -.->|optional link| IS
GR --> ID
RA --> RB
RA --> DV
RA -.->|issue deep links| IS
BL --> ID
BL -->|git clone| GITEA[(Gitea infra)]
OT --> BL
OT --> AND
OT --> IOS
UL --> RB
```
**Dependency rules (enforce in DR/SPEC):**
| Service | Hard depends on | Soft / read depends on | Mobile / public API |
|---------|-----------------|------------------------|---------------------|
| ac-ms-identity | ac-platform-db (users schema) | ac-ms-notifications (mail) | register, login |
| ac-ms-rbac | identity (JWT/session validation) | — | — |
| ac-ms-devices | rbac (company scope) | identity | — |
| ac-ms-issues | devices, rbac | tags catalog | **upload.php** |
| ac-ms-tickets | rbac | issues (link ticket↔report) | — |
| ac-ms-graphs | identity | — | graph_upload |
| ac-ms-remote-access | rbac, devices | issues (device context URLs) | remote_access.php |
| ac-ms-url-shortener | rbac (API tokens) | — | s.f0xx.org |
| ac-ms-build | identity | gitea mirror | — |
| ac-ms-ota | build artifacts | mobile/ios SHAs | `/v0/ota/` |
| ac-be-hub | identity (session for nav) | **P2 platform-web** assets | — |
**Cross-cutting fixes vs PO draft:**
1. **Auth must be first MS** — every UI and API currently includes `bootstrap.php` → Auth.
2. **Devices before issues** — upload auto-registers device + company ([README](../examples/crash_reporter/backend/README.md) RBAC).
3. **Hub → crashes assets** — today `app_hub/index.php` loads `/crashes/assets/css/app.css`; extract **ac-platform-web** before splitting hub.
4. **Builder → same DB users** — build_console uses `androidcast_crashes.users`; cannot split S9 before S1.
5. **Short links admin** — UI in monolith, API in submodule; UI calls S8, not duplicate repo **ac-be-url-shortener**.
6. **Graphs** — already separate nginx location `/graphs/` ([apps.conf](../../examples/crash_reporter/backend/nginx/fe/apps.conf)) — good MS boundary.
**Suggested new intermediates (actors):**
| Service | Why |
|---------|-----|
| **ac-ms-identity** | Single login/register/2FA; avoids 8 copies of Auth.php |
| **ac-ms-devices** | Shared by issues, RA, graphs device keys |
| **ac-platform-edge** | One nginx config for POs URL map + SSO cookie |
| **ac-ms-ota** | PO multi-repo Android+iOS same version (§N) |
| **ac-ms-notifications** | Decouple SMTP from identity (task 2.x mail frozen) |
| **ac-ms-attachments** (later) | Ticket files → object store when > local disk |
──────────────────────────────────────────────────────────────────────────────
L. Public URL migration map (PO §4)
──────────────────────────────────────────────────────────────────────────────
Base prefix (discussion): keep **`/app/androidcast_project/`** for alpha compatibility, or shorten to **`/app/ac/`** later. Below uses POs intent under current prefix.
| Today | Target path | MS / UI | Notes |
|-------|-------------|---------|-------|
| `/crashes/?view=reports` | **`/issues/`** | B1 → S4 | “Issue tracker” / crash reports list |
| `/crashes/?view=report&id=N` | **`/issues/N`** or `/issues/report/N` | B1 | Detail |
| `/crashes/?view=tickets` | **`/tickets/`** | B2 → S5 | Tickets catalog |
| `/crashes/?view=ticket&id=N` | **`/tickets/N`** | B2 | Detail |
| `/crashes/?view=rbac` | **`/access/`** | B5 → S2 | RBAC admin |
| `/crashes/?view=remote_access` | **`/remote-access/`** | B4 → S7 | RA admin |
| `/crashes/?view=short_links` | **`/short-links/`** or hub panel | B0/B5 → S8 | API stays on s.f0xx.org |
| `/crashes/?view=home` | **`/`** hub or `/console/` | B0 | Retire crashes “home” |
| `/crashes/api/upload.php` | **`/issues/api/upload`** or `/api/v1/issues/upload` | S4 | Update `BackendEndpoints.java`, `CrashSettings.java` |
| `/crashes/api/*` (tickets) | **`/tickets/api/*`** | S5 | |
| `/graphs/` | **`/graphs/`** (keep) | B3 → S6 | Already separate vhost block |
| `/build/` | **`/build/`** (keep) | B6 → S9 | |
| `/` (hub) | **`/`** (keep) | B0 | |
| `/git/` | **`/git/`** (keep) | Gitea | Not a MS |
| `/v0/ota/` | **`/v0/ota/`** (keep) | S10 | |
**Migration mechanics:** ac-platform-edge 301 redirects old URLs ≥ 1 release; mobile app legacy URL rewrite already in `BackendEndpoints.normalizeUploadUrl()`.
**Naming note:** Today “reports” in code = **issues/crashes** in product language — align UI strings when moving to `/issues/`.
──────────────────────────────────────────────────────────────────────────────
M. ac-workspace + OTA multi-repo versioning (PO §5)
──────────────────────────────────────────────────────────────────────────────
**ac-workspace is NOT:**
- A single Gradle/Composer build root
- Required for CI (each repo has own pipeline)
**ac-workspace IS:**
- Optional manifest: “which repos at which SHA for a release train”
- Convenience for developers who want `clients/android` + `services/issues` side by side
**OTA same version, different client SHAs (Android + iOS):**
`ac-ms-ota` channel manifest example:
```json
{
"channel": "staging",
"version": "00.02.00.00",
"artifacts": {
"android": { "repo": "ac-mobile-android", "git_sha": "abc123", "apk_url": "..." },
"ios": { "repo": "ac-mobile-ios", "git_sha": "def456", "ipa_url": "..." }
}
}
```
Builder (S9) triggers per-repo builds; **S10** assembles manifest. Mobile apps read **`version`** for UX; **`git_sha`** per platform for support.
──────────────────────────────────────────────────────────────────────────────
N. Cloud & VM strategy (PO §6 — no K8s experience)
──────────────────────────────────────────────────────────────────────────────
**Recommendation: Phase 1 = VM lift-and-shift** (matches cluster0 lab, scaling SPEC §6.3, PO skill set).
| Stage | Where | Pattern |
|-------|-------|---------|
| **Now** | FE + BE Alpine | nginx + PHP-FPM + MariaDB ([INFRA.md](../INFRA.md)) |
| **Lab** | cast0103 | GTID MariaDB, NFS config only, apps local ([cluster0 ARCHITECTURE](../../orchestration/sim/cluster0/ARCHITECTURE.md)) |
| **Cloud phase A** | 46 VMs (be-web, be-data, be-ops, be-build) | Same as scaling table; **docker only on build** |
| **Cloud phase B** | Managed DB (RDS-class) | Apps use DSN secret; **ac-platform-db** migrations as job |
| **Cloud phase C** (optional) | K8s / compose swarm | **Not required** — introduce when MS count > ~8 and PO wants auto-scale |
**ac-deploy deliverables for cloud:** Terraform optional; minimum **Ansible + docker-compose fragments per VM role** + env templates. Each MS = one PHP-FPM pool or one container behind edge nginx.
**Inter-service calls (PO poor on microservices):** Start with **HTTP on localhost/private VLAN** (same BE host), not service mesh. Edge nginx routes public paths; internal `127.0.0.1:900x` or docker network. OpenAPI spec in **ac-docs/openapi/** is the contract.
──────────────────────────────────────────────────────────────────────────────
O. DR readiness checklist
──────────────────────────────────────────────────────────────────────────────
- [x] Map monolith → full MS catalog (§G)
- [x] PO decisions recorded (§I)
- [x] Comparison table (§J)
- [x] Dependency graph + fixes (§K)
- [x] URL migration map (§L)
- [x] Workspace / OTA model (§M)
- [x] Cloud recommendation (§N)
- [ ] PO confirms URL prefix (`/app/androidcast_project/` vs `/app/ac/`) — **locked: full prefix**
- [ ] PO confirms **ac-ms-identity** as P3 gate — **approved**
- [x] Write `docs/DRs/20260618_repos_reorganizing.md` + PDF
- [ ] Update gitea migrate scripts for org **`ac`**
- [ ] Migration runbook P0P7
[AI]: **Create Gitea repos from §G table in waves:** Wave 1 = P4,P5,D0,C2,S8; Wave 2 = S1,S2,S3; Wave 3 = S4,S5 + B1,B2; then edge + URL migration.