{"id":22728799,"url":"https://github.com/scottmckendry/ccinvoice","last_synced_at":"2026-02-14T21:06:59.728Z","repository":{"id":204843273,"uuid":"712761662","full_name":"scottmckendry/ccinvoice","owner":"scottmckendry","description":"A mobile-first invoice generation system for Canine Club - a dog walking business 🐕","archived":false,"fork":false,"pushed_at":"2024-12-02T22:20:24.000Z","size":594,"stargazers_count":48,"open_issues_count":0,"forks_count":5,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-12-10T17:17:49.583Z","etag":null,"topics":["fiber","go","golang","htmx"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/scottmckendry.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-11-01T06:13:39.000Z","updated_at":"2024-12-02T22:20:21.000Z","dependencies_parsed_at":"2024-02-07T21:46:04.540Z","dependency_job_id":"a3e0e8d6-598f-4f50-853f-79dbfa8d519d","html_url":"https://github.com/scottmckendry/ccinvoice","commit_stats":null,"previous_names":["scottmckendry/ccinvoice"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scottmckendry%2Fccinvoice","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scottmckendry%2Fccinvoice/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scottmckendry%2Fccinvoice/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scottmckendry%2Fccinvoice/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/scottmckendry","download_url":"https://codeload.github.com/scottmckendry/ccinvoice/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230501172,"owners_count":18236061,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["fiber","go","golang","htmx"],"created_at":"2024-12-10T17:17:58.562Z","updated_at":"2026-02-06T08:10:28.446Z","avatar_url":"https://github.com/scottmckendry.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003e💸 Canine Club Invoicing System 💸\u003c/h1\u003e\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://github.com/scottmckendry/ccinvoice/releases/latest\"\u003e\n        \u003cimg alt=\"GitHub release (latest by date)\" src=\"https://img.shields.io/github/v/release/scottmckendry/ccinvoice?style=for-the-badge\u0026logo=github\u0026color=%235ef1ff\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://github.com/scottmckendry/ccinvoice/actions/workflows/cicd.yml\"\u003e\n        \u003cimg alt=\"GitHub Workflow Status (with event)\" src=\"https://img.shields.io/github/actions/workflow/status/scottmckendry/ccinvoice/cicd.yml?style=for-the-badge\u0026logo=github\u0026label=CICD\u0026color=%235ea1ff\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://github.com/scottmckendry/ccinvoice/blob/main/LICENSE\"\u003e\n        \u003cimg alt=\"License\" src=\"https://img.shields.io/github/license/scottmckendry/ccinvoice?style=for-the-badge\u0026logo=github\u0026color=%239ece6a\"\u003e\n    \u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n    A mobile-first web application I built for my wife's dog-walking business. Built with \u003ca href=\"https://go.dev\"\u003eGo\u003c/a\u003e and \u003ca href=\"https://htmx.org\"\u003eHTMX\u003c/a\u003e\u003cbr\u003e\u003cbr\u003e\n    \u003cimg alt=\"demo\" src=\"https://github.com/scottmckendry/ccinvoice/assets/39483124/cccc727d-b9b2-419b-9766-20116f1b2c87\"\u003e\n\u003c/p\u003e\n\n## 🚀 Deploying\n\nTo run the app in a docker container, you'll need to create a `.env` file in the root directory with the following environment variables:\n\n```env\nDATABASE_URL=postgres://user:password@host:5432/dbname?sslmode=disable\nSMTP_HOST=smtp.example.com\nSMTP_PORT=587\nSMTP_USER=john@example.com\nSMTP_PASS=P@ssw0rd\nFROM_NAME=John Doe\nFROM_ADDRESS=4 Privet Drive, Little Whinging, Surrey\nFROM_CITY=London\nACCOUNT_NUMBER=12-3456-7890123-45\nBASE_URL=http://invoices.example.com\n```\n\nI recommend using a docker-compose file to run the app. Here's an example:\n\n```yaml\nservices:\n    db:\n        image: postgres:18-alpine\n        restart: unless-stopped\n        environment:\n            POSTGRES_USER: ccinvoice\n            POSTGRES_PASSWORD: ccinvoice\n            POSTGRES_DB: ccinvoice\n        volumes:\n            - postgres_data:/var/lib/postgresql/data\n        healthcheck:\n            test: [\"CMD-SHELL\", \"pg_isready -U ccinvoice\"]\n            interval: 10s\n            timeout: 5s\n            retries: 5\n\n    app:\n        image: ghcr.io/scottmckendry/ccinvoice:main\n        container_name: invoices\n        depends_on:\n            db:\n                condition: service_healthy\n        env_file:\n            - .env\n        environment:\n            DATABASE_URL: postgres://ccinvoice:ccinvoice@db:5432/ccinvoice?sslmode=disable\n        ports:\n            - 3000:3000\n        restart: unless-stopped\n\nvolumes:\n    postgres_data:\n```\n\nThis will run the app on port 3000 with a PostgreSQL database. The database data will be persisted in a Docker volume. I recommend using [Traefik](https://traefik.io) as a reverse proxy. Take a look at my [setup guide](https://scottmckendry.tech/traefik-setup/) for more information.\n\n\u003e [!WARNING]\\\n\u003e Do not expose the app to the internet without a reverse proxy running authentication middleware. The app does not have any authentication built in.\n\n## 🧑‍💻 Development\n\nTo run the app locally, create a `.env` file matching the example above. Then use the docker-compose file in the root of the repository by running `docker compose up`. This will run the app on port 3000. You can then access the app at [http://localhost:3000](http://localhost:3000).\n\nThe project uses [air](https://github.com/cosmtrek/air) for live reloading. To run the app locally without docker, run `air` in the root of the repository.\n\n## 🤝 Contributing\n\nPull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscottmckendry%2Fccinvoice","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fscottmckendry%2Fccinvoice","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscottmckendry%2Fccinvoice/lists"}