@insignia-education/api-sdk-js 0.15.71 → 0.15.74
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +7 -2
- package/src/api/v1/Courses.js +4 -4
- package/src/api/v1/Employee.js +2 -0
- package/src/api/v1/Users.js +7 -0
- package/.ai/guidelines/research-order.md +0 -29
- package/.claude/agents/product-spec-architect.md +0 -163
- package/.claude/agents/senior-code-reviewer.md +0 -109
- package/.claude/agents/senior-software-developer.md +0 -90
- package/.claude/agents/senior-software-maintainer.md +0 -121
- package/.claude/skills/general/documentation/SKILL.md +0 -49
- package/.claude/skills/general/handoff/SKILL.md +0 -15
- package/.claude/skills/general/investigation/SKILL.md +0 -53
- package/.claude/skills/general/performance/SKILL.md +0 -31
- package/.claude/skills/git/pull-request/SKILL.md +0 -47
- package/.claude/skills/how-to-create-skills/SKILL.md +0 -82
- package/.github/hooks/pre-commit +0 -22
- package/.github/workflows/npm-publish-github-packages.yml +0 -29
- package/.nvmrc +0 -1
- package/AGENTS.md +0 -140
- package/CLAUDE.md +0 -51
- package/babel.config.cjs +0 -1
- package/eslint.config.mjs +0 -29
- package/jest.config.mjs +0 -47
- package/scss/Services/_notification.scss +0 -0
- package/scss/index.scss +0 -2
- package/tests/client.test.js +0 -265
- package/tests/helpers.js +0 -21
- package/tests/integration/api/v1/accounts.test.js +0 -31
- package/tests/integration/api/v1/auth/login.test.js +0 -44
- package/tests/integration/api/v1/changelogs.test.js +0 -21
- package/tests/integration/api/v1/contact-forms.test.js +0 -24
- package/tests/integration/api/v1/conversational-topics.test.js +0 -17
- package/tests/integration/api/v1/countries.test.js +0 -20
- package/tests/integration/api/v1/coupons.test.js +0 -19
- package/tests/integration/api/v1/courses/by-cod.test.js +0 -19
- package/tests/integration/api/v1/courses/index.test.js +0 -46
- package/tests/integration/api/v1/currencies/history.test.js +0 -23
- package/tests/integration/api/v1/currencies/index.test.js +0 -24
- package/tests/integration/api/v1/currencies/values.test.js +0 -24
- package/tests/integration/api/v1/files.test.js +0 -42
- package/tests/integration/api/v1/forums/index.test.js +0 -23
- package/tests/integration/api/v1/hashes.test.js +0 -18
- package/tests/integration/api/v1/insignias.test.js +0 -19
- package/tests/integration/api/v1/languages.test.js +0 -28
- package/tests/integration/api/v1/mail-blacklist.test.js +0 -19
- package/tests/integration/api/v1/offers.test.js +0 -20
- package/tests/integration/api/v1/organizations.test.js +0 -89
- package/tests/integration/api/v1/payment-methods/by-currencies.test.js +0 -51
- package/tests/integration/api/v1/quizzes/index.test.js +0 -37
- package/tests/integration/api/v1/short-links.test.js +0 -20
- package/tests/integration/api/v1/surveys/index.test.js +0 -40
- package/tests/integration/api/v1/taxes.test.js +0 -19
- package/tests/integration/api/v1/teacher/index.test.js +0 -53
- package/tests/integration/api/v1/telegram.test.js +0 -33
- package/tests/integration/api/v1/user-types.test.js +0 -17
- package/tests/integration/api/v1/users/cash-receivers.test.js +0 -19
- package/tests/integration/api/v1/users/index.test.js +0 -32
- package/tests/integration/api/v1/users/telegram.test.js +0 -36
- package/tests/integration/api/v1/zoom.test.js +0 -17
- package/tests/integration/loadEnv.js +0 -16
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: handoff
|
|
3
|
-
description: Compact the current conversation into a handoff document for another agent to pick up.
|
|
4
|
-
argument-hint: "What will the next session be used for?"
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
Write a handoff document summarising the current conversation so a fresh agent can continue the work. Save to the temporary directory of the user's OS - not the current workspace.
|
|
8
|
-
|
|
9
|
-
Include a "suggested skills" section in the document, which suggests skills that the agent should invoke.
|
|
10
|
-
|
|
11
|
-
Do not duplicate content already captured in other artifacts (PRDs, plans, ADRs, issues, commits, diffs). Reference them by path or URL instead.
|
|
12
|
-
|
|
13
|
-
Redact any sensitive information, such as API keys, passwords, or personally identifiable information.
|
|
14
|
-
|
|
15
|
-
If the user passed arguments, treat them as a description of what the next session will focus on and tailor the doc accordingly.
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: investigation
|
|
3
|
-
description: General method for investigating why an SDK method is failing or behaving unexpectedly before changing code — pin the symptom, check the real `api` endpoint first, map every call site, and find the true cause (SDK bug vs. API drift vs. consumer version skew) before writing a fix. Use for failing integration tests, `front`-reported bugs, and suspected SDK/API drift. Triggers on "investigate", "root cause", "debug", "why is this failing", "drift", "test failing".
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Investigation — Root-Cause Method
|
|
7
|
-
|
|
8
|
-
A reusable method for getting from a symptom to the true cause before writing a fix, adapted for a
|
|
9
|
-
thin SDK that has no runtime of its own — the vast majority of "bugs" here are actually **drift**
|
|
10
|
-
between this SDK and `api`, not logic bugs.
|
|
11
|
-
|
|
12
|
-
> **Verify against current `api` behavior before asserting — the backend moves.** Do not propose a
|
|
13
|
-
> fix until you've confirmed what the real endpoint does right now, not what it did when the SDK
|
|
14
|
-
> method was written.
|
|
15
|
-
|
|
16
|
-
## Method
|
|
17
|
-
1. **Pin the symptom.** From a failing integration test, get the exact test name, assertion, and
|
|
18
|
-
actual vs. expected values. From a `front`-reported bug, get the exact method call (args) and
|
|
19
|
-
observed vs. expected behavior.
|
|
20
|
-
2. **Locate the code.** Start from the implicated resource file in `src/api/v1/{Resource}.js` →
|
|
21
|
-
the method in question → `src/api/v1/index.js` for how it's wired up. This repo's code is flat
|
|
22
|
-
and shallow — there's rarely more than one or two files to trace through.
|
|
23
|
-
3. **Check `api` first, before assuming the SDK is wrong.** Since this SDK has no independent
|
|
24
|
-
business logic, the most common root cause is that `api`'s route, controller, or response shape
|
|
25
|
-
changed and the sync rule (`AGENTS.md`) was missed. Find the real endpoint in `api` and compare
|
|
26
|
-
its current behavior to what the SDK method assumes.
|
|
27
|
-
4. **Map affected call sites.** Grep `front` for every call to the implicated method — a fix that
|
|
28
|
-
changes params or return shape without checking all callers reintroduces the bug for a
|
|
29
|
-
different caller. Also check sibling SDK methods for the same pattern (e.g. a shared
|
|
30
|
-
param-passing helper) in case the drift is systemic, not local to one method.
|
|
31
|
-
5. **Classify the true cause:**
|
|
32
|
-
- **SDK bug** — the method never matched `api` correctly, and a test/report just caught it.
|
|
33
|
-
- **API drift** — `api` changed and the SDK sync rule (per `AGENTS.md`) wasn't followed.
|
|
34
|
-
- **Version skew** — the SDK is already correct, but `front` (or another consumer) is pinned to
|
|
35
|
-
an older published version. Check the consumer's `package.json` for the installed version
|
|
36
|
-
against the current one.
|
|
37
|
-
6. **Plan the fix with downstream impact in mind.** State what changes, whether it's `v1`-safe or
|
|
38
|
-
needs `v2` (per the freeze rule), and how you'll verify — then update/add the integration test
|
|
39
|
-
that fails before the fix and passes after.
|
|
40
|
-
|
|
41
|
-
## Evidence sources
|
|
42
|
-
|
|
43
|
-
- **A failing integration test against a live `api` is the primary and strongest signal** — per
|
|
44
|
-
`AGENTS.md`, this is the artifact that proves the SDK and `api` agree. Reproduce or run the
|
|
45
|
-
relevant test in `tests/integration/api/v1/` before proposing a fix.
|
|
46
|
-
- **`api`'s actual response shape** — this repo has no logs, no Telescope, no error tracker of its
|
|
47
|
-
own. If the SDK's assumption about a response looks wrong, check it via `api`'s own Telescope
|
|
48
|
-
(`/telescope`, local) or logs (`storage/logs/laravel.log`) in the `api` repo — don't guess from
|
|
49
|
-
the SDK side alone.
|
|
50
|
-
- **`api`'s route/controller source** — the ground truth for path, params, and response shape.
|
|
51
|
-
Read it directly rather than inferring from the SDK's existing (possibly stale) assumption.
|
|
52
|
-
- **No third-party error tracker or APM exists in this repo** — don't assume Datadog/Sentry/Bugsnag
|
|
53
|
-
are wired up here; they aren't.
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: performance
|
|
3
|
-
description: Minimal performance checklist for this thin HTTP client SDK — there is very little performance surface here (no rendering, no queries, no server). Use when a consumer reports a resource method being called redundantly or a method doing unnecessary work per call. Triggers on "performance", "slow", "redundant calls", "optimize", "duplicate requests".
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Performance — Minimal Checklist
|
|
7
|
-
|
|
8
|
-
This is a thin, zero-dependency HTTP wrapper. It has no database, no rendering, no compute-heavy
|
|
9
|
-
work, and no server process — most of the performance surface that a full application has simply
|
|
10
|
-
doesn't exist here. Don't manufacture a heavier profiling process than the codebase warrants; this
|
|
11
|
-
skill is intentionally short.
|
|
12
|
-
|
|
13
|
-
The two things actually worth checking:
|
|
14
|
-
|
|
15
|
-
1. **Redundant/duplicate calls from a consumer using a method in a loop.** A resource method is a
|
|
16
|
-
1:1 wrapper around one `api` call — if `front` (or another consumer) calls the same method
|
|
17
|
-
repeatedly inside a loop with the same or overlapping args, that's a consumer-side batching
|
|
18
|
-
problem, not something to fix inside the SDK method itself. Flag it to the consumer rather than
|
|
19
|
-
adding caching/batching logic into a resource class (that would violate thin-wrapper discipline
|
|
20
|
-
— see `AGENTS.md` and the `senior-software-developer`/`senior-code-reviewer` agents).
|
|
21
|
-
2. **Unnecessary payload transformation or cloning per call.** A resource method should pass
|
|
22
|
-
params/body through to the client with the minimum work needed to shape the HTTP request — no
|
|
23
|
-
deep-cloning, no reshaping the response, no redundant `JSON.parse(JSON.stringify(...))`-style
|
|
24
|
-
copies. If a method is doing more than constructing the call and returning the client's
|
|
25
|
-
response, that's very likely a correctness/scope issue (see `general/investigation` and the
|
|
26
|
-
thin-wrapper rule), not just a performance one.
|
|
27
|
-
|
|
28
|
-
If a real latency problem is reported, it is almost certainly in `api` (query performance, N+1,
|
|
29
|
-
slow external integration) or in network conditions — not in this SDK. Point the investigation at
|
|
30
|
-
`api`'s own performance tooling (see its `AGENTS.md`/performance skill) rather than profiling this
|
|
31
|
-
repo.
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: create-pull-request-api-sdk-js
|
|
3
|
-
description: Create a pull request following insignia-education conventions for this repo — no Jira link, no PR template, but a repo-specific pre-flight checklist (endpoint exists in api, integration test present, v1-freeze respected, publish-pipeline awareness). Use whenever creating a PR in `api-sdk-js`.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Create Pull Request — insignia-education/api-sdk-js
|
|
7
|
-
|
|
8
|
-
No `.github/PULL_REQUEST_TEMPLATE.md` exists in this repo — write a plain body with `## Summary`
|
|
9
|
-
and `## Test plan` sections (see the repo-level PR instructions for the exact mechanics of
|
|
10
|
-
`gh pr create`). This skill adds the checks specific to this repo, on top of that.
|
|
11
|
-
|
|
12
|
-
## Pre-flight checklist
|
|
13
|
-
|
|
14
|
-
- **The `api` endpoint is real and already merged/available.** Never add a speculative SDK method
|
|
15
|
-
for an endpoint that doesn't exist yet in `api` — confirm the route/controller is merged (and,
|
|
16
|
-
ideally, deployed somewhere reachable) before opening this PR. Per `AGENTS.md`'s sync rule, this
|
|
17
|
-
SDK follows `api`; it never leads it.
|
|
18
|
-
- **An integration test was added or updated.** Per `AGENTS.md`, a new/changed method isn't
|
|
19
|
-
verified until its test in `tests/integration/api/v1/` passes against a locally running `api`.
|
|
20
|
-
A PR that changes a resource method without a corresponding test change is incomplete — call it
|
|
21
|
-
out explicitly if deferring this is unavoidable.
|
|
22
|
-
- **Test coverage includes missing/malformed params and permissions per role**, not just the happy
|
|
23
|
-
path — per `AGENTS.md`'s testing coverage requirements.
|
|
24
|
-
- **`v1` freeze respected.** If the diff touches `src/api/v1/`, confirm it's additive (new
|
|
25
|
-
method/resource) and not a breaking change to an existing method's signature or return shape, and
|
|
26
|
-
that `InsigniaApiV1`'s constructor is unchanged. A breaking change belongs under a future
|
|
27
|
-
`src/api/v2/`, not a `v1` edit.
|
|
28
|
-
- **No runtime dependency added**, no hardcoded base URL, no hardcoded human-readable string in
|
|
29
|
-
source (errors must expose `status`/`data` only — see `AGENTS.md`'s i18n rule).
|
|
30
|
-
- **Merging this PR to `master` is a deploy action, not a routine merge.** Per `CLAUDE.md`'s
|
|
31
|
-
deployment section, a push to `master` (unless `[skip ci]`) auto-bumps this package's patch
|
|
32
|
-
version, publishes it to npm, pushes a direct commit to `front`'s `beta` branch, and opens a PR
|
|
33
|
-
against `front`'s `master` — all without further human action beyond the merge itself. Don't
|
|
34
|
-
merge here as though it's a no-op; know that it triggers all of the above.
|
|
35
|
-
|
|
36
|
-
## Body format
|
|
37
|
-
|
|
38
|
-
```
|
|
39
|
-
## Summary
|
|
40
|
-
<1-3 bullets>
|
|
41
|
-
|
|
42
|
-
## Test plan
|
|
43
|
-
<checklist of what was tested / how to verify>
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
Omit sections that would be empty. No ticket link, no deployment labels — this repo doesn't use
|
|
47
|
-
them.
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: how-to-create-skills
|
|
3
|
-
description: How to author and organize skills in this repo's `.claude/skills/` — the domain/general taxonomy, the composability principle (split knowledge from method), SKILL.md frontmatter, naming, and when to split vs combine a skill. Use whenever creating a new skill, editing an existing one, splitting a monolithic skill, or deciding where a skill belongs. Triggers on "create a skill", "new skill", "add a skill", "organize skills", "skill structure".
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# How to Create Skills
|
|
7
|
-
|
|
8
|
-
This is the meta-skill. It defines the conventions every other skill in `.claude/skills/` follows. **This skill is intentionally exempt from those conventions** — it lives at the top level with no domain, because it describes the system rather than participating in it.
|
|
9
|
-
|
|
10
|
-
## The one principle: split *knowledge* from *method*, then compose
|
|
11
|
-
|
|
12
|
-
A skill is either:
|
|
13
|
-
- **Domain knowledge** — *what exists and where it lives* (a map): resource/versioning structure, file paths, conventions, entry points. No domain-map skill exists here yet — the closest thing today is `AGENTS.md` plus `.ai/guidelines/research-order.md`.
|
|
14
|
-
- **A general process** — *how to do something*, independent of domain (a method): investigating drift, documenting, opening a PR. Example: `investigation`, `general/documentation`.
|
|
15
|
-
|
|
16
|
-
Never fuse the two. If a domain-map skill is added later (e.g. `v2` once the next API version gets its own resource modules), there should not be a `v2-investigation` skill — there should be `v2` (the map) and `investigation` (the method), composed together. The cross-product emerges from composition, not from a bespoke combined skill.
|
|
17
|
-
|
|
18
|
-
**Why:** the method is reusable across every version/resource, and the map is reusable across every process. Fusing them forces you to re-teach the investigation method for each version and re-map the resources for each activity.
|
|
19
|
-
|
|
20
|
-
### How composition works in practice
|
|
21
|
-
- A general process skill says: *"pair me with the relevant domain skill for the map."*
|
|
22
|
-
- A domain skill says: *"for investigating drift, also load `investigation`; for a new method, also load `general/documentation`."*
|
|
23
|
-
- Cross-reference by skill `name` in prose so the reader knows what to load alongside.
|
|
24
|
-
|
|
25
|
-
## Folder taxonomy: domain → sub-domain → process → skill-name
|
|
26
|
-
|
|
27
|
-
Organize the path from most-specific domain down to the leaf. Cross-cutting process skills that belong to no single domain live under `general/`.
|
|
28
|
-
|
|
29
|
-
```
|
|
30
|
-
.claude/skills/
|
|
31
|
-
├── how-to-create-skills/ ← this meta-skill (exempt from the pattern)
|
|
32
|
-
├── <domain>/ ← domain knowledge (git, v2, …)
|
|
33
|
-
│ ├── SKILL.md ← the domain map itself (optional)
|
|
34
|
-
│ └── <sub-domain-or-process>/SKILL.md
|
|
35
|
-
└── general/ ← domain-agnostic process skills
|
|
36
|
-
└── <process>/SKILL.md ← performance, investigation, documentation, handoff, …
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
Rules:
|
|
40
|
-
- **Domain first.** If a skill is about *one* domain, nest it under that domain (`git/pull-request`).
|
|
41
|
-
- **General bucket.** If a skill's method applies across domains, put it in `general/` (`general/performance`).
|
|
42
|
-
- Any `SKILL.md` anywhere under `.claude/skills/**` is discovered — folders are for humans, the `name` field is the identifier.
|
|
43
|
-
- Prefer the **most general** phrasing a skill can honestly carry. Keep repo-specific specifics (class names, endpoint paths) inside the skill, but frame the transferable method first.
|
|
44
|
-
|
|
45
|
-
## Deciding: split or combine?
|
|
46
|
-
|
|
47
|
-
| Signal | Action |
|
|
48
|
-
|---|---|
|
|
49
|
-
| The skill mixes "where the code is" with "how to profile/debug it" | **Split** into a domain skill + a `general/` process skill |
|
|
50
|
-
| Two skills always get loaded together and neither stands alone | Consider **combining** — but first check whether one is really a sub-domain of the other |
|
|
51
|
-
| A process skill keeps accreting domain-specific class/resource names | Move those facts into the **domain** skill; keep the method general |
|
|
52
|
-
| A domain skill starts explaining testing/PR mechanics in depth | Move that into a **general** process skill and cross-reference |
|
|
53
|
-
|
|
54
|
-
## SKILL.md format
|
|
55
|
-
|
|
56
|
-
```markdown
|
|
57
|
-
---
|
|
58
|
-
name: <kebab-case, unique across all skills>
|
|
59
|
-
description: <what it does + WHEN to use it + trigger phrases. This is the ONLY thing the model sees when deciding to load the skill — make it match how people actually phrase the task. For composables, name the skills to load alongside.>
|
|
60
|
-
argument-hint: "<optional, for slash-invoked skills>"
|
|
61
|
-
disable-model-invocation: true # optional — manual /invoke only
|
|
62
|
-
---
|
|
63
|
-
|
|
64
|
-
# Title
|
|
65
|
-
|
|
66
|
-
Body: tables and short imperative steps first, prose last. Cross-reference
|
|
67
|
-
composable skills by name. Note file:line references but tell the reader to
|
|
68
|
-
verify them against current code.
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
Frontmatter notes:
|
|
72
|
-
- **`name`** must be unique and stable — it's the slash command and the invocation id. Renaming breaks existing references, so rename deliberately.
|
|
73
|
-
- **`description`** is load-bearing: it's matched against the user's request to auto-activate the skill. Lead with capability, then "Use when…", then trigger phrases.
|
|
74
|
-
- **`disable-model-invocation: true`** makes the skill manual-only (`/name …`). Use for router/workflow skills that shouldn't fire automatically.
|
|
75
|
-
|
|
76
|
-
## Authoring checklist
|
|
77
|
-
1. Is this **knowledge** or **method**? Put it in the right place; don't fuse.
|
|
78
|
-
2. Does an existing skill already cover it? Extend that instead of duplicating.
|
|
79
|
-
3. Can the wording be more general without losing accuracy? Generalize.
|
|
80
|
-
4. Name the composable siblings to load alongside.
|
|
81
|
-
5. Write the `description` the way a user would ask for it.
|
|
82
|
-
6. Keep the body scannable: tables + steps first.
|
package/.github/hooks/pre-commit
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
set -e
|
|
3
|
-
|
|
4
|
-
PACKAGE=$(node -p "require('./package.json').name")
|
|
5
|
-
VERSION=$(node -p "require('./package.json').version")
|
|
6
|
-
|
|
7
|
-
echo "Running lint..."
|
|
8
|
-
npm run lint
|
|
9
|
-
|
|
10
|
-
echo "Running tests..."
|
|
11
|
-
npm test
|
|
12
|
-
|
|
13
|
-
echo "Checking if ${PACKAGE}@${VERSION} is already published..."
|
|
14
|
-
STATUS=$(curl -s -o /dev/null -w "%{http_code}" "https://registry.npmjs.org/${PACKAGE}/${VERSION}")
|
|
15
|
-
echo $STATUS
|
|
16
|
-
if [ "$STATUS" = "200" ]; then
|
|
17
|
-
echo "Error: ${PACKAGE}@${VERSION} is already published on NPM."
|
|
18
|
-
echo "Bump the version in package.json before committing."
|
|
19
|
-
exit 1
|
|
20
|
-
fi
|
|
21
|
-
|
|
22
|
-
exit 0
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
name: Publish Package
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
branches:
|
|
6
|
-
- master
|
|
7
|
-
|
|
8
|
-
permissions:
|
|
9
|
-
id-token: write # Required for OIDC
|
|
10
|
-
|
|
11
|
-
jobs:
|
|
12
|
-
publish:
|
|
13
|
-
runs-on: ubuntu-latest
|
|
14
|
-
steps:
|
|
15
|
-
- uses: actions/checkout@v6
|
|
16
|
-
|
|
17
|
-
- uses: actions/setup-node@v6
|
|
18
|
-
with:
|
|
19
|
-
node-version: '24'
|
|
20
|
-
registry-url: 'https://registry.npmjs.org'
|
|
21
|
-
package-manager-cache: false # never use caching in release builds
|
|
22
|
-
- run: npm ci
|
|
23
|
-
- run: npm run build --if-present
|
|
24
|
-
# npm test disabled: integration suite needs a live api backend, no CI service for it yet
|
|
25
|
-
|
|
26
|
-
# The version in package.json is whatever was committed — this workflow never bumps it.
|
|
27
|
-
# The pre-commit hook (.github/hooks/pre-commit) already refuses a commit whose version is
|
|
28
|
-
# already published, so publishing here just fails loudly if someone forgot to bump it.
|
|
29
|
-
- run: npm publish # Or: npm stage publish
|
package/.nvmrc
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
25
|
package/AGENTS.md
DELETED
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
# Insignia Education — API SDK (JavaScript)
|
|
2
|
-
|
|
3
|
-
## Requirements
|
|
4
|
-
- Node 24 LTS (`nvm use 24`)
|
|
5
|
-
|
|
6
|
-
## Quick start
|
|
7
|
-
```bash
|
|
8
|
-
nvm use 24
|
|
9
|
-
npm install
|
|
10
|
-
npm test # runs Jest test suite
|
|
11
|
-
npm run lint # ESLint
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
## What this is
|
|
15
|
-
A zero-dependency JavaScript SDK that wraps the Insignia Education API (`/api/v1`).
|
|
16
|
-
Consumed by `insignia-education/front` via `@insignia-education/api-sdk-js`.
|
|
17
|
-
|
|
18
|
-
## API versioning
|
|
19
|
-
The SDK is versioned to match the API:
|
|
20
|
-
|
|
21
|
-
- `src/index.js` — base client
|
|
22
|
-
- `src/api/index.js` — appends `/api` to the base URL
|
|
23
|
-
- `src/api/v1/index.js` — appends `/v1` → all requests land at `<host>/api/v1/...`
|
|
24
|
-
- **v1 is being finalized. Once stable it is permanently frozen.**
|
|
25
|
-
- A future v2 API will live in `src/api/v2/index.js` (new class, new resource modules).
|
|
26
|
-
- Never modify the URL construction logic in `v1/` to point at a different version.
|
|
27
|
-
- Tests for each version live in `tests/integration/api/v1/` — mirror this structure for v2+.
|
|
28
|
-
- The `upload(path, formData)` method on `Client` sends multipart — use `api.files.upload(fd)` for any file upload, never raw `fetch()`.
|
|
29
|
-
|
|
30
|
-
## Structure
|
|
31
|
-
```
|
|
32
|
-
src/
|
|
33
|
-
├── index.js ← main export
|
|
34
|
-
├── api/v1/
|
|
35
|
-
│ ├── index.js ← InsigniaApiV1 class (root client)
|
|
36
|
-
│ ├── Auth.js ← /auth endpoints
|
|
37
|
-
│ ├── Courses.js ← /courses endpoints
|
|
38
|
-
│ ├── Users.js ← /users endpoints
|
|
39
|
-
│ └── ... ← one file per API resource
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
## Usage pattern
|
|
43
|
-
```js
|
|
44
|
-
import InsigniaApiV1 from '@insignia-education/api-sdk-js/api/v1';
|
|
45
|
-
const api = new InsigniaApiV1('http://localhost:8000');
|
|
46
|
-
|
|
47
|
-
api.auth.login({ email, password });
|
|
48
|
-
api.courses.get(null, { page: 1 });
|
|
49
|
-
api.users.cashReceivers();
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
## Conventions
|
|
53
|
-
- One class per API resource
|
|
54
|
-
- Methods match HTTP verbs: `get`, `post`, `put`, `patch`, `delete`
|
|
55
|
-
- No external runtime dependencies — only Node built-ins
|
|
56
|
-
- ESM modules (`"type": "module"`)
|
|
57
|
-
|
|
58
|
-
## Adding a new resource
|
|
59
|
-
1. Create `src/api/v1/ResourceName.js` with a class that receives the client
|
|
60
|
-
2. Register it in `src/api/v1/index.js`
|
|
61
|
-
3. Write integration tests in `tests/integration/api/v1/resource-name.test.js`
|
|
62
|
-
|
|
63
|
-
Verify a new/changed method by running its integration test against a locally running `api`
|
|
64
|
-
(`npm test`), not by scripting one-off `curl`/fetch calls in a shell. The integration test is the
|
|
65
|
-
artifact that proves the SDK and the API agree, and it's what keeps both repos in sync going
|
|
66
|
-
forward — a curl call proves nothing once the terminal closes.
|
|
67
|
-
|
|
68
|
-
## Testing coverage requirements
|
|
69
|
-
|
|
70
|
-
Same pattern as `api`'s endpoint tests (see its `AGENTS.md`), applied per SDK method:
|
|
71
|
-
|
|
72
|
-
- **Missing/malformed params** — call each method with required params omitted and with wrong-format values; confirm the SDK surfaces the API's validation error correctly rather than swallowing it or throwing something unrelated.
|
|
73
|
-
- **Permissions** — exercise each method as every relevant user role (including unauthenticated) against the API and confirm the SDK surfaces 401/403 correctly — not just the happy-path success response for the one role the method was built for.
|
|
74
|
-
|
|
75
|
-
## Internationalisation (i18n)
|
|
76
|
-
The SDK is language-neutral — it must never contain human-readable strings.
|
|
77
|
-
|
|
78
|
-
- Do not include hardcoded error messages or labels in SDK source.
|
|
79
|
-
- Error objects thrown by the SDK must expose a machine-readable `status` (HTTP code) and `data` (raw API body). The consuming app handles translation.
|
|
80
|
-
- Do not add locale/language logic to the SDK — that belongs to the frontend.
|
|
81
|
-
|
|
82
|
-
## API ↔ SDK sync rule
|
|
83
|
-
|
|
84
|
-
**This SDK must stay in sync with [`insignia-education/api`](../api) at all times.** Any endpoint added, renamed, or removed in the API must be reflected here in the same task/commit.
|
|
85
|
-
|
|
86
|
-
- New endpoint in `api` → new method in the correct `src/api/v1/*.js` class
|
|
87
|
-
- Removed endpoint → remove or deprecate the corresponding SDK method
|
|
88
|
-
- Never leave the SDK behind the API; the `front` repo relies solely on this SDK
|
|
89
|
-
|
|
90
|
-
## Consumption — never symlink
|
|
91
|
-
|
|
92
|
-
Consumers (`front`, `api`) must install this package the normal npm way — **never** via a symlink
|
|
93
|
-
(`npm link`, a manual `ln -s` into a consumer's `node_modules`, etc.), even for local iteration.
|
|
94
|
-
|
|
95
|
-
- A symlinked package looks like it works, but an `npm install`/`npm ci` in the consumer repo can
|
|
96
|
-
silently replace the link with a stale registry copy — the consumer keeps running old SDK code
|
|
97
|
-
with no error, and edits stop propagating until someone notices at runtime.
|
|
98
|
-
- Instead: bump this package's version (`npm version patch|minor` — the pre-commit hook rejects a
|
|
99
|
-
commit whose version is already published, so this can't be skipped) and commit it. CI
|
|
100
|
-
(`.github/workflows/npm-publish-github-packages.yml`) publishes automatically on push to
|
|
101
|
-
master — it does **not** bump the version itself, and it does **not** touch any consumer repo,
|
|
102
|
-
so pin the exact new version (no `^`/`~`) in the consumer's `package.json` and run
|
|
103
|
-
`npm install` there yourself.
|
|
104
|
-
- Never publish on your own initiative — pushing the version-bump commit to master is what
|
|
105
|
-
triggers it; don't run `npm publish` by hand.
|
|
106
|
-
|
|
107
|
-
## Never do
|
|
108
|
-
- Don't add runtime dependencies
|
|
109
|
-
- Don't change the constructor signature of `InsigniaApiV1`
|
|
110
|
-
- Don't hardcode API base URLs — always receive from constructor
|
|
111
|
-
- Don't let the SDK lag behind `api` — update both in the same task
|
|
112
|
-
- Don't symlink this package into a consumer's `node_modules` — publish it instead
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
---
|
|
116
|
-
|
|
117
|
-
## Working Style
|
|
118
|
-
|
|
119
|
-
- **Think before coding.** State your assumptions out loud. If the request is ambiguous, ask. If a simpler approach exists, push back. Stop when confused — name what is unclear; do not pick one interpretation and run.
|
|
120
|
-
- **Simplicity first.** Write the minimum code that solves the problem. No speculative abstractions. No flexibility nobody asked for. The test: would a senior engineer call this overcomplicated?
|
|
121
|
-
- **Surgical changes.** Touch only what the task requires. Do not improve neighboring code. Do not refactor what is not broken. Every changed line must trace back to the request.
|
|
122
|
-
- **Goal-driven execution.** Turn vague instructions into verifiable targets before writing a line. "Add validation" becomes "write tests for invalid inputs, then make them pass."
|
|
123
|
-
## Git
|
|
124
|
-
|
|
125
|
-
- **NEVER commit in the agent's or Claude's name.** All commits must be authored solely by the human developer. Do not add `Co-Authored-By` trailers that name Claude or any AI agent — in shared/collaborative repositories this would falsely attribute work and obscure accountability.
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
## Communication style
|
|
129
|
-
- Respond as briefly as possible. Caveman mode: shortest answer that works. No fluff, no summaries, no "here is what I did".
|
|
130
|
-
|
|
131
|
-
---
|
|
132
|
-
|
|
133
|
-
## Git safety (CRITICAL — read every session)
|
|
134
|
-
|
|
135
|
-
**DO NOT MESS WITH GIT.** DO NOT run `git checkout`, `git stash`, `git reset`, `git restore`,
|
|
136
|
-
`git clean`, or any command that discards or overwrites working-tree changes. These repos often
|
|
137
|
-
carry large amounts of **uncommitted** work, and these commands will destroy it irreversibly.
|
|
138
|
-
|
|
139
|
-
If you need to change the current branch: **commit the work first, or ask the user to commit.**
|
|
140
|
-
Never revert, discard, or overwrite changes via git without explicit permission from the user.
|
package/CLAUDE.md
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
# CLAUDE.md
|
|
2
|
-
|
|
3
|
-
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
-
|
|
5
|
-
> **Status: Active — the sole client for `insignia-education/api`.**
|
|
6
|
-
> A thin, zero-runtime-dependency JavaScript SDK wrapping the Laravel 12 backend
|
|
7
|
-
> [`insignia-education/api`](../api). Its only consumer is
|
|
8
|
-
> [`insignia-education/front`](../front) (React 19 + Vite 8 SPA) — `front` never calls `api`
|
|
9
|
-
> directly. `v1` is being finalized and will be permanently frozen once stable; a future `v2`
|
|
10
|
-
> is added alongside `v1`, never in place of it.
|
|
11
|
-
|
|
12
|
-
---
|
|
13
|
-
|
|
14
|
-
> The canonical agent-readable version of these instructions is **`AGENTS.md`** (same directory). Both
|
|
15
|
-
> files are kept in sync; CLAUDE.md adds Claude Code–specific detail where needed. Read `AGENTS.md` first
|
|
16
|
-
> for versioning rules, structure, conventions, testing coverage requirements, the i18n rule, the
|
|
17
|
-
> API↔SDK sync rule, and the "Never do" list — none of that is repeated here.
|
|
18
|
-
|
|
19
|
-
---
|
|
20
|
-
|
|
21
|
-
## Related repos
|
|
22
|
-
|
|
23
|
-
| Repo | Role |
|
|
24
|
-
|---|---|
|
|
25
|
-
| [`api`](../api) | Laravel backend this SDK wraps. Any endpoint added, renamed, or removed there must be mirrored here in the same task — see `AGENTS.md`'s sync rule. |
|
|
26
|
-
| [`front`](../front) | The sole consumer. Talks to `api` exclusively through this package — a method missing here is a method `front` cannot use. |
|
|
27
|
-
|
|
28
|
-
This SDK has no independent purpose — it only exists to mirror `api`. When in doubt about what a
|
|
29
|
-
method should do, the answer is "whatever the matching `api` endpoint does," not a judgment call
|
|
30
|
-
made here.
|
|
31
|
-
|
|
32
|
-
## Deployment / publish (GitHub Actions — read this before touching `master`)
|
|
33
|
-
|
|
34
|
-
`.github/workflows/npm-publish-github-packages.yml` runs on every push to `master`. It is **not**
|
|
35
|
-
a manual `npm publish` a human runs by hand — merging a PR to `master` is the trigger, and that
|
|
36
|
-
merge is a human action, so the "never publish on your own initiative" rule in `AGENTS.md` still
|
|
37
|
-
applies to *merging to master*, not just to running `npm publish` directly.
|
|
38
|
-
|
|
39
|
-
What the workflow actually does: installs, builds, then `npm publish`. That's it — it does **not**
|
|
40
|
-
bump the version (the pre-commit hook already forces that before the commit even lands), and it
|
|
41
|
-
does **not** touch `front` or any other consumer repo.
|
|
42
|
-
|
|
43
|
-
**Practical implications:**
|
|
44
|
-
- The version published is exactly whatever `package.json` says at the commit that landed on
|
|
45
|
-
`master`. If that version is already on npm (e.g. someone forgot to bump it), the publish step
|
|
46
|
-
fails loudly — there's no silent overwrite or skip.
|
|
47
|
-
- Nothing else updates automatically: after a merge here, a human still has to pin the exact new
|
|
48
|
-
version (no `^`/`~`) in `front/package.json` and run `npm install` there — see this repo's
|
|
49
|
-
`AGENTS.md` and `front/AGENTS.md`'s API ↔ SDK sync rule.
|
|
50
|
-
- Publishes via npm's OIDC trusted publishing (`permissions: id-token: write`) — no `NPM_TOKEN` or
|
|
51
|
-
other secret, and no cross-repo permissions, are needed anymore.
|
package/babel.config.cjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
module.exports = {presets: [['@babel/preset-env', {targets: {node: 'current'}}]]}
|
package/eslint.config.mjs
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import js from "@eslint/js";
|
|
2
|
-
import globals from "globals";
|
|
3
|
-
|
|
4
|
-
export default [
|
|
5
|
-
js.configs.recommended,
|
|
6
|
-
{
|
|
7
|
-
files: ["src/**/*.js"],
|
|
8
|
-
languageOptions: {
|
|
9
|
-
globals: {
|
|
10
|
-
...globals.node,
|
|
11
|
-
fetch: "readonly",
|
|
12
|
-
},
|
|
13
|
-
},
|
|
14
|
-
rules: {
|
|
15
|
-
"no-unused-vars": "warn",
|
|
16
|
-
"no-console": "warn",
|
|
17
|
-
},
|
|
18
|
-
},
|
|
19
|
-
{
|
|
20
|
-
files: ["tests/**/*.js"],
|
|
21
|
-
languageOptions: {
|
|
22
|
-
globals: {
|
|
23
|
-
...globals.node,
|
|
24
|
-
...globals.jest,
|
|
25
|
-
fetch: "readonly",
|
|
26
|
-
},
|
|
27
|
-
},
|
|
28
|
-
},
|
|
29
|
-
];
|
package/jest.config.mjs
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
/** @type {import('jest').Config} */
|
|
2
|
-
const config = {
|
|
3
|
-
collectCoverage: true,
|
|
4
|
-
coverageDirectory: 'coverage',
|
|
5
|
-
coverageProvider: 'v8',
|
|
6
|
-
|
|
7
|
-
reporters: [
|
|
8
|
-
'default',
|
|
9
|
-
['jest-html-reporter', {
|
|
10
|
-
outputPath: 'coverage/test-report.html',
|
|
11
|
-
pageTitle: 'API SDK Test Report',
|
|
12
|
-
includeFailureMsg: true,
|
|
13
|
-
includeConsoleLog: true,
|
|
14
|
-
}],
|
|
15
|
-
],
|
|
16
|
-
|
|
17
|
-
// Run via `npm test`, which invokes unit and integration as two separate
|
|
18
|
-
// `jest --selectProjects` calls (integration also with --runInBand)
|
|
19
|
-
// rather than one combined parallel run: Jest has a multi-project quirk
|
|
20
|
-
// where a later project's tests can silently fall back to the global
|
|
21
|
-
// 5000ms default instead of this project's own testTimeout when both
|
|
22
|
-
// projects run together in one process, and integration tests hit a
|
|
23
|
-
// single-threaded `php artisan serve` backend that serializes requests
|
|
24
|
-
// anyway — parallel workers just queue up and time out against it.
|
|
25
|
-
projects: [
|
|
26
|
-
{
|
|
27
|
-
displayName: 'unit',
|
|
28
|
-
testMatch: [
|
|
29
|
-
'<rootDir>/tests/client.test.js',
|
|
30
|
-
'<rootDir>/tests/api/**/*.test.js',
|
|
31
|
-
],
|
|
32
|
-
transform: { '^.+\\.(js|jsx)$': 'babel-jest' },
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
displayName: 'integration',
|
|
36
|
-
testMatch: ['<rootDir>/tests/integration/**/*.test.js'],
|
|
37
|
-
transform: { '^.+\\.(js|jsx)$': 'babel-jest' },
|
|
38
|
-
setupFiles: ['<rootDir>/tests/integration/loadEnv.js'],
|
|
39
|
-
// Generous — amd64 emulation (api-sdk-js's Docker test env on
|
|
40
|
-
// Apple Silicon) occasionally makes an individual request take
|
|
41
|
-
// 10-20s+ under CPU contention.
|
|
42
|
-
testTimeout: 60000,
|
|
43
|
-
},
|
|
44
|
-
],
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
export default config;
|
|
File without changes
|
package/scss/index.scss
DELETED