- Added `POST /api/equipments` endpoint to create equipment from an existing asset.
- Created `UploadEquipmentDialog` component with drag-and-drop and clipboard paste support.
- Added "Upload" button to the Equipments page header.
- Verified new equipment creation flow via frontend verification script.
- Update prisma/schema.prisma to use @default(ulid()) for all relevant models
- Remove manual ulid() calls from all service files
- Update list APIs to order by id descending
- Update AssetService tests to match new behavior
- Update AGENTS.md with new conventions
- Remove empty migration file (20260217022222_add_ulid_default)
* I added `DialogFooter` to `ExtractorDialog`.
* I moved the action buttons (Start, Cancel, and the finish button) from `AnalyzeStage`, `SelectionStage`, and `RefineStage` to the `ExtractorDialog` footer.
* I lifted the `selectedIndices` state from `SelectionStage` to `ExtractorDialog`.
* I updated `AnalyzeStage` to show the status in the primary action button.
* I enabled cancellation during analysis.
* I ensured that `onSuccess` is called only when the user clicks the finish button in the Refine stage.
- Refactor `ExtractorDialog.tsx` into modular stages: `UploadStage`, `AnalyzeStage`, `SelectionStage`, `RefineStage`.
- Implement new UI flow: Upload -> Analyze -> Select -> Refine.
- Adapt "vibe" reference visuals to application's Light Mode theme (Slate/Cyan/Amber).
- Implement real-time status updates for analysis and refinement steps using backend streams.
- Add drag-and-drop and paste support for image upload.
- Visualize candidate selection grid and refinement progress.
- Implement manual confirmation for analysis start.
- Increase dialog size to `max-w-[98vw]` and `h-[95vh]`.
- Simplify title bar and adjust candidate grid cell size to 140px.
Updates the test expectations in `src/service/extraction.test.ts` to match the actual prompt content used in `src/service/extraction.ts`. The previous test was asserting the presence of specific instructions regarding cropping artifacts that are no longer present in the codebase. The updated test now verifies the presence of the task name and the instruction to return only the image.
- Restored the centered logo `<div>` block at the top as requested.
- Replaced generic intro with "Why Forgery?", "Highlights", and "Core Concepts" sections derived from marketing copy.
- Corrected tech stack information (Bun, Hono, React, SQLite) to match the codebase.
- Replaced incorrect `curl` demos with a UI-focused "How It Works" workflow.
- Updated installation instructions to use `bun` commands.
- Added "Architecture Overview" to explain the modular pipeline.
- Replaced generic intro with "Why Forgery?", "Highlights", and "Core Concepts" sections derived from marketing copy.
- Corrected tech stack information (Bun, Hono, React, SQLite) to match the codebase.
- Replaced incorrect `curl` demos with a UI-focused "How It Works" workflow.
- Updated installation instructions to use `bun` commands.
- Added "Architecture Overview" to explain the modular pipeline.
- Add semi-transparent dark background to delete button for better visibility on light images.
- Remove equipment labels from generation cards in Fitting Room.
- Implement `ExampleDataService` to export/import Characters, Equipments, Poses, Expressions, and Generations.
- Add `generate-example` script to `package.json` to generate example data from current DB.
- Add startup logic in `src/index.ts` to seed example data if system is uninitialized and no data exists.
- Store system initialization state in `Setting` table.
- Add comprehensive tests for `ExampleDataService` in `src/service/example-data.test.ts` mocking `Bun` file API and `node:fs`.
- Refactor `src/service/example-data.ts` to use `Bun.file` and `Bun.write` for file I/O, ensuring better compatibility with Bun's test runner.
- Implement `ExampleDataService` to export/import Characters, Equipments, Poses, Expressions, and Generations.
- Add `generate-example` script to `package.json` to generate example data from current DB.
- Add startup logic in `src/index.ts` to seed example data if system is uninitialized and no data exists.
- Store system initialization state in `Setting` table.
- Add comprehensive tests for `ExampleDataService` in `src/service/example-data.test.ts` mocking filesystem and database operations.
- Refactor `src/service/example-data.ts` to use default `node:fs` import for better test compatibility.
- Implement `ExampleDataService` to export/import Characters, Equipments, Poses, Expressions, and Generations.
- Add `generate-example` script to `package.json` to generate example data from current DB.
- Add startup logic in `src/index.ts` to seed example data if system is uninitialized and no data exists.
- Store system initialization state in `Setting` table.
- Add comprehensive tests for `ExampleDataService` in `src/service/example-data.test.ts` mocking filesystem and database operations.
- Implement `ExampleDataService` to export/import Characters, Equipments, Poses, Expressions, and Generations.
- Add `generate-example` script to `package.json` to generate example data from current DB.
- Add startup logic in `src/index.ts` to seed example data if system is uninitialized and no data exists.
- Store system initialization state in `Setting` table.
- Add comprehensive tests for `ExampleDataService` in `src/service/example-data.test.ts` mocking filesystem and database operations.
- Implement `ExampleDataService` to export/import Characters, Equipments, Poses, Expressions, and Generations.
- Add `generate-example` script to `package.json` to generate example data from current DB.
- Add startup logic in `src/index.ts` to seed example data if system is uninitialized and no data exists.
- Store system initialization state in `Setting` table.
- Add comprehensive tests for `ExampleDataService` in `src/service/example-data.test.ts` mocking filesystem and database operations.
- Add `DELETE /api/equipments/:id` endpoint.
- Add `deleteEquipment` method to `EquipmentService` which also cleans up associated assets and generation references.
- Implement delete action in `Equipments` page UI.
- Pass `actions` prop to `VibeCard` to enable context menu.
Split the equipment extraction process into two phases:
1. Analyze & Split: Generates texture sheet and crops assets.
2. Refine & Save: Allows user to select which assets to keep before refining and saving.
- Refactored `src/api/extract.ts` to expose `/analyze` and `/refine` endpoints.
- Updated `src/ui/components/ExtractorDialog.tsx` to handle the multi-step flow and selection UI.
- Added `CandidateAsset` type and updated `ExtractionStatus` in `src/ui/types.ts`.
- Added `deleteFile` to `FileService` and `deleteAsset` to `AssetService` to support file deletion.
- Implemented cascading deletion in `CharacterService` (delete looks -> delete character image -> delete character).
- Updated `GenerationService`, `PoseService`, and `ExpressionService` to delete associated image assets upon deletion.
- Added `DELETE /api/generations/:id` endpoint.
- Created `DropdownMenu` and `DeleteConfirmDialog` UI components.
- Updated `VibeCard` to include an internal `DropdownMenu` driven by a new `actions` prop.
- Updated `Characters`, `Poses`, and `Expressions` pages to use the new `VibeCard` `actions` prop for deletion.
- Updated `FittingRoom` page to use the `DropdownMenu` and `DeleteConfirmDialog` for deleting looks.
- Updated `CreateLookDialog` to enforce single selection for equipment categories.
- Added necessary tests adjustments.
- Added `deleteFile` to `FileService` and `deleteAsset` to `AssetService` to support file deletion.
- Implemented cascading deletion in `CharacterService` (delete looks -> delete character image -> delete character).
- Updated `GenerationService`, `PoseService`, and `ExpressionService` to delete associated image assets upon deletion.
- Added `DELETE /api/generations/:id` endpoint.
- Created `DropdownMenu` and `DeleteConfirmDialog` UI components.
- Updated `Characters`, `Poses`, `Expressions`, and `FittingRoom` pages to use the new delete UI (3-dot menu + confirmation).
- Updated `CreateLookDialog` to enforce single selection for equipment categories.
- Added necessary tests adjustments.
- Update `src/service/backup.test.ts` to fully mock `node:fs` methods (`existsSync`, `renameSync`, `mkdirSync`, `rmSync`).
- This prevents the test from interacting with the real file system, eliminating the `ENOENT` race condition error observed in CI pipelines.
- Ensures the test is idempotent and safely verifies the service logic without side effects.
- Verified all 49 tests pass locally.
- Create `BackupService` in `src/service/backup.ts` to encapsulate tar stream creation and restore logic (db connection, fs operations).
- Refactor `src/api/backup.ts` and `src/api/restore.ts` to use `BackupService`.
- Add unit tests for `BackupService` in `src/service/backup.test.ts`.
- Add API tests for backup and restore endpoints in `src/api/backup.test.ts` and `src/api/restore.test.ts`.
- Maintain existing functionality: uncompressed tar streaming, safe restore with rollback.
- Implement `GET /api/backup` to stream `data` directory as a tarball using `node-tar`.
- Implement `POST /api/restore` to accept and extract tarballs to the `data` directory.
- Update `BackupRestoreDialog` to accept `.tar` files and remove gzip references.
- Ensure safe restore with database connection management and rollback.
- Disabled Gzip compression as requested since assets are already compressed WebP files.
- Implement `GET /api/backup` to stream `data` directory as a gzipped tarball using `node-tar`.
- Implement `POST /api/restore` to accept and extract gzipped tarballs to the `data` directory, handling database disconnection/reconnection and rollbacks.
- Add `BackupRestoreDialog` UI component for downloading backups and uploading restore files.
- Integrate backup dialog trigger into the AppSidebar logo.
- Ensure type safety and add temporary integration tests for verification.
- Add `GET /api/backup` endpoint to stream `data` directory as a tar file.
- Add `POST /api/restore` endpoint to handle tar file upload and restore.
- Implement `BackupRestoreDialog` in the UI for user interaction.
- Integrate backup/restore dialog into the sidebar via the logo.
- Ensure safe restore with rollback on failure and database connection management.