data | ||
frontend | ||
.air.toml | ||
.dockerignore | ||
.gitignore | ||
build-container.sh | ||
Containerfile | ||
demo.sh | ||
docker-compose.yml | ||
go.mod | ||
go.sum | ||
main.go | ||
README.md |
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
- Initial Connection: When a client connects to a checklist, the SSE endpoint sends the complete current state
- Real-time Updates: All subsequent changes (add, update, delete, lock) are broadcast via SSE
- 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
-
Initialize the Go module (already done):
go mod init gocheck
-
Install dependencies:
go mod tidy
-
Build the application:
go build
-
Run the server:
./gocheck
Or use the demo script for a guided experience:
./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:
# 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)
# 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 Docker
# 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, distroless for runtime
- Minimal footprint: Runtime container is only ~2MB
- Persistent data: SQLite database is stored in a named volume
- Security: Runs as non-root user in distroless container
- Configurable: Supports environment variables for customization
Environment Variables
PORT
: Set the port the application listens on (default: 8080)# 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
# 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
- Start the backend server:
./gocheck
- Start the frontend dev server:
cd frontend && npm run dev
- Access the app at:
http://localhost:5173
(frontend dev server) - 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 checklistPOST /api/checklists/{uuid}/items
- Add an item to a checklistPATCH /api/checklists/{uuid}/items/{id}
- Update an itemDELETE /api/checklists/{uuid}/items/{id}
- Delete an itemPOST /api/checklists/{uuid}/items/{id}/lock
- Lock an item for editingGET /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:
{
"success": true,
"message": "Operation completed successfully"
// ... additional data specific to the endpoint
}
Example Responses
Create Checklist:
{
"success": true,
"message": "Checklist created successfully",
"uuid": "123e4567-e89b-12d3-a456-426614174000"
}
Add Item:
{
"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:
{
"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:
{
"success": true,
"message": "Item deleted successfully",
"id": 1
}
Lock Item:
{
"success": true,
"message": "Item locked successfully",
"id": 1,
"locked_by": "user123",
"expires": "2024-01-01T12:00:00Z"
}
Get Items:
{
"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 generationgithub.com/mattn/go-sqlite3
- SQLite driver for Go
Database
The application uses SQLite with the following schema:
checklists
table: Stores checklist metadataitems
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
.