diff --git a/.sisyphus/plans/docker-swagger-fix.md b/.sisyphus/plans/docker-swagger-fix.md new file mode 100644 index 0000000..3441661 --- /dev/null +++ b/.sisyphus/plans/docker-swagger-fix.md @@ -0,0 +1,146 @@ +# Docker Build Fix — Swagger docs.go Not Found + +## TL;DR + +> **Quick Summary**: The Swagger-generated file `docs/docs.go` is `.gitignore`-d, so Docker build fails with `no required module provides package .../docs`. Fix: add `swag init` step in the Dockerfile builder stage so docs are generated during build before compilation. +> +> **Deliverables**: +> - Dockerfile updated with `swag init` before `go build` +> - Docker build succeeds without error +> +> **Estimated Effort**: Trivial (single-line addition) +> **Parallel Execution**: N/A (single task) + +--- + +## Context + +### Original Request +Docker build fails with: +``` +main.go:17:2: no required module provides package git.datadunia.com/nexusguard/nexus-server-core/docs +``` + +Root cause: `apps/server-core/.gitignore` (lines 40-43) ignores `docs/docs.go`, `docs/swagger.json`, `docs/swagger.yaml`. These files were generated locally by `swag init` but are gitignored. When `docker build` runs `COPY . .`, these files are not included, so the Go compilation fails because `main.go` has `_ "git.datadunia.com/nexusguard/nexus-server-core/docs"`. + +### Metis Analysis +- Must pin swag CLI version to match `go.mod`: `v1.16.6` +- Must keep `.gitignore` as-is (generated files should not be tracked) +- No other files cause similar issues — audit confirmed +- Build tag approach is unnecessary complexity + +--- + +## Work Objectives + +### Core Objective +Make Docker build succeed with Swagger docs generated during build process. + +### Must Have +- [ ] `apps/server-core/Dockerfile` runs `swag init` before `go build` +- [ ] `swag init` uses pinned CLI version matching `go.mod` (`v1.16.6`) +- [ ] `docker compose build server-core` passes + +### Must NOT Have +- Do NOT remove swagger files from `.gitignore` +- Do NOT restructure `main.go` with build tags +- Do NOT modify Makefile or any other files + +--- + +## Execution Strategy + +Single task, no waves needed. + +--- + +## TODOs + +- [ ] 1. Fix Dockerfile — Add `swag init` in builder stage + + **What to do**: + - Edit `apps/server-core/Dockerfile` + - Between `COPY . .` and `RUN CGO_ENABLED=0 go build -o /app/server-core .`, add: + ```dockerfile + RUN go install github.com/swaggo/swag/cmd/swag@v1.16.6 && swag init -g main.go --parseDependency --parseInternal + ``` + - This runs `swag` CLI pinned to v1.16.6 (matching `go.mod`), generates `docs/docs.go`, then Go compliation finds the package. + + **Final Dockerfile should look like:** + ```dockerfile + # Stage 1: Builder + FROM golang:1.25-alpine AS builder + WORKDIR /app + COPY go.mod go.sum ./ + RUN go mod download + COPY . . + RUN go install github.com/swaggo/swag/cmd/swag@v1.16.6 && swag init -g main.go --parseDependency --parseInternal + RUN CGO_ENABLED=0 go build -o /app/server-core . + ``` + + **Recommended Agent Profile**: + - **Category**: `quick` + - **Skills**: `[]` + + **Parallelization**: Single task + + **References**: + - `apps/server-core/Dockerfile` — Current Dockerfile (multi-stage, golang:1.25-alpine) + - `apps/server-core/.gitignore:40-43` — Lines that gitignore swagger output + - `apps/server-core/main.go:17` — Import of `_ "docs"` package + + **Acceptance Criteria**: + - [ ] `docker build -f apps/server-core/Dockerfile -t test-fix apps/server-core` succeeds (exit 0) + - [ ] Swagger route `/swagger/index.html` works when container runs + + **QA Scenarios**: + + ``` + Scenario: Docker build succeeds with swagger docs generated + Tool: Bash + Preconditions: Docker is installed, at project root + Steps: + 1. docker build -f apps/server-core/Dockerfile -t nexusguard-server-core apps/server-core + 2. echo "Exit: $?" + Expected Result: Build completes without errors (exit 0) + Failure Indicators: Error about missing docs package + Evidence: .sisyphus/evidence/task-1-docker-build-success.txt + + Scenario: Make not installed — fallback works + Tool: Bash + Preconditions: make is NOT installed (simulate with `which make || true`) + Steps: + 1. docker compose build server-core + 2. docker compose up -d + Expected Result: Services start without requiring `make` + Failure Indicators: `make: command not found` blocks deployment + Evidence: .sisyphus/evidence/task-1-direct-docker-compose.txt + ``` + +--- + +## Final Verification + +- [ ] F1. **Verify Docker Build** — Run `docker build` and confirm exit 0 +- [ ] F2. **Verify Swagger** — Start container, `curl http://localhost:8080/swagger/index.html` returns 200 +- [ ] F3. **Verify Clean Environment** — Simulate fresh clone + build + +--- + +## Commit Strategy + +- **1**: `fix(server-core): generate swagger docs in Docker build step` + +--- + +## Success Criteria + +```bash +# Fix: Docker build +docker build -f apps/server-core/Dockerfile -t nexusguard-server-core apps/server-core +# Expected: Build successful, exit 0 + +# Verify no more make dependency +docker compose build server-core && docker compose up -d +# Expected: Services start +``` diff --git a/.sisyphus/plans/nxg-fix-cors.md b/.sisyphus/plans/nxg-fix-cors.md deleted file mode 100644 index 8f5348e..0000000 --- a/.sisyphus/plans/nxg-fix-cors.md +++ /dev/null @@ -1,108 +0,0 @@ -# Plan: Fix CORS Configuration - -**Scope**: Trivial — 3 files, ~20 lines -**Goal**: Ensure server-core CORS properly accepts requests from frontend origins, configurable via `CORS_ALLOWED_ORIGINS` env var, documented in `.env.example`. - ---- - -## Context - -Current CORS config in `main.go:114-130`: -- Uses `CORS_ALLOWED_ORIGINS` env var (defaults to `*`) -- Has BOTH `AllowOrigins` AND `AllowOriginFunc` — redundant -- `strings.Contains(corsOrigins, origin)` is weak (substring match: `"example.com"` matches `"notexample.com"`) -- `AllowCredentials: true` is needed for JWT `Authorization` header -- `CORS_ALLOWED_ORIGINS` is NOT documented in any `.env.example` file -- `SHARE_LINK_TTL` (from Phase 5.0) also missing from `.env.example` - ---- - -## Task 1: Fix CORS config in `main.go` -- [x] **File**: `apps/server-core/main.go` lines 114-130 - -**Replace** the current CORS block with: - -```go -// CORS Configuration -corsOrigins := os.Getenv("CORS_ALLOWED_ORIGINS") -if corsOrigins == "" { - corsOrigins = "*" -} - -corsConfig := cors.Config{ - AllowMethods: []string{"GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"}, - AllowHeaders: []string{"Origin", "Content-Length", "Content-Type", "Authorization", "X-Admin-Key", "X-Device-Token"}, - ExposeHeaders: []string{"Content-Length"}, - AllowCredentials: true, -} - -if corsOrigins == "*" { - // Wildcard: allow all origins but use AllowOriginFunc so the response - // header echoes the actual origin (required when AllowCredentials=true). - corsConfig.AllowOriginFunc = func(origin string) bool { - return true - } -} else { - // Explicit list: split by comma, trim spaces, exact match only. - origins := strings.Split(corsOrigins, ",") - for i := range origins { - origins[i] = strings.TrimSpace(origins[i]) - } - corsConfig.AllowOrigins = origins -} - -r.Use(cors.New(corsConfig)) -``` - -**Key changes**: -1. Remove simultaneous `AllowOrigins` + `AllowOriginFunc` (pick one based on `*` vs explicit) -2. When `*`: use `AllowOriginFunc` returning `true` → gin-contrib/cors echoes the requesting origin (compatible with `AllowCredentials: true`) -3. When explicit: use `AllowOrigins` with trimmed values, exact match (no more `strings.Contains` substring bug) - -**Verify**: `go build ./...` passes - ---- - -## Task 2: Add `CORS_ALLOWED_ORIGINS` to root `.env.example` -- [x] **File**: `.env.example` - -**Add** after `VITE_API_BASE_URL` line (section 5): - -```env -# 7. CORS Configuration -# Comma-separated list of allowed origins for the API. -# Use '*' to allow all origins (NOT recommended for production). -# Example: https://dash.yourdomain.com,https://admin.yourdomain.com -CORS_ALLOWED_ORIGINS=http://localhost:5173 - -# 8. Share Link Configuration -# TTL for peer config share links (Go duration format) -SHARE_LINK_TTL=24h -``` - ---- - -## Task 3: Add `CORS_ALLOWED_ORIGINS` to server-core `.env.example` -- [x] **File**: `apps/server-core/.env.example` - -**Add** at the end: - -```env -# CORS -# Comma-separated allowed origins. '*' = allow all (not recommended for production) -CORS_ALLOWED_ORIGINS=http://localhost:5173 - -# Share Link TTL (Go duration format) -SHARE_LINK_TTL=24h -``` - -**Verify**: all `.env.example` files contain `CORS_ALLOWED_ORIGINS` - ---- - -## Final Verification Wave - -- [x] `go build ./...` passes in `apps/server-core/` -- [x] `CORS_ALLOWED_ORIGINS` present in root `.env.example` -- [x] `CORS_ALLOWED_ORIGINS` present in `apps/server-core/.env.example` -- [x] No other files reference `CORS_ALLOWED_ORIGINS` that need updating