Commit Graph

172 Commits

Author SHA1 Message Date
b2c27fb285 Merge pull request 'docs(website): record the uo-link client config-decrypt contract and the dashboard mixed tier' (#61) from fix/uolink-client-contract-and-sitemode-gate into main
Reviewed-on: #61
2026-07-28 05:31:52 +00:00
2b93529ef6 docs(website): record the uo-link client's config-decrypt contract and the dashboard's mixed tier
Two corrections found by a live smoke test of all 200 routes at every access
level (website PR: fix/uolink-client-throw-and-sitemode-gate).

ARCHITECTURE.md: the "uoLinkClient never throws" invariant was true of the HTTP
call but not of resolving the config, which decrypts the stored auth token and
throws when the ciphertext can't be authenticated (SECRET_ENC_KEY rotated, or a
DB dump restored under a different key). Spell out that this is now handled
inside the client, reported as { ok: false, error: 'uo-link config unreadable' }
with a distinct ERROR log, and that GET /admin/uo-link/config keeps working —
it is the screen an admin needs to re-enter the token and recover.

BACKEND_DESIGN.md: GET /dashboard is staff-wide while PUT /site-mode on the
same screen is adminOnly — the one place a single screen spans two tiers. Note
that the client must gate that control itself rather than relying on the route
gate that admitted the user to the page.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-28 00:23:22 -05:00
9f3f014f34 Merge pull request 'docs(website): record PR 5 — public, player and auth capability split' (#60) from docs/router-split-5 into main
Reviewed-on: #60
Reviewed-by: Colby Whitlock <whitlocktech@gmail.com>
2026-07-28 01:56:22 +00:00
257ed2166c docs(website): record PR 5 — public, player and auth capability split
The domain split is complete. API_V2_PLAN.md gains a "PR 5 — as landed"
section (route table, the four zero-diff gates, and the findings worth
carrying forward) and its status line and sequencing list are updated: only
the CSP enforce PR remains, blocked on soak data rather than on code.

BACKEND_DESIGN.md §2 replaces the auth.routes.js / public.routes.js entries
with the full per-capability tree for auth/, public/ and player/, and §4's
group headings now point at the index.js files. The /player prose names the
three routers behind the shared gate.

Findings recorded rather than left in the code alone:

- public/ and auth/ deliberately have no group gate — the obvious hardening
  edit to either is an outage.
- GET /auth/me depends on session.router.js being mounted last, because
  use('/me', meRouter) matches the bare /me and supplies its noindex header.
- Two root-mounted routers (public/site, auth/session) on the PR 4 dashboard
  precedent, safe only because neither declares router-level middleware.
- loginGuards is the PR's shared module, the counterpart to PR 3's
  imageUpload.js.
- Filename deviations from the target tree (posts not news, session.router.js
  added) and why public.controller.js was not split.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-27 20:52:29 -05:00
bab70a3f6f Merge pull request 'docs(tree): sync website/PROJECT_TREE.md' (#57) from chore/sync-website-tree into main
Reviewed-on: #57
2026-07-28 01:32:42 +00:00
9c0c8f902c Merge branch 'main' into chore/sync-website-tree 2026-07-28 01:32:33 +00:00
a3e3ca817e Merge pull request 'docs(website): record the PR 4 admin router split and the end of admin.routes.js' (#58) from docs/admin-router-split-4 into main
Reviewed-on: #58
2026-07-28 01:31:55 +00:00
45fce7cb9f docs(website): record the PR 4 admin router split and the end of admin.routes.js
Covers website PR 4, the last admin split PR: shard (16), uo-link (5), email
(6), discord-bot (2), settings (2) and dashboard/site-mode (2) leave the
residual file, which is deleted. The admin group is fully split.

API_V2_PLAN.md gains a "PR 4 — as landed" section recording the two decisions a
reviewer would otherwise have to reconstruct: dashboard.router.js is mounted at
the group root (the single relaxation of the mount-at-a-prefix rule, safe only
because it declares no router-level middleware), and /shard keeps two gate tiers
in one router because prefix ownership beats swagger-tag grouping. Sequencing
item 7 is marked landed; PR 5 (public/player/auth) is the only split PR left.

BACKEND_DESIGN.md §2 gets the six new routers in the folder tree and drops the
residual entry; §4's /admin preamble now describes the ops/config gates instead
of pointing at a file that no longer exists.

WIKI_UPGRADE.md's two links into admin.routes.js are repointed at wiki.router.js
and admin/imageUpload.js.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-27 20:02:49 -05:00
runic-docs-bot
2efc32c022 docs(tree): sync website/PROJECT_TREE.md from RunicGateway/website@812b895 [skip ci] 2026-07-28 00:36:40 +00:00
e892d80aa8 Merge pull request 'docs(tree): sync website/PROJECT_TREE.md' (#55) from chore/sync-website-tree into main
Reviewed-on: #55
2026-07-28 00:36:08 +00:00
43d01fde03 Merge branch 'main' into chore/sync-website-tree 2026-07-28 00:35:57 +00:00
9f6ad6888d Merge pull request 'docs(website): record the PR 3 admin router split (posts, uploads, wiki, pages)' (#56) from docs/admin-router-split-3 into main
Reviewed-on: #56
2026-07-28 00:28:24 +00:00
d515d42b7c docs(website): record the PR 3 admin router split (posts, uploads, wiki, pages)
Adds a "PR 3 — as landed" section to API_V2_PLAN.md and ticks the sequencing
list. 31 routes extracted, 33 left in admin.routes.js; all four zero-diff gates
came back clean and 434 server tests passed.

Findings carried forward:

- The residual 33 is exactly PR 4's list, so admin.routes.js is deleted by
  PR 4 rather than PR 5.
- First shared module in the split: the multer config, because POST
  /posts/upload and POST /uploads no longer live in the same file.
- POST /uploads keeps its Admin · Posts swagger tag — retagging is a real
  OpenAPI diff and does not belong in a route-move PR.
- The wiki router has load-bearing intra-file route order (/categories and
  /tags ahead of /:slug) that no gate can catch, because the manifest sorts
  its entries. Verified by introspecting the built router stack instead.

BACKEND_DESIGN.md §2 gets the four new routers plus imageUpload.js in the
folder tree, and §4 notes that the content capabilities add no gate beyond
staffOnly.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-27 19:24:58 -05:00
runic-docs-bot
c47c89c023 docs(tree): sync website/PROJECT_TREE.md from RunicGateway/website@4938432 [skip ci] 2026-07-28 00:12:16 +00:00
d034c6f673 Merge pull request 'docs(website): record the PR 2 admin router split (moderation, bot-activity, activity)' (#54) from docs/admin-router-split-2 into main
Reviewed-on: #54
Reviewed-by: Colby Whitlock <whitlocktech@gmail.com>
2026-07-28 00:11:13 +00:00
a4d03bd956 docs(website): record the PR 2 admin router split (moderation, bot-activity, activity)
Matches the code change in website: 18 more admin routes carved into
moderation.router.js (15), botActivity.router.js (2) and activity.router.js (1),
leaving 64 in the residual admin.routes.js.

API_V2_PLAN.md gains a "PR 2 — as landed" section recording the four zero-diff
gates and two decisions worth carrying into PRs 3-5:

  - /activity gets its own file rather than the target tree's plan to park it as
    a singleton inside dashboard.router.js — honouring the tree would have left
    one route in the residual file for two PRs, and it is a genuinely separate
    capability (the staff audit log, not the dashboard's stats overview and not
    the botScore middleware's ban state). PR 4 therefore mounts dashboard and
    site-mode only; the target tree is updated to match.
  - A gate moves to a router-level `use` only where it was already a *prefix*
    mount (moderation's modAccess). Bot-activity's per-route adminOnly stays
    per-route, because the per-route handler count is the only thing in
    routes.guards.json that would catch a dropped gate — requireRole(...) returns
    an anonymous arrow and never appears by name.

BACKEND_DESIGN.md §2 (folder structure) and §4 (the /admin contract preamble) are
updated for the new files and their gates. PROJECT_TREE.md is left alone — since
website#98 it is auto-generated by the sync-project-tree workflow.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-27 18:54:01 -05:00
7b699301e7 Merge pull request 'docs(tree): sync website/PROJECT_TREE.md' (#50) from chore/sync-website-tree into main
Reviewed-on: #50
2026-07-27 21:42:01 +00:00
runic-docs-bot
bd8adf1c54 docs(tree): sync website/PROJECT_TREE.md from RunicGateway/website@0e11e28 [skip ci] 2026-07-27 21:01:09 +00:00
fec3aa0d5d Merge pull request 'docs(website): record split PR 1 — admin users, account, invites, auth providers' (#53) from docs/admin-router-split-1 into main
Reviewed-on: #53
2026-07-27 20:59:05 +00:00
a7186e2fb9 Merge branch 'main' into docs/admin-router-split-1 2026-07-27 20:58:55 +00:00
b7244a24b0 docs(website): record split PR 1 — admin users, account, invites, auth providers
Documentation half of the first of five domain-split PRs (API_V2_PLAN.md § Phase 2).

BACKEND_DESIGN.md
- §2 folder structure: admin/ now shows index.js (shared gate + mount table) and
  the four capability routers with their route counts, prefixes and extra gates;
  admin.routes.js is labelled as the 82-route residual that goes away with PR 5.
- §4 /admin heading: was "admin.routes.js -> admin.controller.js", now points at
  admin/index.js and notes staffOnly, which the old heading omitted.
- The "planned change" note becomes "in progress" with what has landed.

API_V2_PLAN.md
- Status: planning -> in progress; PR 1 marked landed in the sequencing list.
- New "PR 1 — as landed" section: the route-count table (6+15+3+4+82 = 110) and
  three findings for PRs 2-5 — why the self-service /shard/* routes stay with the
  shard capability despite their Admin · Account tag, why a prefix mount must not
  be "simplified" to a pathless one (a bare use(gate) would then run for requests
  headed to later mounts), and that routes.guards.json came back zero-diff too.
- New section on the swagger path-normalization prerequisite and its consequence:
  with sorted path keys, a pure route move produces no spec diff, so the spec
  becomes a third zero-diff gate alongside the manifest and guards files.
- Correction to step 6: PROJECT_TREE.md is auto-generated by the sync-project-tree
  workflow since website#98 and must not be hand-edited in split PRs.

api-route-inventory.json is unchanged — verified still byte-identical to
server/routes.manifest.json (200 public + 2 internal), which is the point.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-27 15:55:37 -05:00
6cea1c24c4 Merge pull request 'docs(website): document the OpenAPI path-key normalization' (#52) from docs/swagger-normalize-paths into main
Reviewed-on: #52
Reviewed-by: Colby Whitlock <whitlocktech@gmail.com>
2026-07-27 20:52:09 +00:00
31c91fb307 docs(website): document the OpenAPI path-key normalization
Matches website PR "build(swagger): normalize and sort generated OpenAPI path
keys", which post-processes swagger-autogen's output ahead of the admin router
domain split (API_V2_PLAN.md § Phase 2).

- website-README.md § Regenerating the spec: why trailing slashes are stripped
  (a capability router mounted at /users declaring router.get('/') would document
  /api/v1/admin/users/, a URL no client calls) and why path keys are sorted.
- BACKEND_DESIGN.md § generated artifacts: note that both the route manifest and
  the spec are emitted sorted, so a diff in either is proportional to the change.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-27 15:50:01 -05:00
8c46af7e54 Merge pull request 'docs(website): correct the CSP delta to one directive and document the report sink' (#51) from feature/csp-report-only into main
Reviewed-on: #51
Reviewed-by: Colby Whitlock <whitlocktech@gmail.com>
2026-07-27 20:22:28 +00:00
9a3e1cc1e7 docs(website): correct the CSP delta to one directive and document the report sink
Companion to website "feat(security): soak the tightened CSP on report-only".

The plan's Phase 1 claimed a two-directive delta, one of which was adding
`form-action 'self'` as "currently absent". It was not absent. The directives
object in app.js does not list it, but the middleware runs `useDefaults: true`
and helmet's default set already supplies it, so production has been serving it
all along. The plan was written from the config rather than from the live
header; the correction, and how it was caught, are now recorded in place rather
than quietly fixed.

That leaves `frame-ancestors 'self'` -> `'none'` as the entire behavioural delta
of the phase. Worth noting that this is also the directive that most justifies a
soak: a frame-ancestors violation is reported by the browser of whoever framed
the site, so it is the only available way to discover a legitimate embed before
an enforcing policy breaks it.

Also documented:

  * POST /api/csp-report -- the same-origin sink report-to/report-uri point at,
    why it is same-origin, why it lives outside /api/v1, both wire formats, the
    Reporting-Endpoints header requirement, and the properties that make an
    unauthenticated public POST safe (always-204, caps, truncation, rate limit).
  * That the sink is scoped to the soak, so the enforce PR must decide
    explicitly whether to retire it or keep a report-to group on the enforced
    policy -- rather than leaving an orphan route behind.
  * The `[csp]` log tag in section 7.5 as the thing to watch during the soak,
    and what silence across one release means.
  * client/vite.config.js already sets `modulePreload: { polyfill: false }`, so
    the plan's inline-polyfill prerequisite was already satisfied.

api-route-inventory.json moves 199 -> 200 for the new route. That is the PR 0
freeze working as intended: the first manifest diff since the baseline is a
deliberate, reviewed one.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-27 15:19:43 -05:00
9ecfe610de Merge pull request 'docs(website): record the landed route manifest and resequence CSP after PR 0' (#49) from chore/route-manifest into main
Reviewed-on: #49
Reviewed-by: Colby Whitlock <whitlocktech@gmail.com>
2026-07-27 20:00:08 +00:00
b1a474a7eb docs(website): record the landed route manifest and resequence CSP after PR 0
Companion to website PR 0 (chore(server): freeze the URL surface with a
generated route manifest).

BACKEND_DESIGN.md gains § 4.0, naming the two generated artifacts that are
actually authoritative about the API and what each is authoritative *for*: the
manifest records which URLs exist (introspection-derived, reality), the Swagger
spec records what they mean (annotation-derived, intent). The prose tables in
§ 4 are orientation and can drift; those two files cannot. Also documents
routes.guards.json as a review aid that is explicitly not a contract.

API_V2_PLAN.md marks PR 0 shipped and records its two deviations. The optional
unauthenticated-status snapshot was tried and dropped exactly as that section
allowed — against the dead-port mariadb pool the tests use it sits on the acquire
timeout rather than failing fast — replaced by a deterministic assertion that
every /admin/** and /player/** route still carries requireAuth.
routes.guards.json is committed and staleness-checked even though a diff in it
is not a contract change, because an ungenerated review aid rots into a
misleading one.

The sequencing section is corrected: PR 0 now runs before the CSP pair. The CSP
report-only PR must stand up a POST /api/csp-report collector for `report-to` to
target, which is a new URL under /api/**; landing it first would have left PR 0
generating 200 routes against a 199-route baseline, destroying its own acceptance
test. With PR 0 first, the collector appears as a reviewed, deliberate +1 in the
manifest — the mechanism working as intended.

api-route-inventory.json is unchanged, which is the point: the generator
reproduced it byte-for-byte on first run.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-27 14:55:57 -05:00
40cd9375d7 Merge pull request 'docs(website): finalize the API plan — in-place router split, no /api/v2' (#48) from docs/api-plan-final into main
Reviewed-on: #48
Reviewed-by: Colby Whitlock <whitlocktech@gmail.com>
2026-07-27 19:41:11 +00:00
5de5e19445 docs(website): finalize the API plan — in-place router split, no /api/v2
The API v2 plan is revised down to the work that is actually justified: a CSP
hardening pass and an in-place domain split of the monolithic route wiring.

- Auth merge (httpOnly cookies -> bearer + rotating refresh for every client) is
  removed and re-filed as deferred behind trigger conditions. httpOnly+SameSite
  is the stronger model, session.service.js already unifies cookie and bearer,
  the SSO/PKCE transaction cookies survive any merge, and it dragged the admin
  SSE fetch/ReadableStream rewrite along as a dependency for no user-visible
  payoff. A revival must first spec refresh-token reuse detection and a rollback
  procedure.
- No parallel /api/v2. The URL surface is already grouped by capability, so each
  new router file mounts at the prefix it already owns and every URL stays
  byte-identical. No dual mount, no per-route migration, no v1 retirement; the
  SPA, Discord bot, and Android app are all untouched. API_V2_SKELETON.md is
  marked superseded (kept as the recipe if a versioned API is ever forced).
- The /api/mobile facade and app-version floor are deferred with the revival note
  that it starts as a one-line alias mount, not ~70 hand-written delegates. The
  M11 milestone is dropped from android/PLAN.md.
- Adds PR 0: a generated route manifest, so "every URL is unchanged" is proved by
  a zero-line diff rather than asserted in review. The baseline
  api-route-inventory.json (199 API routes + 2 internal) is committed here and is
  what PR 0's generator must reproduce byte-for-byte.
- Split sequenced as five grouped PRs; CSP fixed to report-only first, then
  enforce (the old plan contradicted itself), with the verified delta being just
  form-action 'self' and frame-ancestors 'none'.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-27 14:31:26 -05:00
81f7d58fbe Merge pull request 'docs(website): cross-component blast-radius review + /api/mobile facade (Phase 0)' (#47) from docs/api-v2-blast-radius-mobile-facade into main
Reviewed-on: #47
Reviewed-by: Colby Whitlock <whitlocktech@gmail.com>
2026-07-23 05:00:00 +00:00
3eafaef97e docs(website): add cross-component blast-radius review + /api/mobile facade (Phase 0)
Expand the API v2 plan to account for consumers beyond the browser and
insulate the Android app from version churn before the v2 work begins.

- Inventory the three v1 API consumers (browser, Android app, Discord bot)
  and map the cross-component contracts (site<->link, site<->mobile).
- Fix two concrete plan bugs: the public shard SSE stream must stay
  anonymous (logged-out browsers and the app's ShardStreamClient send no
  auth header), and the useShardFeed fetch-rewrite is admin-stream-only.
- Add "Phase 0 - the mobile facade": a version-agnostic /api/mobile
  namespace (a thin BFF delegating to current controllers behind pinned
  wire shapes), landed before v2 so the auth merge never touches the app.
- Note link/ is essentially out of scope (no PROTOCOL_VERSION bump), with
  the admin-stream allowlist split as the only shared seam.
- Resequence PRs (Phase 0 first) and gate v1 retirement on the pre-facade
  app fleet aging out via an app-version floor, not the web client.
- Add M11 to docs/android/PLAN.md: migrate the app to /api/mobile + ship
  the app-version floor, cross-referenced with the website plan's Phase 0.

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NgyHnrNa8WwG3doxvxjuCr
2026-07-22 23:54:15 -05:00
4810830c8a Merge pull request 'docs(website): add /api/v2 skeleton (PR 1 scaffold)' (#46) from docs/api-v2-skeleton into main
Reviewed-on: #46
Reviewed-by: Colby Whitlock <whitlocktech@gmail.com>
2026-07-22 21:57:19 +00:00
bfb006c888 Merge branch 'main' into docs/api-v2-skeleton 2026-07-22 21:57:09 +00:00
2cb6f7a3b9 docs(website): add /api/v2 skeleton (PR 1 scaffold), link from plan
Companion doc to API_V2_PLAN.md describing PR 1: stand up router/v2/ empty but
wired next to a frozen /api/v1, with a trivial GET /api/v2/version to make the
mount testable and no behavior change. Includes the file tree, the api.router.js
/ v2.router.js wiring, empty capability-router stubs, and acceptance criteria.
Adds a forward link from the plan's PR-1 line to the skeleton doc.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-22 16:54:23 -05:00
cfd202b23e Merge pull request 'docs(website): add API v2 plan (auth merge, CSP hardening, domain split)' (#45) from docs/api-v2-plan into main
Reviewed-on: #45
Reviewed-by: Colby Whitlock <whitlocktech@gmail.com>
2026-07-22 21:52:04 +00:00
eb19556802 docs(website): add API v2 plan (auth merge, CSP hardening, domain split)
Plan for website API v2, sequenced in two phases behind a parallel /api/v2:

- Phase 1: retire httpOnly session cookies; unify web + mobile on the existing
  bearer access + rotating/revocable refresh model. Separates removable session
  cookies from the SSO/email transaction cookies that must stay. SSE moves to
  fetch-based streaming with Authorization: Bearer.
- Phase 1b: tighten the shipped CSP for the now-JS-held token (add form-action
  'self', frame-ancestors 'none'); self-host fonts + Trusted Types as follow-ups.
- Phase 2: break the monolithic route wiring (admin.routes.js, ~100 routes) into
  one router per business capability so the URL predicts the file.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-22 16:50:33 -05:00
c2f4866012 Merge pull request 'docs(tree): sync website/PROJECT_TREE.md' (#44) from chore/sync-website-tree into main
Reviewed-on: #44
2026-07-22 21:43:28 +00:00
runic-docs-bot
daf735f48f docs(tree): sync website/PROJECT_TREE.md from RunicGateway/website@cbe54fc [skip ci] 2026-07-22 21:31:42 +00:00
57395c51b1 Merge pull request 'docs(tree): sync link/PROJECT_TREE.md' (#42) from chore/sync-link-tree into main
Reviewed-on: #42
2026-07-22 21:27:34 +00:00
a458d4f594 Merge branch 'main' into chore/sync-link-tree 2026-07-22 21:27:11 +00:00
3e98a6c437 Merge pull request 'docs(tree): sync android/PROJECT_TREE.md' (#43) from chore/sync-android-tree into main
Reviewed-on: #43
2026-07-22 21:26:59 +00:00
runic-docs-bot
468c9b5541 docs(tree): sync android/PROJECT_TREE.md from RunicGateway/Android-app@f3da6ea [skip ci] 2026-07-22 21:25:02 +00:00
runic-docs-bot
7f9d63308b docs(tree): sync link/PROJECT_TREE.md from RunicGateway/link@7e4177c [skip ci] 2026-07-22 21:20:56 +00:00
d10aefa755 Merge pull request 'docs(tree): add per-repo PROJECT_TREE snapshots + index them' (#41) from docs/add-project-trees into main
Reviewed-on: #41
Reviewed-by: Colby Whitlock <whitlocktech@gmail.com>
2026-07-22 21:16:08 +00:00
3ae4d1c3db docs(tree): add per-repo PROJECT_TREE snapshots + index them
Add auto-generated project-tree snapshots for the website, link, and
Android-app repos under docs/<repo>/PROJECT_TREE.md, and link them from
the README (adding a previously-missing android/ section). These files
are maintained going forward by the sync-project-tree CI workflow in each
source repo, which opens a PR here whenever the tracked layout changes.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-22 16:14:52 -05:00
f773a13c23 Merge pull request 'docs(android): add test coverage plan to reach the 50% gate' (#40) from docs/android-coverage-plan into main
Reviewed-on: #40
Reviewed-by: Colby Whitlock <whitlocktech@gmail.com>
2026-07-22 19:30:04 +00:00
43d9782d2e docs(android): add test coverage plan to reach the 50% gate
Post-#26 the JaCoCo→Sonar wiring is live and coverage measures 16.4% on new
code — under the 50% gate. Add COVERAGE_PLAN.md: a bucketed analysis of the
gap (ViewModels 0.1%/1153 lines is the dominant lever; DTOs, repositories,
core utils next) and a phased plan — Phase 0 broadens coverage exclusions to
drop non-unit-testable UI/framework code, Phases 1–4 test DTOs, ViewModels,
repositories, and core. Includes a MainDispatcherRule harness + VM test
pattern and per-phase coverage projections (Phase 2 clears the gate at ~65%).
Cross-linked from PLAN.md §12.1.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NgyHnrNa8WwG3doxvxjuCr
2026-07-22 14:27:39 -05:00
1e6710dd50 Merge pull request 'docs(android): record SonarQube coverage wiring and issue triage (§12.1)' (#39) from docs/android-sonar-coverage into main
Reviewed-on: #39
Reviewed-by: Colby Whitlock <whitlocktech@gmail.com>
2026-07-22 19:00:35 +00:00
a743b6000c docs(android): record SonarQube coverage wiring and issue triage (§12.1)
Add §12.1 documenting the Android-app SonarQube setup: the coverage gate
failed at 0% because the source-only scan received no JaCoCo report (a
reporting gap, not a testing gap). Records the JaCoCo wiring (jacoco plugin +
report task, sonar.coverage.jacoco.xmlReportPaths, pure-UI coverage
exclusions, a Gradle step in sonarqube.yml) and the 2026-07-22 triage:
3 smells fixed in code, 12 marked Won't Fix (snake_case DTO fields that
mirror the wire contract; idiomatic Compose/nav complexity).

Pairs with RunicGateway/Android-app chore/sonar-coverage-and-cleanup.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NgyHnrNa8WwG3doxvxjuCr
2026-07-22 13:59:14 -05:00
2686ade632 Merge pull request 'docs(android): note the empty-subscriptions PUT serialization gotcha' (#38) from docs/notifications-empty-subscriptions-gotcha into main
Reviewed-on: #38
Reviewed-by: Colby Whitlock <whitlocktech@gmail.com>
2026-07-22 16:39:30 +00:00