# 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) - 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" } } ``` **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" } } ``` **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 - `github.com/google/uuid` - UUID generation - `github.com/mattn/go-sqlite3` - SQLite driver for Go ## Database The application uses SQLite with the following schema: - `checklists` table: Stores checklist metadata - `items` table: Stores checklist items with hierarchical relationships ## 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 ## Development To run in development mode with automatic reloading, you can use tools like `air` or `realize`.