# 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`