cheekylist/README.md
2025-07-25 16:27:30 +02:00

571 lines
16 KiB
Markdown

# GoCheck - Collaborative Checklist Application
A real-time collaborative checklist application built with Go and React,
featuring Server-Sent Events (SSE) for live updates and SQLite for data
persistence.
## Features
- Create and manage checklists
- Add, update, and delete checklist items
- Real-time collaboration with Server-Sent Events
- Item locking mechanism to prevent conflicts
- Hierarchical items (parent-child relationships)
- **Item dependencies: Define prerequisites for completing items**
- **Date constraints: Set "not before" and "not after" times for item
completion**
- SQLite database for data persistence
- **Modern web frontend with React and TypeScript**
- **Real-time updates across multiple browser tabs/windows**
- **SSE-first architecture: All data flows through Server-Sent Events**
## Architecture
### SSE-First Design
This application follows an **SSE-first architecture** where all checklist data
flows through Server-Sent Events:
- **No API calls for data retrieval**: The frontend never calls the
`/api/checklists/{uuid}/items` endpoint
- **SSE as primary data source**: All checklist items are received via SSE
streaming
- **Real-time state management**: The frontend maintains state purely through
SSE events
- **Immediate updates**: Changes appear instantly across all connected clients
#### Data Flow
1. **Initial Connection**: When a client connects to a checklist, the SSE
endpoint sends the complete current state
2. **Real-time Updates**: All subsequent changes (add, update, delete, lock) are
broadcast via SSE
3. **State Synchronization**: The frontend updates its local state based on SSE
events without API calls
This design ensures:
- **Consistency**: All clients see the same data at the same time
- **Performance**: No unnecessary API calls to reload data
- **Real-time Experience**: Changes appear instantly across all connected
browsers
- **Scalability**: Reduces server load by eliminating polling
## Prerequisites
- Go 1.16 or later
- SQLite3 (usually included with Go)
## Setup
1. **Initialize the Go module** (already done):
```bash
go mod init gocheck
```
2. **Install dependencies**:
```bash
go mod tidy
```
3. **Build the application**:
```bash
go build
```
4. **Run the server**:
```bash
./gocheck
```
Or use the demo script for a guided experience:
```bash
./demo.sh
```
The server will start on `http://localhost:8080`
## Deployment
The application is built as a single binary with embedded static files, making
deployment simple:
- **Single Executable**: The `gocheck` binary contains all necessary files
- **No External Dependencies**: Just copy the binary to your server
- **Cross-Platform**: Build for different platforms as needed
### Binary Deployment
To build for different platforms:
```bash
# Linux
GOOS=linux GOARCH=amd64 go build -o gocheck-linux
# Windows
GOOS=windows GOARCH=amd64 go build -o gocheck.exe
# macOS
GOOS=darwin GOARCH=amd64 go build -o gocheck-macos
```
### Container Deployment
The application includes a multi-stage Containerfile for containerized
deployment:
#### Using Podman (Recommended)
The application is optimized for rootless Podman operation:
```bash
# Build and run with the provided script
./build-container.sh
# Or manually:
podman build -t gocheck -f Containerfile .
podman run -d --name gocheck-container -p 8080:8080 -v gocheck-data:/app gocheck
# With custom port:
PORT=3000 ./build-container.sh
# Or manually:
podman run -d --name gocheck-container -p 3000:8080 -e PORT=8080 -v gocheck-data:/app gocheck
# Using Podman Compose (recommended for rootless):
podman-compose -f podman-compose.yml up -d
# Or with Docker Compose (also works with Podman):
docker-compose up -d
```
**Rootless Podman Compatibility:**
- Uses UID/GID 1000 for better user mapping
- Includes security options for rootless operation
- Supports both `podman-compose` and `docker-compose`
- Alternative compose file available: `podman-compose.yml`
#### Using Docker
```bash
# Build the image
docker build -t gocheck -f Containerfile .
# Run the container
docker run -d --name gocheck-container -p 8080:8080 -v gocheck-data:/app gocheck
# With custom port:
docker run -d --name gocheck-container -p 3000:8080 -e PORT=8080 -v gocheck-data:/app gocheck
```
#### Container Features
- **Multi-stage build**: Uses Go Alpine for building, Alpine for runtime
- **Minimal footprint**: Runtime container is optimized for size
- **Persistent data**: SQLite database is stored in a named volume
- **Security**: Runs as non-root user with UID 1000
- **Rootless Podman compatible**: Optimized for rootless container operation
- **Configurable**: Supports environment variables for customization
#### Environment Variables
- `PORT`: Set the port the application listens on (default: 8080)
```bash
# Example: Run on port 3000
PORT=3000 ./build-container.sh
```
## Frontend
The application includes a modern web frontend built with **React**:
- **Single Page Application**: No page reloads needed
- **Home Page**: Welcome page for creating new checklists
- **Checklist Page**: Dedicated page for viewing and editing checklists
- **Local Storage**: Automatically saves and lists your checklists
- **Real-time Updates**: Changes appear instantly across all connected browsers
- **Responsive Design**: Works on desktop and mobile devices
- **Item Locking**: Visual indicators when items are being edited
- **Hierarchical Items**: Support for parent-child relationships
- **Modern UI**: Clean, intuitive interface
- **TypeScript**: Full type safety and better developer experience
- **Component-based**: Modular, maintainable code structure
- **URL-based Routing**: Share checklist URLs directly
- **ESLint**: Code quality enforcement with no-semicolon style
### Frontend Development
The frontend is located in the `frontend/` directory and uses:
- **React**: Modern JavaScript library for building user interfaces
- **TypeScript**: Type-safe JavaScript
- **Vite**: Fast build tool and dev server
- **CSS Modules**: Scoped styling
#### Development Commands
```bash
# Install dependencies
cd frontend && npm install
# Start development server (with API proxy)
cd frontend && npm run dev
# Build for production
cd frontend && npm run build
# Lint code (check for issues)
cd frontend && npm run lint
# Lint and auto-fix issues
cd frontend && npm run lint:fix
# Build frontend and copy to static directory
./build-frontend.sh
```
#### Development Workflow
1. Start the backend server: `./gocheck`
2. Start the frontend dev server: `cd frontend && npm run dev`
3. Access the app at: `http://localhost:5173` (frontend dev server)
4. The frontend will proxy API requests to the backend at
`http://localhost:8080`
Simply open `http://localhost:8080` in your browser to use the production
application.
#### Page Structure
- **Home Page** (`/`): Welcome page with option to create new checklists and
view saved checklists
- **Checklist Page** (/{uuid}`): View and edit specific checklists
- when opening this route and that checklistid is not yet saved into
localstorage it should be committed there
- **URL Sharing**: Share checklist URLs directly with others for collaboration
- **Local Storage**: Checklists are automatically saved and can be renamed or
removed from the home page
## API Endpoints
### Checklists
- `POST /api/checklists` - Create a new checklist
- `POST /api/checklists/{uuid}/items` - Add an item to a checklist
- `PATCH /api/checklists/{uuid}/items/{id}` - Update an item
- `DELETE /api/checklists/{uuid}/items/{id}` - Delete an item
- `POST /api/checklists/{uuid}/items/{id}/lock` - Lock an item for editing
- `GET /api/checklists/{uuid}/sse` - Server-Sent Events stream for real-time
updates (primary data source)
**Note**: The `GET /api/checklists/{uuid}/items` endpoint exists but is not used
by the frontend. All data flows through the SSE endpoint for real-time updates.
### API Response Format
All API endpoints return JSON responses with a consistent format:
```json
{
"success": true,
"message": "Operation completed successfully"
// ... additional data specific to the endpoint
}
```
#### Example Responses
**Create Checklist:**
```json
{
"success": true,
"message": "Checklist created successfully",
"uuid": "123e4567-e89b-12d3-a456-426614174000"
}
```
**Add Item:**
```json
{
"success": true,
"message": "Item added successfully",
"item": {
"id": 1,
"content": "New item",
"checked": false,
"parent_id": null,
"checklist_uuid": "123e4567-e89b-12d3-a456-426614174000",
"dependencies": [],
"not_before": "2025-07-25T16:20:00Z",
"not_after": "2025-07-25T18:00:00Z"
}
}
```
**Update Item:**
```json
{
"success": true,
"message": "Item updated successfully",
"item": {
"id": 1,
"content": "Updated content",
"checked": true,
"parent_id": null,
"checklist_uuid": "123e4567-e89b-12d3-a456-426614174000",
"dependencies": [2, 3],
"not_before": "2025-07-25T16:20:00Z",
"not_after": "2025-07-25T18:00:00Z"
}
}
```
**Delete Item:**
```json
{
"success": true,
"message": "Item deleted successfully",
"id": 1
}
```
**Lock Item:**
```json
{
"success": true,
"message": "Item locked successfully",
"id": 1,
"locked_by": "user123",
"expires": "2024-01-01T12:00:00Z"
}
```
**Get Items:**
```json
{
"success": true,
"message": "Items loaded successfully",
"items": [
{
"id": 1,
"content": "Item 1",
"checked": false,
"parent_id": null,
"checklist_uuid": "123e4567-e89b-12d3-a456-426614174000",
"dependencies": [],
"not_before": null,
"not_after": null
},
{
"id": 2,
"content": "Item 2",
"checked": true,
"parent_id": null,
"checklist_uuid": "123e4567-e89b-12d3-a456-426614174000",
"dependencies": [1],
"not_before": "2025-07-25T16:20:00Z",
"not_after": null
}
]
}
```
## Dependencies
- `github.com/google/uuid` - UUID generation
- `github.com/mattn/go-sqlite3` - SQLite driver for Go
## Database
The application uses SQLite with the following schema:
- `checklist_info` table: Stores checklist metadata (uuid, name)
- `items` table: Stores checklist items with hierarchical relationships and date
constraints
- `dependencies` table: Stores item dependencies (item_id, dependency_id)
## Real-time Features
- **SSE-first architecture**: All data flows through Server-Sent Events
- **Real-time state synchronization**: No API polling required
- **Item locking with automatic expiration** (30 seconds)
- **Broadcast updates to all connected clients**
- **Immediate UI updates**: Changes appear instantly across all browsers
## Item Dependencies
The application supports item dependencies, allowing you to define prerequisites
that must be completed before an item can be marked as done.
### How Dependencies Work
- **Prerequisites**: Items can depend on other items being completed first
- **Visual Indicators**: Items with unmet dependencies show warning indicators
- **Prevention**: Items cannot be completed until all dependencies are satisfied
- **Circular Prevention**: The system prevents circular dependencies
- **Real-time Updates**: Dependency status updates in real-time across all
clients
### Managing Dependencies
1. **Add Dependencies**: Click the dependency icon (⚡) on any item to open the
dependency manager
2. **Select Prerequisites**: Choose which items must be completed first
3. **Visual Feedback**: Items show dependency status with color-coded
indicators:
- 🟠 Orange: Dependencies not met (shows count)
- 🟢 Green: All dependencies met (shows "Ready")
4. **Completion Prevention**: Items with unmet dependencies cannot be checked
off
### Dependency Features
- **Flexible Dependencies**: Items can depend on any number of other items
- **Hierarchical Support**: Dependencies work with parent-child relationships
- **Real-time Validation**: Dependency status updates immediately when items are
completed
- **Clear Feedback**: Users see exactly which items need to be completed first
- **Error Prevention**: System prevents circular dependencies automatically
## Item Date Constraints
The application supports date constraints, allowing you to set time windows when
items can be completed.
### How Date Constraints Work
- **Not Before**: Set the earliest time an item can be completed
- **Not After**: Set the latest time an item can be completed
- **Validation**: Items cannot be completed outside their allowed time window
- **Visual Indicators**: Items show date constraint status with color-coded
indicators
- **Real-time Updates**: Constraint status updates in real-time
### Managing Date Constraints
1. **Set Constraints**: Click the clock icon (🕐) on any item to open the date
constraint manager
2. **Configure Times**: Set "not before" and/or "not after" times
3. **Visual Feedback**: Items show constraint status:
- 🟢 Green: Time constraints met (shows "Ready")
- 🔴 Red: Time constraints not met (shows "Time locked")
4. **Completion Prevention**: Items cannot be checked off outside their time
window
### Date Constraint Features
- **Flexible Scheduling**: Set any combination of start and end times
- **ISO 8601 Format**: Uses standard datetime format for precision
- **Real-time Validation**: Constraint status updates immediately
- **Clear Feedback**: Users see exactly when items can be completed
- **Error Prevention**: System prevents completion outside allowed times
### Example Use Cases
- **Meeting Preparation**: Set items to be completed before a meeting starts
- **Deadline Management**: Set items to be completed by a specific deadline
- **Time-sensitive Tasks**: Ensure tasks are completed within business hours
- **Sequential Workflows**: Use in combination with dependencies for complex
workflows
## Development
### Local Development
To run in development mode with automatic reloading, you can use tools like
`air` or `realize`.
#### Using the Development Script
The project includes a development script that runs both backend and frontend
with hot reloading:
```bash
# Start development environment
./dev.sh
```
This will:
- Start the Go backend with Air for hot reloading
- Start the React frontend with Vite for hot reloading
- Proxy API requests from frontend to backend
- Clean up processes on exit
### Docker Development
For a consistent development environment using Docker with hot reloading:
#### Prerequisites
- Docker and Docker Compose installed
- Ports 8080 and 5173 available
#### Quick Start
```bash
# Start development environment with Docker
./dev-docker.sh
```
This will:
- Build a development container with all dependencies
- Mount your source code for hot reloading
- Start both backend (Air) and frontend (Vite) with hot reloading
- Make the application available at:
- Backend: http://localhost:8080
- Frontend: http://localhost:5173
#### Manual Docker Commands
```bash
# Build and start the development container
docker-compose -f docker-compose.dev.yml up --build
# Stop the development container
docker-compose -f docker-compose.dev.yml down
# View logs
docker-compose -f docker-compose.dev.yml logs -f
# Rebuild the container
docker-compose -f docker-compose.dev.yml up --build --force-recreate
```
#### Development Features
The Docker development environment includes:
- **Hot Reloading**: Both Go backend and React frontend reload automatically on
code changes
- **Volume Mounts**: Your local code is mounted into the container for live
editing
- **Dependency Management**: All dependencies are pre-installed in the container
- **Consistent Environment**: Same environment across all developers
- **Easy Cleanup**: Simple commands to start/stop the development environment
#### File Watching
The development container uses:
- **Air** for Go backend hot reloading (watches `.go` files)
- **Vite** for React frontend hot reloading (watches all frontend files)
- **inotify-tools** for efficient file system watching
#### Troubleshooting
If you encounter issues:
1. **Port conflicts**: Ensure ports 8080 and 5173 are not in use
2. **Permission issues**: The container runs with appropriate permissions
3. **Hot reload not working**: Check that your files are being watched by the
respective tools
4. **Container won't start**: Check Docker logs with
`docker-compose -f docker-compose.dev.yml logs`