@kudusov.takhir/ba-toolkit 1.3.0 → 1.3.2

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/CHANGELOG.md CHANGED
@@ -11,6 +11,40 @@ Versions follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
11
11
 
12
12
  ---
13
13
 
14
+ ## [1.3.2] — 2026-04-08
15
+
16
+ ### Fixed
17
+
18
+ - **`bin/ba-toolkit.js` `cmdInit` ignored `runInstall` return value.** When the user declined the "Overwrite? (y/N)" prompt for an existing skill destination, `runInstall` returned `false`, but `cmdInit` ignored it and printed the success path ("Project is ready. Next steps: Restart Claude Code to load the new skills") even though no skills were installed. The next-steps block now branches on the install result and tells the user how to retry: `ba-toolkit install --for {agentId}`.
19
+ - **`parseArgs` did not accept `--key=value` form.** The hand-rolled parser only understood `--key value` (space-separated). Users typing the GNU long-option style accepted by git/npm/gh (`--name=MyApp`, `--domain=saas`) silently lost the value — the flag was stored as `name=MyApp` set to `true` and the script then prompted for the project name interactively. Both forms now work and can be mixed in a single invocation. Splits on the first `=` only, so values containing further `=` characters are preserved (e.g. `--name="Foo=Bar"`).
20
+ - **No SIGINT handler / readline lifecycle issues.** Each `prompt()` call previously created a fresh `readline.Interface` and closed it after the answer. Hitting Ctrl+C mid-prompt killed Node abruptly and left some terminals in raw mode. Piped stdin that closed mid-flow caused the next prompt's promise to hang forever and the process to exit silently with no error message. Fixed by switching to a single shared `readline.Interface` per CLI invocation, adding a `process.on('SIGINT')` handler that prints a clean `Cancelled.` message and exits with code 130, and rejecting in-flight prompt promises with `err.code = 'INPUT_CLOSED'` when the input stream closes prematurely. The outer `main().catch(...)` filters this code to print a friendly two-line message instead of a Node stack trace.
21
+ - **Silent failure when slug could not be derived from a non-ASCII name.** `sanitiseSlug` strips everything outside `[a-z0-9-]`, so `--name "Проект Космос"` or `--name "🚀"` produced an empty derived slug. In the non-interactive path the script then exited with a generic `Invalid or empty slug` error with no clue about why. Now in the non-interactive path it prints `Cannot derive a slug from "{name}" — it contains no ASCII letters or digits` plus a one-line workaround (`Pass an explicit slug with --slug, e.g. --slug my-project`). In the interactive path it prints a gray hint above the manual slug prompt explaining we couldn't auto-derive.
22
+ - **`AGENTS.md` template was missing 8 of the 21 skills.** `renderAgentsMd` emitted a "Pipeline Status" table with 13 rows — the 12 numbered stages + the `7a` sub-step. The 8 cross-cutting utilities added in v1.1 and v1.2 (`/trace`, `/clarify`, `/analyze`, `/estimate`, `/glossary`, `/export`, `/risk`, `/sprint`) were missing entirely. Since `AGENTS.md` is the project context every AI agent reads on entry to a new session, those 8 skills were effectively invisible — agents didn't know they existed without re-reading README. Added a second "Cross-cutting Tools" section below the pipeline table listing all 8, with descriptions copied from the canonical README pipeline table. A `MAINTENANCE` comment above the function reminds future-me to update both tables when adding a new skill.
23
+
24
+ ---
25
+
26
+ ## [1.3.1] — 2026-04-08
27
+
28
+ ### Fixed
29
+
30
+ - **`/brief` and `/srs` now load all 9 domain references, not just 3.** Both `skills/brief/SKILL.md` and `skills/srs/SKILL.md` hardcoded a check for `igaming`, `fintech`, `saas` only — a stale list from v1.0 that was never updated when v1.1.0 added six new domain references (`ecommerce`, `healthcare`, `logistics`, `on-demand`, `social-media`, `real-estate`). As a result, users on any of those six domains silently got no domain-specific interview questions, mandatory entities, or glossary. The check now covers all nine shipped domain files, matching the supported list advertised in the CLI and README. No other skill files had the same stale list — only `brief` and `srs` did hardcoded domain matching.
31
+
32
+ ### Changed
33
+
34
+ - **`sprint-template.md` rewritten end-to-end as Nova Analytics (SaaS).** The sprint-plan reference template loaded by `/sprint` was previously a Dragon Fortune iGaming example (slot games, RTP, responsible gambling, bonus wagering, Telegram Mini App). It's now a B2B SaaS product analytics plan — workspace sign-up, data source integration, dashboards with funnel/cohort widgets, metric alerts, SSO, and admin workspace management. Structure (sprint goals, DoD, capacity math, epic labels) is unchanged.
35
+ - **`risk-template.md` rewritten end-to-end as Nova Analytics.** The risk-register reference template loaded by `/risk` had iGaming-specific risks (regulated iGaming jurisdiction, Telegram Mini App API breakage, RTP / bonus wagering knowledge gap). It's now a SaaS analytics risk register: third-party data source rate limits, GDPR DPA, columnar query performance at scale, OIDC/SSO library breaking changes, and columnar analytics storage knowledge gap. Structure (probability × impact scoring, priority tiers, mitigation/contingency sections) is unchanged.
36
+ - **`export-template.md`** — one-line fix: the example Jira label changed from `dragon-fortune` to `nova-analytics`.
37
+ - **iGaming-first ordering removed from user-facing documentation.** README intro, README Domain support table, `docs/FAQ.md`, `docs/USAGE.md`, and `docs/TROUBLESHOOTING.md` all listed iGaming first when enumerating the 9 supported domains. They now follow the SaaS-first order the CLI has used since v1.3.0: `saas → fintech → ecommerce → healthcare → logistics → on-demand → social-media → real-estate → igaming`. The iGaming row in the Domain support table stays — it just moved from position 1 to position 9.
38
+ - **`dragon-fortune` slug example in README.md:186 replaced with `nova-analytics`.** This was the last stray placeholder outside the real `example/dragon-fortune/` project.
39
+
40
+ ### Not changed (deliberately)
41
+
42
+ - `skills/references/domains/igaming.md` — the domain reference itself. iGaming remains a first-class supported domain.
43
+ - `example/dragon-fortune/` — the real end-to-end example project referenced from README.
44
+ - `bin/ba-toolkit.js` / `init.sh` / `init.ps1` `DOMAINS` array iGaming entry — iGaming remains a menu choice in the CLI and shell initialisers.
45
+
46
+ ---
47
+
14
48
  ## [1.3.0] — 2026-04-08
