docs: add phase 32 plan summaries
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
42
.planning/phases/32-setup-sharing-system/32-01-SUMMARY.md
Normal file
42
.planning/phases/32-setup-sharing-system/32-01-SUMMARY.md
Normal file
@@ -0,0 +1,42 @@
|
||||
# Plan 32-01 Summary: Schema Migration (isPublic -> visibility)
|
||||
|
||||
**Status:** Complete
|
||||
**Commit:** edc9793
|
||||
|
||||
## What was done
|
||||
|
||||
1. **Schema changes** (`src/db/schema.ts`):
|
||||
- Replaced `isPublic: boolean` with `visibility: text` (default "private") on setups table
|
||||
- Added `shares` table with columns: id, setupId, token, permission, expiresAt, userId, createdAt, revokedAt
|
||||
- Removed `boolean` import from drizzle-orm/pg-core
|
||||
|
||||
2. **Migration** (`drizzle-pg/0005_true_green_goblin.sql`):
|
||||
- Creates shares table with FK constraints
|
||||
- Adds visibility column with data migration (`UPDATE setups SET visibility = 'public' WHERE is_public = true`)
|
||||
- Drops is_public column
|
||||
|
||||
3. **Full-stack isPublic -> visibility replacement** across 16 files:
|
||||
- `src/shared/schemas.ts`: `z.enum(["private", "link", "public"])` replaces `z.boolean()`
|
||||
- `src/server/services/setup.service.ts`: createSetup, getAllSetups, updateSetup
|
||||
- `src/server/services/discovery.service.ts`: `eq(setups.visibility, "public")`
|
||||
- `src/server/services/profile.service.ts`: Two occurrences updated
|
||||
- `src/server/routes/account.ts`: Delete account reassignment query
|
||||
- `src/client/hooks/useSetups.ts`: Types and mutation signatures
|
||||
- `src/client/components/SetupCard.tsx`: Visibility badge (public=green, link=blue)
|
||||
- `src/client/components/SetupsView.tsx`: Passes visibility prop
|
||||
- `src/client/routes/setups/$setupId.tsx`: Temporary visibility badge with lock/link/globe icons
|
||||
- `src/db/dev-seed.ts` and `src/db/dev-seed-data.ts`: Seed data updated
|
||||
|
||||
4. **Tests updated** across 4 test files (46 tests pass):
|
||||
- `tests/services/profile.service.test.ts`
|
||||
- `tests/services/discovery.service.test.ts`
|
||||
- `tests/routes/discovery.test.ts`
|
||||
- `tests/routes/profiles.test.ts`
|
||||
- `tests/helpers/db.ts`: Added shares to truncation list
|
||||
|
||||
## Verification
|
||||
|
||||
- `bun run lint`: Passes (0 errors)
|
||||
- All affected tests pass (46/46)
|
||||
- Zero isPublic/is_public references in src/ (except unrelated `isPublicRoute` in __root.tsx)
|
||||
- Zero isPublic references in tests/
|
||||
43
.planning/phases/32-setup-sharing-system/32-02-SUMMARY.md
Normal file
43
.planning/phases/32-setup-sharing-system/32-02-SUMMARY.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# Plan 32-02 Summary: Share Link Backend
|
||||
|
||||
**Status:** Complete
|
||||
**Commit:** da159d1
|
||||
|
||||
## What was done
|
||||
|
||||
1. **Share service** (`src/server/services/share.service.ts`):
|
||||
- `createShareLink`: 128-bit random base64url token, configurable expiration
|
||||
- `getShareLinks`: Lists all shares for a setup (ownership verified)
|
||||
- `revokeShareLink`: Sets revokedAt (ownership verified via join)
|
||||
- `validateShareToken`: Returns setupId/permission, rejects expired/revoked/nonexistent
|
||||
- `deactivateShareLinks`: Bulk revoke all active links for a setup
|
||||
- `reactivateShareLinks`: Clears revokedAt on non-expired shares
|
||||
|
||||
2. **Visibility transition side effects** (`src/server/services/setup.service.ts`):
|
||||
- `updateSetup` now detects visibility transitions and calls deactivate/reactivate
|
||||
- Uses dynamic import to avoid circular dependency
|
||||
|
||||
3. **New function** `getSetupWithItemsById` for share-token-authorized access (no user/visibility check)
|
||||
|
||||
4. **API routes** (added to `src/server/routes/setups.ts`):
|
||||
- `POST /api/setups/:id/shares` — Create share link (auth required)
|
||||
- `GET /api/setups/:id/shares` — List share links (auth required)
|
||||
- `DELETE /api/setups/:id/shares/:shareId` — Revoke share link (auth required)
|
||||
|
||||
5. **Public endpoints** (added to `src/server/index.ts`):
|
||||
- `GET /api/shared/:token` — Access setup via share token (no auth)
|
||||
- `GET /s/:token` — Short URL redirect to `/setups/:id?share=:token`
|
||||
- Auth middleware skip for `/api/shared/` and rate limiting applied
|
||||
|
||||
6. **Share schema** (`src/shared/schemas.ts`):
|
||||
- `createShareLinkSchema` with `expiresInDays: 7 | 14 | 30 | null`
|
||||
|
||||
7. **Tests** (`tests/services/share.service.test.ts`):
|
||||
- 16 tests covering all service functions and visibility transitions
|
||||
- All pass (62/62 across 5 affected test files)
|
||||
|
||||
## Verification
|
||||
|
||||
- `bun run lint`: Passes
|
||||
- All share service tests pass (16/16)
|
||||
- All affected tests pass (62/62 across 5 files)
|
||||
33
.planning/phases/32-setup-sharing-system/32-03-SUMMARY.md
Normal file
33
.planning/phases/32-setup-sharing-system/32-03-SUMMARY.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# Plan 32-03 Summary: Share Modal UI
|
||||
|
||||
**Status:** Complete
|
||||
**Commit:** 7003e99
|
||||
|
||||
## What was done
|
||||
|
||||
1. **Share hooks** (`src/client/hooks/useShares.ts`):
|
||||
- `useShareLinks(setupId)` — Query hook for fetching share links
|
||||
- `useCreateShareLink(setupId)` — Mutation with query invalidation
|
||||
- `useRevokeShareLink(setupId)` — Mutation with query invalidation
|
||||
|
||||
2. **ShareModal component** (`src/client/components/ShareModal.tsx`):
|
||||
- Visibility picker with three options (private/link/public) — immediate API call on change
|
||||
- Color-coded options: gray (private), blue (link), green (public)
|
||||
- Share link creation with expiration dropdown (7/14/30 days, no expiration)
|
||||
- Active links list with copy-to-clipboard and revoke actions
|
||||
- Deactivation warning when links exist and switching to private
|
||||
- Empty state "No share links yet"
|
||||
- Escape key and overlay click to close
|
||||
- Responsive: works on desktop and mobile
|
||||
|
||||
3. **Setup detail page update** (`src/client/routes/setups/$setupId.tsx`):
|
||||
- Replaced static visibility badge with interactive share button
|
||||
- Desktop: "Share" text + visibility icon
|
||||
- Mobile: Icon-only with 44px touch target
|
||||
- ShareModal rendered with visibility change wired to `updateSetup.mutate`
|
||||
|
||||
## Verification
|
||||
|
||||
- `bun run lint`: Passes
|
||||
- ShareModal follows existing modal patterns (overlay, escape key, z-50)
|
||||
- Colors match UI-SPEC: gray-500/gray-50, blue-600/blue-50, green-700/green-50
|
||||
33
.planning/phases/32-setup-sharing-system/32-04-SUMMARY.md
Normal file
33
.planning/phases/32-setup-sharing-system/32-04-SUMMARY.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# Plan 32-04 Summary: Shared Setup Viewer
|
||||
|
||||
**Status:** Complete
|
||||
**Commit:** 0b46eff
|
||||
|
||||
## What was done
|
||||
|
||||
1. **useSharedSetup hook** (`src/client/hooks/useSetups.ts`):
|
||||
- Fetches `/api/shared/:token` with retry disabled (404 = invalid token)
|
||||
- Returns same SetupWithItems type as other setup hooks
|
||||
|
||||
2. **Route search params** (`src/client/routes/setups/$setupId.tsx`):
|
||||
- Added `validateSearch` with Zod schema for `share` query param
|
||||
- Three-way data source: share token > authenticated owner > public viewer
|
||||
|
||||
3. **Shared setup banner**:
|
||||
- Blue banner with link icon: "Shared setup" shown when share token present
|
||||
- Positioned above the sticky header bar
|
||||
|
||||
4. **Error state for invalid tokens**:
|
||||
- Shows "Link not available" with link icon and descriptive text
|
||||
- Renders instead of the normal page when shared fetch errors
|
||||
|
||||
5. **Read-only mode**:
|
||||
- `showOwnerControls` computed from `!isSharedView && isAuthenticated`
|
||||
- Hidden in shared view: Add Items, Share button, Delete Setup, item removal, classification cycling
|
||||
- Item Picker, Share Modal, and Delete Dialog all gated behind `showOwnerControls`
|
||||
|
||||
## Verification
|
||||
|
||||
- `bun run lint`: Our files pass (pre-existing errors in unrelated files only)
|
||||
- Share token detection and three-way data source logic correct
|
||||
- All owner controls properly hidden in shared view
|
||||
Reference in New Issue
Block a user