Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
Complete MVP implementation of the Cast GHL Conversation Provider bridge: - Go module setup with chi router and mongo-driver dependencies - Config loading with env var validation and defaults - MongoDB token store with upsert, get, update, delete operations - Cast.ph SMS client with 429 retry logic and typed errors - Phone number normalization (E.164 ↔ Philippine local format) - GHL OAuth 2.0 install/callback/refresh flow - GHL webhook handler with ECDSA signature verification (async dispatch) - GHL API client for message status updates and inbound message stubs - Multi-stage Dockerfile, docker-compose with MongoDB, Woodpecker CI pipeline - Unit tests for phone normalization, Cast client, GHL webhook, and OAuth handlers Co-Authored-By: SideKx <sidekx.ai@sds.dev>
120 lines
2.6 KiB
Markdown
120 lines
2.6 KiB
Markdown
# Task 01: Project Initialization
|
|
|
|
## Objective
|
|
Set up the Go project, directory structure, go.mod, and placeholder files.
|
|
|
|
## Steps
|
|
|
|
### 1. Initialize Go module
|
|
```bash
|
|
go mod init github.com/nicknacnic/cast-ghl-provider
|
|
```
|
|
(Adjust module path to match your Gitea repo at git.sds.dev)
|
|
|
|
### 2. Install dependencies
|
|
```bash
|
|
go get github.com/go-chi/chi/v5
|
|
go get go.mongodb.org/mongo-driver/v2/mongo
|
|
```
|
|
|
|
### 3. Create directory structure
|
|
```
|
|
cmd/server/main.go # placeholder: log.Println("cast-ghl-provider starting...")
|
|
internal/config/config.go # placeholder: package config
|
|
internal/ghl/oauth.go # placeholder: package ghl
|
|
internal/ghl/webhook.go # placeholder
|
|
internal/ghl/api.go # placeholder
|
|
internal/ghl/types.go # placeholder
|
|
internal/cast/client.go # placeholder: package cast
|
|
internal/cast/types.go # placeholder
|
|
internal/phone/normalize.go # placeholder: package phone
|
|
internal/store/mongo.go # placeholder: package store
|
|
```
|
|
|
|
### 4. Create `.env.example`
|
|
```env
|
|
PORT=3002
|
|
BASE_URL=https://ghl.cast.ph
|
|
|
|
# GHL OAuth
|
|
GHL_CLIENT_ID=
|
|
GHL_CLIENT_SECRET=
|
|
GHL_WEBHOOK_PUBLIC_KEY=
|
|
GHL_CONVERSATION_PROVIDER_ID=
|
|
|
|
# Cast.ph
|
|
CAST_API_KEY=
|
|
CAST_API_URL=https://api.cast.ph
|
|
CAST_SENDER_ID=
|
|
|
|
# MongoDB
|
|
MONGO_URI=mongodb://localhost:27017/cast-ghl
|
|
|
|
# Inbound (Phase 2)
|
|
INBOUND_API_KEY=
|
|
```
|
|
|
|
### 5. Create `.gitignore`
|
|
```
|
|
.env
|
|
cast-ghl-provider
|
|
/tmp/
|
|
```
|
|
|
|
### 6. Create `Dockerfile` (placeholder)
|
|
```dockerfile
|
|
FROM golang:1.22-alpine AS builder
|
|
WORKDIR /app
|
|
COPY go.mod go.sum ./
|
|
RUN go mod download
|
|
COPY . .
|
|
RUN CGO_ENABLED=0 go build -o /cast-ghl-provider ./cmd/server/
|
|
|
|
FROM alpine:3.19
|
|
RUN apk add --no-cache ca-certificates
|
|
COPY --from=builder /cast-ghl-provider /cast-ghl-provider
|
|
EXPOSE 3002
|
|
CMD ["/cast-ghl-provider"]
|
|
```
|
|
|
|
### 7. Create `docker-compose.yaml`
|
|
```yaml
|
|
services:
|
|
bridge:
|
|
build: .
|
|
ports:
|
|
- "${PORT:-3002}:${PORT:-3002}"
|
|
env_file: .env
|
|
depends_on:
|
|
- mongo
|
|
restart: unless-stopped
|
|
|
|
mongo:
|
|
image: mongo:7
|
|
volumes:
|
|
- mongo-data:/data/db
|
|
restart: unless-stopped
|
|
|
|
volumes:
|
|
mongo-data:
|
|
```
|
|
|
|
### 8. Copy API reference docs
|
|
- Copy `CAST_API_REFERENCE.md` into repo root (from the Cast API docs provided)
|
|
- Create `GHL_API_REFERENCE.md` with the GHL Conversation Provider docs
|
|
|
|
### 9. Verify
|
|
```bash
|
|
go build ./cmd/server/
|
|
go vet ./...
|
|
```
|
|
|
|
## Acceptance Criteria
|
|
- [ ] `go build ./cmd/server/` succeeds
|
|
- [ ] `go vet ./...` passes with no issues
|
|
- [ ] All packages have at least a placeholder file
|
|
- [ ] `.env.example` has all config vars documented
|
|
- [ ] `Dockerfile` builds successfully
|
|
- [ ] `docker-compose.yaml` is valid
|
|
- [ ] `.gitignore` excludes `.env` and binary
|