---
gsd_state_version: 1.0
milestone: v2.4
milestone_name: Admin Foundation
status: executing
stopped_at: Phase 38 context gathered
last_updated: "2026-04-19T19:30:00.000Z"
last_activity: 2026-04-19 -- Phase 38 context gathered (tag management, hierarchy decisions)
progress:
  total_phases: 20
  completed_phases: 8
  total_plans: 34
  completed_plans: 32
  percent: 94
---

# Project State

## Project Reference

See: .planning/PROJECT.md (updated 2026-04-19)

**Core value:** Help people make better gear decisions — discover what others use, compare real-world data, and see how a potential buy affects your setup before committing.
**Current focus:** Phase 36 — Admin Role & Panel Foundation

## Current Position

Phase: 36 (Admin Role & Panel Foundation) — EXECUTING
Plan: 1 of 2
Status: Executing Phase 36
Last activity: 2026-04-19 -- Phase 36 execution started

Progress: [████████░░] 94%

## Performance Metrics

**Velocity:**

- Total plans completed: 110+ (all milestones through v2.3)
- v2.3: 18 plans across 3 phases (2026-04-13 → 2026-04-19)

*Updated after each plan completion*

## Accumulated Context

### Decisions

Key decisions carried forward from v2.3:

- External auth provider: Logto (self-hosted OIDC) — RESOLVED
- Structured UGC only — ratings and predefined fields, no freeform text — ACTIVE
- Separate globalItems table — not a flag on user items table — RESOLVED
- COALESCE merge for reference items — RESOLVED
- Detail pages replacing slide-out panels — RESOLVED
- Setup visibility: private/link/public column + shares table — RESOLVED
- Multi-currency: market_prices + community_prices + ECB rates — RESOLVED
- i18n: react-i18next, 7 namespaces, English + German — RESOLVED

v2.4 decisions:

- Admin role: isAdmin boolean flag on users table (simplest, no Logto role claims needed)
- Admin grant mechanism: CLI script or seed — no public UI for granting admin
- Sub-items/component attachment: explicitly deferred to a future milestone
- Catalog spec system (typed specs per tag): deferred to v2.5
- Engagement stats (views/likes/saves/appearances): deferred to v2.5

Phase 35 decisions (35-01):

- FIX-01: Add Candidate on thread page routes through CatalogSearchOverlay (thread mode), not a local modal
- FIX-02: ItemWithCategory type extended client-side only — server already returns image fields via withImageUrls()
- FIX-04: Login page is a server pass-through; no client auth check or card UI needed

Phase 35 decisions (35-02):

- FIX-03: Browser-native loading=lazy used for image deferral — no library needed, zero bundle overhead
- FIX-03: Skeleton is absolute inset-0 overlay removed on onLoad (not conditional branch swap) for stable layout
- FIX-03: GearImage accepts optional onLoad prop forwarded to all three img render paths
- [Phase ?]: FIX-05: cursor-pointer explicitly added to ItemCard navigable case, FabMenu buttons, and BottomTabBar anonymous tab buttons

### Pending Todos

- Cursor pointer on all clickable links — Phase 35 (FIX-05, plan 35-03)

Resolved in 35-01:

- Fix Add Candidate button shows wrong modal on thread page — DONE (FIX-01)
- Fix item image not showing on collection overview — DONE (FIX-02)
- Auth prompt sign-in button should redirect directly to Logto — DONE (FIX-04)

Resolved in 35-02:

- Investigate slow image loading — DONE (FIX-03)

### Blockers/Concerns

None.

## Deferred Items

Items carried forward from v2.3:

| Category | Item | Status |
|----------|------|--------|
| todo | 2026-04-10-add-cursor-pointer-to-all-clickable-links | promoted to v2.4 FIX-05 |
| todo | 2026-04-10-fix-item-image-not-showing-on-collection-overview | promoted to v2.4 FIX-02 |
| todo | 2026-04-10-investigate-slow-image-loading | promoted to v2.4 FIX-03 |
| todo | 2026-04-13-auth-prompt-sign-in-button-should-redirect-directly-to-logto | promoted to v2.4 FIX-04 |
| todo | 2026-04-13-fix-add-candidate-button-shows-wrong-modal-on-thread-page | promoted to v2.4 FIX-01 |
| Phase 35 P03 | 5m | 2 tasks | 3 files |

## Session Continuity

Last session: 2026-04-19T17:52:29.341Z
Stopped at: Completed 35-03-PLAN.md — FIX-05 (cursor-pointer audit) resolved
Resume file: None
