Commit Graph

11 Commits

Author SHA1 Message Date
SoftwareEngineer
027e9a4a49 Add E2E smoke test — one-command DoD gate (ELF-23 Task 8)
TestSmokeE2E starts a real server and exercises the full product flow:
- Phase 1: Health check (liveness probe)
- Phase 2: Capture all 5 HTTP methods, verify stored
- Phase 3: Inspect page renders HTML with request cards, replay UI, SSE script
- Phase 4: SSE stream receives live events on capture
- Phase 5: Mock configuration and response (set mock → capture returns mock)
- Phase 6: Replay a captured request to a sink server
- Phase 7: Edge cases (query params, binary body, SSRF protection)

The one-command gate: go test ./cmd/hatch -run TestSmokeE2E -v

Also fix .gitignore: the bare 'hatch' entry was matching cmd/hatch/
directory, preventing test files from being tracked. Narrowed to /hatch
(root binary only) and hatch.exe.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-06-22 19:22:56 +02:00
SoftwareEngineer
7668661f74 Add mock handler tests and fix env leakage in main_test.go
- Added TestMockSetsAndConfiguresResponse: verifies PUT /e/{id}/mock stores mock config
- Added TestMockReturnsConfiguredResponseOnCapture: verifies capture returns mock response
  when one is configured, and the request is still recorded
- Added TestMockAutoCreatesEndpointOnSet: verifies mock endpoint auto-creates if missing
- Fixed TestHealthzSmoke to use t.Setenv instead of os.Setenv to prevent env leak

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-06-22 19:13:12 +02:00
SoftwareEngineer
8c5e75b06b feat(inspect): polish server-rendered request list page
- Add formatTime template func for human-readable timestamps (just now, 2m ago, etc.)
- Add client-side formatTimeStr for SSE live-update timestamps
- Fix SSE body rendering: buildRequestBody() populates headers/query/body for live-added requests
- Fix SSE body encoding: use string in sseRequest to avoid base64 encoding of []byte
- Add inspect handler tests: renders HTML, empty state, auto-creates endpoint
- Timestamps include title attr with full ISO timestamp for hover detail
2026-06-22 19:09:58 +02:00
SoftwareEngineer
cf5b2f185c fix(sse): flush response headers before blocking select loop
Without flusher.Flush() after WriteHeader, the HTTP response headers
were buffered and never sent to the client, causing SSE clients to hang
indefinitely waiting for the initial response.

- Add flusher.Flush() after WriteHeader in HandleSSE
- Add TestSSEStreamReceivesEventOnCapture integration test:
  starts test server, subscribes to SSE, captures a request, and
  verifies the event arrives within 2s

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-06-22 19:05:50 +02:00
SoftwareEngineer
4256d34c27 feat: add one-click replay for captured requests
- Add POST /e/{endpoint}/requests/{id}/replay endpoint
- Replay re-sends captured method, path, headers, query, body to target URL
- Response includes target status code, headers, body (truncated 64KB)
- SSRF guard: denies replay to private/loopback by default
- Opt-in env var HATCH_ALLOW_PRIVATE_REPLAY=true for local dev
- Server-rendered inspect page at GET /e/{endpoint} with replay button UI
- SSE live stream for new requests (EventSource)
- Mock configuration at PUT /e/{endpoint}/mock
- Store: GetRequest, GetMock, SetMock methods added
- Chi router migration from stdlib ServeMux
- 26 passing tests including replay unit tests and E2E capture-to-replay

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-06-22 16:58:42 +02:00
Designer
fcfde5660c brand: add Hatch v1 wordmark, mark, favicon, banner, OG image, usage guide
v1 brand kit for the Hatch launch (ELF-53).

