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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions knowledge/changelogs/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
3.16.1 || 26.08.2026
docs(kb) + docs(strategy): D50 — the app store's endpoint surface is spec'd, and the product page's identity gap is closed on paper. Operator: "in the apps would be cool if there was a little button that said to see more … it expands, has a deeper paragraph description from the manifest, and then has ALL the available stats, the 90d users, the visits, the 30d users, you get what i mean, everything in one screen, and the apps reviews comments kind of thing" — then "clicking the tile opens this modal or whatever it is" — then "in the knowledge base we need to talk about how the app store is going to work, it will need its own endpoints." **The finding that shaped the call:** the product page (PR #426, `/app-store/app/:id`) is broken in two independent ways — it fetches `PATCH /discover/app/{id}`, a route that does not exist in the API (every page 404s into "App not found"), and `list_store_apps` blanks `web10apps_post_id` to `""` (the v3 `apps` table never had the column — it's a v2 vestige), so the card never takes the internal-Link path and the tile opens the site directly. The root cause is an identity gap: the UI wanted a short ID for the route, but D47 already made the full URL the app's identity. **Decided (D50 — renumbered from D49, which #681 took for the real-user metrics model):** (1) the product page is a PAGE, not a modal — the existing route is the surface; tap tile → page, Open button → launch (App Store convention; a modal with no URL state is a review rejection per the deep-link rule, and it's cramped for "everything in one screen"); a "see more" expander on the card is rejected too (third tap target on a small tile, breaks grid row alignment); (2) a new `GET /v3/apps/detail?url=` serves the page — public, pure read, one call: app + rating aggregate + rating list + the full five-metric breakdown (D49 item 5: the grid card shows the headline, the detail page shows the full breakdown — this spec is what that line points at) + the node macro, and NO visit bump (a product-page view is not an app visit; `app_visits` rows come only from SDK pings carrying a verified token); (3) the URL is the key — `web10apps_post_id` is retired, `list_store_apps` stops blanking it, the route param becomes the URL-encoded canonical URL; a parallel ID (post_id / slug / numeric) is rejected — D47: the URL is the identity, a second ID system is drift by construction; (4) reviews = rating + optional comment — `app_ratings` gains a `comment` column, one voice per author (dedup key `(target_app_id, author)`), no separate reviews table; (5) the page shows D49's metric set, not an invention — per app: visits + users_1d/30d/90d/1y (the same realtime `get_app_metrics` queries the grid runs over `app_visits`, exact countDistinct) + the `/v3/stats` node macro (users, app_count, active_users, storage); a consent-based user count (`app_contracts` holders) is rejected — D49's metric set is the store's number, consent is a separate trust surface. **New KB doc:** `knowledge-base/web10-v3/app-store/endpoints.md` — the full surface (register / detail / list / rating / ratings / admin / approve / pwa_listing / stats), the auth split (reads public, writes signed or admin — D41), the detail response shape, what each number means, the product-page flow, and a logistics table (built vs scoped). The build itself (the detail endpoint, the comment column, the card-to-page wiring) is the next bite — this is the spec, per the KB-is-root-of-trust rule. No code changes; docs only.
3.16.0 || 26.08.2026
fix(api) + fix(ui) + feature(ui): the Node Config panel shows what the node actually runs — and its Save button works. Operator review of the panel on auth.dev.web10.app: "seeing alot of blanks", "clickhouse url is blank though... should default to the docker network thing", "media storage settings are empty too... should have the minio values", plus field-trimming asks. Root cause of the blanks: `POST /config` returned the raw saved `node_config` row — empty on a fresh node — so the form rendered blank even though the node was running on its `settings.py` values (env-overridden). New `config_svc.effective_config()`: settings.py is the base (what the node connects with and enforces at boot), the saved config overlays it field by field; `POST /config` now returns that. The ClickHouse URL defaults to the docker-network connection string composed from the `CLICKHOUSE_*` settings (`clickhouse://web10:web10@clickhouse:8123/web10` — the node connects with those parts, the URL is the human-readable reference form), and the S3 section defaults to the MinIO values (`http://minio:9000`, `web10-media`, `minioadmin`/`minioadmin`, `us-east-1`). `effective_config` coerces the env-override loop's raw strings back to typed values (int/float/bool). Field trimming per the operator: Node Identity drops Brand Name, Logo (dark), Logo (light), and Signing Algorithm (kept: Provider Domain, CORS Service Managers, Token Expiry); Stripe drops the four subscription-ID fields + Dev Pay Split (kept: Mode, Test API Key, Live API Key). Credential fields (ClickHouse URL, S3 secret, Twilio auth token, Stripe keys) render as visible text instead of password dots — the panel's job is to show the operator what the node runs, and the surface is admin-gated (`check_admin`: node-signed JWT + admin list); `POST /config` correspondingly strips only `private_key` (the signing secret — the UI has no field for it) instead of the five-field strip list. **The Save button was dead** — it sent `PATCH /config`, a route that does not exist (only `POST /config` and `POST /config/update` do), so every save 405'd; it now POSTs the diff-only payload to `/config/update` (the diff logic stays — unchanged values, including the billing fields the form no longer shows, stay off the wire). Tests: 7 new API unit tests in `test_node_config.py` (effective-config defaults, CH-URL composition, saved-overlay, env-string coercion; endpoint: admin sees effective config + no `private_key`, saved values surface, non-admin → 403 through the real exception handler). 708 API tests + 96 UI tests green, `tsc -b` + build clean.

Expand Down
5 changes: 3 additions & 2 deletions knowledge/knowledge-base/web10-v3/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ web10-v3/
├── setup/ ← node setup & operator config
│ └── node-config.md ← the node_config table, admins model, setup flow, /am_admin gate
├── app-store/ ← the node's public storefront
│ └── overview.md ← registration (a path is an app), visits, PWA manifests, store UI
│ ├── overview.md ← registration (a path is an app), visits, PWA manifests, store UI
│ └── endpoints.md ← the store's endpoint surface: the product page, ratings, stats
├── groups/ ← groups as a platform primitive
│ ├── overview.md ← policy containers, roles, join policies
│ ├── identity.md ← profiles, URLs, service-scoped roles
Expand Down Expand Up @@ -60,7 +61,7 @@ web10-v3/
- **Auth & Consent** — `auth/auth.md` (token flow), `auth/consent.md` (consent experience, ideal UX)
- **DB** — `db/clickhouse.md` (tables, indexes, patterns)
- **Setup & Config** — `setup/node-config.md` (node_config table, admins, /am_admin)
- **App Store** — `app-store/overview.md` (registration, visits, PWA manifests)
- **App Store** — `app-store/overview.md` (registration, visits, PWA manifests), `app-store/endpoints.md` (the endpoint surface: product page, ratings, stats)
- **Security** — `security/overview.md` (invariants I1–I5, two-contract model, blocking)
- **Groups** — `groups/overview.md` (primitive), `groups/identity.md` (profiles)
- **Social** — `social/overview.md` (implementation), `social/cross-app-sharing.md` (patterns)
Expand Down
Loading