MotirBuilding in public
MOTIR · moooon
onMotir
You’re viewing a public project. Anyone can view it — no account needed. Sign in to submit, upvote, or comment on requests.View-only — you can’t edit work items
MOTIR-421

6.13 The project square (system-level public-project directory)

Done
Description

The project square — a SYSTEM-level directory of every project made public in 6.12, as a fully public (no sign-in) web page at motir.co/explore, reached from the Motir marketing site (NOT an app-shell route, NO left-nav entry). A crawlable gallery anyone can browse: project cards (name, org, description, viewer / upvote / activity stats — NO redundant “Public” pill), a search bar, category / tag filters, and sort / rank tabs (trending / popular / recent-new), paginated at scale, SEO + GEO optimised (server-rendered, JSON-LD, semantic HTML, sitemap’d real URLs + per-topic landing pages, answer-engine framing) — then click any card through to that project’s public read-only view (6.12.4). It is the cross-org DISCOVERY surface that 6.12 was missing: 6.12 made each project openable but reachable only by share-link; 6.13 is the place all public projects surface together so anyone can FIND them without a link.

Model revision (Yue, 2026-06-14): fully public / no auth; not in the left nav (a marketing-site page); no per-card “Public” pill; SEO + GEO optimised. Supersedes the earlier account-required + shell-entry framing.

The model (locked — see the module header for the full rationale + the verified mirror):

  • A thin DISCOVERY index over 6.12, not a new access system. The square lists ONLY projects whose access level is already public (the single cross-org READ exception 6.12.3 fixed); a private / open / limited project NEVER appears, for any viewer. It adds NO new write, NO new cross-org grant — the page itself is fully public (no sign-in), and every card click lands on the 6.12.4 public view that already enforces the public projection.
  • A public, crawlable web page (SEO + GEO), not an app surface. Server-rendered with a real <h1> + descriptive lede, semantic HTML, JSON-LD (CollectionPageItemList), head meta / OpenGraph / canonical, and a sitemap of real indexable URLs (each rank / search / topic / page) + per-topic landing pages (/explore/topic/<slug>); a GEO answer-engine framing (citable lead + FAQ). Reached from the marketing site, NOT the app left-nav.
  • The card projection. A card shows name, org, description, and the three public demand signals from 6.12.6 (viewers / upvotes / recent activity) — the directory read surfaces ONLY these card-projection fields, never an internal project field.
  • Three ranks (the GitHub-Trending / GitLab-Explore-tabs set), deterministic + cursor-paginated. Trending = recent upvotes + activity in a recency window (a project freshly surging rises); Popular = total upvotes + total viewers (lifetime); Recent / New = newly-made-public, by the moment it turned public. Each is a stable total order (tiebreak on project id) computed at the read layer over the 6.12.6 signals — NOT load-all (a system list could be thousands — finding #57).
  • Search + category / tag filters (the GitHub-Topics / GitLab-Topics browse axis). A name/description search over public projects (riding the shipped 6.1.1 FilterAST where it fits, else a scoped search) + category/tags so the square is browsable by topic, with a categories view sorted by project count.

Scope: the project-square design (6.13.1); the cross-org public-projects directory service, cursor-paginated, card-projection, EXCLUDING non-public projects (6.13.2); search + category/tag filtering (6.13.3); the trending / popular / recent ranking (6.13.4); the public-project categories/tags model + tagging + tag-facet (6.13.5); the project-square UI — the fully-public marketing-site page (top bar + footer), the SEO hero, gallery + cards + search/filter/sort tabs + the SEO/GEO scaffolding (metadata, JSON-LD, semantic HTML, sitemap, topic landing pages), each card linking to the 6.12.4 public view (6.13.6); the directory + ranking + search/filter + pagination tests (6.13.7); the anonymous browse → search → sort-by-trending → click-into-public-view e2e (6.13.8).

Out of scope (named so they land in their own story, not here): a curated / editorially-featured "collections" surface (GitHub Collections — a later editorial layer; 6.13 ships the algorithmic ranks + the category browse); per-account personalization / "projects for you" recommendation (a signal-driven enhancement); cross-org GLOBAL search beyond public projects (the shipped FilterAST stays project-scoped — 6.13 searches only the public directory); and AI-assisted discovery / semantic ranking (an Epic-7 enhancement).

Verification

  • Pull the Story branch; run the migration + pnpm db:seed against the local Postgres (localhost:5433); pnpm dev. Seed a HANDFUL of public projects across MORE THAN ONE org (with varied upvote/viewer/activity + made-public timestamps) plus at least one NON-public project per org.
  • The square shows only public projects, cross-org — fully public, no sign-in. Open /explore while LOGGED OUT (no session) → the gallery renders project CARDS (name, org, description, viewer / upvote / activity stats — NO “Public” pill) for the public projects across ALL orgs. Confirm the page is reached as a standalone web page (NOT from the app left-nav — there is no left-nav entry), and view-source shows a real <h1>, <meta>/OpenGraph tags, and a JSON-LD CollectionPage block (SEO/GEO). Confirm the seeded NON-public projects are ABSENT from the square for everyone (a private/open/limited project never appears), and that the 404-not-403 posture for those projects is unchanged when hit directly.
  • Sort / rank tabs. Switch the tabs: Trending orders by recent upvotes + activity (a project given a fresh burst of upvotes rises above a higher-lifetime-but-stale one); Popular orders by total upvotes / viewers; Recent / New orders by made-public time (the newest public project first). Each ordering is stable on reload (deterministic tiebreak) and paginates (no load-all) — scroll/next past the first page and confirm no row is skipped or duplicated at the page boundary.
  • Search + category / tag filter. Type a query in the search bar → the gallery narrows to public projects matching name/description; pick a category/tag → the gallery narrows to that topic; the categories view lists topics with their project counts. Clearing returns to the full ranked gallery. Confirm search/filter compose with the active rank tab + the cursor pagination.
  • Click-through to the public view. Click a card → it lands on that project’s 6.12.4 public read-only view (the board / issues / public roadmap), which still enforces the public projection (internal fields absent) — proving the square is a discovery index over the 6.12 surface, not a second view path.
  • pnpm test (6.13.7) covers: the directory lists ONLY public projects cross-org (non-public excluded); each rank’s ordering correctness + determinism + cursor pagination (no skip/dupe); search + category/tag filter correctness; the card projection surfaces no internal field — all on a real Postgres respecting the per-file coverage gate.
  • 4-layer + token review. No raw Prisma in any route; the directory / ranking / search reads go through the service → repository layer with the card projection (the access_level = public filter lives in the repository read, not a route); the square surfaces reference only --el-* / [data-display-style] tokens + shipped components/ui/*.
  • Dep audit. Confirm no 6.13 subtask references any id > 6.13 (deps are 6.13.x / 6.12.x / 6.1.1 only).
  • If every step holds, approve and merge the Story PR. If anything fails, comment with what didn’t work and Motir will produce a follow-up Subtask under the same Story.