diff --git a/AGENTS.md b/AGENTS.md index 9c273ba..ee7bf11 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 @@ -256,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 685add3..ee5a352 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -5,9 +5,7 @@ services: ports: - "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"] @@ -15,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 diff --git a/specs/18-typescript-sdk.md b/specs/18-typescript-sdk.md new file mode 100644 index 0000000..ac2fd65 --- /dev/null +++ b/specs/18-typescript-sdk.md @@ -0,0 +1,30 @@ +# 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`. +- [ ] Add a CI job step to run OpenAPI lint/validate on push and pull requests. + +### feat: add generated TypeScript client scaffold +- [ ] 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 +- [ ] 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). + +- [ ] 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. +