@openora/create 0.1.0 → 0.4.1-canary.101
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/README.md +74 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/generated/core-version.d.ts +1 -1
- package/dist/generated/core-version.d.ts.map +1 -1
- package/dist/generated/core-version.js +1 -1
- package/dist/generated/core-version.js.map +1 -1
- package/package.json +3 -3
- package/template/README.md.tpl +1 -1
- package/template/__dot__env.example +3 -1
- package/template/__dot__gitignore +1 -1
- package/template/__dot__rulesync/commands/adr.md +32 -0
- package/template/__dot__rulesync/commands/check.md +3 -3
- package/template/__dot__rulesync/commands/doctor.md +16 -0
- package/template/__dot__rulesync/commands/scaffold-module.md +2 -2
- package/template/__dot__rulesync/commands/scaffold-plugin.md +1 -1
- package/template/__dot__rulesync/commands/scaffold-route.md +1 -1
- package/template/__dot__rulesync/hooks/guard-generated.mjs +3 -3
- package/template/__dot__rulesync/rules/conventions.md +90 -0
- package/template/__dot__rulesync/rules/e2e-conventions.md +48 -0
- package/template/__dot__rulesync/rules/oss-boundaries.md +31 -0
- package/template/__dot__rulesync/rules/overview.md +9 -2
- package/template/__dot__rulesync/skills/add-feature/SKILL.md +3 -3
- package/template/__dot__rulesync/skills/create-plugin/SKILL.md +6 -6
- package/template/__dot__rulesync/skills/create-pr/SKILL.md +1 -1
- package/template/__dot__rulesync/skills/create-ui-module/SKILL.md +58 -0
- package/template/__dot__rulesync/skills/handoff/SKILL.md +94 -0
- package/template/__dot__rulesync/skills/review/SKILL.md +111 -0
- package/template/__dot__rulesync/subagents/builder.md +3 -3
- package/template/__dot__rulesync/subagents/debugger.md +1 -2
- package/template/__dot__rulesync/subagents/qa.md +1 -1
- package/template/__dot__rulesync/subagents/quality-reviewer.md +67 -0
- package/template/__dot__rulesync/subagents/security-reviewer.md +54 -0
- package/template/apps/api/package.json.tpl +1 -2
- package/template/apps/api/src/main.ts.tpl +1 -3
- package/template/apps/api/src/seed.ts.tpl +5 -1
- package/template/docker-compose.yml +11 -0
- package/template/docs/standards/comments.md +16 -0
- package/template/{__dot__rulesync/rules/db-conventions.md → docs/standards/database.md} +15 -21
- package/template/docs/standards/enforcement.md +12 -0
- package/template/docs/standards/errors.md +26 -0
- package/template/docs/standards/frontend.md +60 -0
- package/template/docs/standards/functions.md +38 -0
- package/template/docs/standards/git-delivery.md +16 -0
- package/template/docs/standards/module-structure.md +37 -0
- package/template/docs/standards/testing.md +48 -0
- package/template/docs/standards/types.md +31 -0
- package/template/package.json.tpl +4 -4
- package/template/rulesync.jsonc +1 -1
- package/template/turbo/generators/config.ts +1 -1
- package/template/turbo.json +14 -2
- package/template/__dot__rulesync/skills/code-review/SKILL.md +0 -111
- package/template/apps/api/src/migrate.ts.tpl +0 -46
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
---
|
|
2
|
+
root: false
|
|
3
|
+
targets:
|
|
4
|
+
- '*'
|
|
5
|
+
globs:
|
|
6
|
+
- '**/*'
|
|
7
|
+
description: Engineering code conventions (TS, DB, frontend, testing, git) - the always-on core, with a routing table to full detail in docs/standards/.
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Engineering conventions
|
|
11
|
+
|
|
12
|
+
The always-on core of the code standard: what you must obey while typing. Detail, examples, and
|
|
13
|
+
rationale live in `docs/standards/` - read the one file that matches the change instead of
|
|
14
|
+
carrying all of it. The enforced import graph lives in `oss-boundaries`; Playwright rules in
|
|
15
|
+
`e2e-conventions`.
|
|
16
|
+
|
|
17
|
+
| Change you are making | Read first |
|
|
18
|
+
| ------------------------------------- | ------------------------------------ |
|
|
19
|
+
| schema, type, enum-like value set | `docs/standards/types.md` |
|
|
20
|
+
| function, service method, constructor | `docs/standards/functions.md` |
|
|
21
|
+
| new package, overlay, module layout | `docs/standards/module-structure.md` |
|
|
22
|
+
| a comment or JSDoc | `docs/standards/comments.md` |
|
|
23
|
+
| error class, catch, money path | `docs/standards/errors.md` |
|
|
24
|
+
| a test | `docs/standards/testing.md` |
|
|
25
|
+
| commit, PR | `docs/standards/git-delivery.md` |
|
|
26
|
+
| a failing gate, a new lint rule | `docs/standards/enforcement.md` |
|
|
27
|
+
| React/UI component, page, styling | `docs/standards/frontend.md` |
|
|
28
|
+
| SQL, Drizzle, migration, seed | `docs/standards/database.md` |
|
|
29
|
+
|
|
30
|
+
`docs/standards/frontend.md` doesn't apply to a headless/api-only repo - delete it (and its row
|
|
31
|
+
above) if this repo has no UI apps.
|
|
32
|
+
|
|
33
|
+
## Philosophy
|
|
34
|
+
|
|
35
|
+
- Functional and declarative: pure functions, immutable data, composition. No stateful classes, no
|
|
36
|
+
imperative accumulation loops.
|
|
37
|
+
- Explicit over magic: no decorators, no auto-discovery, no reflection. Every wiring point is a
|
|
38
|
+
greppable typed call (`ctx.provide(TOKEN, factory)`).
|
|
39
|
+
- Self-documenting: clear names beat comments (`percentChange`, not `d` + a comment).
|
|
40
|
+
- YAGNI then DRY: don't build for imagined futures; abstract on the third occurrence, not the
|
|
41
|
+
first.
|
|
42
|
+
- Boring and consistent: match the surrounding code's idiom, naming, and density.
|
|
43
|
+
|
|
44
|
+
## Never (lint-enforced unless noted)
|
|
45
|
+
|
|
46
|
+
- `any` outside tests, `!` non-null assertions, `as` casts to silence the compiler (`as const` is
|
|
47
|
+
fine).
|
|
48
|
+
- `interface`, TS `enum`, decorators, inheritance for reuse, default exports (exceptions:
|
|
49
|
+
`*.config.*`, `plugin.ts`, Next.js App Router files).
|
|
50
|
+
- Hand-written duplicates of an inferrable type, re-inferring an imported schema, re-typing
|
|
51
|
+
derived schema fields, ad-hoc/duplicated Zod schemas outside a module's `contract/`.
|
|
52
|
+
- Re-exporting types "to be nice" - import from where defined.
|
|
53
|
+
- Inline `fetch`/`axios` in module code - third-party access is a port + adapter bound at the
|
|
54
|
+
composition root.
|
|
55
|
+
- Deep (`../../`+) relative imports that leave your module/zone, imports of another module's
|
|
56
|
+
internals, import cycles, deep `dist/`/`src/` paths into another package.
|
|
57
|
+
- SQL anti-patterns (bare `timestamp()`, CamelCase identifiers, hand-edited migrations) - detail
|
|
58
|
+
in `docs/standards/database.md`.
|
|
59
|
+
|
|
60
|
+
## Always
|
|
61
|
+
|
|
62
|
+
- **Naming:** files `kebab-case.ts`, one concept per file, filename names the concept
|
|
63
|
+
(`wallet.service.ts`, never `helpers.ts`); types `PascalCase`; values/functions `camelCase`;
|
|
64
|
+
true global constants `SCREAMING_SNAKE_CASE`; Zod schemas `<Name>Schema` with inferred type
|
|
65
|
+
`<Name>`; booleans read as predicates (`isActive`, `canEdit`); money is a decimal string plus a
|
|
66
|
+
`currency` field alongside it, never `amountCents`.
|
|
67
|
+
- **One source of truth per shape** - infer, never hand-write: `z.infer<typeof XSchema>`,
|
|
68
|
+
`typeof x.$inferSelect`. Full detail: `docs/standards/types.md`.
|
|
69
|
+
- **Literal config arrays/objects (option lists, key sets) use `as const`**, not an explicit union
|
|
70
|
+
type annotation - let TypeScript infer the literal types.
|
|
71
|
+
- **Schema-first at every boundary** (HTTP, config, env, events); validate once at the edge, trust
|
|
72
|
+
the type after.
|
|
73
|
+
- **Entity ids typed through their owning type** (`playerId: Player['id']`), never a bare
|
|
74
|
+
`string`.
|
|
75
|
+
- **Guard clauses first, main path last; more than 3 params -> one named object.** Detail:
|
|
76
|
+
`docs/standards/functions.md`.
|
|
77
|
+
- **Construct objects by spread + override**, never a hand-copied field list.
|
|
78
|
+
- **Side effects at the edges**; money paths are transactional AND idempotent (a DB guard inside
|
|
79
|
+
the transaction, not just an idempotency key). Detail: `docs/standards/errors.md`.
|
|
80
|
+
- **Typed, named error classes** from the shared factories, mapped to transport in the router's
|
|
81
|
+
`mapErrors`.
|
|
82
|
+
- **Pin exact dependency versions** (no `^`/`~`); add a dependency deliberately - std lib or a few
|
|
83
|
+
lines often beat a tree.
|
|
84
|
+
- **Test at the outermost tier that reaches the behaviour:** a UI journey -> browser E2E; an API
|
|
85
|
+
route, an overlay, a vendor adapter, anything with SQL -> API E2E against real Postgres with the
|
|
86
|
+
vendor stubbed at its HTTP boundary; a pure function -> a co-located unit test in `__tests__/`.
|
|
87
|
+
Never fake a query builder and never let a spy assertion be the point of a test; always cover
|
|
88
|
+
authz negatives. Detail: `docs/standards/testing.md`.
|
|
89
|
+
- **Green before review:** `pnpm verify` passes. Conventional commits, lowercase subject, one PR
|
|
90
|
+
per concern. Never push without explicit confirmation. Detail: `docs/standards/git-delivery.md`.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
---
|
|
2
|
+
root: false
|
|
3
|
+
targets:
|
|
4
|
+
- '*'
|
|
5
|
+
globs:
|
|
6
|
+
- 'apps/e2e/**'
|
|
7
|
+
description: Playwright E2E conventions - specs run against the real stack; mocking is a narrow, justified exception.
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# E2E conventions (`apps/e2e`)
|
|
11
|
+
|
|
12
|
+
Two kinds of spec live here:
|
|
13
|
+
|
|
14
|
+
- **Browser specs** (`tests/<app>/**`) - a player or admin journey through the UI.
|
|
15
|
+
- **API specs** (`tests/api/**`) - the `api` Playwright project: no browser, no `page`. Drives the real API over HTTP against real Postgres, with each external vendor replaced by a stub HTTP server the API is pointed at by env. This is the tier that proves an overlay end to end: request -> route -> service -> rows -> webhook -> resulting state. `USE_MOCKS` does not apply here at all.
|
|
16
|
+
|
|
17
|
+
## Real stack by default
|
|
18
|
+
|
|
19
|
+
Every spec runs against the real seeded stack - API, Postgres, and the apps under test - and that
|
|
20
|
+
run is what blocks merge. A test that never executes the backend cannot tell you the backend works.
|
|
21
|
+
|
|
22
|
+
`USE_MOCKS=true` intercepts responses in the browser and exists only for a state you cannot produce
|
|
23
|
+
for real: a third-party widget or redirect you are not allowed to run in CI. It is an exception you
|
|
24
|
+
justify per spec, never the mode a suite is written for. Anything reachable by seeding data or by
|
|
25
|
+
scripting a vendor stub is NOT such a state - script the stub instead, and prefer the API tier when
|
|
26
|
+
the behaviour under test is the backend's.
|
|
27
|
+
|
|
28
|
+
Existing mocked specs are converted as they are touched; delete the fixture with the last spec that
|
|
29
|
+
used it.
|
|
30
|
+
|
|
31
|
+
## Rules
|
|
32
|
+
|
|
33
|
+
- Import `test`/`expect` from `fixtures.ts`, NEVER from `@playwright/test` - fixtures add `cleanup()` and shared setup.
|
|
34
|
+
- Set up state through the product: seed data or drive the API, so the spec exercises the same path a player would. `mockApi(page, routes)` (from `lib/mocks.ts`) is the escape hatch above - reach for it only after the real setup is genuinely impossible, and never branch test logic on the mode.
|
|
35
|
+
- A mock that stays is typed: fixture shapes in `mocks/<domain>.ts` mirror the response contract - type platform-endpoint fixtures with the `z.infer` contract type from `@openora/*` so a contract change fails typecheck. No loose hand-written JSON.
|
|
36
|
+
- Selectors use `data-testid` - kebab-case, domain-prefixed (`chat-message`, `chat-input`). Never assert on CSS classes or component-library structure; shared UI components spread props so `data-testid` passes through.
|
|
37
|
+
- Page objects in `pages/<name>.page.ts` are functional factories - no classes, no `this`; locators + actions returned as a plain object.
|
|
38
|
+
- Test names are behavioural: "shows masked standings", not "table renders".
|
|
39
|
+
- `cleanup(fn)` reverses any data a test creates (runs in reverse order) - the suite shares one database, so a spec that leaks rows breaks the next one.
|
|
40
|
+
- Layout: `tests/<app>/<domain>/<scenario>.spec.ts` (one Playwright project per app, sharing fixtures/mocks/pages; run one with `--project=<app>`), `mocks/<domain>.ts`, `pages/<name>.page.ts`.
|
|
41
|
+
|
|
42
|
+
## API specs (`tests/api/**`)
|
|
43
|
+
|
|
44
|
+
- Use `request` (Playwright's APIRequestContext), never `page`. Assert status, body, and the state a follow-up request reports - not internals.
|
|
45
|
+
- A vendor stub is a plain `node:http` server under `apps/e2e/`, modelled on `mock-identity-server.mjs`: it answers only the vendor endpoints the flow reaches and records the calls a spec asserts on. Point the API at it with the vendor's base-URL env var; every vendor adapter must accept one.
|
|
46
|
+
- Drive the vendor's inbound side the way the vendor does - post the real webhook shape to the real route with a signature the stub's key material produces. Never call the adapter directly.
|
|
47
|
+
- Own your data: create the player the spec needs and reverse it with `cleanup(fn)`. The suite shares one database.
|
|
48
|
+
- Layout: `tests/api/<domain>/<scenario>.spec.ts`.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
root: false
|
|
3
|
+
targets:
|
|
4
|
+
- '*'
|
|
5
|
+
globs:
|
|
6
|
+
- '**/*'
|
|
7
|
+
description: OSS core is read-only; enforced import/module boundaries.
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# OSS core + import boundaries
|
|
11
|
+
|
|
12
|
+
## Never modify OSS core
|
|
13
|
+
|
|
14
|
+
`@openora/*` is a third-party dependency - read it for reference, never write to it.
|
|
15
|
+
|
|
16
|
+
- Do NOT edit `node_modules/**` or a linked OSS checkout. Those paths are write-denied in `.claude/settings.json`; don't route around it with `sed`, redirection, or scripts. A patched dependency is lost on reinstall and diverges from the published package.
|
|
17
|
+
- Extend from the OUTSIDE only: overlay plugins, adapter rebindings, UI plugins, config.
|
|
18
|
+
- If something can only be fixed in core, STOP and report it upstream (problem, expected behavior, likely location).
|
|
19
|
+
|
|
20
|
+
## Import boundaries (enforced)
|
|
21
|
+
|
|
22
|
+
Enforced by `pnpm check:lint` (oxlint, per-edit), `pnpm check:boundaries` (dependency-cruiser, whole graph), the pre-commit hook, CI, and the agent PostToolUse hook. Fix the import, never work around a violation.
|
|
23
|
+
|
|
24
|
+
- No deep OSS imports: `@openora/*/src/*` or `/dist/*` - import only the published entrypoint or subpath export.
|
|
25
|
+
- No deep imports into your own shared packages - only the barrel/index entrypoint.
|
|
26
|
+
- No app-to-app imports (`apps/api` <-> `apps/web` <-> `apps/backoffice`) - extract shared code to `packages/*`.
|
|
27
|
+
- No cross-module imports inside an app - go through the module barrel, a query invalidation, or a domain event.
|
|
28
|
+
- No overlay-to-overlay imports - couple via a command port, a domain event, or a shared contract.
|
|
29
|
+
- No import cycles.
|
|
30
|
+
|
|
31
|
+
`pnpm check:boundaries:graph` renders the graph (needs Graphviz).
|
|
@@ -14,10 +14,16 @@ this repo. Every per-tool instruction file (`AGENTS.md` - shared, also Codex's b
|
|
|
14
14
|
subagent and command mirrors are generated by
|
|
15
15
|
[rulesync](https://github.com/dyoshikawa/rulesync) from the single source in `.rulesync/`
|
|
16
16
|
(`rules/`, `subagents/`, `commands/`, `mcp.json`). Edit the source under `.rulesync/`, then
|
|
17
|
-
run `pnpm
|
|
17
|
+
run `pnpm gen:agents`. Do not hand-edit the generated files.
|
|
18
18
|
|
|
19
19
|
This repo is a downstream igaming operator built on the OSS platform (`@openora/*`).
|
|
20
20
|
|
|
21
|
+
Sibling rules (load on demand; don't reopen settled questions):
|
|
22
|
+
|
|
23
|
+
- `conventions` - the always-on code standard (naming, types, functions, package structure, errors, testing, git, frontend, DB), with a table routing each kind of change to its deep-dive file in `docs/standards/`.
|
|
24
|
+
- `oss-boundaries` - OSS core is read-only; enforced import/module boundaries.
|
|
25
|
+
- `e2e-conventions` - dual-mode Playwright specs, fixtures, mocks, page objects.
|
|
26
|
+
|
|
21
27
|
## HARD RULE: never modify OSS core
|
|
22
28
|
|
|
23
29
|
`@openora/*` is a third-party dependency - treat it like any published npm package. You may READ it for reference, never write to it.
|
|
@@ -72,6 +78,8 @@ Delegate work to these scoped agents - the `start` / `enhance-intent` playbooks
|
|
|
72
78
|
- `builder` - senior fullstack engineer. Implements overlays, swaps adapters, mounts UI pages.
|
|
73
79
|
- `qa` - writes/runs Playwright E2E tests; triages whether a bug is in OSS core (upstream) or your overlay (local fix).
|
|
74
80
|
- `debugger` - root-causes failures, build-time (Next/Turbopack, tsc, module resolution) and runtime (Chrome DevTools: console/network/DOM). Spawn it whenever something errors or behaves wrong; it finds the cause and routes the fix.
|
|
81
|
+
- `quality-reviewer` - reviews a diff: boundaries, conventions, frontend rules, perf, duplication. Findings only.
|
|
82
|
+
- `security-reviewer` - reviews a diff: authz, secrets/PII, money paths, input validation. Findings only.
|
|
75
83
|
|
|
76
84
|
This repo consumes OSS core as linked packages - never edit `@openora/*` source. If a bug is in core, report it upstream; extend from the outside via plugins.
|
|
77
85
|
|
|
@@ -86,7 +94,6 @@ This server reads the platform CATALOG (not OSS source) - it tells you what exis
|
|
|
86
94
|
- `list-adapters` - vendor swap seams (interface + token + status)
|
|
87
95
|
- `list-routes [module]` - oRPC route namespaces
|
|
88
96
|
- `list-events` - cross-module domain events you can subscribe to
|
|
89
|
-
- `list-slots` - named UI slots you can fill from a UI plugin
|
|
90
97
|
- `describe-module <name>` - one module's group, tables, routes
|
|
91
98
|
- `schema-get <name>` - locate a Zod contract schema's file
|
|
92
99
|
- `get-config-schema` - the igaming-config fields a consumer can set
|
|
@@ -4,7 +4,7 @@ name: add-feature
|
|
|
4
4
|
description: >
|
|
5
5
|
Deliver a feature end-to-end in this consumer repo. Aggregates context (Jira + Confluence + Slack +
|
|
6
6
|
Google Drive + Notion + local docs + past sessions + codebase), produces an approved plan, then drives
|
|
7
|
-
delivery by calling sibling skills - create-plugin (build),
|
|
7
|
+
delivery by calling sibling skills - create-plugin (build), review, create-pr (MR) -
|
|
8
8
|
and create-task for ticket hygiene. Transitions Jira (no comments) and drafts a one-line Slack
|
|
9
9
|
notice. Use on "add feature", "plan <KEY>-XXX", "deliver <KEY>-XXX", or /add-feature [<KEY>-XXX].
|
|
10
10
|
Read-only until the plan is approved; never pushes, transitions Jira, or sends Slack without OK.
|
|
@@ -33,7 +33,7 @@ re-implement their work. The platform-core twin is the `/add-feature` skill in t
|
|
|
33
33
|
- **Read-only until the Step 3 plan is approved.** No edits, commits, pushes, Jira writes, or Slack
|
|
34
34
|
sends before sign-off.
|
|
35
35
|
- Reuse sibling skills, don't reinvent: **create-task** (ticket format), **create-plugin** (build an
|
|
36
|
-
overlay), **
|
|
36
|
+
overlay), **review** (review), **create-pr** (MR). Delegate code to subagents.
|
|
37
37
|
|
|
38
38
|
## Steps
|
|
39
39
|
|
|
@@ -82,7 +82,7 @@ When implementation starts, transition Jira to In Progress (Step 7 - confirm fir
|
|
|
82
82
|
|
|
83
83
|
### 5. Review + tests
|
|
84
84
|
|
|
85
|
-
- Run **
|
|
85
|
+
- Run **review** on the change set; loop `[BLOCK]`/`[WARN]` fixes back through `builder`.
|
|
86
86
|
- Run `/check` (typecheck + lint). Don't proceed on red.
|
|
87
87
|
- Derive an e2e checklist from the AC (happy path, edge cases, authz negatives, error states), then
|
|
88
88
|
`qa`: write/run the E2E specs, drive `chrome-devtools` on failure.
|
|
@@ -13,7 +13,7 @@ description: >
|
|
|
13
13
|
|
|
14
14
|
The platform is extended from the **outside only** (overlay plugin / adapter rebind / UI page /
|
|
15
15
|
config) - never by editing `@openora/*`. This skill picks the correct seam and scaffolds it.
|
|
16
|
-
Domain questions go to `expert` first; review the result with `
|
|
16
|
+
Domain questions go to `expert` first; review the result with `review`.
|
|
17
17
|
|
|
18
18
|
## 1. Classify the seam (ask if unclear)
|
|
19
19
|
|
|
@@ -30,9 +30,9 @@ Hand off via the `add-feature` skill's `handoff.md`. Do not patch the linked OSS
|
|
|
30
30
|
## 2. Ground first
|
|
31
31
|
|
|
32
32
|
- Read `.claude/rules/overview.md` (what you may and may not touch) and
|
|
33
|
-
|
|
33
|
+
`docs/standards/database.md` (if the extension owns tables).
|
|
34
34
|
- Inspect what already exists with the `oss` MCP: `catalog-overview`, `list-adapters` (token +
|
|
35
|
-
default binding to swap), `list-routes` (collision check), `list-
|
|
35
|
+
default binding to swap), `list-routes` (collision check), `list-events`.
|
|
36
36
|
- For a domain rule you can't safely assume (a limit, a KYC threshold, a jurisdiction behavior),
|
|
37
37
|
spawn `expert` before scaffolding.
|
|
38
38
|
|
|
@@ -54,8 +54,8 @@ plugins: [myCustomPspAdapter, walletModule];
|
|
|
54
54
|
|
|
55
55
|
- **Boundaries**: import only package entrypoints (`@openora/core`, not `.../src` or `.../dist`).
|
|
56
56
|
No imports between extensions; cross-extension data goes through the oRPC client or a schema subpath.
|
|
57
|
-
- **Tables**: live in the overlay's own `src/schema/index.ts`; follow `
|
|
58
|
-
`timestamp({ withTimezone: true })`). Run `pnpm db:migrate` after.
|
|
57
|
+
- **Tables**: live in the overlay's own `src/schema/index.ts`; follow `docs/standards/database.md`
|
|
58
|
+
(snake_case, `timestamp({ withTimezone: true })`). Run `pnpm db:migrate` after.
|
|
59
59
|
- **Audit every mutation**: each state-changing action emits a domain event the `audit` add-on
|
|
60
60
|
subscribes to, or resolves `AUDIT_WRITER` and calls `record(...)`. A mutation with no audit is not done.
|
|
61
61
|
- **Validate at the edge**: Zod schemas for every route input/output; no inline `fetch`/SQL in handlers.
|
|
@@ -64,7 +64,7 @@ plugins: [myCustomPspAdapter, walletModule];
|
|
|
64
64
|
|
|
65
65
|
- `/check` (typecheck + lint) green.
|
|
66
66
|
- Plugin boots (API health check / `pnpm dev`).
|
|
67
|
-
- Hand to `
|
|
67
|
+
- Hand to `review` before opening an MR.
|
|
68
68
|
|
|
69
69
|
## Rules
|
|
70
70
|
|
|
@@ -31,7 +31,7 @@ If the current branch isn't in the table, target `dev`.
|
|
|
31
31
|
3. **Commit.** Conventional-commit message (`feat:`, `fix:`, `docs:`, `refactor:`,
|
|
32
32
|
`chore:`); for ticket work prefix the ticket key (e.g. `feat(<KEY>-123): ...`).
|
|
33
33
|
4. **Verify before pushing** (cheap insurance): run the repo's check (e.g.
|
|
34
|
-
`pnpm
|
|
34
|
+
`pnpm check:types && pnpm check:lint`). Don't push a red tree.
|
|
35
35
|
5. **Push** the current branch - but STOP and get an explicit per-action "yes push"
|
|
36
36
|
from the user FIRST. Report the commit SHA, then ask. Invoking this skill is NOT
|
|
37
37
|
push authorization. Pushing to a shared/env branch (`dev`, `stage`, `prod`)
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: create-ui-module
|
|
3
|
+
targets: ['*']
|
|
4
|
+
description: >
|
|
5
|
+
Create a frontend feature module in apps/backoffice or apps/web following ADR-0001's
|
|
6
|
+
modular architecture: standard folder shape, co-located locales, DI hooks, pure
|
|
7
|
+
components, barrel entry, route wiring. Use on "create module", "new feature module",
|
|
8
|
+
"add a backoffice/web module", "/create-ui-module <app> <name>".
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# create-ui-module (consumer)
|
|
12
|
+
|
|
13
|
+
Scaffold a feature module under `src/modules/<name>/` per ADR-0001 (`docs/adr/0001-modular-architecture.md`). The shape is lint-enforced (`tools/oxlint-module-structure.mjs`: folder structure, `use-` hook naming, kebab-case files, client-component naming). Copy an existing module as the reference - `apps/backoffice/src/modules/roles/` is canonical.
|
|
14
|
+
|
|
15
|
+
## 1. Resolve input
|
|
16
|
+
|
|
17
|
+
`<app> <name>` from `$ARGUMENTS` (`backoffice` | `web`, kebab-case name). Ask if missing. Confirm the module doesn't exist and the concern isn't already owned by another module.
|
|
18
|
+
|
|
19
|
+
## 2. Create the shape
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
src/modules/<name>/
|
|
23
|
+
pages/<name>-page.tsx page entrypoint(s)
|
|
24
|
+
components/ presentational only - props in, JSX out
|
|
25
|
+
hooks/use-<x>.ts ALL logic/queries/mutations; deps passed as parameters
|
|
26
|
+
utils/ local helpers (only if needed)
|
|
27
|
+
locales/en.json translation keys
|
|
28
|
+
locales/index.ts registration (below)
|
|
29
|
+
index.ts public barrel - the ONLY entry other code may import
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
`locales/index.ts` pattern (exact):
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
import { registerTranslations } from '@<scope>/ui';
|
|
36
|
+
import en from './en.json';
|
|
37
|
+
|
|
38
|
+
export const locales = { en };
|
|
39
|
+
export const ns = registerTranslations('<name>', locales);
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Components use `useTranslation(ns)`; no hardcoded copy. Non-`en` files mirror `en.json` keys exactly.
|
|
43
|
+
|
|
44
|
+
## 3. Wire the route
|
|
45
|
+
|
|
46
|
+
- backoffice: `src/routes/_authed/<name>.tsx` -> `createFileRoute` with `component` imported from `@/modules/<name>` (see `src/routes/_authed/roles.tsx`).
|
|
47
|
+
- web: the App Router page under `app/(shell)/<name>/` imports from `@/modules/<name>`; client components get `'use client'` line 1 + `.client.tsx` suffix.
|
|
48
|
+
|
|
49
|
+
## 4. Non-negotiables
|
|
50
|
+
|
|
51
|
+
- No cross-module imports - cross-module effects go through query cache invalidation, never a direct import.
|
|
52
|
+
- Outside code imports ONLY the barrel via `@/modules/<name>`; inside the module use relative paths.
|
|
53
|
+
- Hooks take their clients (oRPC/API) as parameters (see `roles/hooks/use-iam-client-deps.ts`) so they're testable without global mocks.
|
|
54
|
+
- Follow `docs/standards/frontend.md` (daisyUI, theme tokens, hoisted `styles` const, React Compiler - no manual memo).
|
|
55
|
+
|
|
56
|
+
## 5. Verify
|
|
57
|
+
|
|
58
|
+
`/check` green (the structure lint runs inside `pnpm check:lint`); route renders (`pnpm dev`). Hand to `review` before an MR.
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: handoff
|
|
3
|
+
description: >
|
|
4
|
+
Package the current task into a self-contained prompt another agent (a
|
|
5
|
+
teammate, or a fresh Claude session in another repo) can execute without this
|
|
6
|
+
conversation. Gathers context from the chat so far plus live repo/environment
|
|
7
|
+
state, then emits a copy-pasteable handoff. Use on "hand this off", "prompt for
|
|
8
|
+
another agent", "write a handoff", when routing an OSS-core change into the
|
|
9
|
+
platform repo, or /handoff [what to hand off | target agent/repo]. Produces a
|
|
10
|
+
copy-pasteable prompt and may use any tool to gather context; the one hard line
|
|
11
|
+
is never force-push.
|
|
12
|
+
allowed-tools:
|
|
13
|
+
- Read
|
|
14
|
+
- Grep
|
|
15
|
+
- Glob
|
|
16
|
+
- Write
|
|
17
|
+
- Edit
|
|
18
|
+
- Bash
|
|
19
|
+
disallowed-tools:
|
|
20
|
+
- Bash(git push --force:*)
|
|
21
|
+
- Bash(git push -f:*)
|
|
22
|
+
- Bash(git push --force-with-lease:*)
|
|
23
|
+
- Bash(git push --force-with-lease)
|
|
24
|
+
- Bash(git push -f)
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
# handoff - write a self-contained prompt for another agent
|
|
28
|
+
|
|
29
|
+
Turn "what we're doing" into a prompt a _stranger_ agent can act on with zero access to this
|
|
30
|
+
chat. The receiver has none of our context, so the prompt must carry all of it.
|
|
31
|
+
|
|
32
|
+
Common use here: an OSS-core change this consumer can't make itself. The receiver is a teammate
|
|
33
|
+
(agent teams on) or a new Claude session rooted in the platform checkout (agent teams off) - see
|
|
34
|
+
the "Fixing something in OSS core" rule. Either way it needs a standalone brief.
|
|
35
|
+
|
|
36
|
+
Optional argument = what to hand off / who to (e.g. `the OSS core publish fix`, `to a teammate in
|
|
37
|
+
the platform repo`, a repo path, an issue/MR#). No argument -> hand off the current in-flight task.
|
|
38
|
+
|
|
39
|
+
## Rules
|
|
40
|
+
|
|
41
|
+
- **One hard line: never force-push** (`git push --force` / `-f` / `--force-with-lease`), in any
|
|
42
|
+
repo, ever - it rewrites shared history. Every other tool is fair game. The skill's main output
|
|
43
|
+
is still the prompt; take further action (commit, push, spawn, launch) only on explicit confirmation.
|
|
44
|
+
- **Self-contained.** The receiver can't see this conversation. Inline every fact they need:
|
|
45
|
+
exact paths, branch/remote names, IDs (MR/PR/ticket), commands, versions, error strings.
|
|
46
|
+
No "as discussed", no "the file we changed", no unresolved pronouns.
|
|
47
|
+
- **Facts over memory.** Verify the moving parts against live state (git, files, CLIs) before
|
|
48
|
+
writing them - don't trust half-remembered branch names or versions.
|
|
49
|
+
- **No secrets.** Never inline tokens, passwords, or `.env` values. Reference the env var name.
|
|
50
|
+
- **Scope, don't dump.** Include what's load-bearing for the task; link/name the rest.
|
|
51
|
+
|
|
52
|
+
## Step 1 - Resolve scope
|
|
53
|
+
|
|
54
|
+
From the argument + the conversation, state in one line: the goal, the target repo/dir, and (if
|
|
55
|
+
known) the agent type or persona best suited. If genuinely ambiguous, ask one clarifying question;
|
|
56
|
+
otherwise proceed with the obvious reading and note the assumption.
|
|
57
|
+
|
|
58
|
+
## Step 2 - Gather live context
|
|
59
|
+
|
|
60
|
+
Pull only what the task touches (skip irrelevant ones):
|
|
61
|
+
|
|
62
|
+
- Repo/env: `pwd`; `git -C <dir> remote -v`; `git -C <dir> branch --show-current`;
|
|
63
|
+
`git -C <dir> status --short`; recent `git log --oneline -5`. Note default/target branch.
|
|
64
|
+
- Work state: relevant file paths (verify they exist), functions/symbols, versions/pins,
|
|
65
|
+
exact error messages or failing job names, IDs (MR/PR/ticket/pipeline).
|
|
66
|
+
- Conventions the receiver must follow: point at the repo's rules (`CLAUDE.md`,
|
|
67
|
+
`.rulesync/`, `AGENTS.md`) rather than restating them; call out any that bit us.
|
|
68
|
+
- What's already done vs. what remains (so they don't redo or undo work).
|
|
69
|
+
|
|
70
|
+
## Step 3 - Emit the handoff
|
|
71
|
+
|
|
72
|
+
Output one fenced markdown block (so it copy-pastes cleanly), using these headings - drop any
|
|
73
|
+
that don't apply, never pad:
|
|
74
|
+
|
|
75
|
+
- **Task** - one imperative sentence: the outcome wanted.
|
|
76
|
+
- **Environment** - repo(s), absolute path(s), remote(s), current + target branch, sibling deps.
|
|
77
|
+
- **Background** - the why + current state + root cause/findings already established. This is
|
|
78
|
+
where prior investigation goes so it isn't repeated.
|
|
79
|
+
- **Do this** - ordered, concrete steps. Name files/symbols/commands. Mark decisions that need
|
|
80
|
+
a human ("report the plan first, don't push").
|
|
81
|
+
- **Verify** - the exact commands/gates that must pass, and the expected green result.
|
|
82
|
+
- **Constraints** - boundaries (read-only zones, "never push without explicit yes", conventional
|
|
83
|
+
commits, branch-off-target, don't touch X). Inherit the repo's rules; restate only the sharp edges.
|
|
84
|
+
|
|
85
|
+
After the block, in <=2 lines: state the key assumption you made, and offer to (a) tweak the
|
|
86
|
+
prompt, (b) save it to a file, or (c) launch it now (spawn a teammate with a suitable agent type,
|
|
87
|
+
or hand it to the operator to paste into a session rooted in the target repo). Only save or launch
|
|
88
|
+
on explicit confirmation.
|
|
89
|
+
|
|
90
|
+
## Quality bar
|
|
91
|
+
|
|
92
|
+
A good handoff passes this test: **hand it to someone who has never seen this repo or chat, and
|
|
93
|
+
they can start in under a minute and finish without asking you anything.** If a step assumes
|
|
94
|
+
context the block doesn't contain, fix the block.
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: review
|
|
3
|
+
targets: ['*']
|
|
4
|
+
description: Multi-agent code review of the working branch against this repo's conventions, OSS-core boundaries, frontend rules, security, and operator-domain fit. Fans out a configurable number of parallel reviewers, each grounded in the rule docs, then synthesizes one verdict. Use on "review this", "code review", "/review", optionally "--agents N", "--base <ref>", "--fix", "--post" (publish findings to the MR as inline comments + a summary verdict), "--yes" (post without confirming), a GitLab MR number, or paths.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# review
|
|
8
|
+
|
|
9
|
+
You are the orchestrator: scope the diff, fan out N reviewers across dimensions, dedup findings, report ONE verdict. Report-only unless `--fix`.
|
|
10
|
+
|
|
11
|
+
Checklist - tick as you go:
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
- [ ] 1. Parse args (--agents / --base / MR# / paths / --fix / --post / --yes)
|
|
15
|
+
- [ ] 2. Scope the diff; if empty, ask
|
|
16
|
+
- [ ] 3. Collect task context (ticket AC + MR discussion)
|
|
17
|
+
- [ ] 4. Pick applicable dimensions; small diff -> review inline, else spawn reviewers in ONE message
|
|
18
|
+
- [ ] 5. Dedup + apply the evidence gate
|
|
19
|
+
- [ ] 6. Report one verdict (+ apply fixes only if --fix)
|
|
20
|
+
- [ ] 7. Post to the MR as inline comments + summary (only if --post)
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## 1. Parse `$ARGUMENTS`
|
|
24
|
+
|
|
25
|
+
- `--agents N` - parallel reviewers (1-5); default one per applicable dimension.
|
|
26
|
+
- `--base <ref>` - diff base; default `dev`.
|
|
27
|
+
- `<number>` - a GitLab MR: `glab mr diff <n>` for the patch, `glab mr view <n>` for intent.
|
|
28
|
+
- paths - restrict review to those files/dirs.
|
|
29
|
+
- `--fix` - apply BLOCK/WARN fixes after the review; default report-only.
|
|
30
|
+
- `--post` - publish findings to the GitLab MR as inline diff-line comments + a one-line summary verdict (§8). Requires an MR number. Draft-and-confirm by default.
|
|
31
|
+
- `--yes` - with `--post`, skip the confirmation and publish straight away.
|
|
32
|
+
|
|
33
|
+
## 2. Scope the diff
|
|
34
|
+
|
|
35
|
+
`git diff <base>...HEAD --name-only`; if empty, fall back to `git status -s`; if still empty, ask. Group changed files by app/package so reviewers and any file-split share the same map. Note the total changed-line count - it picks the mode in §4.
|
|
36
|
+
|
|
37
|
+
## 2b. Collect task context
|
|
38
|
+
|
|
39
|
+
Distill everything here into ONE context block of at most ~30 lines; it is the only task context reviewers receive.
|
|
40
|
+
|
|
41
|
+
- **Ticket.** Extract the BF key from the branch name / MR title. Fetch it (Atlassian MCP or REST) and distill: goal in one line + acceptance criteria as bullets. No key or no access: skip silently.
|
|
42
|
+
- **MR discussion.** If reviewing an MR: `glab mr view <n>` + unresolved discussion threads. Distill to stated intent + open reviewer asks, so the review doesn't repeat or contradict them. No MR: use branch commit subjects as intent.
|
|
43
|
+
- The AC bullets feed the verdict (§7) - a finding "AC not met" needs a specific bullet.
|
|
44
|
+
|
|
45
|
+
## 3. Ground every reviewer (mandatory)
|
|
46
|
+
|
|
47
|
+
Each reviewer MUST read the changed code AND the rule docs owning its dimension before judging - never infer behavior from a diff hunk; if a finding depends on a called function, open it. Cite the docs in findings:
|
|
48
|
+
|
|
49
|
+
- `.claude/rules/conventions.md` - the always-on code standard, with a table routing to the deep-dive file in `docs/standards/`.
|
|
50
|
+
- `docs/standards/frontend.md` - React/UI rules (React Compiler, daisyUI, module isolation) when the diff touches a UI app or the shared UI package.
|
|
51
|
+
- `.claude/rules/oss-boundaries.md` - OSS core read-only; enforced import boundaries.
|
|
52
|
+
- `docs/standards/database.md` - SQL/Drizzle rules for overlay tables.
|
|
53
|
+
- `.claude/rules/workflow.md` + `.claude/rules/overview.md` - how this repo operates.
|
|
54
|
+
|
|
55
|
+
## 4. Dimensions
|
|
56
|
+
|
|
57
|
+
Dimensions and the roster agent that owns each - never `general-purpose`:
|
|
58
|
+
|
|
59
|
+
1. **Boundaries, conventions, frontend, perf, duplication** - `quality-reviewer` (its prompt carries the full lens checklists; always applicable).
|
|
60
|
+
2. **Security & secrets** - `security-reviewer`; only if overlay routes, adapters, auth/session, env/config, or money-adjacent code changed.
|
|
61
|
+
3. **Operator/domain fit** - `expert`; only if business logic changed AND AC exists to judge against.
|
|
62
|
+
|
|
63
|
+
**Small-diff fast path (<= 150 changed lines): no subagents.** Read the changed files in the main thread and apply the applicable agents' checklists yourself (they live in `.claude/agents/<name>.md` - skim, don't spawn). This is the common case and costs a fraction of a fan-out.
|
|
64
|
+
|
|
65
|
+
## 5. Allocate to `--agents N` (large diffs only)
|
|
66
|
+
|
|
67
|
+
- N unset: one reviewer per applicable dimension.
|
|
68
|
+
- N > dimensions: extras are additional `quality-reviewer` instances split by file group (state the split; never silently drop files).
|
|
69
|
+
- N < dimensions: drop `expert` first, then merge security into quality (say so in the report).
|
|
70
|
+
|
|
71
|
+
Spawn all reviewers in a SINGLE message (parallel). Pass each: the changed-file list for its dimension (pre-grouped - reviewers never re-scope), the base ref, the §2b context block, and hard caps: read only changed files + immediate callees; max 10 findings; compact `[SEV] file:line - finding - evidence - fix` lines, no prose; do NOT run `/check`/tests.
|
|
72
|
+
|
|
73
|
+
## 6. Evidence gate (cut false positives)
|
|
74
|
+
|
|
75
|
+
Every reviewer applies this before returning; re-apply it yourself when synthesizing:
|
|
76
|
+
|
|
77
|
+
- Every `[BLOCK]`/`[WARN]` cites a concrete `file:line` AND the rule doc violated - otherwise downgrade to `[INFO]` or drop.
|
|
78
|
+
- High-confidence findings only; unsure = downgrade or omit. Few actionable findings beat flooding.
|
|
79
|
+
- No invented runtime failures - state the trigger path or don't raise it.
|
|
80
|
+
- Don't duplicate what tooling enforces (oxlint, the `/check` gate); for a suspected lint/boundary issue say "confirm with `pnpm check:lint`" - flag only what the gates miss.
|
|
81
|
+
|
|
82
|
+
## 7. Synthesize
|
|
83
|
+
|
|
84
|
+
Dedup by `file:line`, group by dimension, order BLOCK -> WARN -> INFO. Each line: `[SEV] file:line - finding - evidence - rule cited - fix`. Lead with a one-line summary (counts per severity + verdict); end with **APPROVED** / **CHANGES REQUESTED** + the single most critical finding.
|
|
85
|
+
|
|
86
|
+
Severities: `[BLOCK]` must fix before merge (core edit, boundary break, authz/secret/PII risk, broken extension wiring); `[WARN]` should fix (convention violation, missing test, weak validation); `[INFO]` FYI / hardening.
|
|
87
|
+
|
|
88
|
+
If `--fix`: apply BLOCK + WARN fixes in the working tree (smallest diff satisfying the cited rule), run `/check`, report green/red. Leave INFO untouched. Never commit or push.
|
|
89
|
+
|
|
90
|
+
## 8. Post to the MR (`--post`)
|
|
91
|
+
|
|
92
|
+
Only when `--post` is set and the target is an MR number. Turns findings into terse review comments: one line each, brief why, backtick every identifier.
|
|
93
|
+
|
|
94
|
+
Post BLOCK + WARN as inline threads; include INFO only if it maps to a concrete `file:line`. One comment per finding, one line each.
|
|
95
|
+
|
|
96
|
+
1. **Draft.** Rewrite each finding as a terse comment keyed to its `file:line`. Compose the summary as ONE sentence stating whether the changes block prod/push, e.g. `Not a blocker for push - a few cleanups worth doing.` or `Blocker: BLOCK finding in `x.ts` must be fixed before we push.`
|
|
97
|
+
2. **Confirm.** Show all drafted comments + the summary and stop for approval - UNLESS `--yes`, then skip straight to posting.
|
|
98
|
+
3. **Post inline comments** as positional discussions on the diff. Mechanics + gotchas are in the Notion memory `glab MR inline diff-line comments (positional discussions)` (query the Memories DB) - the short of it:
|
|
99
|
+
- Diff SHAs from `glab api "projects/consumer%2Fconsumer/merge_requests/<n>" | jq .diff_refs`.
|
|
100
|
+
- Anchor on the NEW-file line of an added (`+`) line (`git show <src-branch>:<file> | grep -n`).
|
|
101
|
+
- POST JSON (build with Python `json.dumps` to dodge quoting) to `.../merge_requests/<n>/discussions` with a `position` object; `glab api -H "Content-Type: application/json" ... --input -`. Do NOT use `-f "position[...]"` - nested params silently drop the position.
|
|
102
|
+
- Verify each response's `.notes[0].position.new_line`; if null it fell back to a general note - delete (`glab api -X DELETE .../notes/<id>`) and retry.
|
|
103
|
+
4. **Post the summary** as one general MR note (`glab mr note <n> -m "<one sentence>"`).
|
|
104
|
+
5. Report back the count posted + the summary verdict. Never resolve threads; never push.
|
|
105
|
+
|
|
106
|
+
## Constraints
|
|
107
|
+
|
|
108
|
+
- Reviewers report; only the orchestrator edits, and only under `--fix` (working tree only - no commit, no push).
|
|
109
|
+
- NEVER edit `@openora/*` core or `node_modules`.
|
|
110
|
+
- Every finding cites a rule doc - no ungrounded opinions.
|
|
111
|
+
- Cap at 5 parallel reviewers.
|
|
@@ -46,17 +46,17 @@ my-igaming/
|
|
|
46
46
|
2. Create `apps/api/src/extensions/<vendor>/plugin.ts`:
|
|
47
47
|
|
|
48
48
|
```ts
|
|
49
|
-
import {
|
|
49
|
+
import type { CoreTokenCatalog, Plugin } from '@openora/core/server';
|
|
50
50
|
import { KYC_ADAPTER } from '@openora/adapters';
|
|
51
51
|
import { MyKycAdapter } from './src/my-kyc-adapter.js';
|
|
52
52
|
|
|
53
|
-
export default
|
|
53
|
+
export default {
|
|
54
54
|
id: 'my-kyc',
|
|
55
55
|
dependsOn: ['identity'], // always load after the default-binding module
|
|
56
56
|
register(ctx) {
|
|
57
57
|
ctx.provide(KYC_ADAPTER, () => new MyKycAdapter());
|
|
58
58
|
},
|
|
59
|
-
}
|
|
59
|
+
} as const satisfies Plugin<CoreTokenCatalog>;
|
|
60
60
|
```
|
|
61
61
|
|
|
62
62
|
3. Register it in `extensions.config.ts` AFTER the module that owns the default binding.
|
|
@@ -26,7 +26,7 @@ Reproduce deterministically with a build, not the dev server (dev caches aggress
|
|
|
26
26
|
|
|
27
27
|
```bash
|
|
28
28
|
pnpm -C apps/web exec next build # or apps/backoffice
|
|
29
|
-
pnpm
|
|
29
|
+
pnpm check:types
|
|
30
30
|
```
|
|
31
31
|
|
|
32
32
|
Common consumer-side causes (this stack links `@openora/*` from a sibling checkout):
|
|
@@ -35,7 +35,6 @@ Common consumer-side causes (this stack links `@openora/*` from a sibling checko
|
|
|
35
35
|
| ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
36
36
|
| `Module not found: Can't resolve '@openora/...'` but `node -e "require.resolve(...)"` works | A bundler won't compile across the link: boundary (packages live outside the project root) | point the bundler's project root at the common ancestor of your frontend repo and the OSS checkout, and allow imports from outside the root (eg Next.js `turbopack.root` + `experimental.externalDir: true`). |
|
|
37
37
|
| `extends "@openora/tsconfig/..." doesn't resolve` | An `extends` chain through a symlinked tsconfig | the `@openora/tsconfig` configs must be self-contained (no `extends`) |
|
|
38
|
-
| Resolves but won't import | `@openora/*` not built | run `pnpm build:oss` |
|
|
39
38
|
| Stale error after a fix | Turbopack cache | `rm -rf apps/*/.next` and rebuild |
|
|
40
39
|
|
|
41
40
|
To confirm a resolution issue is the bundler (not a missing dep):
|
|
@@ -23,7 +23,7 @@ The OSS platform is headless (API + modules only) - the player app and backoffic
|
|
|
23
23
|
| Player app | http://localhost:3000 | operator |
|
|
24
24
|
| Backoffice | http://localhost:3002 | operator |
|
|
25
25
|
|
|
26
|
-
Seed credentials (after `pnpm seed`): `admin@oss.dev` / `password123`
|
|
26
|
+
Seed credentials (after `pnpm db:seed`): `admin@oss.dev` / `password123`
|
|
27
27
|
|
|
28
28
|
Confirm actual ports and which UIs exist with the operator - they may have only an API, or a single combined app.
|
|
29
29
|
|