Wire API services to PostGIS in docker-compose, broaden CORS handling for cross-origin clients, and align developer docs with the production momswap URL. Made-with: Cursor
This commit is contained in:
@@ -20,7 +20,9 @@ go test ./...
|
||||
go run ./cmd/api
|
||||
```
|
||||
|
||||
Server default: `http://localhost:8080`.
|
||||
Primary deployed base URL: `https://momswap.produktor.duckdns.org/`.
|
||||
|
||||
Local default (for development): `http://localhost:8080`.
|
||||
|
||||
Optional environment variables:
|
||||
|
||||
@@ -35,6 +37,11 @@ Build and run the backend service:
|
||||
COMPOSE_BAKE=true docker compose up --build -d
|
||||
```
|
||||
|
||||
This starts:
|
||||
|
||||
- `db` (`postgis/postgis`) on `5432`
|
||||
- `api` on `8080`, wired with `DATABASE_URL` to the `db` service
|
||||
|
||||
Stop the service:
|
||||
|
||||
```bash
|
||||
@@ -52,6 +59,7 @@ Notes:
|
||||
- `api` service uses the production `runtime` image target.
|
||||
- `api-dev` profile uses the `dev` image target and Docker Compose watch.
|
||||
- Build cache is persisted at `.docker/buildx-cache` via `cache_from`/`cache_to`.
|
||||
- DB defaults can be overridden via `POSTGRES_DB`, `POSTGRES_USER`, `POSTGRES_PASSWORD`.
|
||||
|
||||
## Frontend
|
||||
|
||||
@@ -63,7 +71,10 @@ Example:
|
||||
go run ./cmd/api
|
||||
```
|
||||
|
||||
Then visit `http://localhost:8080/web/`.
|
||||
Then visit:
|
||||
|
||||
- Production: `https://momswap.produktor.duckdns.org/web/`
|
||||
- Local: `http://localhost:8080/web/`
|
||||
|
||||
## API client library
|
||||
|
||||
|
||||
@@ -1,4 +1,23 @@
|
||||
services:
|
||||
db:
|
||||
image: postgis/postgis:17-3.5
|
||||
container_name: momswap-backend-db
|
||||
environment:
|
||||
POSTGRES_DB: "${POSTGRES_DB:-momswap}"
|
||||
POSTGRES_USER: "${POSTGRES_USER:-momswap}"
|
||||
POSTGRES_PASSWORD: "${POSTGRES_PASSWORD:-momswap}"
|
||||
ports:
|
||||
- "5432:5432"
|
||||
volumes:
|
||||
- ./var/posrgres:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-momswap} -d ${POSTGRES_DB:-momswap}"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 10
|
||||
start_period: 10s
|
||||
restart: unless-stopped
|
||||
|
||||
api:
|
||||
build:
|
||||
context: .
|
||||
@@ -13,6 +32,10 @@ services:
|
||||
environment:
|
||||
ADDR: ":8080"
|
||||
ADMIN_PUBLIC_KEY: "${ADMIN_PUBLIC_KEY:-}"
|
||||
DATABASE_URL: "postgres://${POSTGRES_USER:-momswap}:${POSTGRES_PASSWORD:-momswap}@db:5432/${POSTGRES_DB:-momswap}?sslmode=disable"
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
ports:
|
||||
- "8080:8080"
|
||||
restart: unless-stopped
|
||||
@@ -32,6 +55,10 @@ services:
|
||||
environment:
|
||||
ADDR: ":8080"
|
||||
ADMIN_PUBLIC_KEY: "${ADMIN_PUBLIC_KEY:-}"
|
||||
DATABASE_URL: "postgres://${POSTGRES_USER:-momswap}:${POSTGRES_PASSWORD:-momswap}@db:5432/${POSTGRES_DB:-momswap}?sslmode=disable"
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
ports:
|
||||
- "8080:8080"
|
||||
restart: unless-stopped
|
||||
@@ -50,3 +77,4 @@ services:
|
||||
path: ./go.mod
|
||||
- action: rebuild
|
||||
path: ./Dockerfile
|
||||
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
|
||||
This document explains how frontend developers should integrate with the backend through the reusable TypeScript client at `libs/geo-api-client`.
|
||||
|
||||
Primary backend URL for integration:
|
||||
|
||||
- `https://momswap.produktor.duckdns.org/`
|
||||
|
||||
## Goals
|
||||
|
||||
- Keep cryptographic signing logic in one place.
|
||||
@@ -68,7 +72,7 @@ const storageLike = {
|
||||
removeItem: (key: string) => storage.removeItem(key),
|
||||
};
|
||||
|
||||
const client = new GeoApiClient("http://localhost:8080", storageLike);
|
||||
const client = new GeoApiClient("https://momswap.produktor.duckdns.org", storageLike);
|
||||
|
||||
const keys = await client.ensureKeysInStorage();
|
||||
await client.loginWithSignature(keys.publicKey, keys.privateKey);
|
||||
@@ -97,3 +101,5 @@ For no-bundler apps, import the built ESM file:
|
||||
```
|
||||
|
||||
The backend itself serves static UI at `/web/`, but this library can be consumed by any frontend runtime that supports `fetch`, `TextEncoder`, and ES modules.
|
||||
|
||||
For local development you can switch the client base URL to `http://localhost:8080`.
|
||||
|
||||
@@ -45,8 +45,15 @@ func (a *API) Routes() http.Handler {
|
||||
func withCORS(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Access-Control-Allow-Origin", "*")
|
||||
w.Header().Set("Access-Control-Allow-Headers", "Authorization, Content-Type")
|
||||
w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PATCH, DELETE, OPTIONS")
|
||||
w.Header().Set("Vary", "Origin, Access-Control-Request-Method, Access-Control-Request-Headers")
|
||||
w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE, OPTIONS, HEAD")
|
||||
w.Header().Set("Access-Control-Max-Age", "86400")
|
||||
requestHeaders := r.Header.Get("Access-Control-Request-Headers")
|
||||
if requestHeaders != "" {
|
||||
w.Header().Set("Access-Control-Allow-Headers", requestHeaders)
|
||||
} else {
|
||||
w.Header().Set("Access-Control-Allow-Headers", "Authorization, Content-Type, Accept, Origin, X-Requested-With")
|
||||
}
|
||||
if r.Method == http.MethodOptions {
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user