{"id":44671983,"url":"https://github.com/johnstosh/library","last_synced_at":"2026-02-15T02:12:17.631Z","repository":{"id":318786301,"uuid":"1074912639","full_name":"johnstosh/library","owner":"johnstosh","description":"Card catalog software for home libraries","archived":false,"fork":false,"pushed_at":"2026-02-13T00:05:03.000Z","size":5635,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-13T09:53:15.125Z","etag":null,"topics":["library","library-management","library-management-system"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/johnstosh.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-10-12T17:57:55.000Z","updated_at":"2026-02-13T00:05:06.000Z","dependencies_parsed_at":"2025-10-30T03:18:30.451Z","dependency_job_id":"541b51e8-6a62-434a-9552-72ad1ef4cb45","html_url":"https://github.com/johnstosh/library","commit_stats":null,"previous_names":["johnstosh/library"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/johnstosh/library","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnstosh%2Flibrary","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnstosh%2Flibrary/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnstosh%2Flibrary/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnstosh%2Flibrary/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/johnstosh","download_url":"https://codeload.github.com/johnstosh/library/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnstosh%2Flibrary/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29465428,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-15T01:01:38.065Z","status":"online","status_checked_at":"2026-02-15T02:00:07.449Z","response_time":118,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["library","library-management","library-management-system"],"created_at":"2026-02-15T02:12:16.962Z","updated_at":"2026-02-15T02:12:17.624Z","avatar_url":"https://github.com/johnstosh.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Library Management System\n\nA full-stack library management system with book cataloging, patron tracking, library card generation, and Google Photos integration.\n\n## Technology Stack\n\n### Backend\n- **Java 17** with Spring Boot 3.5+\n- **PostgreSQL** (production) / **H2** (development/testing)\n- **Spring Security** with OAuth2 (Google SSO)\n- **Spring Data JPA** with Hibernate ORM\n- **MapStruct** for DTO mapping\n- **iText 8** for PDF generation\n- **Google Photos API** for photo storage\n- **Marc4J** for Library of Congress lookup\n\n### Frontend\n- **React 18.3** with TypeScript 5.3\n- **Tailwind CSS v4** for styling\n- **TanStack Query v5** for server state\n- **React Router v6** for routing\n- **Zustand** for client state\n- **Vite 7.3** for builds\n\n## Quick Start\n\n### Prerequisites\n- Java 17+\n- Node.js 18+ and npm\n- Docker (for deployment)\n- Google Cloud SDK (for deployment)\n\n### Development Mode\n\n**Option 1: Run both servers together (Recommended)**\n```bash\n./dev.sh\n```\nThis starts:\n- React dev server at http://localhost:5173 (with hot reload)\n- Spring Boot API at http://localhost:8080\n\n**Option 2: Run servers separately**\n\nTerminal 1 - Backend:\n```bash\n./gradlew bootRun\n```\n\nTerminal 2 - Frontend:\n```bash\ncd frontend\nnpm install\nnpm run dev\n```\n\nThen open http://localhost:5173 in your browser.\n\n### Production Build\n\nBuild the entire application (frontend + backend):\n```bash\n./build-frontend.sh  # Build React and copy to static resources\n./gradlew build      # Build Spring Boot JAR with embedded frontend\n```\n\nRun the production JAR:\n```bash\njava -jar build/libs/library-*.jar\n```\n\nThen open http://localhost:8080 in your browser.\n\n## Development Workflow\n\n### Frontend Development\n\nThe frontend lives in `frontend/` and uses Vite for fast development:\n\n```bash\ncd frontend\n\n# Install dependencies\nnpm install\n\n# Start dev server with hot reload (http://localhost:5173)\nnpm run dev\n\n# Build for production\nnpm run build\n\n# Lint and format\nnpm run lint\n```\n\n**Development Server Features:**\n- Hot Module Replacement (HMR) for instant updates\n- API proxy to Spring Boot (requests to /api/* → http://localhost:8080)\n- TypeScript type checking\n- Fast rebuild times (~50ms)\n\n**Frontend Project Structure:**\n```\nfrontend/src/\n├── api/          # API clients with TanStack Query hooks\n├── pages/        # Page components (routes)\n├── components/   # Reusable components\n├── stores/       # Zustand state stores\n├── utils/        # Utility functions\n├── types/        # TypeScript types\n└── config/       # Configuration\n```\n\n### Backend Development\n\nThe backend is a Spring Boot application:\n\n```bash\n# Run with H2 in-memory database (default)\n./gradlew bootRun\n\n# Run with PostgreSQL (requires configuration)\n./gradlew bootRun --args='--spring.profiles.active=prod'\n\n# Run tests (excluding UI tests)\n./fast-tests.sh\n\n# Run all tests\n./gradlew test\n\n# Run specific test\n./gradlew test --tests \"com.muczynski.library.controller.BookControllerTest\"\n\n# Clean build\n./gradlew clean build\n```\n\n**Backend Project Structure:**\n```\nsrc/main/java/com/muczynski/library/\n├── controller/   # REST controllers (@RestController)\n├── service/      # Business logic (@Service)\n├── repository/   # Data access (@Repository)\n├── entity/       # JPA entities\n├── dto/          # Data Transfer Objects\n├── mapper/       # MapStruct mappers\n├── config/       # Spring configuration\n└── security/     # Security configuration\n```\n\n### Making Changes\n\n**Adding a Backend API Endpoint:**\n1. Create/update entity in `entity/`\n2. Create repository in `repository/`\n3. Create DTO in `dto/`\n4. Create MapStruct mapper in `mapper/`\n5. Create service in `service/`\n6. Create controller in `controller/`\n7. Add tests in `src/test/java/`\n\n**Adding a Frontend Feature:**\n1. Create API functions in `frontend/src/api/feature.ts`\n2. Add React Query hooks (useFeatures, useCreateFeature, etc.)\n3. Create page component in `frontend/src/pages/feature/`\n4. Add child components (filters, table, form, modals)\n5. Add route in `frontend/src/App.tsx` (lazy-loaded)\n6. Add navigation link in `frontend/src/components/layout/Navigation.tsx`\n7. Add TypeScript interfaces in `frontend/src/types/dtos.ts`\n\n## Testing\n\n### Unit \u0026 Integration Tests (Backend)\n```bash\n# Fast tests (excludes UI tests)\n./fast-tests.sh\n\n# All tests\n./gradlew test\n\n# Single test class\n./gradlew test --tests \"com.muczynski.library.controller.BookControllerTest\"\n```\n\n### UI Tests (Playwright)\n```bash\n# Run UI tests\n./gradlew test --tests \"com.muczynski.library.ui.*\"\n```\n\n### Frontend Tests (Future)\n```bash\ncd frontend\nnpm run test  # React Testing Library (planned)\n```\n\n## Building \u0026 Deployment\n\n### Building for Production\n\n**Step 1: Build Frontend**\n```bash\n./build-frontend.sh\n```\nThis:\n- Runs `npm run build` in frontend/\n- Copies the production build to `src/main/resources/static/`\n- Clears old static files\n- Creates optimized bundles with code splitting\n\n**Step 2: Build Backend**\n```bash\n./gradlew clean build\n```\nThis:\n- Compiles Java code\n- Runs all tests\n- Packages frontend static files into the JAR\n- Creates `build/libs/library-*.jar`\n\n**All-in-One Build:**\n```bash\n./build-frontend.sh \u0026\u0026 ./gradlew clean build\n```\n\n### Deployment to Google Cloud Run\n\n**Prerequisites:**\n- Google Cloud account\n- Project configured\n- Cloud SQL instance\n\n**Environment Variables Required:**\n```bash\nexport GCP_PROJECT_ID=\"your-project-id\"\nexport DB_PASSWORD=\"your-db-password\"\nexport GCP_REGION=\"us-east1\"\nexport BINARY_REPO_NAME=\"scrabble-game\"  # Optional, defaults to this\nexport CLOUD_RUN_SERVICE_ACCOUNT=\"service-account-name\"  # Optional\n```\n\n**Deploy:**\n```bash\n./deploy.sh\n```\n\nThis script:\n1. Builds the React frontend\n2. Creates/updates Cloud SQL database\n3. Builds Spring Boot JAR\n4. Creates Docker image\n5. Pushes to Artifact Registry\n6. Deploys to Cloud Run\n7. Configures environment variables\n8. Connects to Cloud SQL\n\n### Manual Docker Build\n\n```bash\n# Build frontend first\n./build-frontend.sh\n\n# Build Docker image\ndocker build -t library-app .\n\n# Run locally\ndocker run -p 8080:8080 \\\n  -e SPRING_PROFILES_ACTIVE=prod \\\n  -e DB_PASSWORD=yourpassword \\\n  library-app\n```\n\n## Configuration\n\n### Backend Configuration\n\n**Development (H2 Database):**\n`src/main/resources/application.properties`\n\n**Production (PostgreSQL):**\n`src/main/resources/application-prod.properties`\n\n**Key Settings:**\n- `server.port=8080` - API port\n- `spring.jpa.hibernate.ddl-auto=update` - Auto-update schema\n- `app.show-test-data-page=true` - Show test data menu (dev only)\n\n### Frontend Configuration\n\n**Vite Configuration:**\n`frontend/vite.config.ts`\n- Path aliases (@/)\n- Dev server port (5173)\n- API proxy to Spring Boot\n\n**API Base URL:**\n`frontend/src/api/client.ts`\n- Development: Proxied through Vite\n- Production: Same origin (served by Spring Boot)\n\n## Application Features\n\n### Core Features\n- **Books Management**: CRUD operations, filters, status tracking\n- **Authors Management**: Biographical info, book counts\n- **Library Management**: Multiple library branches\n- **Loans**: Checkout, return, overdue tracking\n- **Users**: Patron and staff accounts with roles\n- **Search**: Public book/author search (no auth required)\n\n### Advanced Features\n- **Photo Management**: Upload, crop, rotate, reorder\n- **Google Photos Integration**: Import books from photo feed\n- **Library of Congress Lookup**: Automatic call number retrieval\n- **Library Cards**: Generate wallet-sized PDF cards\n- **Book Labels**: PDF spine labels with LOC numbers\n- **Data Management**: JSON import/export, photo backup\n- **Google OAuth SSO**: Login with Google account\n\n### Access Control\n- **PUBLIC**: Search functionality (no login)\n- **USER**: Books, Authors, Loans, My Card, Settings\n- **LIBRARIAN**: Full access including Users, Libraries, Data Management\n\n## Architecture\n\n### Request Flow (Development)\n\n```\nBrowser → http://localhost:5173\n         ↓\n    Vite Dev Server (React)\n         ↓\n    /api/* requests proxied to →\n         ↓\n    http://localhost:8080\n         ↓\n    Spring Boot (API)\n         ↓\n    H2 Database\n```\n\n### Request Flow (Production)\n\n```\nBrowser → http://localhost:8080\n         ↓\n    Spring Boot\n    ├─ /api/* → REST Controllers\n    └─ /* → index.html (React SPA)\n         ↓\n    PostgreSQL / H2\n```\n\n### Frontend Architecture\n- **Routing**: React Router with protected routes\n- **State**: TanStack Query (server) + Zustand (client) + useState (local)\n- **Styling**: Tailwind CSS utility classes\n- **API**: TanStack Query hooks with automatic caching\n- **Code Splitting**: Lazy-loaded page components (49% bundle reduction)\n- **Login Page**: Split layout with left form panel and right branding panel for improved UX (responsive on mobile)\n\n### Backend Architecture\n- **Controller Layer**: REST endpoints with DTOs\n- **Service Layer**: Business logic, transactions\n- **Repository Layer**: Spring Data JPA\n- **Security**: Spring Security with authorities (not roles)\n- **DTOs**: MapStruct for entity-DTO conversion\n\n## Performance\n\n### Frontend Optimization\n- **Code Splitting**: 34 separate chunks, 275 KB initial bundle\n- **Query Caching**: 5-minute stale time, 30-minute garbage collection\n- **Lazy Loading**: All page components loaded on demand\n- **Error Boundaries**: Graceful error handling\n\n### Backend Optimization\n- **Database**: Connection pooling, JPA lazy loading\n- **Caching**: Browser-based photo caching\n- **Queries**: LEFT JOIN FETCH for performance\n\n## Documentation\n\nDetailed documentation in root directory:\n\n- `feature-design-frontend.md` - Frontend architecture (React)\n- `feature-design-security.md` - Authentication \u0026 authorization\n- `feature-design-photos.md` - Photo storage \u0026 Google Photos\n- `feature-design-loc.md` - Library of Congress integration\n- `feature-design-import-export.md` - Data import/export\n- `feature-design-libraries.md` - Library card design\n- `backend-requirements.md` - Backend development guidelines\n- `endpoints.md` - API endpoint documentation\n- `FRONTEND_PROGRESS.md` - Migration status and features\n- `CLAUDE.md` - AI assistant context\n\n## Troubleshooting\n\n### Frontend Issues\n\n**Build Errors:**\n```bash\ncd frontend\nrm -rf node_modules package-lock.json\nnpm install\nnpm run build\n```\n\n**Dev Server Won't Start:**\n- Check port 5173 is available: `lsof -i :5173`\n- Check Node.js version: `node --version` (need 18+)\n\n**API Requests Failing:**\n- Verify backend is running on port 8080\n- Check Vite proxy config in `vite.config.ts`\n- Check browser Network tab for errors\n\n### Backend Issues\n\n**Database Connection:**\n- Development: Uses H2 in-memory (no config needed)\n- Production: Check `application-prod.properties` settings\n\n**Port Already in Use:**\n```bash\n# Kill process on port 8080\nlsof -i :8080\nkill -9 \u003cPID\u003e\n```\n\n**Tests Failing:**\n```bash\n# Run fast tests only (excludes UI tests)\n./fast-tests.sh\n\n# Clean and rebuild\n./gradlew clean build\n```\n\n### Production Build Issues\n\n**Static Files Not Found:**\n```bash\n# Rebuild frontend and copy to static/\n./build-frontend.sh\n\n# Verify files copied\nls -la src/main/resources/static/\n\n# Rebuild JAR\n./gradlew clean build\n```\n\n**React Router 404s:**\n- Check `SpaController.java` is mapping all routes\n- Verify `index.html` is in static/ directory\n\n## Git Workflow\n\nThis project uses direct commits to the `dev` branch:\n\n```bash\n# Before starting work\ngit checkout dev\ngit pull\n\n# After completing work\ngit add .\ngit commit -m \"Description of changes\"\ngit push origin dev\n```\n\n## Environment Variables\n\n### Development\nNo environment variables required (uses H2 in-memory database).\n\n### Production Deployment\nRequired:\n- `GCP_PROJECT_ID` - Google Cloud project ID\n- `DB_PASSWORD` - PostgreSQL password\n- `GCP_REGION` - Google Cloud region (default: us-east1)\n\nOptional:\n- `BINARY_REPO_NAME` - Artifact Registry repo (default: scrabble-game)\n- `CLOUD_RUN_SERVICE_ACCOUNT` - Service account name\n\n## Scripts Reference\n\n### Development Scripts\n- `./dev.sh` - Run both frontend and backend dev servers\n- `./fast-tests.sh` - Run tests excluding UI tests\n\n### Build Scripts\n- `./build-frontend.sh` - Build React and copy to static/\n- `./gradlew bootRun` - Run Spring Boot\n- `./gradlew build` - Build production JAR\n\n### Deployment Scripts\n- `./deploy.sh` - Deploy to Google Cloud Run\n- `./docker-test.sh` - Run tests in Docker\n- `./docker-stop-testing.sh` - Stop Docker test containers\n\n## Support\n\nFor issues or questions:\n1. Check documentation in `.md` files\n2. Check troubleshooting section above\n3. Review error logs in console\n4. Check browser DevTools Network tab\n\n## License\n\n(c) Copyright 2025 by Muczynski\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjohnstosh%2Flibrary","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjohnstosh%2Flibrary","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjohnstosh%2Flibrary/lists"}