open ai service
This commit is contained in:
300
books_flutter/CLAUDE.md
Normal file
300
books_flutter/CLAUDE.md
Normal file
@@ -0,0 +1,300 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Project Overview
|
||||
|
||||
This is a Flutter mobile application for managing a personal book library. The app features book cataloging, categorization, reading status tracking, and cover scanning capabilities (via camera + Gemini AI).
|
||||
|
||||
**Tech Stack:**
|
||||
- Flutter SDK ^3.10.8
|
||||
- State Management: flutter_bloc ^9.1.0
|
||||
- UI: Material 3 with Google Fonts (Inter)
|
||||
- AI: google_generative_ai ^0.4.6 (for book cover analysis)
|
||||
- Camera: camera ^0.11.1
|
||||
|
||||
## Development Commands
|
||||
|
||||
### Running the App
|
||||
```bash
|
||||
# Run on connected device/simulator
|
||||
flutter run
|
||||
|
||||
# Run on specific device
|
||||
flutter run -d <device-id>
|
||||
|
||||
# Run in release mode
|
||||
flutter run --release
|
||||
|
||||
# List available devices
|
||||
flutter devices
|
||||
```
|
||||
|
||||
### Building
|
||||
```bash
|
||||
# Build APK for Android
|
||||
flutter build apk
|
||||
|
||||
# Build iOS
|
||||
flutter build ios
|
||||
|
||||
# Build for web (not currently configured)
|
||||
flutter build web
|
||||
```
|
||||
|
||||
### Code Quality
|
||||
```bash
|
||||
# Install/update dependencies
|
||||
flutter pub get
|
||||
|
||||
# Check for outdated packages
|
||||
flutter pub outdated
|
||||
|
||||
# Run static analysis
|
||||
flutter analyze
|
||||
|
||||
# Format all Dart files
|
||||
flutter format lib/
|
||||
|
||||
# Run tests
|
||||
flutter test
|
||||
```
|
||||
|
||||
### Using Dart MCP Tools
|
||||
When the Dart MCP server is available, prefer using these tools instead of bash commands:
|
||||
- `mcp__dart__analyze_files` instead of `flutter analyze`
|
||||
- `mcp__dart__dart_format` instead of `flutter format`
|
||||
- `mcp__dart__run_tests` instead of `flutter test`
|
||||
- `mcp__dart__list_devices` to see available devices
|
||||
- `mcp__dart__launch_app` to run the app with DTD integration
|
||||
|
||||
## Architecture
|
||||
|
||||
### State Management (BLoC Pattern)
|
||||
|
||||
The app uses **flutter_bloc** for state management with two main BLoCs:
|
||||
|
||||
#### 1. BookBloc (`lib/bloc/book_bloc.dart`)
|
||||
Manages the book collection state and operations:
|
||||
- **State**: `BookState` containing `List<Book>`
|
||||
- **Events**:
|
||||
- `AddBook(book)` - Add new book to library
|
||||
- `UpdateBook(book)` - Update existing book
|
||||
- `DeleteBook(id)` - Remove book from library
|
||||
- `ToggleFavorite(id)` - Toggle favorite status
|
||||
- **Initial State**: Loads from `initialBooks` in `constants.dart`
|
||||
- **Note**: Currently uses in-memory storage; no persistence layer
|
||||
|
||||
#### 2. NavigationBloc (`lib/bloc/navigation_bloc.dart`)
|
||||
Manages app navigation and screen state:
|
||||
- **State**: `NavigationState` with:
|
||||
- `screen` (AppScreen enum) - Current screen
|
||||
- `selectedBook` - Book being viewed/edited
|
||||
- `prefilledData` - Data for pre-populating forms
|
||||
- **Event**: `NavigateTo(screen, {selectedBook, prefilledData})`
|
||||
- **Pattern**: Declarative navigation where UI rebuilds based on state
|
||||
- **Important**: `prefilledData` is used when scanning covers to prefill book form, while `selectedBook` is used for editing existing books
|
||||
|
||||
### Data Models (`lib/models/models.dart`)
|
||||
|
||||
Uses Dart 3 **record types** for immutability:
|
||||
|
||||
```dart
|
||||
typedef Book = ({
|
||||
String id,
|
||||
String title,
|
||||
String author,
|
||||
String genre,
|
||||
String annotation,
|
||||
String? coverUrl,
|
||||
int? pages,
|
||||
String? language,
|
||||
int? publishedYear,
|
||||
double? rating,
|
||||
String status, // 'reading', 'done', 'want_to_read'
|
||||
double? progress, // 0-100 for reading progress
|
||||
bool isFavorite,
|
||||
});
|
||||
```
|
||||
|
||||
**Important**: Records are immutable. To update a book, create a new record with updated fields using record syntax:
|
||||
```dart
|
||||
final updatedBook = (
|
||||
id: book.id,
|
||||
title: newTitle,
|
||||
// ... copy all other fields
|
||||
);
|
||||
```
|
||||
|
||||
### Navigation Flow
|
||||
|
||||
The app uses a custom navigation system via `NavigationBloc`:
|
||||
|
||||
1. **Library Screen** (default) → Shows all books in grid/category view
|
||||
2. **Categories Screen** → Browse books by predefined categories
|
||||
3. **Book Details** → View/edit single book (triggered by tapping book card)
|
||||
4. **Add/Edit Book** → Form for adding new books or editing existing
|
||||
5. **Scanner Screen** → Camera interface for scanning book covers
|
||||
6. **Wishlist/Settings** → Placeholder screens
|
||||
|
||||
**Navigation Pattern:**
|
||||
```dart
|
||||
context.read<NavigationBloc>().add(
|
||||
NavigateTo(AppScreen.details, selectedBook: book)
|
||||
);
|
||||
```
|
||||
|
||||
The main shell (`_AppShell` in `main.dart`) rebuilds based on `NavigationState.screen`.
|
||||
|
||||
### Theme System (Material 3)
|
||||
|
||||
**Critical**: This app uses a **centralized theme system**. Never hardcode colors, text styles, or spacing.
|
||||
|
||||
**Theme Files:**
|
||||
- `lib/theme/app_colors.dart` - Semantic color constants (cyan-based palette)
|
||||
- `lib/theme/app_spacing.dart` - Spacing scale (8px base) and border radius
|
||||
- `lib/theme/app_theme.dart` - Material 3 ThemeData with component themes
|
||||
|
||||
**Usage Pattern:**
|
||||
```dart
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final textTheme = Theme.of(context).textTheme;
|
||||
|
||||
// Use semantic colors
|
||||
Container(color: colorScheme.primary)
|
||||
|
||||
// Use text styles
|
||||
Text('Title', style: textTheme.displayMedium)
|
||||
|
||||
// Use spacing constants
|
||||
Padding(padding: EdgeInsets.all(AppSpacing.md))
|
||||
|
||||
// Use shadows
|
||||
BoxDecoration(boxShadow: AppTheme.shadowMd)
|
||||
```
|
||||
|
||||
**Color Scheme:**
|
||||
- Primary: #0891B2 (Cyan-600)
|
||||
- Success/CTA: #22C55E (Green-500)
|
||||
- Background: #ECFEFF (Cyan-50)
|
||||
- Surface: #FFFFFF
|
||||
|
||||
**Typography:** Inter font family loaded via Google Fonts with weights 300-700.
|
||||
|
||||
### Screen Structure
|
||||
|
||||
All main screens follow this pattern:
|
||||
1. Wrap in `SafeArea` for notch/status bar handling
|
||||
2. Use `BlocBuilder` to listen to relevant BLoC state
|
||||
3. Access theme via `Theme.of(context)`
|
||||
4. Use `AppSpacing.*` constants for all padding/margins
|
||||
5. Use theme colors and text styles exclusively
|
||||
|
||||
**Example:**
|
||||
```dart
|
||||
class MyScreen extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final textTheme = Theme.of(context).textTheme;
|
||||
|
||||
return SafeArea(
|
||||
child: BlocBuilder<BookBloc, BookState>(
|
||||
builder: (context, state) {
|
||||
return Padding(
|
||||
padding: EdgeInsets.all(AppSpacing.lg),
|
||||
child: Text(
|
||||
'Hello',
|
||||
style: textTheme.headlineMedium,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Widget Conventions
|
||||
|
||||
**BookCard** (`lib/widgets/book_card.dart`):
|
||||
- Displays book cover with metadata overlay
|
||||
- Includes Hero animation with tag `'book-cover-${book.id}'`
|
||||
- Shows shimmer loading while image loads
|
||||
- Has hover effect on desktop/web (1.02 scale)
|
||||
- Displays favorite badge, status badge, or progress bar based on book state
|
||||
|
||||
**Hero Animations:**
|
||||
When navigating from library to book details, book covers animate smoothly:
|
||||
```dart
|
||||
Hero(
|
||||
tag: 'book-cover-${book.id}',
|
||||
child: Image.network(book.coverUrl),
|
||||
)
|
||||
```
|
||||
Both `BookCard` and `BookDetailsScreen` must use matching tags.
|
||||
|
||||
### Gemini AI Integration
|
||||
|
||||
The `GeminiService` (`lib/services/gemini_service.dart`) is a placeholder for future AI-powered book cover scanning:
|
||||
- Takes base64-encoded image from camera
|
||||
- Will analyze cover and extract metadata (title, author, etc.)
|
||||
- Returns `Book?` record with prefilled data
|
||||
- Currently returns `null` - implementation pending
|
||||
|
||||
**Intended Flow:**
|
||||
1. User opens Scanner Screen
|
||||
2. Takes photo of book cover
|
||||
3. Image sent to `GeminiService.analyzeBookCover()`
|
||||
4. Extracted data passed to Add Book screen via `NavigationBloc` with `prefilledData`
|
||||
|
||||
## Important Patterns
|
||||
|
||||
### When Adding New Features
|
||||
|
||||
1. **New Book Fields**: Update the `Book` typedef in `models.dart` and all places that construct book records
|
||||
2. **New Screens**: Add to `AppScreen` enum, handle in `_AppShell` switch statement
|
||||
3. **Theme Changes**: Only modify theme files, never inline styles
|
||||
4. **Navigation**: Always use `NavigationBloc`, never `Navigator.push()`
|
||||
|
||||
### Code Style Requirements
|
||||
|
||||
- **Immutability**: Use records for data models, never mutable classes
|
||||
- **Theme Compliance**: Zero hardcoded colors/styles/spacing
|
||||
- **BLoC Pattern**: UI is always a pure function of state
|
||||
- **Const Constructors**: Use `const` for all stateless widgets and values
|
||||
- **Reduced Motion**: Check `MediaQuery.of(context).disableAnimations` for animations
|
||||
|
||||
### Testing Gotchas
|
||||
|
||||
- Books are stored in-memory only; restarting app resets to `initialBooks`
|
||||
- Camera requires physical device or simulator with camera support
|
||||
- Gemini API requires valid API key (not implemented yet)
|
||||
- Hero animations require matching tags between screens
|
||||
|
||||
## Project-Specific Notes
|
||||
|
||||
### Why Records Instead of Classes?
|
||||
|
||||
This codebase uses Dart 3 record types for immutability and simplicity. When updating books, create new records rather than mutating fields. This makes BLoC state updates predictable and prevents accidental mutations.
|
||||
|
||||
### Navigation Without Navigator
|
||||
|
||||
The app doesn't use Flutter's built-in Navigator. Instead, `NavigationBloc` tracks the current screen, and `_AppShell` rebuilds the entire UI tree based on state. This gives centralized control over navigation state but means:
|
||||
- No native back button handling (would need to emit `NavigateTo` events)
|
||||
- No deep linking support (yet)
|
||||
- All screens must be handled in the main switch statement
|
||||
|
||||
### Initial Data
|
||||
|
||||
Books are initialized from `initialBooks` constant in `lib/constants/constants.dart`. Categories are defined in the same file. To add sample data, modify these constants.
|
||||
|
||||
### Future Enhancements
|
||||
|
||||
Based on the codebase structure, likely next steps:
|
||||
- Implement persistence (SharedPreferences, SQLite, or Firebase)
|
||||
- Complete Gemini AI integration for cover scanning
|
||||
- Add native back button handling
|
||||
- Implement book search/filtering
|
||||
- Add reading statistics/charts
|
||||
- Support for book series and collections
|
||||
Reference in New Issue
Block a user