# restxlsx — Task Progress & Decisions ## Architecture Decisions | Decision | Choice | Rationale | |---|---|---| | Language | Go 1.24 | Cross-platform, single-binary, great HTTP/stdlib | | Excel parsing | `excelize/v2` | The de-facto Go xlsx library, full read/write support | | HTTP router | `go-chi/chi/v5` | Lightweight, idiomatic, stdlib-compatible, middleware-friendly | | GraphQL | `graphql-go/graphql` | Pure Go, no code-gen, dynamic schema from data | | OpenAPI generation | Manual struct-to-spec | Schema is dynamic (based on xlsx tables), no code-gen tool fits | | Swagger UI | Embedded static files | Serves swagger-ui in debug mode via `embed` | | Logging | `log/slog` (stdlib) | Structured logging, no deps, configurable levels | | Config | `flag` + env vars | Zero-dependency, clean; flags override env vars override defaults | | ID field | First column of each table | Simple convention; assumed to be unique | | Data storage | In-memory (read from xlsx at startup) | No external DB needed; lightweight proxy to the file | | GraphQL schema | Dynamic per-table | Generated at startup from the xlsx table structure | | xlsx generation | Python + openpyxl | Best Python library for creating rich xlsx files | ## Completed Tasks - [x] Plan architecture & create tasks.md - [x] Generate sample xlsx file with tables (Employees, Products, Orders) - [x] Initialize Go module & install dependencies (chi, excelize, graphql-go) - [x] Implement configuration (CLI flags + env vars: --file, --port, --debug, --quiet, --log-reads, --log-file) - [x] Implement logging (stdout via slog, --quiet suppresses, RESTXLSX_LOG_READS=false skips reads) - [x] Implement Excel file parsing engine (open, list tables, read/write rows, flush to disk) - [x] Implement RESTful CRUD API endpoints (GET/POST/PUT/DELETE per table) - [x] Implement GraphQL endpoint (dynamic Query type with get_/list_/create_ per table) - [x] Implement dynamic OpenAPI spec + Swagger UI (/openapi.json, /swagger in debug mode) - [x] Wire everything in main.go (chi router, graceful shutdown, signal handling) - [x] Build and test the service (all endpoints verified with curl) - [x] Create multi-stage Dockerfile (scratch image, 8080 exposed) - [x] Add auth middleware with admin/writer/reader roles - [x] Change default host to localhost:3000, add --host flag - [x] Add /api/sql endpoint (basic SQL query translation) - [x] Add /api/ddl/* endpoints (create/drop tables and sheets) - [x] Add JSON Content-Type middleware - [x] Wire auth into all endpoints (REST, GraphQL, SQL, DDL) - [x] Change default auth from admin to writer - [x] Create comprehensive README.md with configuration docs ## Log ### 2026-06-10 Initial Build - Created full Go project from scratch - Used Python/openpyxl to generate sample.xlsx with 3 tables - All deps: chi v5.3.0, excelize v2.10.1, graphql-go v0.8.1 - REST API, GraphQL, OpenAPI, Swagger UI all verified working - Config via flags/env vars with sensible defaults - Graceful shutdown on SIGINT/SIGTERM - Multi-stage Dockerfile included ### 2026-06-10 Auth, SQL, DDL, README - Added `--auth` flag (admin/writer/reader) with middleware enforcement - Changed default port to 3000, added `--host` flag (default localhost) - Added `POST /api/sql` endpoint with minimal SQL parser (SELECT, INSERT, UPDATE, DELETE) - Added DDL endpoints under `/api/ddl/` for create/drop sheets and tables - Added JSON Content-Type middleware for consistent API responses - Changed default auth role from admin to writer - Enhanced OpenAPI spec with SQL and DDL endpoints, server URL fix - Created comprehensive README.md with config tables, auth docs, OIDC integration path ## Usage ```bash # Run directly ./restxlsx --file data/sample.xlsx --port 8080 # With debug mode (enables /openapi.json and /swagger) ./restxlsx --debug # Quiet mode (no stdout) ./restxlsx --quiet # Or via env vars RESTXLSX_FILE=data/sample.xlsx RESTXLSX_DEBUG=true ./restxlsx ``` ## Endpoints | Method | Path | Description | |---|---|---| | GET | /health | Health check | | GET | /api/tables | List discovered tables | | GET | /api/{table} | List records | | POST | /api/{table} | Create record | | GET | /api/{table}/{id} | Get record | | PUT | /api/{table}/{id} | Update record | | DELETE | /api/{table}/{id} | Delete record | | POST | /graphql | GraphQL query | | GET | /openapi.json | OpenAPI spec (debug only) | | GET | /swagger | Swagger UI (debug only) |