15
49
 
16
50
  ### Changed
@@ -212,7 +246,9 @@ CI scripts that relied on the old behaviour (`init` creates files only, `install
212
246
 
213
247
  ---
214
248
 
215
- [Unreleased]: https://github.com/TakhirKudusov/ba-toolkit/compare/v1.3.0...HEAD
249
+ [Unreleased]: https://github.com/TakhirKudusov/ba-toolkit/compare/v1.3.2...HEAD
250
+ [1.3.2]: https://github.com/TakhirKudusov/ba-toolkit/compare/v1.3.1...v1.3.2
251
+ [1.3.1]: https://github.com/TakhirKudusov/ba-toolkit/compare/v1.3.0...v1.3.1
216
252
  [1.3.0]: https://github.com/TakhirKudusov/ba-toolkit/compare/v1.2.5...v1.3.0
217
253
  [1.2.5]: https://github.com/TakhirKudusov/ba-toolkit/compare/v1.2.4...v1.2.5
218
254
  [1.2.4]: https://github.com/TakhirKudusov/ba-toolkit/compare/v1.2.3...v1.2.4
package/README.md CHANGED
@@ -24,7 +24,7 @@ Structured BA pipeline for AI coding agents — brief to handoff, 21 skills, 9 d
24
24
 
25
25
  BA Toolkit is a set of 21 interconnected skills that run a full business-analysis pipeline inside your AI coding agent. You go from a rough project brief to a development handoff package, and each skill reads the output of the previous ones — maintaining cross-references between artifacts along the chain `FR → US → UC → AC → NFR → Entity → ADR → API → WF → Scenario`.
26
26
 
27
- Unlike one-shot prompting, every artifact is written to disk as Markdown, every ID links back to its source, and `/trace` verifies coverage across the whole pipeline. `/clarify` and `/analyze` catch ambiguities and quality gaps with CRITICAL/HIGH severity ratings. Domain references for 9 industries (iGaming, Fintech, SaaS, E-commerce, Healthcare, Logistics, On-demand, Social/Media, Real Estate) plug in automatically at `/brief`.
27
+ Unlike one-shot prompting, every artifact is written to disk as Markdown, every ID links back to its source, and `/trace` verifies coverage across the whole pipeline. `/clarify` and `/analyze` catch ambiguities and quality gaps with CRITICAL/HIGH severity ratings. Domain references for 9 industries (SaaS, Fintech, E-commerce, Healthcare, Logistics, On-demand, Social/Media, Real Estate, iGaming) plug in automatically at `/brief`.
28
28
 
29
29
  Artifacts are generated in whatever language you write in — ask in English, get English docs; ask in any other language, the output follows.
30
30
 
@@ -183,7 +183,7 @@ Full traceability: FR → US → UC → AC → NFR → Entity → ADR → API
183
183
  | — | `/risk` | Risk register — probability × impact matrix, mitigation per risk | `00_risks_{slug}.md` |
184
184
  | — | `/sprint` | Sprint plan — stories grouped by velocity and capacity with sprint goals | `00_sprint_{slug}.md` |
185
185
 
186
- The project **slug** (e.g., `dragon-fortune`) is set at `/brief` and reused across all files automatically.
186
+ The project **slug** (e.g., `nova-analytics`) is set at `/brief` and reused across all files automatically.
187
187
 
188
188
  ---
189
189
 
@@ -212,15 +212,15 @@ The pipeline is domain-agnostic by default. At `/brief`, you pick a domain, and
212
212
 
213
213
  | Domain | Industries covered |
214
214
  |--------|-------------------|
215
- | **iGaming** | Online slots, sports betting, casino lobbies, Telegram Mini Apps, promo mechanics |
216
- | **Fintech** | Neobanks, payment systems, crypto exchanges, investment platforms, P2P lending |
217
215
  | **SaaS** | B2B platforms, CRM, analytics, marketplaces, EdTech, HRTech |
216
+ | **Fintech** | Neobanks, payment systems, crypto exchanges, investment platforms, P2P lending |
218
217
  | **E-commerce** | B2C stores, B2B catalogs, multi-vendor marketplaces, D2C brands, digital goods |
219
218
  | **Healthcare** | Telemedicine, patient portals, EHR/EMR, clinic management, mental health apps |
220
219
  | **Logistics** | Last-mile delivery, courier management, freight tracking, WMS, fleet management |
221
220
  | **On-demand** | Ride-hailing, home services, task marketplaces, beauty, tutoring, pet care |
222
221
  | **Social / Media** | Social networks, creator platforms, community forums, newsletters, short-video |
223
222
  | **Real Estate** | Property portals, agency CRM, rental management, property management, mortgage tools |
223
+ | **iGaming** | Online slots, sports betting, casino lobbies, Telegram Mini Apps, promo mechanics |
224
224
  | **Custom** | Any other domain — works with general interview questions |
225
225
 
226
226
  Adding a new domain = creating one Markdown file in `skills/references/domains/`. See [docs/DOMAINS.md](docs/DOMAINS.md).
package/bin/ba-toolkit.js CHANGED
@@ -94,6 +94,15 @@ function parseArgs(argv) {
94
94
  break;
95
95
  }
96
96
  if (a.startsWith('--')) {
97
+ // Support --key=value form (in addition to --key value). The `=` must
98
+ // come after at least one character of key, so `--=value` and `--`
99
+ // alone fall through. Splits on the FIRST `=` only — values may
100
+ // contain further `=` characters.
101
+ const eqIdx = a.indexOf('=');
102
+ if (eqIdx > 2) {
103
+ args.flags[a.slice(2, eqIdx)] = a.slice(eqIdx + 1);
104
+ continue;
105
+ }
97
106
  const key = a.slice(2);
98
107
  const next = argv[i + 1];
99
108
  if (next !== undefined && !next.startsWith('-')) {
@@ -114,16 +123,42 @@ function parseArgs(argv) {
114
123
 
115
124
  // --- Prompt helper -----------------------------------------------------
116
125
 
126
+ // Shared across all prompts in a single CLI invocation. Creating a new
127
+ // readline.Interface for every question (the previous approach) made Ctrl+C
128
+ // handling unreliable, leaked listeners on stdin, and broke when stdin was
129
+ // piped (EOF on the second create). One interface per process, closed by
130
+ // closeReadline() once main() finishes (or by the SIGINT handler).
131
+ let sharedRl = null;
132
+
117
133
  function prompt(question) {
118
- const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
119
- return new Promise((resolve) => {
120
- rl.question(question, (answer) => {
121
- rl.close();
134
+ if (!sharedRl) {
135
+ sharedRl = readline.createInterface({ input: process.stdin, output: process.stdout });
136
+ }
137
+ return new Promise((resolve, reject) => {
138
+ let answered = false;
139
+ const onClose = () => {
140
+ if (!answered) {
141
+ const err = new Error('input stream closed before answer');
142
+ err.code = 'INPUT_CLOSED';
143
+ reject(err);
144
+ }
145
+ };
146
+ sharedRl.once('close', onClose);
147
+ sharedRl.question(question, (answer) => {
148
+ answered = true;
149
+ sharedRl.removeListener('close', onClose);
122
150
  resolve(answer.trim());
123
151
  });
124
152
  });
125
153
  }
126
154
 
155
+ function closeReadline() {
156
+ if (sharedRl) {
157
+ sharedRl.close();
158
+ sharedRl = null;
159
+ }
160
+ }
161
+
127
162
  // --- Utilities ---------------------------------------------------------
128
163
 
129
164
  function sanitiseSlug(input) {
@@ -222,6 +257,12 @@ function skillToMdc(srcPath, destPath) {
222
257
  return { destPath: newDestPath, content: mdcFrontmatter + body };
223
258
  }
224
259
 
260
+ // MAINTENANCE: when adding a new skill, update BOTH tables below.
261
+ // - Sequential pipeline stages (numbered 0-11 + 7a sub-step) go in
262
+ // "Pipeline Status" — they have a per-project status that progresses.
263
+ // - Cross-cutting utilities (no fixed stage) go in "Cross-cutting Tools".
264
+ // The README.md pipeline table is the canonical source of truth for the
265
+ // 21-skill list and ordering; keep this template in sync with it.
225
266
  function renderAgentsMd({ name, slug, domain }) {
226
267
  return `# BA Toolkit — Project Context
227
268
 
@@ -253,6 +294,21 @@ function renderAgentsMd({ name, slug, domain }) {
253
294
  | 10 | /scenarios | ⬜ Not started | — |
254
295
  | 11 | /handoff | ⬜ Not started | — |
255
296
 
297
+ ## Cross-cutting Tools
298
+
299
+ Utilities available throughout the pipeline. No fixed stage — invoke whenever they help. See README.md for the prerequisites of each.
300
+
301
+ | Tool | Purpose |
302
+ |------|---------|
303
+ | /trace | Traceability Matrix + coverage gaps |
304
+ | /clarify [focus] | Targeted ambiguity resolution for any artifact |
305
+ | /analyze | Cross-artifact quality report with severity-rated findings |
306
+ | /estimate | Effort estimation — Fibonacci SP, T-shirt sizes, or person-days |
307
+ | /glossary | Unified project glossary with terminology drift detection |
308
+ | /export [format] | Export User Stories to Jira / GitHub Issues / Linear / CSV |
309
+ | /risk | Risk register — probability × impact matrix, mitigation per risk |
310
+ | /sprint | Sprint plan — stories grouped by velocity and capacity with sprint goals |
311
+
256
312
  ## Key Constraints
257
313
 
258
314
  - Domain: ${domain}
@@ -293,12 +349,22 @@ async function cmdInit(args) {
293
349
  if (!slug) {
294
350
  const derived = sanitiseSlug(name);
295
351
  if (nameFromFlag) {
296
- // Non-interactive path: silently accept the derived slug.
352
+ // Non-interactive path. Either accept the derived slug, or fail
353
+ // loudly with a hint when the name has no ASCII letters/digits to
354
+ // derive from (e.g. `--name "Проект"` or `--name "🚀"`). Without
355
+ // this branch the user got an opaque "Invalid or empty slug" with
356
+ // no clue why.
357
+ if (!derived) {
358
+ logError(`Cannot derive a slug from "${name}" — it contains no ASCII letters or digits.`);
359
+ log('Pass an explicit slug with --slug, e.g. --slug my-project');
360
+ process.exit(1);
361
+ }
297
362
  slug = derived;
298
363
  } else if (derived) {
299
364
  const custom = await prompt(` Project slug [${cyan(derived)}]: `);
300
365
  slug = custom || derived;
301
366
  } else {
367
+ log(' ' + gray(`(could not derive a slug from "${name}" — please type one manually)`));
302
368
  slug = await prompt(' Project slug (lowercase, hyphens only): ');
303
369
  }
304
370
  }
@@ -389,9 +455,13 @@ async function cmdInit(args) {
389
455
  }
390
456
 
391
457
  // --- 6. Install skills for the selected agent ---
458
+ // installed: null = no install attempted (--no-install or no agentId),
459
+ // true = install succeeded,
460
+ // false = install was cancelled (e.g. user declined overwrite).
461
+ let installed = null;
392
462
  if (!skipInstall && agentId) {
393
463
  log('');
394
- await runInstall({
464
+ installed = await runInstall({
395
465
  agentId,
396
466
  isGlobal: !!args.flags.global,
397
467
  isProject: !!args.flags.project,
@@ -405,10 +475,16 @@ async function cmdInit(args) {
405
475
  log(' ' + cyan(`Project '${name}' (${slug}) is ready.`));
406
476
  log('');
407
477
  log(' ' + yellow('Next steps:'));
408
- if (!skipInstall && agentId) {
478
+ if (installed === true) {
409
479
  log(' 1. ' + AGENTS[agentId].restartHint);
410
480
  log(' 2. Optional: run /principles to define project-wide conventions');
411
481
  log(' 3. Run /brief to start the BA pipeline');
482
+ } else if (installed === false) {
483
+ log(' 1. Skill install was cancelled. To install later, run:');
484
+ log(' ' + gray(`ba-toolkit install --for ${agentId}`));
485
+ log(' 2. Open your AI assistant (Claude, Cursor, etc.)');
486
+ log(' 3. Optional: run /principles to define project-wide conventions');
487
+ log(' 4. Run /brief to start the BA pipeline');
412
488
  } else {
413
489
  log(' 1. Install skills for your agent:');
414
490
  log(' ' + gray('ba-toolkit install --for claude-code'));
@@ -597,7 +673,26 @@ async function main() {
597
673
  }
598
674
  }
599
675
 
600
- main().catch((err) => {
601
- logError(err && (err.stack || err.message) || String(err));
602
- process.exit(1);
676
+ // Clean exit on Ctrl+C: print on a fresh line so we don't append to a
677
+ // half-typed prompt, close the readline interface so the terminal is
678
+ // returned to a sane state, then exit with the conventional 130 code.
679
+ process.on('SIGINT', () => {
680
+ console.log('\n ' + yellow('Cancelled.'));
681
+ closeReadline();
682
+ process.exit(130);
603
683
  });
684
+
685
+ main()
686
+ .then(() => {
687
+ closeReadline();
688
+ })
689
+ .catch((err) => {
690
+ closeReadline();
691
+ if (err && err.code === 'INPUT_CLOSED') {
692
+ logError('Input stream closed before all prompts could be answered.');
693
+ log('Pass remaining values as flags (e.g. --name, --domain, --for) or run interactively.');
694
+ process.exit(1);
695
+ }
696
+ logError(err && (err.stack || err.message) || String(err));
697
+ process.exit(1);
698
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kudusov.takhir/ba-toolkit",
3
- "version": "1.3.0",
3
+ "version": "1.3.2",
4
4
  "description": "AI-powered Business Analyst pipeline — 21 skills from project brief to development handoff. Works with Claude Code, Codex CLI, Gemini CLI, Cursor, and Windsurf.",
5
5
  "keywords": [
6
6
  "business-analyst",
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: ba-brief
3
3
  description: >
4
- Generate a high-level Project Brief for projects in any domain (iGaming, Fintech, SaaS, and others). Use this skill when the user enters /brief, or asks to "create a project brief", "describe the project", "start a new project", "project brief", or mentions the starting stage of the analytical pipeline. Also triggers on requests like "begin with a brief", "describe the product", "form a product description". First step of the BA Toolkit pipeline.
4
+ Generate a high-level Project Brief for projects in any domain (SaaS, Fintech, E-commerce, Healthcare, Logistics, and others). Use this skill when the user enters /brief, or asks to "create a project brief", "describe the project", "start a new project", "project brief", or mentions the starting stage of the analytical pipeline. Also triggers on requests like "begin with a brief", "describe the product", "form a product description". First step of the BA Toolkit pipeline.
5
5
  ---
6
6
 
7
7
  # /brief — Project Brief
@@ -10,7 +10,7 @@ Starting point of the BA Toolkit pipeline. Generates a structured Project Brief
10
10
 
11
11
  ## Loading domain reference
12
12
 
13
- Domain references are located in `references/domains/` relative to the `ba-toolkit` directory. Supported domains: `igaming`, `fintech`, `saas`. For other domains, work without a reference file.
13
+ Domain references are located in `references/domains/` relative to the `ba-toolkit` directory. Supported domains: `saas`, `fintech`, `ecommerce`, `healthcare`, `logistics`, `on-demand`, `social-media`, `real-estate`, `igaming`. For other domains, work without a reference file.
14
14
 
15
15
  ## Workflow
16
16
 
@@ -26,7 +26,7 @@ If `00_principles_*.md` exists in the output directory, load it and apply its co
26
26
 
27
27
  ### 3. Domain selection
28
28
 
29
- Ask the user about the project domain. If the domain matches `igaming`, `fintech`, or `saas`, load the corresponding `references/domains/{domain}.md`. Use domain-specific interview questions (section `1. /brief`), typical business goals, risks, and glossary from that file.
29
+ Ask the user about the project domain. If a matching `references/domains/{domain}.md` file exists (currently: `saas`, `fintech`, `ecommerce`, `healthcare`, `logistics`, `on-demand`, `social-media`, `real-estate`, `igaming`), load it and use its domain-specific interview questions (section `1. /brief`), typical business goals, risks, and glossary.
30
30
 
31
31
  If the domain does not match any supported one, record it as `custom:{name}` and use general questions only.
32
32
 
@@ -54,7 +54,7 @@ If a domain reference is loaded, supplement general questions with domain-specif
54
54
  ```markdown
55
55
  # Project Brief: {Project Name}
56
56
 
57
- **Domain:** {igaming | fintech | saas | custom:{name}}
57
+ **Domain:** {saas | fintech | ecommerce | healthcare | logistics | on-demand | social-media | real-estate | igaming | custom:{name}}
58
58
  **Date:** {date}
59
59
 
60
60
  ## 1. Project Summary
@@ -39,7 +39,7 @@ Actual values are filled in by the skill based on the project's artifacts.
39
39
  },
40
40
  "issuetype": { "name": "Story" },
41
41
  "priority": { "name": "High" },
42
- "labels": ["dragon-fortune", "E-01"],
42
+ "labels": ["nova-analytics", "E-01"],
43
43
  "customfield_10016": 3,
44
44
  "customfield_10014": null
45
45
  }
@@ -23,19 +23,19 @@
23
23
 
24
24
  | ID | Title | Category | Probability | Impact | Score | Priority | Status |
25
25
  |----|-------|----------|:-----------:|:------:|:-----:|---------|--------|
26
- | RISK-01 | Payment provider SLA not guaranteed | External | 4 | 5 | 20 | 🔴 Critical | Open |
27
- | RISK-02 | Regulatory approval timeline unknown | Compliance | 3 | 4 | 12 | 🟡 High | Open |
28
- | RISK-03 | Real-time leaderboard at scale unproven | Technical | 3 | 3 | 9 | 🟡 High | Open |
26
+ | RISK-01 | Third-party data source rate limits unclear | External | 4 | 5 | 20 | 🔴 Critical | Open |
27
+ | RISK-02 | GDPR data-processing agreement unsigned | Compliance | 3 | 4 | 12 | 🟡 High | Open |
28
+ | RISK-03 | Columnar query performance under concurrent load unproven | Technical | 3 | 3 | 9 | 🟡 High | Open |
29
29
  | RISK-04 | Scope creep from stakeholder wish list | Business | 3 | 2 | 6 | 🟢 Medium | Open |
30
- | RISK-05 | Telegram Mini App API breaking changes | External | 2 | 3 | 6 | 🟢 Medium | Open |
30
+ | RISK-05 | OIDC / SSO library breaking changes | External | 2 | 3 | 6 | 🟢 Medium | Open |
31
31
  | RISK-06 | Data model changes after /datadict | Technical | 2 | 3 | 6 | 🟢 Medium | Open |
32
- | RISK-07 | Development team unfamiliar with domain | Business | 2 | 1 | 2 | ⚪ Low | Open |
32
+ | RISK-07 | Development team unfamiliar with analytics domain | Business | 2 | 1 | 2 | ⚪ Low | Open |
33
33
 
34
34
  ---
35
35
 
36
36
  ## Risk Details
37
37
 
38
- ### RISK-01 — Payment provider SLA not guaranteed
38
+ ### RISK-01 — Third-party data source rate limits unclear
39
39
 
40
40
  **Category:** External
41
41
  **Probability:** 4 / 5 — Likely
@@ -45,19 +45,19 @@
45
45
  **Source:** `07a_research_{slug}.md`
46
46
 
47
47
  **Description:**
48
- The selected payment provider has not provided a written SLA. If the provider experiences downtime during peak traffic, transactions will fail and user funds may be delayed, directly impacting revenue and trust.
48
+ The product depends on timely event delivery from third-party integrations (Segment and warehouse connectors). The published rate limits do not guarantee sustained throughput at the projected MVP event volume. If a critical integration is rate-limited or breaks its contract, dashboards will show stale or incomplete data and user trust erodes quickly.
49
49
 
50
50
  **Mitigation:**
51
- Negotiate and sign an SLA before launch. Implement a fallback payment provider in the API contract. Add payment provider availability as a monitored NFR metric.
51
+ Run a sustained-throughput test against each integration in sprint 0. Negotiate higher quotas with the providers before launch. Add per-source ingestion lag as a monitored NFR metric with an alert threshold.
52
52
 
53
53
  **Contingency:**
54
- Enable the fallback provider automatically via feature flag if primary provider error rate exceeds 5% over a 5-minute window.
54
+ Enable an ingestion backpressure queue and surface a workspace-level banner when a source is lagging more than 5 minutes behind real-time. Prioritise critical event streams over low-value ones until the lag recovers.
55
55
 
56
56
  **Owner:** Tech Lead
57
57
 
58
58
  ---
59
59
 
60
- ### RISK-02 — Regulatory approval timeline unknown
60
+ ### RISK-02 — GDPR data-processing agreement unsigned
61
61
 
62
62
  **Category:** Compliance
63
63
  **Probability:** 3 / 5 — Possible
@@ -67,19 +67,19 @@ Enable the fallback provider automatically via feature flag if primary provider
67
67
  **Source:** `01_brief_{slug}.md`
68
68
 
69
69
  **Description:**
70
- The product operates in a regulated iGaming jurisdiction. The licensing timeline was listed as an assumption in the Brief. If approval is delayed, the launch date will slip regardless of development readiness.
70
+ The product collects first-party user-behavioural events from EU workspaces. The Brief listed the GDPR data-processing agreement (DPA) with the selected cloud provider as an assumption. If the DPA is delayed or blocked by legal review, the EU launch date will slip regardless of development readiness.
71
71
 
72
72
  **Mitigation:**
73
- Engage legal counsel early to track approval status. Decouple development milestones from the licensing timeline so that technical readiness does not block on regulatory process.
73
+ Engage legal counsel early to track DPA status. Decouple development milestones from the legal timeline so that technical readiness does not block on paperwork. Draft the workspace-level privacy controls (PII redaction, data residency) independently of the final DPA text.
74
74
 
75
75
  **Contingency:**
76
- Prepare a soft launch in an unregulated market while the primary jurisdiction approval is pending.
76
+ Launch in non-EU regions first (US, CA, APAC) while the EU DPA is pending. Gate EU workspace signups behind a feature flag tied to DPA status.
77
77
 
78
78
  **Owner:** Product Manager
79
79
 
80
80
  ---
81
81
 
82
- ### RISK-03 — Real-time leaderboard at scale unproven
82
+ ### RISK-03 — Columnar query performance under concurrent load unproven
83
83
 
84
84
  **Category:** Technical
85
85
  **Probability:** 3 / 5 — Possible
@@ -89,13 +89,13 @@ Prepare a soft launch in an unregulated market while the primary jurisdiction ap
89
89
  **Source:** `07a_research_{slug}.md`
90
90
 
91
91
  **Description:**
92
- The ADR for the leaderboard service chose Redis Sorted Sets as the primary data structure. This approach has not been load-tested for the projected 10,000 concurrent users. If throughput assumptions are wrong, real-time updates will lag and degrade UX.
92
+ The ADR for the analytics query layer chose ClickHouse as the primary store. This setup has not been load-tested for the projected 200 concurrent dashboard viewers reading against a 10 M-event dataset. If query throughput assumptions are wrong, dashboards will exceed the 500 ms p95 NFR target and degrade UX.
93
93
 
94
94
  **Mitigation:**
95
- Conduct a load test spike in the first development sprint. Define a fallback to polling-based updates (every 5s) if WebSocket throughput targets are not met.
95
+ Run a load-test spike in the first development sprint against the reference dataset. Define a caching fallback (5-minute materialised query cache) if raw query throughput does not meet targets.
96
96
 
97
97
  **Contingency:**
98
- Switch to polling-based leaderboard refresh with a 10-second interval. Communicate the change as a phased rollout feature.
98
+ Enable the query cache globally and mark cached dashboards with a "last refreshed" timestamp. Communicate the change as a phased rollout feature.
99
99
 
100
100
  **Owner:** Tech Lead
101
101
 
@@ -123,7 +123,7 @@ Freeze scope at the start of each sprint. Defer any mid-sprint scope additions t
123
123
 
124
124
  ---
125
125
 
126
- ### RISK-05 — Telegram Mini App API breaking changes
126
+ ### RISK-05 — OIDC / SSO library breaking changes
127
127
 
128
128
  **Category:** External
129
129
  **Probability:** 2 / 5 — Unlikely
@@ -133,13 +133,13 @@ Freeze scope at the start of each sprint. Defer any mid-sprint scope additions t
133
133
  **Source:** `07a_research_{slug}.md`
134
134
 
135
135
  **Description:**
136
- The product is built as a Telegram Mini App. Telegram has released breaking changes to the Mini Apps API in previous versions. If the API changes after development, UI components and deep links may require rework.
136
+ The product uses a third-party OIDC / SAML library for workspace SSO. Similar libraries have released breaking changes in previous majors without long deprecation windows. If the library releases a breaking change after development, sign-up and SSO flows may require rework.
137
137
 
138
138
  **Mitigation:**
139
- Pin the Telegram Web App SDK version used in development. Monitor the Telegram changelog and the `@twa-dev/sdk` release notes. Abstract SDK calls behind a thin adapter layer.
139
+ Pin the library version used in development. Monitor the library changelog and security advisories. Abstract SSO calls behind a thin adapter layer so a future swap to a different provider is isolated to one module.
140
140
 
141
141
  **Contingency:**
142
- Allocate a 3-day buffer in the release plan for SDK compatibility fixes.
142
+ Allocate a 3-day buffer in the release plan for library compatibility fixes.
143
143
 
144
144
  **Owner:** Frontend Lead
145
145
 
@@ -167,7 +167,7 @@ Use `/revise` on affected artifacts to propagate changes. Document the delta in
167
167
 
168
168
  ---
169
169
 
170
- ### RISK-07 — Development team unfamiliar with domain
170
+ ### RISK-07 — Development team unfamiliar with analytics domain
171
171
 
172
172
  **Category:** Business
173
173
  **Probability:** 2 / 5 — Unlikely
@@ -177,10 +177,10 @@ Use `/revise` on affected artifacts to propagate changes. Document the delta in
177
177
  **Source:** `01_brief_{slug}.md`
178
178
 
179
179
  **Description:**
180
- The engineering team has limited prior experience with iGaming products. Domain-specific concepts (RTP, bonus wagering, KYC flows) may be misunderstood during implementation, leading to minor defects in edge cases.
180
+ The engineering team has limited prior experience with columnar analytics storage. Domain-specific concepts (event schemas, funnel aggregation, cohort joins) may be misunderstood during implementation, leading to query correctness bugs on edge cases.
181
181
 
182
182
  **Mitigation:**
183
- Include a domain onboarding session as part of sprint 0. Reference the iGaming domain glossary in the Handoff document.
183
+ Include a domain onboarding session as part of sprint 0. Reference the SaaS domain glossary in the Handoff document.
184
184
 
185
185
  **Contingency:**
186
186
  Schedule a BA review checkpoint after the first feature is implemented end-to-end.
@@ -1,11 +1,11 @@
1
- # Sprint Plan: Dragon Fortune
1
+ # Sprint Plan: Nova Analytics
2
2
 
3
- **Domain:** iGaming
3
+ **Domain:** saas
4
4
  **Date:** 2026-04-08
5
- **Slug:** dragon-fortune
5
+ **Slug:** nova-analytics
6
6
  **Sprint length:** 2 weeks
7
7
  **Team velocity:** 35 SP per sprint
8
- **Sources:** `00_estimate_dragon-fortune.md`, `03_stories_dragon-fortune.md`, `00_risks_dragon-fortune.md`, `02_srs_dragon-fortune.md`
8
+ **Sources:** `00_estimate_nova-analytics.md`, `03_stories_nova-analytics.md`, `00_risks_nova-analytics.md`, `02_srs_nova-analytics.md`
9
9
 
10
10
  ---
11
11
 
@@ -13,11 +13,11 @@
13
13
 
14
14
  | Sprint | Goal | Stories | Points | Capacity |
15
15
  |--------|------|:-------:|:------:|:--------:|
16
- | SP-00 | Setup: environment, CI/CD, Telegram Mini App scaffold | — | — | — |
17
- | SP-01 | Players can register via Telegram and spin a slot for the first time | 6 | 34 SP | 97% |
18
- | SP-02 | Players can deposit, withdraw, and view wallet balance | 5 | 32 SP | 91% |
19
- | SP-03 | Referral programme and bonus mechanics are live | 5 | 30 SP | 86% |
20
- | SP-04 | Admin panel: player management, game configuration, reporting | 4 | 28 SP | 80% |
16
+ | SP-00 | Setup: environment, CI/CD, event-ingestion pipeline scaffold | — | — | — |
17
+ | SP-01 | Users can sign up, connect a data source, and see events arrive | 6 | 34 SP | 97% |
18
+ | SP-02 | Users can build dashboards with funnel, cohort, and trend widgets | 5 | 32 SP | 91% |
19
+ | SP-03 | Alerts and collaboration: thresholds, notifications, sharing, SSO | 5 | 30 SP | 86% |
20
+ | SP-04 | Admin workspace: usage, retention, billing, audit log | 4 | 28 SP | 80% |
21
21
  | **Total** | | **20** | **124 SP** | |
22
22
 
23
23
  **Planned:** 20 stories / 124 SP across 4 sprints (8 weeks)
@@ -35,104 +35,104 @@
35
35
  **Tasks:**
36
36
  - Configure CI/CD pipeline (GitHub Actions).
37
37
  - Provision staging environment on cloud infrastructure.
38
- - Scaffold Telegram Mini App project with base authentication stub.
39
- - Establish database schema baseline from `/datadict`.
40
- - Team domain onboarding session (iGaming concepts, RTP, KYC flow).
38
+ - Scaffold Next.js web app and Node ingestion service with a base authentication stub.
39
+ - Establish OLTP (Postgres) and columnar analytics (ClickHouse) schema baselines from `/datadict`.
40
+ - Team alignment session on analytics domain concepts (event taxonomy, funnel modelling, cohort analysis).
41
41
 
42
42
  **Definition of Done for SP-00:**
43
43
  - [ ] All developers can run the project locally.
44
- - [ ] Staging environment is accessible via Telegram.
44
+ - [ ] Staging environment is reachable from the team's workstations.
45
45
  - [ ] Base CI pipeline runs lint + unit tests on every push.
46
46
 
47
47
  ---
48
48
 
49
- ### SP-01 — Players can register via Telegram and spin a slot for the first time
49
+ ### SP-01 — Users can sign up, connect a data source, and see events arrive
50
50
 
51
51
  **Duration:** Weeks 1–2
52
52
  **Capacity:** 35 SP
53
53
 
54
54
  | US | Title | Epic | Priority | Risk | Estimate |
55
55
  |----|-------|------|---------|------|---------|
56
- | US-001 | Register via Telegram | E-01 Auth | Must | RISK-02 ↑ | 5 SP |
57
- | US-002 | Launch slot game from Mini App | E-02 Gameplay | Must | — | 3 SP |
58
- | US-003 | Execute a spin and see result | E-02 Gameplay | Must | RISK-03 ↑ | 13 SP |
59
- | US-004 | View current wallet balance | E-03 Wallet | Must | — | 3 SP |
60
- | US-005 | See responsible gambling session limit warning | E-05 Compliance | Must | — | 5 SP |
61
- | US-006 | View game history (last 20 spins) | E-02 Gameplay | Should | — | 5 SP |
56
+ | US-001 | Sign up via email or Google SSO | E-01 Onboarding | Must | RISK-02 ↑ | 5 SP |
57
+ | US-002 | Create a workspace and invite a teammate | E-01 Onboarding | Must | — | 3 SP |
58
+ | US-003 | Connect first data source (Segment or warehouse) | E-06 Integrations | Must | RISK-03 ↑ | 13 SP |
59
+ | US-004 | View the live event stream from the connected source | E-03 Events | Must | — | 3 SP |
60
+ | US-005 | Validate the incoming event schema against expected taxonomy | E-03 Events | Must | — | 5 SP |
61
+ | US-006 | View the default dashboard with sample metrics | E-02 Dashboards | Should | — | 5 SP |
62
62
 
63
63
  **Sprint total:** 34 SP / 35 SP capacity (97%)
64
64
 
65
65
  **Definition of Done for SP-01:**
66
66
  - [ ] All stories pass their Acceptance Criteria.
67
- - [ ] Telegram login tested on iOS and Android Telegram clients.
68
- - [ ] RNG certified spin result returned in under 200 ms at p95.
67
+ - [ ] Sign-up and SSO flows tested on Chrome, Safari, and Firefox.
68
+ - [ ] End-to-end event ingestion latency under 1 s at p95 from source emit to dashboard read.
69
69
  - [ ] No 🔴 Critical open items in `/analyze` for completed stories.
70
70
 
71
71
  ---
72
72
 
73
- ### SP-02 — Players can deposit, withdraw, and view wallet balance
73
+ ### SP-02 — Users can build dashboards with funnel, cohort, and trend widgets
74
74
 
75
75
  **Duration:** Weeks 3–4
76
76
  **Capacity:** 35 SP
77
77
 
78
78
  | US | Title | Epic | Priority | Risk | Estimate |
79
79
  |----|-------|------|---------|------|---------|
80
- | US-007 | Deposit via cryptocurrency | E-03 Wallet | Must | RISK-01 ↑ | 8 SP |
81
- | US-008 | Deposit via local payment system | E-03 Wallet | Must | RISK-01 ↑ | 8 SP |
82
- | US-009 | Request withdrawal | E-03 Wallet | Must | — | 8 SP |
83
- | US-010 | View full transaction history | E-03 Wallet | Should | — | 5 SP |
84
- | US-011 | Complete KYC identity verification | E-04 Compliance | Must | — | 3 SP |
80
+ | US-007 | Create a custom dashboard from scratch | E-02 Dashboards | Must | RISK-01 ↑ | 8 SP |
81
+ | US-008 | Add a funnel widget with 3 configurable steps | E-02 Dashboards | Must | RISK-01 ↑ | 8 SP |
82
+ | US-009 | Add a cohort retention widget for the last 30 days | E-02 Dashboards | Must | — | 8 SP |
83
+ | US-010 | Save a dashboard to the workspace library | E-02 Dashboards | Should | — | 5 SP |
84
+ | US-011 | Filter a dashboard by date range and segment | E-02 Dashboards | Must | — | 3 SP |
85
85
 
86
86
  **Sprint total:** 32 SP / 35 SP capacity (91%)
87
87
 
88
88
  **Definition of Done for SP-02:**
89
89
  - [ ] All stories pass their Acceptance Criteria.
90
- - [ ] Payment provider sandbox integration verified end-to-end.
91
- - [ ] KYC flow tested with test credentials from the provider.
92
- - [ ] Withdrawal processed within 24 h in staging environment.
90
+ - [ ] Dashboard read query latency under 500 ms at p95 for the reference dataset (10 M events).
91
+ - [ ] Funnel and cohort calculations verified against the reference dataset to within 0.1%.
92
+ - [ ] Saved dashboards survive workspace reload and session refresh.
93
93
 
94
94
  ---
95
95
 
96
- ### SP-03 — Referral programme and bonus mechanics are live
96
+ ### SP-03 — Alerts and collaboration: thresholds, notifications, sharing, SSO
97
97
 
98
98
  **Duration:** Weeks 5–6
99
99
  **Capacity:** 35 SP
100
100
 
101
101
  | US | Title | Epic | Priority | Risk | Estimate |
102
102
  |----|-------|------|---------|------|---------|
103
- | US-012 | Share referral link and earn bonus | E-06 Referrals | Must | RISK-04 ↑ | 8 SP |
104
- | US-013 | Claim welcome bonus on first deposit | E-06 Referrals | Must | — | 5 SP |
105
- | US-014 | View active bonuses and wagering progress | E-06 Referrals | Should | — | 5 SP |
106
- | US-015 | Set self-exclusion period | E-05 Compliance | Must | — | 5 SP |
107
- | US-016 | Configure deposit limits | E-05 Compliance | Should | — | 7 SP |
103
+ | US-012 | Set a metric threshold alert on any dashboard widget | E-04 Alerts | Must | RISK-04 ↑ | 8 SP |
104
+ | US-013 | Receive an alert email within 60 s of threshold breach | E-04 Alerts | Must | — | 5 SP |
105
+ | US-014 | Invite a teammate and assign a role (admin, editor, viewer) | E-05 Collaboration | Should | — | 5 SP |
106
+ | US-015 | Share a dashboard read-only link with internal and external viewers | E-05 Collaboration | Must | — | 5 SP |
107
+ | US-016 | Enable SSO (SAML / OIDC) for the workspace | E-05 Collaboration | Should | — | 7 SP |
108
108
 
109
109
  **Sprint total:** 30 SP / 35 SP capacity (86%)
110
110
 
111
111
  **Definition of Done for SP-03:**
112
112
  - [ ] All stories pass their Acceptance Criteria.
113
- - [ ] Fraud scoring on referral payouts is active and logged.
114
- - [ ] Self-exclusion blocks all game access within 5 minutes of activation.
113
+ - [ ] Alert evaluation runs within 60 s of threshold breach in staging.
114
+ - [ ] Read-only share links respect role permissions and expire as configured.
115
115
 
116
116
  ---
117
117
 
118
- ### SP-04 — Admin panel: player management, game configuration, reporting
118
+ ### SP-04 — Admin workspace: usage, retention, billing, audit log
119
119
 
120
120
  **Duration:** Weeks 7–8
121
121
  **Capacity:** 35 SP
122
122
 
123
123
  | US | Title | Epic | Priority | Risk | Estimate |
124
124
  |----|-------|------|---------|------|---------|
125
- | US-017 | Admin views player list and profile | E-07 Admin | Must | — | 5 SP |
126
- | US-018 | Admin adjusts RTP and payline configuration | E-07 Admin | Must | — | 8 SP |
127
- | US-019 | Admin views revenue and activity report | E-07 Admin | Should | — | 8 SP |
128
- | US-020 | Admin flags a player account for review | E-07 Admin | Should | — | 7 SP |
125
+ | US-017 | Admin views the workspace list with per-workspace event volume | E-07 Admin | Must | — | 5 SP |
126
+ | US-018 | Admin adjusts data retention window and event quota per workspace | E-07 Admin | Must | — | 8 SP |
127
+ | US-019 | Admin views the usage-based billing report for the current period | E-07 Admin | Should | — | 8 SP |
128
+ | US-020 | Admin reviews the audit log of workspace and permission changes | E-07 Admin | Should | — | 7 SP |
129
129
 
130
130
  **Sprint total:** 28 SP / 35 SP capacity (80%)
131
131
 
132
132
  **Definition of Done for SP-04:**
133
133
  - [ ] All stories pass their Acceptance Criteria.
134
- - [ ] RTP configuration change takes effect within 1 spin cycle.
135
- - [ ] Revenue report matches transaction ledger to within 0.01%.
134
+ - [ ] Retention changes take effect on the next hourly compaction run.
135
+ - [ ] Billing report matches the underlying usage ledger to within 0.01%.
136
136
 
137
137
  ---
138
138
 
@@ -142,10 +142,10 @@ Stories not assigned to any sprint — below MVP capacity or marked Could/Won't:
142
142
 
143
143
  | US | Title | Epic | Priority | Estimate | Reason |
144
144
  |----|-------|------|---------|---------|--------|
145
- | US-021 | Export transaction history as PDF | E-03 Wallet | Could | 5 SP | Capacity exceeded — defer to v1.1 |
146
- | US-022 | Multi-language support (EN / RU / KZ) | E-01 Auth | Could | 8 SP | Deferred — requires i18n infrastructure |
147
- | US-023 | Live chat support widget | E-08 Support | Could | 3 SP | Deferred — third-party integration |
148
- | US-024 | Affiliate dashboard | E-06 Referrals | Won't | 2 SP | Out of MVP scope |
145
+ | US-021 | Export a dashboard snapshot as PDF | E-02 Dashboards | Could | 5 SP | Capacity exceeded — defer to v1.1 |
146
+ | US-022 | Mobile companion app for alert notifications | E-04 Alerts | Could | 8 SP | Deferred — requires mobile infrastructure |
147
+ | US-023 | In-app chat support widget | E-08 Support | Could | 3 SP | Deferred — third-party integration |
148
+ | US-024 | White-label dashboards for embedded use | E-05 Collaboration | Won't | 2 SP | Out of MVP scope |
149
149
 
150
150
  ---
151
151
 
@@ -15,7 +15,7 @@ Second step of the BA Toolkit pipeline. Generates an SRS adapted from IEEE 830.
15
15
  0. If `00_principles_*.md` exists in the output directory, load it and apply its conventions (artifact language, ID format, traceability requirements, Definition of Ready, quality gate threshold).
16
16
  1. Read `01_brief_*.md` from the output directory. If missing, warn and suggest running `/brief`.
17
17
  2. Extract: slug, domain, business goals, functionality, stakeholders, constraints, glossary.
18
- 3. If domain is `igaming`, `fintech`, or `saas`, load `references/domains/{domain}.md`, section `2. /srs`.
18
+ 3. If a matching `references/domains/{domain}.md` file exists (currently: `saas`, `fintech`, `ecommerce`, `healthcare`, `logistics`, `on-demand`, `social-media`, `real-estate`, `igaming`), load it and apply its section `2. /srs`.
19
19
 
20
20
  ## Environment
21
21