fahrtenbuch/README.md
2025-10-29 21:58:35 +01:00

247 lines
6.5 KiB
Markdown

# Fahrtenbuch - Multi-Target Scala.js Application
A collaborative trip tracking application built with Scala.js, supporting both browser and Node.js environments with real-time peer-to-peer synchronization.
## Architecture
This project uses a multi-target architecture with shared business logic and platform-specific implementations:
```
fahrtenbuch/
├── shared/ # Shared business logic and models
│ └── src/main/scala/fahrtenbuch/
│ ├── model/ # Data models (Entry, EntryId)
│ ├── core/ # Business logic (EntryManager)
│ ├── storage/ # Storage interface
│ └── sync/ # Synchronization interface
├── browser/ # Browser-specific implementation
│ └── src/main/scala/fahrtenbuch/
│ ├── components/ # Laminar UI components
│ ├── storage/ # Dexie (IndexedDB) storage
│ ├── sync/ # Trystero (WebRTC) sync
│ └── BrowserMain.scala
├── nodejs/ # Node.js-specific implementation
│ └── src/main/scala/fahrtenbuch/
│ ├── storage/ # File system storage
│ ├── sync/ # WebSocket sync
│ └── NodeMain.scala
└── dist/ # Build outputs
├── browser/ # Browser build artifacts
└── nodejs/ # Node.js build artifacts
```
## Features
### Shared Features
- **CRDT-based synchronization**: Conflict-free replicated data types ensure consistent state across peers
- **Real-time sync**: Changes are automatically synchronized between connected peers
- **Offline support**: Works offline with automatic sync when reconnected
- **Trip tracking**: Track vehicle trips with distance, cost calculations, and payment status
### Browser Features
- **Modern UI**: Built with Laminar and Bulma CSS framework
- **IndexedDB storage**: Persistent local storage using Dexie
- **WebRTC P2P**: Direct peer-to-peer communication via Trystero
- **Real-time updates**: Live UI updates as data changes
### Node.js Features
- **Command-line interface**: Interactive CLI for managing entries
- **File system storage**: JSON-based persistent storage
- **WebSocket server**: Acts as a hub for peer communication
- **Statistics reporting**: Built-in analytics and reporting
## Getting Started
### Prerequisites
- **Scala**: 3.7.1
- **Node.js**: 16+
- **sbt**: 1.8+
### Installation
1. Clone the repository:
```bash
git clone <repository-url>
cd fahrtenbuch
```
2. Install dependencies:
```bash
npm install
```
3. Build both targets:
```bash
npm run build
```
## Development
### Browser Development
```bash
# Start development server with hot reload
npm run dev
# Build browser version only
npm run build:browser
# Production build
npm run build:browser:prod
```
### Node.js Development
```bash
# Build Node.js version
npm run build:nodejs
# Run Node.js application
npm run start:nodejs
# With custom options
node dist/nodejs/main.js --port 8080 --data-dir ./data
```
### SBT Commands
```bash
# Compile shared code
sbt sharedJs/compile
# Fast build for browser
sbt browser/fastOptJS
# Optimized build for browser
sbt browser/fullOptJS
# Fast build for Node.js
sbt nodejs/fastOptJS
# Optimized build for Node.js
sbt nodejs/fullOptJS
# Build everything
sbt compile
```
## Usage
### Browser Application
1. Build and start the browser version:
```bash
npm run build:browser
npm run dev
```
2. Open your browser and navigate to the displayed URL
3. Share the URL (including the hash) with other users for real-time collaboration
### Node.js Application
1. Build and start the Node.js version:
```bash
npm run build:nodejs
node dist/nodejs/main.js --port 8080
```
2. Use the interactive CLI:
```
fahrtenbuch> help
fahrtenbuch> add 1000 1050 John Dog
fahrtenbuch> list
fahrtenbuch> stats
fahrtenbuch> peers
```
3. Connect multiple instances:
```bash
# Start first instance
node dist/nodejs/main.js --port 8080
# Start second instance and connect to first
node dist/nodejs/main.js --port 8081 --connect localhost:8080
```
## Configuration
### Node.js Options
- `--port <port>`: WebSocket server port (default: 8080)
- `--data-dir <dir>`: Data storage directory (default: ./data)
- `--connect <host:port>`: Connect to peer at host:port
- `--help`: Show help message
### Browser Configuration
The browser version uses URL fragments for room identification. Users sharing the same URL fragment will be connected in the same sync room.
## Data Model
### Entry
Each trip entry contains:
- `id`: Unique identifier
- `startKm`: Starting odometer reading
- `endKm`: Ending odometer reading
- `driver`: Driver name
- `animal`: Animal transported
- `paid`: Payment status
- `date`: Entry creation date
- `gasPricePerKm`: Gas cost per kilometer
- `wearPricePerKm`: Wear cost per kilometer
### Synchronization
- Uses CRDT (Conflict-free Replicated Data Types) for conflict resolution
- Last-writer-wins semantics for most fields
- Automatic merging of concurrent updates
- Peer-to-peer synchronization without central server
## Storage
### Browser Storage
- **IndexedDB**: Via Dexie library
- **Schema versioning**: Automatic migrations
- **Live queries**: Real-time UI updates
### Node.js Storage
- **File system**: JSON files in data directory
- **Atomic writes**: Safe concurrent access
- **Backup friendly**: Human-readable JSON format
## Networking
### Browser Networking
- **WebRTC**: Direct peer-to-peer via Trystero
- **TURN/STUN**: Configurable relay servers
- **Room-based**: URL hash determines sync room
### Node.js Networking
- **WebSocket**: Server-client architecture
- **Auto-discovery**: Automatic peer detection
- **Hub model**: Can act as relay for browser clients
## Development Tips
### Adding New Features
1. Add shared logic to `shared/src/main/scala/fahrtenbuch/`
2. Implement platform-specific parts in `browser/` and `nodejs/`
3. Update interfaces in `storage/` and `sync/` packages
4. Test both targets with `npm run build`
### Debugging
- Browser: Use browser dev tools, network tab for WebRTC
- Node.js: Use `console.log` or Node.js debugging tools
- Storage: Check browser IndexedDB or Node.js data directory
### Performance
- Use `fullOptJS` for production builds
- Browser builds are optimized for incremental loading
- Node.js builds are optimized for startup time
## Contributing
1. Fork the repository
2. Create a feature branch
3. Make changes to shared code and both platform implementations
4. Test both browser and Node.js targets
5. Submit a pull request
## License
[Add your license here]