- Web UI: login, dashboard, links CRUD, collections, API keys, admin pages - Query engine: AND/OR/XOR with field filters, tag search, preview endpoint - Session management: token expiry detection, 401 interceptor, expiry banner - Links search: tags included, multi-word AND, query mode with set operations - Collections: static/dynamic, query builder with preview, public tree view - Save as Collection: convert search results (static) or query (dynamic) - Dashboard stats: resilient loading with allSettled pattern - Login page: redesigned with public collections tree view - Bug fix: query executor None fields crash (notes/description/url/title) - E2E tests: 20 Playwright tests covering all critical user flows - All 104 tests passing (84 unit/integration + 20 E2E)
153 lines
4.7 KiB
Markdown
153 lines
4.7 KiB
Markdown
# AGENTS.md - LinkSyncServer
|
|
|
|
## Project Overview
|
|
|
|
LinkSyncServer is a self-hosted bookmark server with advanced collection and query capabilities. It provides a RESTful API and web interface for managing bookmarks (links), collections (static or dynamic sets), and supports synchronization with browser extensions.
|
|
|
|
## Setup & Build Commands
|
|
|
|
- **Build**: `docker-compose up -d --build`
|
|
- **Test**: `pytest tests/ -v`
|
|
- **E2E Test**: `pytest tests/test_e2e.py -v --browser chromium`
|
|
- **Lint**: `ruff check .` && `mypy app.py models/`
|
|
- **Dev**: `docker-compose up web`
|
|
- **Migrate**: `alembic upgrade head`
|
|
|
|
## Architecture Notes
|
|
|
|
### Core Components
|
|
|
|
1. **Authentication Layer**: JWT-based auth with admin/regular user roles
|
|
2. **Link Management**: CRUD for links with all Firefox bookmark fields
|
|
3. **Collection Engine**: Static and dynamic collections with query support
|
|
4. **Query Parser**: Expression parser supporting AND/OR/XOR set operations
|
|
5. **Sync Protocol**: Extension sync endpoint with conflict resolution
|
|
|
|
### Data Models
|
|
|
|
- **User**: Authentication and authorization
|
|
- **Link**: Bookmark with all Firefox fields
|
|
- **Collection**: Static or dynamic set of links
|
|
- **Tag**: Optional categorization
|
|
- **AuditLog**: Track changes
|
|
|
|
### Query Engine
|
|
|
|
Query syntax: `('term1', 'term2') OR tagA AND tagB XOR url:example.com`
|
|
|
|
- Precedence: `()` > XOR > AND > OR
|
|
- Left-to-right evaluation otherwise
|
|
- Full-text search via PostgreSQL tsvector
|
|
|
|
## Testing Protocol
|
|
|
|
- All tests must pass before committing
|
|
- Run `pytest tests/ -v` for full test suite (84+ unit/integration tests)
|
|
- Run `pytest tests/test_e2e.py -v --browser chromium` for E2E tests (20+ tests)
|
|
- Coverage target: >80%
|
|
- E2E tests cover critical user flows:
|
|
- Login, dashboard stats, session expiry
|
|
- Link CRUD, search (simple, multi-word, query mode)
|
|
- Collection CRUD, query builder, save as collection
|
|
- API key management, admin user management
|
|
|
|
## Web Interface Requirements
|
|
|
|
### Session Management
|
|
- Token expiry detection on page load (decode JWT `exp` claim)
|
|
- 401 interceptor redirects to login on authentication failure
|
|
- Session expiry warning banner when token expires in <2 minutes
|
|
- Graceful logout clears storage and redirects to login
|
|
- Login page shows expiry message when redirected with `?expired=1`
|
|
|
|
### Dashboard
|
|
- Stats display always shows numbers (0, never `-`)
|
|
- Quick actions for creating links, collections, API keys
|
|
- Admin section visible only to admin users
|
|
- Resilient loading (allSettled pattern - one failing API doesn't break others)
|
|
|
|
### Links Page
|
|
- **Simple search mode**: Keyword search across title, URL, description, notes, and tags
|
|
- **Query mode**: Full set operations (AND, OR, XOR, NOT, parentheses, field filters)
|
|
- Multi-word search uses AND logic (all terms must match)
|
|
- Tags are included in all searches
|
|
- **Save as Collection**: Convert current results to static collection or query to dynamic collection
|
|
|
|
### Collections Page
|
|
- Static collections: Manual link management
|
|
- Dynamic collections: Query expression with preview
|
|
- Query builder UI with syntax hints
|
|
- Preview button shows matching links and count
|
|
- Query expression displayed on collection cards
|
|
|
|
### Error Handling
|
|
- API errors return structured responses with user-friendly messages
|
|
- Form validation before submission
|
|
- Network errors show graceful fallbacks
|
|
|
|
## Conventions
|
|
|
|
### File Naming
|
|
|
|
- Models: `{entity}.py` in `models/` directory
|
|
- Endpoints: `endpoints/{resource}.py`
|
|
- Queries: `queries/{operation}.py`
|
|
|
|
### Error Handling
|
|
|
|
- Use HTTP status codes appropriately
|
|
- Return structured error responses
|
|
- Log errors with stack traces in debug mode
|
|
|
|
### API Design
|
|
|
|
- RESTful conventions
|
|
- JSON responses with Content-Type
|
|
- Paginated lists with limit/offset
|
|
- OpenAPI documentation via `@openapi`
|
|
|
|
### Database
|
|
|
|
- UUID primary keys
|
|
- Timestamps on all records
|
|
- Foreign keys with cascade delete where appropriate
|
|
- Full-text search indexes on searchable fields
|
|
|
|
## Known Issues / Technical Debt
|
|
|
|
- None at initialization
|
|
- Query engine performance to be optimized
|
|
- Caching layer to be implemented
|
|
|
|
## Project-Specific Tools
|
|
|
|
- **Query Parser**: `queries/parser.py`
|
|
- **Query Executor**: `queries/executor.py`
|
|
- **Sync Logic**: `api/endpoints/sync.py`
|
|
|
|
## Related Files
|
|
|
|
- `README.md` - Overview and quick start
|
|
- `design.md` - Architecture and API details
|
|
- `tasks.md` - Implementation checklist
|
|
- `docker-compose.yml` - Deployment configuration
|
|
|
|
## Admin User Creation
|
|
|
|
Admin user is created from environment variables:
|
|
- `ADMIN_USERNAME`
|
|
- `ADMIN_PASSWORD`
|
|
- `SECRET_KEY` (generate securely)
|
|
|
|
Admin can create:
|
|
- Regular users
|
|
- Admin users
|
|
- API keys
|
|
- System settings
|
|
|
|
## Security Notes
|
|
|
|
- Never commit `.env` files
|
|
- Use strong passwords
|
|
- Rotate SECRET_KEY periodically
|
|
- Enable HTTPS in production |