atproto Thingiverse but good
10

Configure Feed

Select the types of activity you want to include in your feed.

Strip completed-ticket (PM-NN) references from src/ comments

Audit cleanup: remove Jira ticket refs for Done tickets (PM-9/14/19/20/21/22/25/26/27/38/45) from code comments and the foundation route copy. Keep refs to open/future work (PM-23 In Review, PM-46/47 To Do).

Orual (Jun 29, 2026, 7:06 PM EDT) 4bd075db c1837818

+36 -31
+6
Cargo.toml
··· 138 138 "fmt", 139 139 "env-filter", 140 140 ] } 141 + # Mirror the optional server-only deps so the `#[cfg(any(feature = "server", 142 + # test))]` server modules (indexing/appview/oauth) compile and their tests run 143 + # under a plain `cargo test`, not only `--features server`. 144 + axum-extra = { version = "0.10", features = ["cookie"] } 145 + base64 = "0.22" 146 + keyring = "3" 141 147 142 148 [build-dependencies] 143 149 dotenvy = "0.15"
+2 -2
e2e/tests/home.spec.ts
··· 43 43 await expect(page.getByRole('img', { name: 'Blueprint placeholder for missing preview media' })).toHaveCount(2); 44 44 }); 45 45 46 - test('foundation route shows PM-38 primitives and reusable states', async ({ page }) => { 46 + test('foundation route shows foundation primitives and reusable states', async ({ page }) => { 47 47 await page.goto('/foundation'); 48 48 49 49 await expect(page.getByRole('heading', { name: 'Foundation', exact: true })).toBeVisible(); ··· 61 61 await expect(page.getByText('Project lexicon')).toHaveCount(0); 62 62 await expect(page.getByText('Jira and Confluence')).toHaveCount(0); 63 63 await expect(page.getByText('Polytoken workflow')).toHaveCount(0); 64 - await expect(page.getByText('PM-38 foundation')).toHaveCount(0); 64 + await expect(page.getByText('Front-end foundation')).toHaveCount(0); 65 65 });
+3 -3
src/appview/actor.rs
··· 1 1 //! `space.polymodel.actor.*` read endpoint handlers: `getProfile` (typed union 2 2 //! of polymodel profileView / app.bsky profileViewDetailed) and `getSession` 3 - //! (PM-9 identity primitive; PM-26 returns the unauthenticated marker). 3 + //! (the session identity primitive). 4 4 5 5 use axum::extract::State; 6 6 use jacquard::identity::PublicResolver; ··· 66 66 } 67 67 68 68 /// Fetch `app.bsky.actor.getProfile` from `https://public.api.bsky.app` via the 69 - /// unauthenticated jacquard client. This is the only network path in PM-26's 70 - /// read endpoints; tests exercise union-variant construction without it. 69 + /// unauthenticated jacquard client. This is the only network path in the read 70 + /// endpoints; tests exercise union-variant construction without it. 71 71 async fn fetch_bsky_profile( 72 72 state: &AppState, 73 73 ident: &AtIdentifier,
+4 -5
src/appview/mod.rs
··· 1 - //! PM-26 XRPC read endpoints (appview query layer). 1 + //! XRPC read endpoints (appview query layer). 2 2 //! 3 3 //! All read endpoints are backed by the SQLite projection — records in 4 4 //! `record_json`, handles in `identities`, profiles in `profiles` — so the read ··· 6 6 //! [`IntoRouter`] and share [`AppState`] (SQLite pool + identity resolver + bsky 7 7 //! client). 8 8 //! 9 - //! Scope (PM-26): read endpoints only. Authenticated `getSession`/viewer state is 10 - //! PM-27; the client appview/session UX is PM-45; the SSR bridge is PM-46; the 11 - //! PDS passthrough proxy is PM-47. 9 + //! Not yet implemented: the SSR bridge (PM-46) and the PDS passthrough proxy 10 + //! (PM-47). 12 11 13 12 pub mod error; 14 13 pub mod state; ··· 51 50 .merge(GetProfileRequest::into_router(actor::get_profile)) 52 51 // getSession takes no parameters, so it bypasses ExtractXrpc (which 53 52 // decodes the query string; a unit-struct request from an empty query is 54 - // rejected by serde_html_form). Identity comes from the session, PM-27. 53 + // rejected by serde_html_form). Identity comes from the session. 55 54 .route( 56 55 GetSessionRequest::PATH, 57 56 axum::routing::get(actor::get_session),
+4 -4
src/appview/state.rs
··· 1 1 //! Shared appview handler state. 2 2 //! 3 - //! PM-26 read endpoints are backed entirely by the SQLite projection (records 3 + //! Read endpoints are backed entirely by the SQLite projection (records 4 4 //! live in `record_json`, handles in `identities`, profiles in `profiles`). The 5 5 //! read path therefore needs no Hydrant handle. `resolver` canonicalizes handle 6 6 //! authorities to DIDs for `getProfile`; `bsky` fetches the 7 7 //! `app.bsky.actor.defs#profileViewDetailed` union variant from the public 8 8 //! AppView for actors with no polymodel profile. 9 9 //! 10 - //! PM-27 adds the confidential OAuth client, single-origin web config, and 10 + //! It also carries the confidential OAuth client, single-origin web config, and 11 11 //! private cookie-jar key. `AppState` is the Axum router state type (local, so 12 12 //! the [`FromRef`] impls for [`OAuthWebConfig`] and the cookie [`Key`] satisfy 13 13 //! the orphan rule); it is cheaply `Clone` (pool/resolver/oauth are ··· 28 28 /// State shared by all XRPC read handlers and the OAuth routes. 29 29 #[derive(Clone)] 30 30 pub struct AppState { 31 - /// SQLite projection (PM-25): content, social counts, profiles, identities. 31 + /// SQLite projection: content, social counts, profiles, identities. 32 32 pub pool: SqlitePool, 33 33 /// Handle→DID resolution for `getProfile` actor canonicalization. 34 34 pub resolver: PublicResolver, ··· 36 36 /// (`https://public.api.bsky.app`) for the bluesky-only profile variant. 37 37 /// `Arc`-wrapped because `BasicClient` (`Agent`) is not `Clone`. 38 38 pub bsky: Arc<BasicClient>, 39 - /// Confidential OAuth client (PM-27) over the SQLite auth store. 39 + /// Confidential OAuth client over the SQLite auth store. 40 40 pub oauth: Arc<OAuthClient<PublicResolver, SqliteAuthStore>>, 41 41 /// Single-origin OAuth web config (cookie name + route paths). 42 42 pub oauth_config: OAuthWebConfig,
+1 -1
src/appview/tests.rs
··· 1 - //! Tests for the PM-26 appview read layer. 1 + //! Tests for the appview read layer. 2 2 //! 3 3 //! The read helpers are exercised against an in-memory SQLite database with the 4 4 //! migrations applied and representative rows seeded directly (the projection is
+1 -1
src/appview/views.rs
··· 1 - //! SQLite read queries and generated-view builders for the PM-26 read endpoints. 1 + //! SQLite read queries and generated-view builders for the read endpoints. 2 2 //! 3 3 //! Records come from the `record_json` column (written by the projection); the 4 4 //! required `record` field on thing/model/part views is built from it via
+1 -1
src/client.rs
··· 3 3 //! Polymodel deliberately uses this thin client rather than Jacquard's 4 4 //! credential/session `BasicClient` path: appview reads should target this 5 5 //! server's `/xrpc/space.polymodel.*` routes and rely on browser-managed 6 - //! cookies once PM-27 wires OAuth sessions. Callers send generated payload 6 + //! cookies for OAuth sessions. Callers send generated payload 7 7 //! request values, for example `client.send(GetSession).await?.into_output()`. 8 8 //! Identity resolution is delegated to Jacquard's resolver over the same 9 9 //! injected HTTP transport; this keeps Polymodel's appview client thin without
+2 -2
src/foundation.rs
··· 7 7 rsx! { 8 8 main { class: "browse-page product-shell", 9 9 header { class: "product-header", 10 - div { class: "product-kicker", "PM-38 foundation" } 10 + div { class: "product-kicker", "Front-end foundation" } 11 11 div { class: "product-header-row", 12 12 div { 13 13 h1 { "Foundation" } ··· 24 24 div { class: "foundation-hero-copy", 25 25 p { class: "eyebrow", "Token and asset check" } 26 26 h2 { "Blueprint styling foundation" } 27 - p { "This route keeps PM-38 primitives visible without making implementation scaffolding the product home." } 27 + p { "This route keeps the front-end primitives visible without making implementation scaffolding the product home." } 28 28 div { class: "button-row", 29 29 button { class: "button button-primary", "Primary action" } 30 30 button { class: "button button-ghost", "Ghost action" }
+1 -1
src/indexing/config.rs
··· 20 20 /// Public origin of this server, e.g. `https://polymodel.example.com`. 21 21 /// 22 22 /// The OAuth `client_id` is `{base_url}/oauth-client-metadata.json` and the 23 - /// redirect URI is `{base_url}/oauth/callback` (PM-27). When unset, bootstrap 23 + /// redirect URI is `{base_url}/oauth/callback`. When unset, bootstrap 24 24 /// defaults the OAuth client origin to `https://polymodel.space`, a functional 25 25 /// hosted client; set `POLYMODEL_BASE_URL` for local or alternate origins. 26 26 pub base_url: Option<String>,
+4 -4
src/main.rs
··· 19 19 // Frontend compile-time configuration, generated by build.rs from POLYMODEL_*. 20 20 mod env; 21 21 // Server-only indexing infrastructure (Hydrant firehose + SQLite projection). 22 - #[cfg(feature = "server")] 22 + #[cfg(any(feature = "server", test))] 23 23 mod indexing; 24 - // Server-only XRPC read endpoints (appview query layer, PM-26). 25 - #[cfg(feature = "server")] 24 + // Server-only XRPC read endpoints (appview query layer). 25 + #[cfg(any(feature = "server", test))] 26 26 mod appview; 27 - #[cfg(feature = "server")] 27 + #[cfg(any(feature = "server", test))] 28 28 mod oauth; 29 29 30 30 use browse::Browse;
+5 -5
src/mesh/mod.rs
··· 4 4 //! [`three_d_asset::TriMesh`] that carries format provenance, unit assumptions, and a 5 5 //! camera framing hint. STL is parsed from in-memory bytes (no filesystem), so this 6 6 //! module compiles to `wasm32-unknown-unknown` and can be consumed by any future 7 - //! renderer ([PM-14 research](https://radiant-industries.atlassian.net/wiki/spaces/PM/pages/131340)). 7 + //! renderer ([format ingestion research](https://radiant-industries.atlassian.net/wiki/spaces/PM/pages/131340)). 8 8 //! 9 9 //! Scope is STL-only for now; OBJ/glTF/3MF direct upload is tracked in PM-23. 10 10 11 - // This module is a renderer-agnostic ingestion foundation: it is consumed by PM-19 12 - // (Dioxus scaffold) and PM-20/PM-21 (renderers), none of which are wired into the 13 - // binary's main path yet. Its public surface is therefore intentionally unused at 14 - // present, so dead-code analysis is relaxed here until those tickets land. 11 + // This module is a renderer-agnostic ingestion foundation: it is consumed by the 12 + // Dioxus viewer scaffold and the renderer, which are not yet wired into the 13 + // binary's main path. Its public surface is therefore intentionally unused at 14 + // present, so dead-code analysis is relaxed here. 15 15 #![allow(dead_code)] 16 16 17 17 pub mod contract;
+1 -1
src/oauth/mod.rs
··· 243 243 } 244 244 245 245 // =========================================================================== 246 - // Confidential OAuth client bootstrap (PM-27) 246 + // Confidential OAuth client bootstrap 247 247 // =========================================================================== 248 248 249 249 use anyhow::Context as _;
+1 -1
src/viewer.rs
··· 2 2 //! 3 3 //! The viewer renders committed STL assets with [`three-d`] on a Dioxus-owned 4 4 //! canvas. The design (see the "STL viewer renderer decision" Confluence note) 5 - //! rests on three production decisions made when closing PM-20/PM-22: 5 + //! rests on three production decisions: 6 6 //! 7 7 //! * **One WebGL2 session per page mount.** The session is retained across 8 8 //! model switches and only the GPU mesh resources are replaced in place