From 8529d1e8635b6b70a409505fcd9a4f1aad186b3f Mon Sep 17 00:00:00 2001 From: Addison Emig Date: Wed, 22 Oct 2025 19:32:57 +0000 Subject: [PATCH 1/4] docs: basic spec --- AGENTS.md | 24 +++++++++++++++--------- specs/18-typescript-sdk.md | 27 +++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 9 deletions(-) create mode 100644 specs/18-typescript-sdk.md diff --git a/AGENTS.md b/AGENTS.md index 7922c96..1a01787 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -27,23 +27,29 @@ Simple-sync is a lightweight REST API built in Go that provides event storage an ### Issue Specifications - **File Naming**: Use format `{issue-number}-{brief-description}.md` in `specs/` -- **Structure**: +- **Structure**: - Title with issue link: `# Title\n\nhttps://github.com/kwila-cloud/simple-sync/issues/{number}` - Brief plan description - - Design decisions section (if applicable) + - Design decisions section (only include decisions explicitly discussed and agreed) - Task List with sections corresponding to atomic pull requests - - Each section header represents one PR - - Items within section are changes included in that PR (not necessarily atomic) + - Each section header represents a PR and MUST use the PR title in convential commit format (not PR number) + - Example header: `### docs: add OpenAPI spec and validation tests` (good) + - Avoid headers like `### PR: 1 - ...` or `### PR: #59` (bad) + - Items within section are changes included in that PR - Use `[ ]` for pending and `[x]` for completed -- **Style**: +- **Spec Writing Rules**: + - Do NOT add extra top-level sections beyond the required sections (Title, Brief plan, Design decisions, Task List). + - Do NOT invent design decisions; include only decisions that were discussed with the user or team. + - Keep design decisions concise and limited to points explicitly agreed. +- **Style**: - ✅ Good: Simple, scannable checklist format - - ✅ Good: Group related items logically - - ❌ Avoid: Verbose descriptions, detailed explanations, multiple sections + - ✅ Good: Use PR titles for section headers and keep each PR section focused + - ❌ Avoid: Verbose descriptions, invented design decisions, multiple unrelated top-level sections - **TDD Approach**: Each task item should include tests first, then implementation - ✅ Good: "Add tests for X", "Implement X" - ❌ Bad: Separate testing section at the end -- **Task List Structure**: - - Each section = one atomic pull request +- **Task List Structure**: + - Each section = one atomic pull request titled with the PR's proposed title - Items within section = changes included in that PR (can be multiple related changes) - ✅ Good: Section with multiple related implementation items - ❌ Bad: Each individual item as separate PR diff --git a/specs/18-typescript-sdk.md b/specs/18-typescript-sdk.md new file mode 100644 index 0000000..63e8809 --- /dev/null +++ b/specs/18-typescript-sdk.md @@ -0,0 +1,27 @@ +# TypeScript SDK + +https://github.com/kwila-cloud/simple-sync/issues/18 + +Build an offline-first TypeScript SDK for the Simple-Sync API and add an OpenAPI spec so we can validate and CI-check SDKs. + +### docs: add OpenAPI spec and spec validation tests +- [ ] Add `specs/openapi.yaml` describing the public API endpoints used by SDK (`/events`, `/auth/setup-token/exchange`, `/acl` endpoints used by clients). +- [ ] Add contract tests that validate the OpenAPI spec is loadable and passes linting (e.g., `swagger-cli validate`) under `tests/contract/openapi_spec_test.go` (or JS test harness `tests/contract/openapi_spec_test.js`) — tests first. +- [ ] Add a CI job step to run OpenAPI lint/validate on push and pull requests. + +### feat: add generated TypeScript client scaffold +- [ ] TBD + +### feat: implement full TypeScript SDK +- [ ] TBD + +### feat: add SDK validation contract tests against test server +- [ ] Add contract tests under `tests/contract/` that start the test server (the repo already has test helpers) and verify the TypeScript SDK behavior against real endpoints (authentication, event post/get, ACL checks). + +- [ ] Ensure tests fail if the OpenAPI spec and server disagree. +- [ ] Wire these contract tests into CI (separate job that starts the test server and runs Node tests). + +### docs: TypeScript SDK +- [ ] Add docs to `docs/` describing the TypeScript SDK example, how to run generation, and how to run the contract tests locally. +- [ ] Add a GitHub Actions workflow (`.github/workflows/sdk-validation.yml`) or extend existing CI to include a job that installs Node, generates the client, builds the example, and runs the contract tests. + From 9996ece8f47abebce7a8bdcd612c5fcfa3dc0c14 Mon Sep 17 00:00:00 2001 From: Addison Emig Date: Thu, 23 Oct 2025 20:49:50 -0400 Subject: [PATCH 2/4] docs: flesh out spec --- specs/18-typescript-sdk.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/specs/18-typescript-sdk.md b/specs/18-typescript-sdk.md index 63e8809..ac2fd65 100644 --- a/specs/18-typescript-sdk.md +++ b/specs/18-typescript-sdk.md @@ -6,14 +6,17 @@ Build an offline-first TypeScript SDK for the Simple-Sync API and add an OpenAPI ### docs: add OpenAPI spec and spec validation tests - [ ] Add `specs/openapi.yaml` describing the public API endpoints used by SDK (`/events`, `/auth/setup-token/exchange`, `/acl` endpoints used by clients). -- [ ] Add contract tests that validate the OpenAPI spec is loadable and passes linting (e.g., `swagger-cli validate`) under `tests/contract/openapi_spec_test.go` (or JS test harness `tests/contract/openapi_spec_test.js`) — tests first. +- [ ] Add contract tests that validate the OpenAPI spec is loadable and passes linting (e.g., `swagger-cli validate`) under `tests/contract/openapi_spec_test.go`. - [ ] Add a CI job step to run OpenAPI lint/validate on push and pull requests. ### feat: add generated TypeScript client scaffold -- [ ] TBD +- [ ] Create directory `clients/typescript` with basic TypeScript project +- [ ] Add prettier config +- [ ] Add eslint config +- [ ] Run prettier and eslint in CI/CD ### feat: implement full TypeScript SDK -- [ ] TBD +- [ ] Generate typescript SDK from `specs/openapi.yaml` ### feat: add SDK validation contract tests against test server - [ ] Add contract tests under `tests/contract/` that start the test server (the repo already has test helpers) and verify the TypeScript SDK behavior against real endpoints (authentication, event post/get, ACL checks). From 5d52ddb3003baf3f57f2f0a068a6420f697d8dd0 Mon Sep 17 00:00:00 2001 From: Addison Emig Date: Thu, 23 Oct 2025 20:53:48 -0400 Subject: [PATCH 3/4] fix: port mapping --- docker-compose.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 685add3..a04d443 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,7 +3,9 @@ services: image: ghcr.io/kwila-cloud/simple-sync:latest container_name: simple-sync ports: - - "8765:8080" + - "8080" + # Add port mapping to expose on your host + # - "8765:8080" volumes: - ./data:/app/data # explicit local bind for persistent DB file (recommended for development) # Alternative: use a named volume managed by Docker From c6b1ea54f24b08f4511cb39c6a1c2455c3fb9628 Mon Sep 17 00:00:00 2001 From: Addison Emig Date: Thu, 23 Oct 2025 21:01:16 -0400 Subject: [PATCH 4/4] chore: add coolify-specific docker compose file --- AGENTS.md | 1 - README.md | 2 -- docker-compose.coolify.yml | 16 ++++++++++++++++ docker-compose.yml | 18 ++---------------- 4 files changed, 18 insertions(+), 19 deletions(-) create mode 100644 docker-compose.coolify.yml diff --git a/AGENTS.md b/AGENTS.md index ed0157b..ee7bf11 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -262,5 +262,4 @@ Prefer `for i := range n` (Go 1.22+) over `for i := 0; i < n; i++` when iteratin ### SQLite Storage - The project uses SQLite for persistent storage; production/dev processes expect a local file under `./data` by default (`./data/simple-sync.db`). - Docker Compose is configured to bind-mount `./data` into the container (`./data:/app/data`) so the DB file is stored on the host. This is the recommended setup for development and simple deployments because it makes backups and inspection straightforward. -- If you need a Docker-managed volume, a named volume `simple-sync-data` exists in `docker-compose.yml` (commented). Using a named volume is fine for environments where host access is not required, but it makes manual backups/restores less obvious. diff --git a/README.md b/README.md index 7b9abd4..2b0cbc5 100644 --- a/README.md +++ b/README.md @@ -50,8 +50,6 @@ services: ### Persistent Data (Docker Compose) The Docker Compose configuration mounts a local `./data` directory into the container (`./data:/app/data`) by default. This is the recommended setup for development and simple deployments because it keeps the SQLite database file on the host, making backups and inspection straightforward. -If you prefer Docker-managed storage, a named volume `simple-sync-data` is declared in `docker-compose.yml`; you can switch to it by uncommenting the named volume line and removing the `./data` bind mount. - Backup and restore helper scripts are provided in `./scripts`: - `./scripts/backup.sh [--stop] [--dir ] [path-to-db]` — copy the DB file to `./backups/` (or specified directory) (use `--stop` to stop the container during backup) - `./scripts/restore.sh [--stop]` — restore a backup into `./data/simple-sync.db` (moves the existing DB aside first) diff --git a/docker-compose.coolify.yml b/docker-compose.coolify.yml new file mode 100644 index 0000000..a15d138 --- /dev/null +++ b/docker-compose.coolify.yml @@ -0,0 +1,16 @@ +services: + simple-sync: + container_name: simple-sync + build: + context: . + expose: + - "8080" + volumes: + - ./data:/app/data + restart: unless-stopped + healthcheck: + test: ["CMD", "curl", "-f", "-s", "http://localhost:8080/api/v1/health"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 40s diff --git a/docker-compose.yml b/docker-compose.yml index a04d443..ee5a352 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,13 +3,9 @@ services: image: ghcr.io/kwila-cloud/simple-sync:latest container_name: simple-sync ports: - - "8080" - # Add port mapping to expose on your host - # - "8765:8080" + - "8765:8080" volumes: - - ./data:/app/data # explicit local bind for persistent DB file (recommended for development) - # Alternative: use a named volume managed by Docker - # - simple-sync-data:/app/data + - ./data:/app/data restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "-s", "http://localhost:8080/api/v1/health"] @@ -17,13 +13,3 @@ services: timeout: 10s retries: 3 start_period: 40s - networks: - - simple-sync-network - -networks: - simple-sync-network: - driver: bridge - -volumes: - simple-sync-data: - driver: local