Skip to content

moooon

Motir

Vibe your whole project. Bring an idea — Motir's three AI layers plan it, track it, and ship it, end to end. You're looking at Motir, built in Motir.

  • Vibe Project
  • Open Source
  • AI Agent
  • AI Loop
1
requests
0
upvotes
145
planned
1,361
shipped

Motir · Roadmap

MOTIR-4110Done

The two DETAIL reads get public routes — one work item, and one feature request

Opened by Zhu Yue ·

/p/* is not only tabs: it has two detail pages, and neither has a public endpoint.

  • app/(public)/p/[identifier]/items/[key]/page.tsx — one work item as the public surface shows it. publicProjectsService.getWorkItemDetail (:993) exists, is tested, and no route reaches it.
  • app/(public)/p/[identifier]/requests/[requestKey]/page.tsx — one feature request with its public comment thread and its vote count. publicProjectsService.getRequestDetail (:899) exists, is tested, and no route reaches it.

Both were deleted by MOTIR-3951, whose service sweep kept the two methods precisely for this card. Add the two GET routes so the renderer on motir.co can fetch them.

Same shape as the reads beside them, and no deviation from it: capability gate first (publicSurfaceUnavailable()), getSession() for an optional actorUserId ?? null, one service call, ProjectNotFoundError / PublicRequestNotFoundError404 with no existence leak (the 404-not-403 posture the request routes already keep). HTTP layer only.

Read the two methods before choosing the paths and the parameters — the request detail is keyed by a request KEY on the page and the existing write routes are keyed by projectId + request id, so the route's identifier must match what the SERVICE actually takes rather than what the old page's URL happened to carry. State the mapping in the route's own comment.

The comment thread that hangs off the request detail is a READ here and a WRITE elsewhere. This card exposes what the page displays; POST /api/public-requests/{id}/comments and …/upvote already exist and are session-gated, and what becomes of them cross-origin is the amendment's and the act path's, not this card's. Do not touch them.

Contract entries are part of the deliverable, exactly as for the tab reads: two operations in lib/api/public/openapi/operations.ts, and both routes present to the cloud-gate and anonymous-posture enumerations without an exemption.

Acceptance criteria

  • A public GET route returns the work-item detail projection for an anonymous caller on a public project, and 404 { code } for an unknown item, a non-public project, or an item the epic-privacy exclusion hides from a non-member.
  • A public GET route returns the feature-request detail projection — including its public comment thread and vote count as the service already returns them — with the same 404 posture.
  • Both routes call publicSurfaceUnavailable() before any session read and answer the gate's response with MOTIR_CLOUD unset.
  • Each route's comment records the identifier it takes and why (key vs id), read from the service signature rather than from the deleted page's URL.
  • lib/api/public/openapi/operations.ts declares both; contract-coverage, contract-drift, cloud-gate-totality and anonymous-posture are green with no new exemption.
  • Neither route writes anything, and neither POST /api/public-requests/{id}/upvote nor …/comments is modified by this card.
  • No file outside motir-core is touched.

Context refs

  • motir-core/lib/services/publicProjectsService.tsgetRequestDetail (:899), getWorkItemDetail (:993)
  • motir-core/lib/dto/publicProjects.ts · lib/dto/publicRequests.ts — the projections these return
  • motir-core/app/api/public/p/[identifier]/items/route.ts — the sibling list read and its posture comment
  • motir-core/app/api/public/projects/[projectId]/requests/route.ts — how the request surface is keyed on the write side
  • motir-core/tests/publicProjects/publicWorkItemDetail.test.ts · publicRequestDetail.test.ts — the service tests kept for this card
  • motir-core/lib/api/public/openapi/operations.ts · motir-core/tests/api/public/
  • the two detail pages on motir.co — the consumer

Discussion

No comments yet.

Adding to this discussion signs you in on app.motir.co and brings you back to this request.

Add a comment