No description
  • TypeScript 51.6%
  • Go 47.7%
  • CSS 0.3%
  • JavaScript 0.2%
  • Dockerfile 0.1%
  • Other 0.1%
Find a file
dtecx 654e2173b5
Some checks failed
CI / checks (push) Has been cancelled
docs: update README.md
2026-05-10 14:45:02 +02:00
.github/workflows inital react structure 2026-05-05 00:58:03 +02:00
cmd feat: add validated demo catalog init 2026-05-09 23:37:35 +02:00
docs feat: add validated demo catalog init 2026-05-09 23:37:35 +02:00
frontend fix(frontend): hero readability, admin overflow, revenue truncation, broken hash link 2026-05-10 10:57:10 +00:00
init docs: update README.md 2026-05-10 14:45:02 +02:00
internal feat: add validated demo catalog init 2026-05-09 23:37:35 +02:00
.dockerignore inital react structure 2026-05-05 00:58:03 +02:00
.env.example feat: add validated demo catalog init 2026-05-09 23:37:35 +02:00
.gitignore updated init mice 2026-05-10 13:47:36 +02:00
AGENTS.md docs: mark phases 20 + 21 complete in AGENTS.md 2026-05-10 10:39:16 +00:00
compose.yaml feat: add validated demo catalog init 2026-05-09 23:37:35 +02:00
Dockerfile feat: add validated demo catalog init 2026-05-09 23:37:35 +02:00
go.mod feat: use bcrypt password hashing 2026-05-04 13:47:57 +02:00
go.sum feat: use bcrypt password hashing 2026-05-04 13:47:57 +02:00
README.md docs: update README.md 2026-05-10 14:45:02 +02:00

Clicky-Store

A focused e-commerce sandbox for gaming and office mice — built with Go on the back, React on the front.

Go React TypeScript Tailwind CSS Vite PostgreSQL Docker CI


Clicky-Store is an educational online shop. It carries two product categories — gaming and office — and ships with the full e-commerce loop: browse, search, view a dedicated product page, add to cart, place an order, simulate payment, and manage everything from an admin dashboard.

Backend is plain net/http Go with a hexagonal layout (domains / ports / adapters). Frontend is a Vite-built React SPA in TypeScript, styled with Tailwind 4 and served by the same Go binary in production. PostgreSQL handles persistence; an in-memory store is the dev-only fallback.


Highlights

Customer Admin Platform
Browse, search, sort, filter Product CRUD with sectioned form PostgreSQL persistence
Dedicated product pages by slug JPEG/PNG image upload (drag-and-drop, max 10 / product) In-memory fallback for tests
Image gallery with thumbnails Image reorder, primary, alt text, delete HMAC-signed bearer tokens
Quantity controls + sticky mobile buy bar Order browsing, filtering, status badges Bcrypt password hashing
Cart, checkout, order placement User browsing + role updates Login rate limiting
Simulated payment (success/failure) Dashboard with revenue + low-stock alerts Local upload storage with safe filename gen
Auth + protected routes Server-side category whitelist (gaming / office) Multi-stage Docker build

Quick start (Docker Compose)

git clone <your-fork-url> clicky-store
cd clicky-store
cp .env.example .env          # optional — defaults work for local dev
docker compose up --build

The storefront and API both serve from one container at:

http://localhost:8080

Health probe:

curl http://localhost:8080/healthz

Seeded admin account (development only):

email:    admin@clicky.local
password: admin12345

Heads up. Outside APP_ENV=development the seeded admin is disabled and AUTH_SECRET must be set to a non-demo value. See docs/deployment.md.


Local dev (without Docker)

Three terminals — Postgres in Compose, the Go backend, and the Vite dev server with API proxy:

# 1. Database
docker compose up db

# 2. Backend
go run ./cmd/server

# 3. Frontend
cd frontend
npm install
npm run dev

The Vite dev server proxies /api/v1, /uploads, and /healthz to localhost:8080, so the SPA at http://localhost:5173 talks to the running Go backend without CORS gymnastics.


Tech stack

Backend     Go 1.25 · net/http · pgx · golang.org/x/crypto
Frontend    React 19 · Vite 8 · TypeScript · Tailwind CSS 4 · React Router 7 · lucide-react
Storage     PostgreSQL 16 (memory fallback)
Auth        HMAC-signed bearer tokens · bcrypt password hashing
DevOps      Docker · Docker Compose · multi-stage build · GitHub Actions CI

API surface

