Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
142 changes: 142 additions & 0 deletions .claude/CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
# Project instructions

## Constitution

### sof-mssql Constitution

#### Core Principles

##### I. Specification conformance (NON-NEGOTIABLE)

Every transpilation feature MUST conform to the [SQL on FHIR v2
specification](https://sql-on-fhir.org/ig/2.0.0/). Conformance is proven, not
asserted: the upstream `sqlonfhir` test submodule is the source of truth, and
all in-scope (non-`#experimental`) tests MUST pass before a change merges. A
feature that diverges from the specification MUST either be tagged
`#experimental` with a documented reason, or not ship. New behaviour MUST cite
the relevant section of the specification.

_Rationale: the project's entire value is being a faithful SQL on FHIR runner.
Silent divergence from the spec produces wrong analytical results that
downstream users cannot detect._

##### II. Valid, executable T-SQL

All generated SQL MUST be valid, executable T-SQL for Microsoft SQL Server 2017
and later. Output MUST NOT rely on engine-specific extensions beyond that
baseline, MUST bracket-quote identifiers where required, and MUST handle empty
collections as SQL `NULL` per the specification's data-type mapping. Generated
SQL is an external contract: it MUST be verified against a real SQL Server
instance, not merely inspected as a string.

_Rationale: a query that parses in TypeScript but fails or silently
mis-executes on SQL Server is a defect the library exists to prevent._

##### III. Test-first (NON-NEGOTIABLE)

Tests MUST be written before implementation. For every feature or bug fix, a
failing test that defines the expected behaviour comes first; implementation
follows only to make it pass. The Red-Green-Refactor cycle is strictly
enforced. Bug fixes MUST include a regression test that fails without the fix.
No change merges without its behaviour expressed as an executable test.

##### IV. Trusted boundaries through validated input

External input - ViewDefinition JSON, CLI arguments, NDJSON resources - MUST be
accepted as `unknown` and narrowed through runtime type predicates
(`data is Type`) before use. Blind type assertions (`as SomeType`) on
unvalidated data are forbidden. Invalid input MUST be rejected with a meaningful
error that references the offending ViewDefinition element.

_Rationale: the library transpiles attacker- or user-controlled documents into
SQL; trusting unvalidated structure invites both crashes and malformed output._

##### V. Functional, composable design

Behaviour MUST be expressed through small, single-responsibility, pure
functions composed together, favouring immutable data. Classes are permitted
only where they provide clear encapsulation of genuine state (e.g. the public
`SqlOnFhir` facade); they MUST NOT be used as namespaces for otherwise-stateless
logic. Each module owns one concern - parsing, FHIRPath translation, T-SQL
generation, loading - and exposes only what callers need.

#### Quality gates

Before any change is considered complete it MUST pass, locally and in CI:

- A clean `npm run build`.
- The full test suite with coverage via `npm run test:coverage`, run with the
database environment sourced (`set -a && source .env && set +a`).
- `npm run lint` with no errors or warnings.
- `npm run format:check` with no formatting differences.

These gates are not advisory. A change that cannot pass them is not done,
regardless of how complete the implementation appears.

#### Amendment and review

A pull request MAY be rejected by citing the specific principle it violates
(e.g. "violates Principle II - emits a SQL Server 2022-only function"). The
constitution governs reviews and is the tie-breaker when guidance conflicts.
Amendments are made by editing this section directly and explaining the change
in the commit message.

## Getting started

Before starting any work on this project, always read the CONTRIBUTING.md file to understand the project's contribution guidelines and requirements.

## Running tests

This project uses environment variables stored in a `.env` file for database connection configuration. When running tests, these variables must be properly sourced into the environment.

To run the test suite:

```bash
set -a && source .env && set +a && npm test
```

This command performs the following steps:

1. `set -a` — Enables the allexport option, which automatically exports all variables that are set or modified.
2. `source .env` — Sources the `.env` file, loading all environment variables.
3. `set +a` — Disables the allexport option.
4. `npm test` — Runs the test suite with the environment variables now available.

### Important notes

- Ensure a `.env` file exists in the project root before running tests.
- The `.env` file should contain all necessary database connection parameters.
- Never commit the `.env` file to version control as it may contain sensitive credentials.

## Environment variables

The project relies on environment variables for database configuration. Check the `.env.example` file (if present) or the project documentation for required variables.

## IntelliJ IDE integration

This project uses IntelliJ IDEA with MCP server integration for code analysis and problem detection.

### Checking for problems

When checking files for problems using the `mcp__intellij__get_file_problems` tool:

- **Always set `errorsOnly: false`** to include both errors and warnings
- Always specify the `projectPath` parameter to avoid ambiguity when multiple projects are open
- Include both SonarQube and IDE warnings to ensure comprehensive code quality checks

Example:

```typescript
mcp__intellij__get_file_problems({
filePath: "src/parser.ts",
projectPath: "/Users/gri306/Code/sof-mssql",
errorsOnly: false, // IMPORTANT: Include warnings
});
```

Warnings often catch important issues such as:

- Using deprecated APIs (e.g., `isNaN` vs `Number.isNaN`)
- Type validation requiring specific error types (e.g., `TypeError` for type checks)
- Complex regex patterns that should be simplified
- Code quality issues flagged by SonarQube
152 changes: 152 additions & 0 deletions .claude/commands/opsx/apply.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
---
name: "OPSX: Apply"
description: Implement tasks from an OpenSpec change (Experimental)
category: Workflow
tags: [workflow, artifacts, experimental]
---

Implement tasks from an OpenSpec change.

**Input**: Optionally specify a change name (e.g., `/opsx:apply add-auth`). If omitted, check if it can be inferred from conversation context. If vague or ambiguous you MUST prompt for available changes.

**Steps**

1. **Select the change**

If a name is provided, use it. Otherwise:
- Infer from conversation context if the user mentioned a change
- Auto-select if only one active change exists
- If ambiguous, run `openspec list --json` to get available changes and use the **AskUserQuestion tool** to let the user select

Always announce: "Using change: <name>" and how to override (e.g., `/opsx:apply <other>`).

2. **Check status to understand the schema**
```bash
openspec status --change "<name>" --json
```
Parse the JSON to understand:
- `schemaName`: The workflow being used (e.g., "spec-driven")
- Which artifact contains the tasks (typically "tasks" for spec-driven, check status for others)

3. **Get apply instructions**

```bash
openspec instructions apply --change "<name>" --json
```

This returns:
- `contextFiles`: artifact ID -> array of concrete file paths (varies by schema)
- Progress (total, complete, remaining)
- Task list with status
- Dynamic instruction based on current state

**Handle states:**
- If `state: "blocked"` (missing artifacts): show message, suggest using `/opsx:continue`
- If `state: "all_done"`: congratulate, suggest archive
- Otherwise: proceed to implementation

4. **Read context files**

Read every file path listed under `contextFiles` from the apply instructions output.
The files depend on the schema being used:
- **spec-driven**: proposal, specs, design, tasks
- Other schemas: follow the contextFiles from CLI output

5. **Show current progress**

Display:
- Schema being used
- Progress: "N/M tasks complete"
- Remaining tasks overview
- Dynamic instruction from CLI

6. **Implement tasks (loop until done or blocked)**

For each pending task:
- Show which task is being worked on
- Make the code changes required
- Keep changes minimal and focused
- Mark task complete in the tasks file: `- [ ]``- [x]`
- Continue to next task

**Pause if:**
- Task is unclear → ask for clarification
- Implementation reveals a design issue → suggest updating artifacts
- Error or blocker encountered → report and wait for guidance
- User interrupts

7. **On completion or pause, show status**

Display:
- Tasks completed this session
- Overall progress: "N/M tasks complete"
- If all done: suggest archive
- If paused: explain why and wait for guidance

**Output During Implementation**

```
## Implementing: <change-name> (schema: <schema-name>)
Working on task 3/7: <task description>
[...implementation happening...]
✓ Task complete
Working on task 4/7: <task description>
[...implementation happening...]
✓ Task complete
```

**Output On Completion**

```
## Implementation Complete
**Change:** <change-name>
**Schema:** <schema-name>
**Progress:** 7/7 tasks complete ✓
### Completed This Session
- [x] Task 1
- [x] Task 2
...
All tasks complete! You can archive this change with `/opsx:archive`.
```

**Output On Pause (Issue Encountered)**

```
## Implementation Paused
**Change:** <change-name>
**Schema:** <schema-name>
**Progress:** 4/7 tasks complete
### Issue Encountered
<description of the issue>
**Options:**
1. <option 1>
2. <option 2>
3. Other approach
What would you like to do?
```

**Guardrails**
- Keep going through tasks until done or blocked
- Always read context files before starting (from the apply instructions output)
- If task is ambiguous, pause and ask before implementing
- If implementation reveals issues, pause and suggest artifact updates
- Keep code changes minimal and scoped to each task
- Update task checkbox immediately after completing each task
- Pause on errors, blockers, or unclear requirements - don't guess
- Use contextFiles from CLI output, don't assume specific file names

**Fluid Workflow Integration**

This skill supports the "actions on a change" model:

- **Can be invoked anytime**: Before all artifacts are done (if tasks exist), after partial implementation, interleaved with other actions
- **Allows artifact updates**: If implementation reveals design issues, suggest updating artifacts - not phase-locked, work fluidly
Loading
Loading