1
0
mirror of git://f0xx.org/ac/ac-docs synced 2026-07-29 05:39:40 +03:00
Files
ac-docs/drafts/20260618_repos_reorganizing.txt
Anton Afanasyeu 69a448f156 initial
2026-06-23 12:20:43 +02:00

557 lines
45 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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.