Public endpoints
GET  /healthz
GET  /api/v1/products
GET  /api/v1/products/{productId}
GET  /api/v1/products/slug/{slug}
POST /api/v1/auth/register
POST /api/v1/auth/login
Customer endpoints (Bearer token)
GET    /api/v1/me
GET    /api/v1/cart
POST   /api/v1/cart/items
PATCH  /api/v1/cart/items/{productId}
DELETE /api/v1/cart/items/{productId}
GET    /api/v1/orders
POST   /api/v1/orders
POST   /api/v1/orders/{orderId}/payment/simulate
Admin endpoints (admin role required)
GET    /api/v1/admin/products
POST   /api/v1/admin/products
PATCH  /api/v1/admin/products/{productId}
DELETE /api/v1/admin/products/{productId}
POST   /api/v1/admin/products/{productId}/images
PATCH  /api/v1/admin/products/{productId}/images/order
PATCH  /api/v1/admin/products/{productId}/images/{imageId}
DELETE /api/v1/admin/products/{productId}/images/{imageId}
GET    /api/v1/admin/orders
GET    /api/v1/admin/users
GET    /api/v1/admin/users/{userId}
PATCH  /api/v1/admin/users/{userId}

The OpenAPI spec lives in docs/openapi.yaml. Runnable curl recipes live in docs/api-examples.md.


Example flow

# Register
curl -sS -X POST http://localhost:8080/api/v1/auth/register \
  -H "Content-Type: application/json" \
  -d '{"name":"Test User","email":"test@example.com","password":"password123"}'

# Browse
curl -sS http://localhost:8080/api/v1/products | jq

# Direct product lookup by slug
curl -sS http://localhost:8080/api/v1/products/slug/viper-x1-gaming-mouse | jq

# Add to cart
curl -sS -X POST http://localhost:8080/api/v1/cart/items \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{"productId":"prod-gaming-viper","quantity":1}'

# Place order
curl -sS -X POST http://localhost:8080/api/v1/orders \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{"paymentMethod":"simulation"}'

# Simulate payment success or failure
curl -sS -X POST http://localhost:8080/api/v1/orders/<order-id>/payment/simulate \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{"result":"success"}'   # or "failure"

Project structure

clicky-store/
├── cmd/
│   ├── server/                  HTTP server composition root
│   └── initcatalog/             Manual validator for init/init.json
├── internal/
│   ├── adapters/
│   │   ├── db/                  In-memory store + contract tests
│   │   ├── db/postgres/         PostgreSQL adapter + embedded migrations
│   │   ├── http/v1/             REST API v1 handlers, requests, middleware
│   │   └── uploads/             Local product image upload storage
│   ├── core/
│   │   ├── domains/             Domain models, validation, shared errors
│   │   └── ports/               Storage interfaces
│   ├── service/                 Application use cases + auth
│   ├── frontend/                React build serving adapter
│   ├── initcatalog/             Validated demo catalog loader
│   ├── config/                  Environment loading + production secret guards
│   └── web/                     Shared HTTP / JSON / middleware helpers
├── frontend/
│   ├── src/                     React + TS source (pages, components, state, API)
│   └── public/assets/products/  Seed product SVGs shipped with the build
├── init/                        Demo catalog JSON + ignored local image source folder
├── docs/                        OpenAPI + dev/deploy/API docs
├── compose.yaml                 Local API + PostgreSQL services
├── Dockerfile                   Multi-stage React + Go production image
└── AGENTS.md                    Contributor + AI-agent guidance + roadmap

Catalog model

Two categories, server-side enforced:

gaming    High-DPI competitive picks
office    Quiet, ergonomic desk mice

Demo catalog seeding is opt-in. Drop matching JPG/PNG files into init/img/{slug}/ to match the entries in init/init.json, then start the server. The initializer validates every JSON field plus every referenced image (extension, MIME sniff, decoded headers, size). If anything fails validation, the original four fallback products remain.

# Validate the demo catalog locally
go run ./cmd/initcatalog -path init/init.json

Documentation

docs/
├── openapi.yaml         Machine-readable API spec
├── api-examples.md      Curl recipes
├── development.md       Local dev workflow + env vars
└── deployment.md        Production deploy + secrets + upload storage

AGENTS.md is the source of truth for contributor and AI-agent rules — design tokens, do/don't lists, phase plans, commit conventions.


Status

Educational project. No license file is attached; treat the repository as "look, learn, fork — no production warranty." Security limitations are documented honestly in AGENTS.md and docs/deployment.md.

CI runs gofmt, go test, go vet, the frontend lint + build, and a full Docker image build on every push to main and every pull request.