{"id":30882050,"url":"https://github.com/balaji01-4d/my-dear-bug","last_synced_at":"2025-09-08T08:04:47.343Z","repository":{"id":307597699,"uuid":"1028494164","full_name":"Balaji01-4D/my-dear-bug","owner":"Balaji01-4D","description":"A lightweight Go + Gin web platform where developers anonymously share, browse, and upvote real-world coding bugs (“confessions”), with tagging, trending views, rate-limited posting, and PostgreSQL-backed storage.","archived":false,"fork":false,"pushed_at":"2025-09-05T15:38:33.000Z","size":133,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-09-05T17:41:37.590Z","etag":null,"topics":["anonymous","api","backend","bug","bug-reporting","community-platform","confession","fortheloveofcode","gin","gin-gonic","go","golang","postgresql","rate-limiting","rest-api","tags"],"latest_commit_sha":null,"homepage":"https://my-dear-bug.vercel.app","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Balaji01-4D.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-07-29T15:59:31.000Z","updated_at":"2025-09-05T15:17:39.000Z","dependencies_parsed_at":"2025-08-01T05:31:39.287Z","dependency_job_id":"cb916ada-a476-4dda-aa1e-7c31ee3cb61c","html_url":"https://github.com/Balaji01-4D/my-dear-bug","commit_stats":null,"previous_names":["balaji01-4d/my-dear-bug"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Balaji01-4D/my-dear-bug","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Balaji01-4D%2Fmy-dear-bug","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Balaji01-4D%2Fmy-dear-bug/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Balaji01-4D%2Fmy-dear-bug/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Balaji01-4D%2Fmy-dear-bug/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Balaji01-4D","download_url":"https://codeload.github.com/Balaji01-4D/my-dear-bug/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Balaji01-4D%2Fmy-dear-bug/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274152754,"owners_count":25231293,"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","status":"online","status_checked_at":"2025-09-08T02:00:09.813Z","response_time":121,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["anonymous","api","backend","bug","bug-reporting","community-platform","confession","fortheloveofcode","gin","gin-gonic","go","golang","postgresql","rate-limiting","rest-api","tags"],"created_at":"2025-09-08T08:02:59.508Z","updated_at":"2025-09-08T08:04:47.327Z","avatar_url":"https://github.com/Balaji01-4D.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🐛 My Dear Bug\n\n\u003e A modern, lightweight community-driven debugging platform built with Go and Gin\n\n[![Go Version](https://img.shields.io/badge/Go-1.24.2-blue.svg)](https://golang.org)\n[![Gin Framework](https://img.shields.io/badge/Gin-Web%20Framework-green.svg)](https://gin-gonic.com)\n[![PostgreSQL](https://img.shields.io/badge/PostgreSQL-Database-blue.svg)](https://postgresql.org)\n[![License](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)\n\n## Overview\n\nMy Dear Bug is a community platform where developers share real-world issues (\"confessions\"), discover tricky bugs, and help each other debug. Submit a confession with details and code, upvote interesting ones, and explore by language or tags.\n\n## Architecture\n\nClean layered architecture with clear separation of concerns:\n\n```\nControllers → Services → Repositories → Database (PostgreSQL)\n            DTOs ↔ Models\n```\n\n### Project Structure\n```\nshit-happens/\n├── config/                  # Configuration \u0026 DB setup\n│   ├── config.go            # Loads env (DATABASE_URL, PORT) \u0026 InitDB\n│   └── devConfig.go         # .env loader (godotenv) for local dev\n├── internals/\n│   ├── confession/          # Confession (bug report) domain\n│   │   ├── controller.go    # HTTP handlers (/confessions)\n│   │   ├── service.go       # Business logic\n│   │   ├── repository.go    # GORM queries (pagination, filters)\n│   │   ├── model.go         # Confession entity + relations\n│   │   └── dto.go           # Request validation\n│   ├── upvote/              # Upvote domain\n│   │   ├── controller.go    # POST /confessions/:id/upvote\n│   │   ├── service.go       # Upvote logic (+1 counter)\n│   │   ├── repository.go    # HasUpvoted + persist\n│   │   └── model.go         # Upvote entity\n│   ├── tag/                 # Tagging \u0026 suggestions\n│   │   ├── controller.go    # /tags endpoints\n│   │   ├── service.go\n│   │   ├── repository.go\n│   │   └── model.go         # Tag entity\n│   └── middleware/\n│       ├── adminAuth.go     # Basic auth for protected routes\n│       └── rateLimit.go     # Per-IP POST rate limiting\n├── migrate/\n│   ├── migrate.go           # GORM AutoMigrate\n│   └── init.sql             # (Legacy) SQL schema\n├── main.go                  # App entrypoint \u0026 route registration\n├── Makefile                 # build/run/test/fmt tasks\n├── go.mod / go.sum\n└── README.md\n```\n\n## Technology Stack\n\n- Go + Gin web framework\n- PostgreSQL + GORM ORM\n- godotenv (local dev)\n- Make for developer tasks\n\n## API Endpoints\n\n### Confession Management\n- GET  `/confessions` — List with pagination (offset, limit)\n- GET  `/confessions/:id` — Get details\n- POST `/confessions` — Create a confession (rate-limited per IP)\n- DELETE `/confessions/:id` — Delete (admin only)\n\n### Filtering \u0026 Discovery\n- GET `/confessions/language/:language` — Filter by language (case-insensitive)\n- GET `/confessions/top` — Highest upvoted confessions\n- GET `/confessions/trending/weekly` — Trending confessions for the last 7 days\n- GET `/confessions/trending/monthly` — Trending confessions for the last 30 days\n- GET `/confessions/hall-of-fame` — All-time notable (e.g. high-impact) confessions\n- GET `/confessions/random` — Random selection (use for inspiration / shuffle)\n\n### Community Voting\n- POST `/confessions/:id/upvote` — Upvote (deduplicated by IP hash)\n\n### Tags\n- GET `/tags` — List tags\n- POST `/tags` — Create tag\n- GET `/tags/suggest?query=\u003cprefix\u003e` — Autocomplete suggestions\n- DELETE `/tags/:id` — Delete tag (admin only)\n\n### Query Parameters\n- `offset` — Pagination offset (default: 0 if omitted)\n- `limit` — Pagination limit (if omitted, no limit is applied by the DB layer)\n\n## Usage Examples\n\n### Submit a Confession\n```bash\ncurl -X POST http://localhost:8080/confessions \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"title\": \"Deadlock Detected\",\n    \"description\": \"Two goroutines wait on each other causing deadlock\",\n    \"snippet\": \"mutex1.Lock(); mutex2.Lock();\",\n    \"language\": \"go\",\n    \"tags\": [\"concurrency\", \"mutex\"]\n  }'\n```\n\n### Browse Confessions\n```bash\n# Get all with pagination\ncurl \"http://localhost:8080/confessions?limit=10\u0026offset=0\"\n\n# Filter by language\ncurl \"http://localhost:8080/confessions/language/go?limit=5\"\n\n# Highest upvoted\ncurl \"http://localhost:8080/confessions/top?limit=10\"\n\n# Trending this week\ncurl \"http://localhost:8080/confessions/trending/weekly?limit=10\"\n\n# Trending this month\ncurl \"http://localhost:8080/confessions/trending/monthly?limit=10\"\n\n# Hall of fame\ncurl \"http://localhost:8080/confessions/hall-of-fame?limit=10\"\n\n# Random selection\ncurl \"http://localhost:8080/confessions/random\"\n```\n\n### Vote on a Confession\n```bash\ncurl -X POST http://localhost:8080/confessions/1/upvote\n```\n\n### Tag APIs\n```bash\n# List tags\ncurl http://localhost:8080/tags\n\n# Create tag\ncurl -X POST http://localhost:8080/tags -H 'Content-Type: application/json' -d '{\"name\": \"performance\"}'\n\n# Suggest tags (prefix search)\ncurl \"http://localhost:8080/tags/suggest?query=per\"\n```\n\n### Sample Confession Response\n```json\n{\n  \"id\": 1,\n  \"title\": \"Deadlock Detected\",\n  \"description\": \"Two goroutines wait on each other.\",\n  \"language\": \"go\",\n  \"snippet\": \"mutex1.Lock(); mutex2.Lock();\",\n  \"tags\": [{ \"id\": 3, \"name\": \"concurrency\" }],\n  \"sentiment\": \"happy\",\n  \"isFlagged\": false,\n  \"createdAt\": \"2025-08-01T15:05:58.156094+05:30\",\n  \"upvotes\": 15\n}\n```\n\n## Data Models\n\n### Confession\n```go\ntype Confession struct {\n    ID          uint       `json:\"id\"`\n    Title       string     `json:\"title\"`\n    Description string     `json:\"description\"`\n    Language    string     `json:\"language\"`\n    Snippet     string     `json:\"snippet\"`\n    Tags        []tag.Tag  `json:\"tags\"`           // many2many: confession_tags\n    Sentiment   string     `json:\"sentiment\"`\n    IsFlagged   bool       `json:\"isFlagged\"`\n    CreatedAt   time.Time  `json:\"createdAt\"`\n    Upvotes     int        `json:\"upvotes\"`\n}\n```\n\n### Upvote\n```go\ntype Upvote struct {\n    ID           uint      `json:\"id\"`\n    ConfessionID uint      `json:\"confessionId\"`\n    IPHash       string    `json:\"-\"`           // privacy protected\n    CreatedAt    time.Time `json:\"createdAt\"`\n}\n```\n\n### Tag\n```go\ntype Tag struct {\n    ID   uint   `json:\"id\"`\n    Name string `json:\"name\"` // unique\n}\n```\n\n## Security \u0026 Middleware\n\n- IP-based upvote deduplication (SHA-256 hash of client IP)\n- Admin authentication (Basic Auth) for DELETE endpoints\n- Rate limiting: 10 POSTs/hour per IP (burst 3) on confession creation\n\n## Development\n\n### Prerequisites\n- Go 1.24.2+\n- PostgreSQL\n- Git\n\n### Install \u0026 Run\n1) Install dependencies\n```bash\nmake install-deps\n```\n\n2) Configure environment (.env)\n```env\nDATABASE_URL=postgres://username:password@localhost:5432/shithappens?sslmode=disable\nPORT=:8080\nADMIN_USERNAME=admin\nADMIN_PASSWORD=supersecret\n```\n\n3) Run migrations\n```bash\ngo run migrate/migrate.go\n```\n\n4) Start the API\n```bash\nmake run\n```\nAPI: http://localhost:8080\n\n### Available Commands\n```bash\nbuild                Build the application binary\nfmt                  Format Go code\nhelp                 Show all available commands\ninstall-deps         Install all Go dependencies\nrun                  Start the development server\ntest                 Run the test suite\n```\n\n### Development Workflow\n1. Make changes\n2. make fmt\n3. make test\n4. make run\n5. Open a PR\n\n## Configuration Notes\n\n- The server address is read from `PORT` (e.g., `:8080`)\n- Gin is started in release mode by default in `main.go`\n- Migrations use GORM AutoMigrate for `Confession` and `Upvote` (and will create tag relations)\n\n## Testing\n\n```bash\nmake test\n# with coverage\ngo test -cover ./...\n```\n\n## Deployment\n\n- Set `PORT` appropriately for your environment\n- Use environment variables for secrets (no hardcoding)\n- Configure reverse proxy and TLS as needed\n\n## Roadmap\n\n- User authentication \u0026 profiles\n- Email notifications\n- Advanced search \u0026 filters\n- Mobile-friendly endpoints\n- Swagger/OpenAPI docs\n- Real-time updates (WebSockets)\n\n---\n\n\u003cdiv align=\"center\"\u003e\nBuilt with ❤️ by the My Dear Bug community\n\u003c/div\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbalaji01-4d%2Fmy-dear-bug","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbalaji01-4d%2Fmy-dear-bug","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbalaji01-4d%2Fmy-dear-bug/lists"}