Files:
  brand/wordmark/   - text+mark wordmark (SVG with embedded Inter Bold,
                     plus PNG exports at 200x60, 400x120, 800x240,
                     1200x360); light/dark and on-light/on-dark variants
  brand/mark/       - the icon alone, in 16/32/48/64/128/192/256/512/1024
  brand/favicon/    - favicon.ico (16+32+48) and the 5 required PNG sizes
  brand/banner/     - README banner at 1280x640 (+ @2x retina)
  brand/og/         - OG image at 1200x630 (+ @2x retina)
  docs/brand/usage.md - one-pager on spacing, clear space, do-not rules,
                     light/dark mode behavior

Concept:
  Mark is a rounded square with a horizontal slot — the literal "hatch".
  A small "request" indicator drops into the slot. At 16px the slot still
  reads; at 512px the proportions hold.

Type:
  Inter Bold for the wordmark; JetBrains Mono for the code/tagline accent.
  Both SIL OFL 1.1, attributed in docs/brand/usage.md.

Color:
  Ink #0A0A0B, Paper #FAFAF9, Accent #F59E0B. No other colors in the kit.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-06-22 16:46:11 +02:00
SoftwareEngineer
5bbf995f32 Fix capture: endpoint ID/URL mismatch, routing, and extractID
- Use URL as endpoint ID so handler path-segment lookups resolve correctly.
  Previously CreateEndpoint generated a random UUID for the ID, but the
  handler always queries by the path segment — every GetEndpoint call
  missed, causing duplicate UNIQUE violations on subsequent requests
  and orphaned request records (endpoint_id mismatch).

- Register both /{endpoint} and /{endpoint}/ patterns so bare and
  nested capture paths both route to the handler (Go 1.22+ ServeMux).

- Strip query string in extractID for robustness, even though the
  library never sends ? in r.URL.Path.

- Remove unused net/http import from handler_test.go (caught by vet).

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-06-22 14:38:50 +02:00
CTO
90c3f6285d feat: mock endpoint — configure response per endpoint
- Add mock_status, mock_headers, mock_body columns to endpoints schema
- Add MockConfig struct and UpsertMock to Repository interface
- Implement UpsertMock in sqliteRepo (INSERT ON CONFLICT UPDATE)
- Update GetEndpoint to return mock configuration when present
- Add PUT /e/{endpoint_id}/mock handler with JSON body {status, headers, body}
- Add catch-all /{endpoint_id} handler returning mock or default 200
- Header sanitization: only allow Content-Type, Cache-Control, X-*
- Wire handler into cmd/hatch main with SQLite store
- Fix Dockerfile: COPY go.sum for reproducible builds
- Tests: store mock CRUD, handler mock config + header sanitization

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-06-22 14:32:53 +02:00
SoftwareEngineer
bc881dcebb feat: foundation Go module, HTTP server, Docker packaging
- Go module (github.com/elfoundation/hatch) with go 1.25
- cmd/hatch: HTTP server with GET /healthz returning 200 OK
- Multi-stage Dockerfile producing static binary from scratch
- docker-compose with hatch + optional Caddy reverse proxy
- CI placeholder with Go test/lint stubs
- .gitignore, .dockerignore, .env.example

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-06-22 14:31:27 +02:00
CEO
2fa4184a32 Engineering foundation: README, CONTRIBUTING, tech stack, ADR template, onboarding, CI placeholder, first engineer role
Sets up the engineering baseline for El Foundation before product work begins.

- README.md: project overview and repo layout
- CONTRIBUTING.md: branch naming, PR process, commit style, definition of done
- docs/engineering/tech-stack.md: frontend, backend, and tooling choices with rationale
- docs/engineering/onboarding.md: 30-day onboarding checklist
- docs/adrs/adr-template.md: decision record template
- .github/workflows/ci.yml: markdown lint + placeholder for TypeScript checks
- docs/engineering/first-engineer-role.md: scope, skills, 30-day priorities, hire recommendation

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-06-22 05:58:34 +02:00
CEO
7ebc502803 Founding documents: charter, operating model, org structure, ways of working, decision framework
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-06-22 05:41:04 +02:00