- Add upsertGlobalItemSchema and bulkUpsertGlobalItemsSchema to schemas.ts
- Add UpsertGlobalItemInput and BulkUpsertGlobalItemsInput types to types.ts
- Implement upsertGlobalItem with onConflictDoUpdate and tag sync
- Implement bulkUpsertGlobalItems processing array in single transaction
- Fix migration 0003 to only add new columns + unique constraint
- All 21 tests pass including 8 new upsert operation tests
Public setup view was missing image URL enrichment, causing item images
to be absent for anonymous visitors. Matches the private endpoint pattern.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove authLoading spinner gate — app renders immediately for all visitors
- Expand isPublicRoute to include /, /global-items/*, /setups/*, /users/, /login
- Replace hard window.location.href redirect with soft navigate() after auth resolves
- Remove onboarding loading spinner — pass isAuthenticated as enabled to guard query
- Add AuthPromptModal to root JSX for global availability
- Guard Add to Collection and Add to Thread buttons with isAuthenticated check
- Rework setup detail page to use usePublicSetup for anonymous visitors
- Wrap all write action UI (Add Items, Delete, Public toggle, remove/classify) in isAuthenticated guards
- Add 24-01-SUMMARY.md with execution results
- Advance plan counter to 2/2
- Update progress to 50% (1 of 2 plans complete)
- Mark INFR-01 requirement complete
- Add factory pattern and tier decisions to STATE.md
- Import createRateLimit in server index
- Create browseTier (120 req/min) for list/search endpoints
- Create detailTier (60 req/min) for individual resource endpoints
- Apply browseTier to /api/global-items and /api/tags GET routes
- Apply detailTier to /api/global-items/:id, /api/setups/:id/public, /api/users/:id/profile GET routes
- Rate limits placed before auth middleware per D-07, D-08
- Extend uiStore with showAuthPrompt/openAuthPrompt/closeAuthPrompt state
- Create AuthPromptModal component with sign in/sign up CTAs pointing to /login
- Add usePublicSetup hook to useSetups for anonymous setup viewing via public API
- Rework useOnboardingComplete to accept enabled param (guards auth-gated call)
- Add createRateLimit(maxAttempts, windowMs) factory function
- Rewrite rateLimit export to delegate to factory (backward compatible)
- Keep shared store, getClientIp, cleanup, and _resetForTesting unchanged
- Add createRateLimit factory test suite with 5 test cases
- All existing rateLimit middleware tests still pass
activeThreads[0].id in useEffect dependency array threw when the array
was empty. Use optional chaining to safely handle the empty case.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The | in Laravel Sanctum tokens gets interpreted as a shell pipe when
injected inline. Using env vars ensures proper quoting.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move hardcoded values to repo variables:
- COOLIFY_URL: Coolify instance base URL
- COOLIFY_APP_UUID: application UUID to deploy
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace simple webhook GET with authenticated POST to Coolify deploy API.
Requires COOLIFY_TOKEN secret in Gitea with deploy permissions.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Gitea's built-in webhook wasn't triggering Coolify deploys reliably.
Restore the explicit curl call to COOLIFY_WEBHOOK after image push.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The /me endpoint was returning auth.sub (Logto's opaque string) as the
user ID, but the frontend and other API endpoints expect numeric DB IDs.
This caused "can't access property 'id', w[0] is undefined" after login.
Also documents Logto OIDC setup requirements (scopes, env vars) in
CLAUDE.md.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The @hono/oidc-auth middleware catches all errors and rethrows as
"Invalid session", hiding the real cause. This adds a startup probe
to OIDC discovery endpoint so the actual error appears in logs.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Deployment trigger is now handled by Gitea webhooks. The Docker
build+push step stays so the image is available in the registry.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Deployment is now handled by Gitea webhooks triggering Coolify
directly, replacing the manual Docker build + webhook approach.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add generated knowledge graph (538 nodes, 664 edges) for codebase
navigation. Outputs are committed for portability across devices;
cache and cost tracking are gitignored.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>