Commit Graph

51 Commits

Author SHA1 Message Date
8d7a668da4 fix: resolve lint errors from phase 32/33/34 execution
All checks were successful
CI / ci (push) Successful in 1m23s
CI / e2e (push) Has been skipped
CI / deploy (push) Successful in 1m20s
Auto-fixed formatting issues and removed unused imports introduced
by background execution agents across currency, i18n, and sharing code.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 18:32:32 +02:00
50bc11c7ed feat(33-01): add currency conversion service with exchange rate caching
- Create currency.service.ts with frankfurter.app ECB rate fetching
- 24h in-memory cache with stale-serve fallback on fetch failure
- convertPrice() handles EUR-base cross-currency conversion
- CURRENCY_MARKET_MAP maps currencies to market regions
- 12 unit tests covering conversion, rounding, unknowns, and mapping

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 18:02:06 +02:00
da159d10b8 feat: add share link service, API routes, and short URL redirect
Create share.service.ts with token generation (128-bit base64url),
CRUD operations, validation, and visibility transition side effects.
Add share endpoints under /api/setups/:id/shares, shared access at
/api/shared/:token, and /s/:token short URL redirect.

Plan: 32-02 (Setup Sharing System - Share Link Backend)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 17:59:39 +02:00
edc9793c2d feat: migrate setup visibility from boolean to three-tier system
Replace isPublic boolean with visibility enum (private/link/public) across
the full stack. Add shares table to schema for future share link support.
Update all services, routes, schemas, hooks, components, and tests.

Plan: 32-01 (Setup Sharing System - Schema Migration)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 17:55:46 +02:00
e8207a33f9 feat(28-01): add account management routes for password, email, and deletion
Creates /api/account routes with password change (verifies current first),
email update, has-password check, and account deletion with public setup
anonymization. Adds Zod validation schemas and registers routes in index.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 17:47:17 +02:00
fcd8279d79 feat(28-01): create Logto Management API client service with M2M auth
Implements LogtoManagementClient with token caching, password verification,
password update, email update, user deletion, and has-password check.
All methods proxy to Logto Management API via M2M credentials.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 17:45:48 +02:00
6e3ce4a31f fix: resolve biome lint errors in discovery files
All checks were successful
CI / ci (push) Successful in 1m8s
CI / e2e (push) Has been skipped
CI / deploy (push) Successful in 14s
Remove unused functions and imports from route tests, fix array index key
warnings in skeleton components, apply biome formatting.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 15:15:58 +02:00
06b6e935f2 test(26-01): add failing tests for discovery service
- getPopularSetups: ordering, privacy filter, cursor pagination, creatorName
- getRecentGlobalItems: ordering, cursor pagination, second page deduplication
- getTrendingCategories: ordering by count desc, null category exclusion, empty state
2026-04-10 14:53:09 +02:00
c8ebbf8139 feat(25-01): Zod schemas, upsert service functions, passing tests
- 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
2026-04-10 10:58:36 +02:00
9093a2c8f6 test(25-01): add failing tests for upsertGlobalItem and bulkUpsertGlobalItems
- Import upsertGlobalItem and bulkUpsertGlobalItems (not yet exported)
- Tests cover: create, conflict update, attribution fields, tag sync
- Tests cover: empty tags clear, tags omitted leaves untouched
- Tests cover: bulk upsert counts (created vs updated)
2026-04-10 10:56:54 +02:00
be1197f3da fix: lint formatting in storage test
Some checks failed
CI / ci (push) Successful in 1m7s
CI / e2e (push) Has been skipped
CI / deploy (push) Failing after 11s
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 15:31:39 +02:00
d519a83cc4 infra: migrate deployment to Coolify with Garage S3
Some checks failed
CI / ci (push) Failing after 19s
CI / deploy (push) Has been skipped
CI / e2e (push) Has been skipped
- Remove docker-compose files (Coolify manages services individually)
- Replace MinIO with Garage (S3-compatible, actively maintained)
- Add CI deploy job: build+push :develop image on every green Develop push
- Add Coolify webhook trigger for automatic redeployment
- Update README, .env.example, and storage references
- Rename migrate script to provider-agnostic name

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 15:28:43 +02:00
27c139de9a fix: update OAuth service tests for userId-from-record refactor
Some checks failed
CI / ci (push) Failing after 58s
CI / e2e (push) Has been skipped
- Add userId param to createAuthorizationCode calls
- Remove userId param from exchangeCode and refreshAccessToken calls
  (now derived from stored records)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 20:30:30 +02:00
