Commit Graph

389 Commits

Author SHA1 Message Date
b4c38134e1 feat(14-05): create SQLite-to-Postgres data migration script
- One-time migration script with type conversions (unix timestamps to Date, int to bool)
- Migrates all 13 tables in FK dependency order
- Resets serial sequences after data migration
- Adds db:migrate-from-sqlite npm script
2026-04-04 12:28:19 +02:00
f7b830a6ff docs(14-02): complete Docker & Compose for PostgreSQL plan
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 12:25:16 +02:00
186e74bcea feat(14-02): update Dockerfile for PostgreSQL (remove native build deps)
- Remove apt-get install of python3/make/g++ (no longer needed without better-sqlite3)
- Change COPY drizzle to COPY drizzle-pg for PostgreSQL migrations
- Remove mkdir -p data (no SQLite data directory needed)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 12:24:00 +02:00
50b451bf65 feat(14-02): add Docker Compose files for PostgreSQL dev and production
- Create docker-compose.dev.yml with Postgres 16 for local development
- Rewrite docker-compose.yml with Postgres service, healthcheck, and app dependency chain
- Production uses externalized POSTGRES_PASSWORD and DATABASE_URL env vars

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 12:23:35 +02:00
ec8d1c362c Merge branch 'worktree-agent-a730aaff' into Develop
# Conflicts:
#	.planning/ROADMAP.md
#	.planning/STATE.md
2026-04-04 12:22:21 +02:00
d2d64279d3 docs(14-01): complete database foundation plan
- Created 14-01-SUMMARY.md with execution results
- Updated STATE.md with plan progress and decisions
- Updated ROADMAP.md progress table (1/6 plans)
- Marked DB-01 and DB-03 requirements complete
2026-04-04 12:21:50 +02:00
3bf1fd7cb8 feat(14-01): add PGlite test helper and generate initial PostgreSQL migration
- Rewrite tests/helpers/db.ts to use drizzle-orm/pglite with async createTestDb()
- Generate initial migration with 13 CREATE TABLE statements in drizzle-pg/
- Add drizzle-pg to biome ignore list (generated files)
- PGlite smoke test confirms migrations apply and seed works
2026-04-04 12:18:50 +02:00
3724cf8348 feat(14-01): rewrite database foundation from SQLite to PostgreSQL
- Replace all 13 sqliteTable definitions with pgTable (pg-core)
- Convert integer timestamps to native timestamp type with defaultNow()
- Convert real columns to doublePrecision, integer used to boolean
- Rewrite db connection to use postgres.js driver with DATABASE_URL
- Rewrite migrate.ts to use postgres-js migrator targeting drizzle-pg/
- Convert seed.ts to async
- Update drizzle.config.ts to postgresql dialect
- Install postgres and @electric-sql/pglite, remove better-sqlite3
2026-04-04 12:17:05 +02:00
f7048a267a docs: bring phase 14 planning files into worktree 2026-04-04 12:15:37 +02:00
1cd2af6a0f docs(state): record phase 14 planning session 2026-04-04 12:12:46 +02:00
30ec9b92d1 fix(14): revise plans based on checker feedback 2026-04-04 12:09:49 +02:00
88708f962a docs(14-postgresql-migration): create phase plan 2026-04-04 12:00:22 +02:00
ebc1693eb1 docs(phase-14): add validation strategy 2026-04-04 11:52:00 +02:00
fc49e63bee docs(14): research phase domain 2026-04-04 11:51:16 +02:00
6d966303c3 docs(state): record phase 14 context session 2026-04-04 11:42:10 +02:00
552817efec docs(14): capture phase context 2026-04-04 11:42:01 +02:00
f7c9f3dc94 fix: add Protected Resource Metadata endpoint (RFC 9728)
All checks were successful
CI / ci (push) Successful in 29s
CI / e2e (push) Successful in 1m1s
The MCP auth spec (2025-06-18+) requires /.well-known/oauth-protected-resource
in addition to /.well-known/oauth-authorization-server. Claude fetches
the protected resource metadata first after receiving a 401, then discovers
the authorization server from it. Also fixes WWW-Authenticate header to
use absolute URL pointing to the protected resource endpoint.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
v1.4.3
2026-04-04 11:17:21 +02:00
b71833ef79 fix: await verifyAccessToken in MCP middleware
All checks were successful
CI / ci (push) Successful in 31s
CI / e2e (push) Successful in 1m4s
verifyAccessToken is async and returns a Promise. Without await,
the Promise object is always truthy, so any Bearer token (even
invalid ones) was accepted. This fixes MCP OAuth authentication.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
v1.4.2
2026-04-04 11:03:30 +02:00
9c7bc2881c fix: add CORS headers for OAuth and MCP endpoints
All checks were successful
CI / ci (push) Successful in 31s
CI / e2e (push) Successful in 1m2s
Required for claude.ai browser-based OAuth flows that make
cross-origin requests to discovery, token, and MCP endpoints.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
v1.4.1
2026-04-04 10:48:22 +02:00
412ca60e42 style: apply biome formatting to OAuth service and tests
All checks were successful
CI / ci (push) Successful in 37s
CI / e2e (push) Successful in 1m55s
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
v1.4.0
2026-04-04 09:27:57 +02:00
5fdf4c3019 docs: add MCP OAuth documentation and fix lint
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 09:27:34 +02:00
6dcb421fb0 test: add end-to-end OAuth to MCP flow integration test
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04 09:26:25 +02:00
f01add3943 feat: add Bearer token auth to MCP alongside API key auth
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04 09:24:10 +02:00
1fad25726d feat: add OAuth 2.1 endpoints (register, authorize, token)
Add well-known metadata, dynamic client registration, authorization
flow with PKCE, and token exchange/refresh endpoints with route-level
integration tests.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 09:22:58 +02:00
7309c080df feat: add OAuth service with PKCE, token management, and tests
Implements client registration, authorization code flow with PKCE (S256),
access/refresh token generation/verification, and cleanup utilities.
Follows TDD — all 12 service-level tests pass.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04 09:20:09 +02:00
f47e1d74ae feat: add OAuth tables (clients, codes, tokens) to schema
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04 09:17:53 +02:00
c04b9b0e09 docs: add MCP OAuth 2.1 implementation plan
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 09:09:30 +02:00
6a77995530 docs: add MCP OAuth 2.1 server design spec
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 09:03:11 +02:00
1344f2f87f docs: create milestone v2.0 roadmap (5 phases) 2026-04-03 22:24:24 +02:00
64403f6977 docs: define milestone v2.0 requirements 2026-04-03 22:19:52 +02:00
443802fc68 docs: complete project research 2026-04-03 22:14:27 +02:00
642ae0d43f docs: start milestone v2.0 Platform Foundation 2026-04-03 21:53:31 +02:00
f9c6693b63 docs: add releasing section to CLAUDE.md
All checks were successful
CI / ci (push) Successful in 27s
CI / e2e (push) Successful in 1m5s
Document the Gitea Actions release pipeline and how to trigger it
via API with patch/minor/major bump types.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 21:11:53 +02:00
bb60168ffb Merge pull request 'feat: user menu dropdown + fix MCP tool schemas' (#10) from feature/user-menu-dropdown into Develop
All checks were successful
CI / ci (push) Successful in 25s
CI / e2e (push) Successful in 1m2s
v1.3.2
2026-04-03 18:59:59 +00:00
68f6647f76 fix: convert MCP tool schemas from JSON Schema to Zod for SDK v1.29.0
All checks were successful
CI / ci (push) Successful in 28s
CI / ci (pull_request) Successful in 25s
CI / e2e (push) Successful in 1m2s
CI / e2e (pull_request) Successful in 1m3s
The MCP SDK v1.29.0 changed server.tool() to require Zod schemas
(raw shapes) instead of plain JSON Schema objects. The old format
triggered "expected a Zod schema or ToolAnnotations" errors.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 20:54:20 +02:00
0a40d7627f feat: add user menu dropdown with settings link and sign out
Replace the plain "Sign out" button in the header with a user icon
that opens a dropdown menu containing Settings and Sign out options.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 20:19:53 +02:00
3eccbb12fd Merge pull request 'v1.4 Collection Tools' (#9) from feature/v1.4-collection-tools into Develop
All checks were successful
CI / ci (push) Successful in 24s
CI / e2e (push) Successful in 1m0s
2026-04-03 18:05:23 +00:00
fb925a9dce fix: include quantity in getAllItems select, createItem values, and updateItem type
All checks were successful
CI / ci (push) Successful in 24s
CI / ci (pull_request) Successful in 25s
CI / e2e (push) Successful in 1m3s
CI / e2e (pull_request) Successful in 1m1s
Quantity was missing from three places in item.service.ts:
- getAllItems didn't select it (API returned undefined)
- createItem didn't pass it to insert (always used DB default of 1)
- updateItem type didn't include it (silently stripped from updates)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 19:57:25 +02:00
70e7cd2f0f fix: show Add Candidate button in comparison view
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 18:51:49 +02:00
33f735af67 fix: remove scale/shadow whileDrag effect that stuck after release
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 18:50:49 +02:00
f8a1a00e0a fix: prevent snap-back after drag and click-opens-edit during drag
Two fixes:
- Remove onSettled clearing tempItems before refetch completes,
  let useEffect clear it when fresh server data arrives
- Track isDragging ref to suppress edit panel click after drag
- Remove layout="position" which interfered with reorder detection

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 18:49:39 +02:00
27c36b6b9a fix: make entire candidate row draggable instead of handle-only
Remove dragControls/dragListener pattern which prevented onReorder
from firing. The whole row is now the drag target with visual feedback
(scale + shadow). Grip icon remains as a visual indicator.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 18:46:52 +02:00
684cfd3789 fix: stabilize drag-to-reorder with layout animation fixes
- Remove transition-all from list items (fights framer-motion layout)
- Add layout="position" to Reorder.Item for proper sibling tracking
- Replace CSS gap with marginBottom (gap confuses layout engine)
- Add explicit short transition duration for snappy reorder

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 18:44:39 +02:00
52751ae9d4 fix: use onDragEnd on Reorder.Item instead of onPointerUp on Group
The previous approach used onPointerUp on the Reorder.Group which
fired unreliably — triggering on non-drag clicks and sometimes not
at all after a drag. Moving to onDragEnd on each Reorder.Item gives
clean, predictable drag-to-reorder behavior.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 18:42:16 +02:00
3fc737c872 fix: add tab navigation to collection page and skip 404 retries
Adds Gear/Planning/Setups pill tabs to the collection page so users
can switch tabs without going back to the dashboard. Also skips
React Query retries on 404 responses for immediate error display.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 18:31:57 +02:00
b993a0a831 fix: skip retries on 404 for single-resource queries
Prevents 10-second loading skeleton when navigating to non-existent
threads, setups, or items. Shows error/not-found state immediately.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 18:28:04 +02:00
a8696c2a85 fix: commit missing migration metadata and run CI on all branches
All checks were successful
CI / ci (push) Successful in 25s
CI / ci (pull_request) Successful in 26s
CI / e2e (push) Successful in 1m24s
CI / e2e (pull_request) Successful in 1m23s
The Drizzle migration journal and snapshot for 0008 (quantity column)
were not committed, causing test failures in CI. Also updates CI to
trigger on all branches, not just Develop.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 18:18:12 +02:00
15f146ee89 feat: add CSV import/export for gear collection
Some checks failed
CI / ci (pull_request) Failing after 22s
CI / e2e (pull_request) Has been skipped
Adds export (GET /api/items/export) and import (POST /api/items/import) routes
backed by a pure csv.service with no external deps, plus useExportItems/useImportItems
hooks and an Import/Export section in the Settings page.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 18:12:07 +02:00
8c1fe47a99 feat: add setup impact preview UI with delta badges across all views
Adds SetupImpactSelector dropdown and ImpactDeltaBadge inline badge, wired into the thread detail page. Delta badges appear on CandidateListItem, CandidateCard, and ComparisonTable (Weight Impact / Price Impact rows) whenever a setup is selected for comparison.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 18:11:57 +02:00
b9a06dd244 feat: add item duplication with copy-and-edit workflow
Adds POST /api/items/:id/duplicate endpoint, useDuplicateItem hook, and a
Duplicate button on ItemCard (collection view only) that opens the new item
for editing immediately after creation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 18:07:20 +02:00