3638e7b240 fix: resolve all lint errors across source and test files
Some checks failed
CI / ci (push) Failing after 11s
CI / e2e (push) Has been skipped
- Fix unused function parameters (prefix with _)
- Fix unused imports in test files
- Fix import ordering in test files
- Auto-fix formatting issues across 22 files

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 19:39:47 +02:00
62249b5b48 Merge branch 'worktree-agent-adbc35a5' into Develop
# Conflicts:
#	.planning/STATE.md
#	drizzle-pg/meta/0002_snapshot.json
#	drizzle-pg/meta/_journal.json
#	src/db/schema.ts
2026-04-06 08:00:04 +02:00
67facea338 feat(20-01): extend UIStore with FAB/catalog state, add useTags hook, update useGlobalItems
- Add fabMenuOpen, openFabMenu, closeFabMenu to UIStore
- Add catalogSearchOpen, catalogSearchMode, openCatalogSearch, closeCatalogSearch
- openCatalogSearch also closes FAB menu (natural flow)
- Create useTags hook with 5-min staleTime cache
- Add optional tags parameter to useGlobalItems for tag filtering
2026-04-06 07:57:47 +02:00
6f07e874f9 test(20-01): add failing tests for tag service and route
- Tag service tests: empty array, alphabetical ordering, id+name projection
- Tag route tests: GET /api/tags returns 200, correct tag objects
2026-04-06 07:56:32 +02:00
ecc6ac689a feat(19-03): add tag filtering to global item search and migrate owner count
- searchGlobalItems now accepts tagNames param with AND intersection logic
- Owner count uses items.globalItemId instead of removed itemGlobalLinks
- Removed linkItemToGlobal and unlinkItemFromGlobal functions
- Route handlers now async with tags query param support
- Rewrote tests to async PGlite pattern, added tag filtering tests

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 20:55:36 +02:00
8a5ee731d0 feat(19-02): add catalog-linked candidates, branched resolution, remove link/unlink routes
- getThreadWithCandidates LEFT JOINs globalItems with COALESCE for name, weight, price, image
- createCandidate accepts and stores globalItemId
- resolveThread branches: reference item (globalItemId set) vs standalone (full data copy)
- Removed link/unlink endpoints from items route (replaced by direct globalItemId FK)
- 6 new tests for catalog-linked candidates and branched resolution
2026-04-05 20:49:56 +02:00
d1ffd79bbb feat(19-02): add COALESCE merge for reference items in item service
- getAllItems and getItemById LEFT JOIN globalItems with COALESCE for name, weight, price, image
- createItem accepts globalItemId and purchasePriceCents, stores brand+model as fallback name
- duplicateItem preserves globalItemId and purchasePriceCents
- updateItem type includes globalItemId and purchasePriceCents
- 10 new tests for reference item creation and merged data retrieval
2026-04-05 20:34:54 +02:00
574a12e6fa fix: OIDC auth flow, Vite proxy, and PostgreSQL query compat
- Add auth redirect in root layout for unauthenticated users
- Proxy OIDC routes (/login, /callback, /logout) through Vite dev server
- Strip Secure flag from OIDC cookies in dev mode (HTTP localhost)
- Disable retry on auth query to prevent stale cookie loops
- Fix SQLite .get()/.all()/.run() calls in category and global-item
  services for PostgreSQL compatibility
- Add userId scoping to category service functions
- Add OIDC error logging in auth middleware
- Apply linter auto-formatting across affected files

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 18:25:31 +02:00
2843351d90 Merge branch 'worktree-agent-a86c0a6d' into Develop
# Conflicts:
#	.planning/REQUIREMENTS.md
#	.planning/STATE.md
#	src/db/schema.ts
#	src/db/seed.ts
#	src/server/index.ts
#	src/server/routes/setups.ts
#	src/server/services/category.service.ts
#	src/server/services/setup.service.ts
#	src/shared/schemas.ts
#	src/shared/types.ts
2026-04-05 13:13:34 +02:00
465297c398 Merge branch 'worktree-agent-a7e6e4b2' into Develop
# Conflicts:
#	.planning/REQUIREMENTS.md
#	.planning/ROADMAP.md
#	.planning/STATE.md
#	drizzle/meta/_journal.json
#	src/db/schema.ts
#	src/db/seed.ts
#	src/shared/schemas.ts
#	src/shared/types.ts
2026-04-05 13:13:26 +02:00
3a6876f7e8 test(18-02): add failing tests for global item service and seed
- 10 test cases covering search, owner count, link/unlink, seed idempotency
- Added globalItems/itemGlobalLinks tables to SQLite schema
- Added Zod schemas and types for global items
- Created 18-item bikepacking gear seed data JSON
2026-04-05 13:05:28 +02:00
2d5d4f9c1a test(18-03): add failing tests for profile service and setup isPublic
- Profile CRUD tests: updateProfile, getPublicProfile, getPublicSetupWithItems
- Setup service isPublic tests: create with isPublic, toggle, list includes isPublic
2026-04-05 13:05:02 +02:00
5ce3f92a78 feat(17-02): refactor image service and routes to use S3 storage service
- Replace Bun.write/mkdir with uploadImage() from storage.service
- Remove uploadsDir parameter from fetchImageFromUrl
- Update tests to mock storage service instead of checking filesystem
2026-04-05 12:20:31 +02:00
544dd5bcd9 Merge branch 'worktree-agent-a402d11d' into Develop
# Conflicts:
#	.env.example
#	.planning/STATE.md
#	bun.lock
#	docker-compose.dev.yml
#	docker-compose.yml
#	package.json
2026-04-05 12:17:35 +02:00
f845f878fe feat(17-01): add S3 storage service with upload, delete, and presigned URL support
- Create storage.service.ts wrapping @aws-sdk/client-s3 with forcePathStyle for MinIO
- Export uploadImage, deleteImage, getImageUrl, withImageUrl, withImageUrls
- Add unit tests with mocked S3Client (8 tests passing)
- Install @aws-sdk/client-s3 and @aws-sdk/s3-request-presigner
2026-04-05 12:15:09 +02:00
5b702a0e98 feat(16-04): update all service tests to pass userId and add isolation tests
- Destructure { db, userId } from createTestDb() in all 8 service test files
- Pass userId to every service function call
- Add cross-user isolation tests for items, categories, threads, setups
- Add composite unique constraint test for categories
- Update verifyApiKey assertions to check { userId } return
- Update verifyAccessToken assertions to check { userId } return
- Pass userId to exchangeCode and refreshAccessToken calls
2026-04-05 11:01:51 +02:00
59e7f4be8a fix(15): convert auth service/tests to async PGlite pattern
The executor agents wrote sync SQLite-style calls (.get(), .all(), .run())
instead of the async Postgres pattern established in Phase 14. Fixed:
- auth.service.ts: use await + destructuring for all DB operations
- auth routes: await listApiKeys
- All auth test files: async createTestDb(), await service calls

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 21:40:12 +02:00
72eefd1a06 Merge branch 'worktree-agent-a7f7c229' into Develop
# Conflicts:
#	.planning/REQUIREMENTS.md
#	.planning/ROADMAP.md
#	.planning/STATE.md
#	tests/routes/auth.test.ts
#	tests/services/auth.service.test.ts
2026-04-04 20:56:29 +02:00
689a56b2b7 feat(15-03): update E2E seed and auth tests for OIDC architecture
- E2E seed creates API key instead of user for authentication
- Auth service tests cover only API key CRUD (removed user/session tests)
- Auth middleware tests validate three-way auth: API key, Bearer token, OIDC session
- Auth route tests mock getAuth for OIDC session, test /me and /keys endpoints
- Remove all references to createUser, verifyPassword, createSession in auth tests
2026-04-04 20:54:18 +02:00
458b33f1c7 feat(14-06): convert all 9 service test files to async PGlite
- All beforeEach now use async/await createTestDb()
- All service calls in tests now awaited
- All direct DB calls (.run()/.all()) replaced with await
- All test callbacks made async
- Fixed PostgreSQL GROUP BY strictness in totals.service.ts (categories.name and categories.icon added to groupBy)
- db type changed to 'any' to accommodate PGlite type differences

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 13:11:52 +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>
2026-04-04 09:27:57 +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
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
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
be168c8329 fix: replace network-dependent image tests with local HTTP server
Some checks failed
CI / ci (push) Failing after 25s
Use Bun.serve to create a local test server instead of hitting
external URLs. Fixes flaky test in CI environments without
network access.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 14:07:16 +02:00
9191f0fe24 fix: resolve all lint errors — exclude generated dirs, auto-fix source
Some checks failed
CI / ci (push) Failing after 20s
Exclude drizzle/ and .planning/ from Biome (generated files with
incompatible formatting). Auto-fix import ordering and formatting
in existing source files.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 14:05:10 +02:00
7c4fa9d9d2 feat: add auth service with user, session, and API key management
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 13:20:27 +02:00
0004329895 feat: add image URL fetching service with tests
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 13:15:56 +02:00
f01d71d6b4 feat(11-01): schema, service, and tests for sort_order + reorderCandidates
- Add sortOrder REAL column to threadCandidates schema (default 0)
- Add sort_order column to test helper CREATE TABLE
- Add reorderCandidatesSchema to shared/schemas.ts
- Add ReorderCandidates type to shared/types.ts
- getThreadWithCandidates now orders candidates by sort_order ASC
- createCandidate appends at max sort_order + 1000 (first = 1000)
- Add reorderCandidates service function (transaction, active-only guard)
- Add 5 new tests: ordering, appending, reorder success, resolved guard, missing thread
2026-03-16 22:21:42 +01:00
719f7082da test(10-01): add failing tests for pros/cons on thread candidates
- createCandidate stores and returns pros/cons fields
- createCandidate returns null when pros/cons not provided
- updateCandidate can set and clear pros/cons
- getThreadWithCandidates includes pros/cons on each candidate
2026-03-16 21:31:39 +01:00
4491e4c6f1 feat(09-01): add classification column to setupItems with service layer and tests
- Add classification text column (default 'base') to setupItems schema
- Add classificationSchema and updateClassificationSchema Zod validators
- Add UpdateClassification type inferred from Zod schema
- Implement updateItemClassification service function
- Modify getSetupWithItems to return classification field
- Modify syncSetupItems to preserve classifications across re-sync
- Add tests for classification CRUD, preservation, and cross-setup independence
- Generate and apply Drizzle migration

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 15:11:18 +01:00
9342085dd1 test(08-01): add failing tests for candidate status field
- 5 tests: create with/without status, update status, getThreadWithCandidates includes status
- Test helper updated with status column in thread_candidates CREATE TABLE

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 14:07:51 +01:00
b496462df5 chore: auto-fix Biome formatting and configure lint rules
All checks were successful
CI / ci (push) Successful in 15s
Run biome check --write --unsafe to fix tabs, import ordering, and
non-null assertions across entire codebase. Disable a11y rules not
applicable to this single-user app. Exclude auto-generated routeTree.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 19:51:34 +01:00
546dff151b feat(06-01): migrate categories from emoji to Lucide icon field
- Rename emoji column to icon in schema, Zod schemas, and all services
- Add Drizzle migration with emoji-to-icon data conversion
- Update test helper, seed, and all test files for icon field
- All 87 tests pass with new icon-based schema

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 17:48:23 +01:00
ed8508110f feat(04-01): update thread service, routes, and hooks for categoryId
- createThread now inserts categoryId from data
- getAllThreads joins categories table, returns categoryName/categoryEmoji
- updateThread accepts optional categoryId
- ThreadListItem interface includes category fields
- useCreateThread hook sends categoryId
- Fix test files to pass categoryId when creating threads

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 16:31:48 +01:00
1e4e74f8d2 test(03-01): add failing tests for setup backend
- Add setups and setupItems tables to DB schema
- Add Zod schemas for setup create/update/sync
- Add Setup/SetupItem types to shared types
- Add setup tables to test helper
- Write service and route tests (RED - no implementation yet)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 12:42:15 +01:00
e146eeab80 test(02-01): add failing tests for thread service
- Add threads and threadCandidates tables to Drizzle schema
- Add Zod schemas for thread/candidate/resolve validation
- Add Thread/ThreadCandidate types to shared types
- Update test helper with threads and thread_candidates tables
- Write comprehensive failing tests for thread service

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 11:36:01 +01:00