toga-ai 1.0.849 → 1.0.850
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/knowledge/2.0/apps/_underscore/features/apirequest-json-content-type.md +14 -2
- package/knowledge/2.0/apps/worker2/INDEX.md +2 -0
- package/knowledge/2.0/apps/worker2/features/committed-secrets-and-config-debt.md +72 -0
- package/knowledge/2.0/apps/worker2/features/team-sprint-management.md +53 -13
- package/knowledge/2.0/apps/worker2/workflows/sprint-clickup-folder-repoint.md +79 -0
- package/knowledge/INDEX.md +1 -1
- package/package.json +1 -1
|
@@ -6,8 +6,8 @@ project: _Underscore
|
|
|
6
6
|
client: shared
|
|
7
7
|
type: feature
|
|
8
8
|
status: active
|
|
9
|
-
updated: 2026-09-
|
|
10
|
-
owners: ["jcardinal", "ajean", "rgirish"]
|
|
9
|
+
updated: 2026-09-21
|
|
10
|
+
owners: ["jcardinal", "ajean", "rgirish", "kyalamarthi"]
|
|
11
11
|
files:
|
|
12
12
|
- _underscore/ApiRequest.php
|
|
13
13
|
- _underscore/Model/Client/Logs/Api.php
|
|
@@ -137,6 +137,18 @@ case-insensitive scan of already-set headers, so a caller-supplied `Content-Type
|
|
|
137
137
|
- **A hand-rolled `curl` never appears in `Logs.Api`.** The logging belongs to `_ApiRequest`, so a
|
|
138
138
|
manual/CLI `curl` reproduction of a vendor call is *correctly* absent from the log. Do not read
|
|
139
139
|
that absence as "the platform did not call the vendor."
|
|
140
|
+
- **⚠ OPEN: valid JSON is rejected as "XML" when the body merely CONTAINS an XML declaration.**
|
|
141
|
+
`ApiRequest.php:360` decides a response is XML with
|
|
142
|
+
`stripos($this->responsePayload, '<?xml version=') === false` — a substring search over the
|
|
143
|
+
**whole body**, not a prefix check. So any JSON response carrying that literal anywhere inside it
|
|
144
|
+
throws `API response was received in XML encoding when it was expecting JSON encoding`. Live case
|
|
145
|
+
(2026-09-21): a ClickUp task description holding a pasted cXML document (an ODP cXML sample on
|
|
146
|
+
task TRUE-82107) broke a valid ClickUp task-page response. **The message blames the API, not the
|
|
147
|
+
ticket**, so it is very hard to diagnose — and the team handles cXML routinely, so expect it
|
|
148
|
+
again. **Workaround:** delete the `<?xml version="1.0"?>` line from the offending record (only
|
|
149
|
+
that exact literal is searched for). **Proposed fix, NOT shipped:** anchor the test —
|
|
150
|
+
`stripos(ltrim($this->responsePayload), '<?xml version=') !== 0`. It sits on every caller's path,
|
|
151
|
+
so get a `cto` opinion plus the normal reviewers before shipping it.
|
|
140
152
|
- **`Logs.Api` is 1.4M+ rows and `source` is NOT indexed.** Any diagnostic query must be bounded by
|
|
141
153
|
`dtStamp` (indexed) or it times out — `WHERE source = '…'` alone will not return.
|
|
142
154
|
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
| [ClickUp Subtask Activity → Parent Opportunity/Epic Comments](features/clickup-subtask-activity.md) | Mirrors subtask status/comment activity up to its top-level Opportunity/Epic as one comment; open for the subtask fan-out, its dedup ledger, or structural ances |
|
|
19
19
|
| [ClickUp Task Description Fluffer (Talos KB Investigation)](features/clickup-task-fluffer-talos.md) | Async worker that "fluffs" a new ClickUp task by running its name+description through the Talos `dev-core` KB agent and writing the report back; open for the fl |
|
|
20
20
|
| [ClickUp Work Type Automation (Committed / Conditional / Stretch)](features/clickup-work-type-automation.md) | Auto-maintains each ClickUp task's Work Type (Committed/Conditional/Stretch) from its dependencies, status, and due date; open when work-type promotion/demotion |
|
|
21
|
+
| [worker2 — Committed Secrets & Config Exposure (debt register)](features/committed-secrets-and-config-debt.md) | Standing list of credentials committed to the worker2 repo (locations only); open before adding a credential to worker2 or assuming a config value is private. |
|
|
21
22
|
| [Compass VIP Support Importer (worker2)](features/compass-vip-support-importer.md) | worker2 action that ingests Compass's quarterly VIP spreadsheet and sets each VIP's support tech (`Users.c_supportedByUserId` in `Client_Compass`); open when wo |
|
|
22
23
|
| [Creating Worker Actions](features/creating-worker-actions.md) | How to add a new callable Worker action — a PHP class whose `public static` methods are invoked as background jobs (via webhook, cron, or `_Worker::runTask()`). |
|
|
23
24
|
| [Cross-account AWS access for worker2 crons (_Component_Aws_Workloads)](features/cross-account-aws-access.md) | The standard, and only sanctioned, way any new worker2 cron obtains AWS access (any account/region/SDK client) via role-assume; open before writing worker2 code |
|
|
@@ -63,4 +64,5 @@
|
|
|
63
64
|
| [Rotating the ClickUp API credential (and migrating to the devteam service account)](workflows/clickup-credential-rotation.md) | Procedure to rotate the ClickUp API token (or move traffic onto the `devteam@togatech.com` service account) without killing the live webhook subscription or sil |
|
|
64
65
|
| [PHP Runtime Upgrade on Elastic Beanstalk (worker2 8.3 → 8.5 + PhpSpreadsheet 1.x → 3.x)](workflows/php-runtime-upgrade-dependency-audit.md) | Reusable checklist for moving a TOGA repo across an EB PHP runtime jump (worker2 8.3 → 8.5 + PhpSpreadsheet 1.x → 3.x); open before any runtime bump or when a c |
|
|
65
66
|
| [Running worker2 locally against real NetSuite (and what EB does instead)](workflows/running-worker2-locally.md) | Boot worker2 on a dev machine to run a real worker action against live NetSuite + a local Forecast DB; open when local boot fails or before any local NetSuite r |
|
|
67
|
+
| [Repointing the Sprint Tooling at a New ClickUp Sprints Folder (+ table reset)](workflows/sprint-clickup-folder-repoint.md) | Move worker2's sprint tooling onto a new ClickUp "True Dev Sprints" folder and reset the Team sprint tables; open when the sprints folder id changes. |
|
|
66
68
|
| [Ticket → ClickUp Pseudocode Planning (Talos-grounded)](workflows/ticket-to-pseudocode-planning.md) | Procedure to turn a ClickUp ticket into a reviewed, formatted plan posted to its `📝 Pseudocode` field (ClickUp + codebase + Talos); open when planning a ticket |
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "worker2 — Committed Secrets & Config Exposure (debt register)"
|
|
3
|
+
framework: "2.0"
|
|
4
|
+
repo: worker2
|
|
5
|
+
project: Worker
|
|
6
|
+
client: shared
|
|
7
|
+
type: feature
|
|
8
|
+
status: active
|
|
9
|
+
updated: 2026-09-21
|
|
10
|
+
owners: ["kyalamarthi"]
|
|
11
|
+
files:
|
|
12
|
+
- worker2/.gitignore
|
|
13
|
+
- worker2/Worker/Team/Github.php
|
|
14
|
+
- worker2/.ebextensions/git.json
|
|
15
|
+
- worker2/Config/production.ini
|
|
16
|
+
- worker2/Config/netsuite_ec_key.pem
|
|
17
|
+
- worker2/Worker/Team/Sprint.php
|
|
18
|
+
related:
|
|
19
|
+
- ./automated-pr-merger-force-push-race.md
|
|
20
|
+
- ./team-sprint-management.md
|
|
21
|
+
- ../../_underscore/features/apirequest-json-content-type.md
|
|
22
|
+
- ../../../../clients/rate/features/paypal-subscription-purchase-webhook.md
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
Standing list of credentials committed to the worker2 repo (locations only); open before adding a credential to worker2 or assuming a config value is private.
|
|
26
|
+
|
|
27
|
+
## Summary
|
|
28
|
+
|
|
29
|
+
Every item below is **pre-existing** debt, found in a 2026-09-21 audit. Root cause:
|
|
30
|
+
`worker2/.gitignore` contains only `/vendor/`, so **every `Config/*.ini` and key file in the repo is
|
|
31
|
+
committed**. The repo is private (verified 2026-09-21 — the unauthenticated GitHub API returns 404),
|
|
32
|
+
which is the only thing containing the blast radius.
|
|
33
|
+
|
|
34
|
+
**Locations only. Never paste a credential value into this or any knowledge doc** — `validate` fails
|
|
35
|
+
the publish on a credential literal.
|
|
36
|
+
|
|
37
|
+
## How it works
|
|
38
|
+
|
|
39
|
+
### Inventory — where each credential lives
|
|
40
|
+
|
|
41
|
+
| Credential | Location | Why it is worse than it looks |
|
|
42
|
+
|---|---|---|
|
|
43
|
+
| GitHub personal access token, `agilantgit` account | `worker2/Worker/Team/Github.php:9` **and** `worker2/.ebextensions/git.json:4` (same token, two copies) | Committed since 2025-01-17 and present in **166 of 167 branches**, so scrubbing history is not a fix — **rotation is the only fix**. Org-wide reach. It is also interpolated into a `shell_exec` clone URL, so it shows up in the instance process list. |
|
|
44
|
+
| NetSuite EC private key | `worker2/Config/netsuite_ec_key.pem` | Tracked in git as a file. |
|
|
45
|
+
| TOGa IQ (`api.togaiq.com`) API key | `worker2/Worker/Team/Sprint.php:43`, used ~L422 | Still a class constant. There is **no `[togaiq]` config group yet**, so moving it means adding the config group first. |
|
|
46
|
+
| PayPal webhook signature verification **off** in production | `worker2/Config/production.ini:182` | Impact already written up — a caller who knows the URL can create a paid SalesOrder. See [Rate PayPal subscription webhook](../../../../clients/rate/features/paypal-subscription-purchase-webhook.md). |
|
|
47
|
+
|
|
48
|
+
### Fixed / no longer true
|
|
49
|
+
|
|
50
|
+
- **ClickUp API token in `Sprint.php`** — the hardcoded `CLICKUP_API_ACCESS_TOKEN` constant is
|
|
51
|
+
**gone**. All 6 call sites now use `_Component_Api_Clickup::accessToken()`, which reads
|
|
52
|
+
`[clickup] token` from config. The component's own hardcoded fallback token, and the plaintext
|
|
53
|
+
`Authorization` header written into `Logs.Api`, are separate open items — see
|
|
54
|
+
[_ApiRequest gotchas](../../_underscore/features/apirequest-json-content-type.md#gotchas).
|
|
55
|
+
|
|
56
|
+
## Gotchas
|
|
57
|
+
|
|
58
|
+
- **Config is not private here.** Moving a secret from a PHP constant into
|
|
59
|
+
`Config/production.ini` hides it from a grep of the source, not from git — it is still committed.
|
|
60
|
+
Treat that move as a refactor, not a remediation.
|
|
61
|
+
- **Any credential that has ever been committed must be rotated**, not just deleted. Deleting the
|
|
62
|
+
line leaves it in history and in every branch that still carries it (166 of 167, for the GitHub
|
|
63
|
+
token).
|
|
64
|
+
- **Keep this table current.** Add an entry whenever a committed credential is found, and move it to
|
|
65
|
+
*Fixed* when it is rotated and relocated, so this stays the one place the team looks.
|
|
66
|
+
|
|
67
|
+
## Related
|
|
68
|
+
|
|
69
|
+
- [Automated PR Merger — force-push clobber race](./automated-pr-merger-force-push-race.md) (owns `Worker/Team/Github.php`)
|
|
70
|
+
- [Team Sprint Management & Reporting](./team-sprint-management.md)
|
|
71
|
+
- [_ApiRequest — encode/decode & api-logging behavior](../../_underscore/features/apirequest-json-content-type.md)
|
|
72
|
+
- [Rate PayPal Subscription Purchase & Webhook Pipeline](../../../../clients/rate/features/paypal-subscription-purchase-webhook.md)
|
|
@@ -6,17 +6,19 @@ project: Worker
|
|
|
6
6
|
client: shared
|
|
7
7
|
type: feature
|
|
8
8
|
status: active
|
|
9
|
-
updated: 2026-09-
|
|
9
|
+
updated: 2026-09-21
|
|
10
10
|
owners: ["jcardinal", "kyalamarthi"]
|
|
11
11
|
files:
|
|
12
12
|
- worker2/Worker/Team/Sprint.php
|
|
13
|
+
- worker2/Config/production.ini
|
|
13
14
|
- _underscore/Model/Team/Sprint.php
|
|
14
|
-
- dbchanges2/Core/CronJobs (SprintLockScheduled seed)
|
|
15
15
|
related:
|
|
16
16
|
- ../architecture.md
|
|
17
17
|
- ./creating-worker-actions.md
|
|
18
18
|
- ./clickup-work-type-automation.md
|
|
19
19
|
- ./clickup-project-routing.md
|
|
20
|
+
- ./committed-secrets-and-config-debt.md
|
|
21
|
+
- ../workflows/sprint-clickup-folder-repoint.md
|
|
20
22
|
- ../workflows/php-runtime-upgrade-dependency-audit.md
|
|
21
23
|
---
|
|
22
24
|
|
|
@@ -48,8 +50,9 @@ everything.
|
|
|
48
50
|
### Key files / entry points
|
|
49
51
|
- `Worker/Team/Sprint.php` — the entire feature (one abstract class, static methods).
|
|
50
52
|
- `initialize()` — registers the `Logs_True` DB connection used for ClickUp API logging.
|
|
51
|
-
- ClickUp config lives in class constants: `CLICKUP_TEAM_ID
|
|
52
|
-
folder whose child lists are the sprints)
|
|
53
|
+
- ClickUp config lives in class constants: `CLICKUP_TEAM_ID` and `CLICKUP_DEV_SPRINTS_FOLDER_ID` (the
|
|
54
|
+
folder whose child lists are the sprints). The API token is **no longer** a constant here — all 6
|
|
55
|
+
call sites use `_Component_Api_Clickup::accessToken()`, reading `[clickup] token` from config.
|
|
53
56
|
- AI config constants: `AI_API_ENDPOINT` (TOGa IQ `…/api/ai/generate`), `AI_MODEL_ID`
|
|
54
57
|
(`bedrock/us.anthropic.claude-haiku-4-5-…`), temperature, max-tokens, timeout.
|
|
55
58
|
- Report distribution: `SEND_LEADERSHIP_REPORTS_TO` (leadership email list); `SEND_EMAILS_FROM` /
|
|
@@ -106,8 +109,8 @@ Otherwise it returns a skip message (captured to `Core.WorkerJobs.output`) and d
|
|
|
106
109
|
`SprintLock()` itself is unchanged — this only decides *whether* to run it today. Action path
|
|
107
110
|
`Team/Sprint/SprintLockScheduled` → `_Worker_Team_Sprint::SprintLockScheduled`.
|
|
108
111
|
|
|
109
|
-
**Deploy coupling.** The worker2 code deploy and the
|
|
110
|
-
|
|
112
|
+
**Deploy coupling.** The worker2 code deploy and the `Core.CronJobs` row insert must land
|
|
113
|
+
**together** (no committed migration seeds it — see Gotchas) — the cron row references the
|
|
111
114
|
`Team/Sprint/SprintLockScheduled` action, which must exist in the deployed code or the scheduled job
|
|
112
115
|
fails when it fires.
|
|
113
116
|
|
|
@@ -327,13 +330,50 @@ see [TOGa IQ Sprint Dashboard API](../../api2/features/sprint-dashboard-api.md)
|
|
|
327
330
|
- **At-lock baseline is load-bearing.** Reliability/Integrity compare *now* vs *at lock*. If
|
|
328
331
|
`SprintLock` did not run (or ran without capture), the `*AtLock` columns are empty and the
|
|
329
332
|
end-of-sprint scores are meaningless. Lock must happen at launch.
|
|
330
|
-
- **
|
|
331
|
-
(
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
333
|
+
- **The sprint list NAME is a contract, and the YEAR is required.** All three capture paths
|
|
334
|
+
(`CaptureSprintDaily` ~L3477, `CaptureSprintEnd` ~L3231, `SprintLock` ~L3801) run the same
|
|
335
|
+
`preg_match('/Sprint (\d+) \((\d{1,2}\/\d{1,2}\/\d{2,4}) - (\d{1,2}\/\d{1,2}\/\d{2,4})\)/')` over
|
|
336
|
+
the list name. A list named `Sprint 1 (9/16 - 9/30)` — no year — does **not** match, `$matches[1]`
|
|
337
|
+
is undefined, and the run **fatals** two lines later (~L3479). A name that merely misses the date
|
|
338
|
+
window instead gives a silent "sprint not found" leadership alert. ClickUp's end date is the
|
|
339
|
+
**next** sprint's start (exclusive); the code stores `dateEnd` minus one day. **Proper fix for a
|
|
340
|
+
future ticket:** take the number from the name but the dates from the list object's `start_date` /
|
|
341
|
+
`due_date` (epoch ms), already fetched for the date-window match.
|
|
342
|
+
- **The tooling cannot bootstrap from an empty `Sprints` table — it deadlocks.** `SprintDaily`
|
|
343
|
+
(~L4806), `SprintEnd` (~L473-474) and `SendSprintEndWarnings` (~L218) all call `getSprint()`
|
|
344
|
+
**before** the `Capture*` method that would create the `Sprints` row, and `getSprint()`
|
|
345
|
+
(~L5702-5740) does `fetchRow()` with **no null check** — so on an empty table every entry point
|
|
346
|
+
fatals with `Attempt to read property "id" on null`. The thing that creates the row is never
|
|
347
|
+
reached. **Workaround (proven in production 2026-09-16):** `INSERT` one `Sprints` row by hand
|
|
348
|
+
(`sprint`, `dateStart`, `dateEnd`); `CaptureSprintDaily`'s "ensure the sprint record exists" block
|
|
349
|
+
(~L3478) self-heals from there. Anyone truncating these tables hits this — see
|
|
350
|
+
[Repointing the sprint tooling](../workflows/sprint-clickup-folder-repoint.md).
|
|
351
|
+
- **`getSprint()` uses `LIMIT 1` with no `ORDER BY`** (~L5717 and ~L5721, both branches). With
|
|
352
|
+
duplicate sprint numbers it returns an **arbitrary** row — a live violation of the
|
|
353
|
+
deterministic-`LIMIT 1` rule in
|
|
354
|
+
[backend-php standards](../../../standards/backend-php.md#a-limit-1-on-a-non-unique-key-must-have-a-deterministic-order-by).
|
|
355
|
+
- **`SprintLock` is NOT a safe way to repopulate empty tables.** It captures before it reads, so it
|
|
356
|
+
looks like a bootstrap (its `getSprint()` call is gated behind `$generateSprintLockReport`), but
|
|
357
|
+
its capture block (~L4016-4030) **writes back to ClickUp for every task** — sets Previous Sprint
|
|
358
|
+
Work Type, sets "Added at sprint launch" = true, sets Condition = "On Track". Run outside the real
|
|
359
|
+
launch ceremony it corrupts those fields across the whole sprint.
|
|
360
|
+
- **`SprintDaily` returns nothing on success** — a production run reads `Successfully Executed
|
|
361
|
+
(4.255 seconds): <no return message>`, so a run that worked is indistinguishable from one that
|
|
362
|
+
never fired. Breaks the return-on-both-paths rule in the
|
|
363
|
+
[worker2 architecture](../architecture.md); fix by returning a structured summary.
|
|
364
|
+
- **The Team/Sprint cron rows are not in git.** Nothing in `dbchanges2/Core/` registers
|
|
365
|
+
`Team/Sprint/%` (searched 2026-09-21), despite this doc previously listing a `CronJobs
|
|
366
|
+
(SprintLockScheduled seed)` file. A concrete case of "a committed migration records intent, not
|
|
367
|
+
deployed state" ([framework-rules](../../../standards/framework-rules.md)) — read the real
|
|
368
|
+
schedule from `Core.CronJobs` in the target environment.
|
|
369
|
+
- **The dev-sprints folder id lives in THREE places** — the `Sprint.php` constant, the
|
|
370
|
+
`Monitor/Oneuptime.php` fallback, and `[clickup] sprint_folder_id` in `Config/production.ini`.
|
|
371
|
+
They must move together, and `Worker/Clickup/Design.php`'s own Design-Sprints folder must not move
|
|
372
|
+
with them. Procedure:
|
|
373
|
+
[Repointing the sprint tooling](../workflows/sprint-clickup-folder-repoint.md).
|
|
374
|
+
- **Credentials.** The ClickUp token now comes from config (`_Component_Api_Clickup::accessToken()`);
|
|
375
|
+
the TOGa IQ AI key is **still a hardcoded constant** at `Sprint.php:43`. Locations and remediation
|
|
376
|
+
status: [committed secrets register](./committed-secrets-and-config-debt.md).
|
|
337
377
|
- **Worker contract.** Like all 2.0 workers this must return cleanly and commit writes via the
|
|
338
378
|
`_Db`/transaction layer to be durable — uncommitted captures can be silently dropped.
|
|
339
379
|
- **ClickUp pagination returns duplicate tasks — the sync loop must be idempotent.** ClickUp's
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Repointing the Sprint Tooling at a New ClickUp Sprints Folder (+ table reset)
|
|
3
|
+
framework: "2.0"
|
|
4
|
+
repo: worker2
|
|
5
|
+
project: Worker
|
|
6
|
+
client: shared
|
|
7
|
+
type: workflow
|
|
8
|
+
status: active
|
|
9
|
+
updated: 2026-09-21
|
|
10
|
+
owners: ["kyalamarthi"]
|
|
11
|
+
files:
|
|
12
|
+
- worker2/Worker/Team/Sprint.php
|
|
13
|
+
- worker2/Worker/Monitor/Oneuptime.php
|
|
14
|
+
- worker2/Config/production.ini
|
|
15
|
+
- dbchanges2/Team/2026-09-16a - Reset sprint tables for new ClickUp folder.sql
|
|
16
|
+
related:
|
|
17
|
+
- ../features/team-sprint-management.md
|
|
18
|
+
- ../features/creating-worker-actions.md
|
|
19
|
+
- ../../dbchanges2/architecture.md
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
Move worker2's sprint tooling onto a new ClickUp "True Dev Sprints" folder and reset the Team sprint tables; open when the sprints folder id changes.
|
|
23
|
+
|
|
24
|
+
## Summary
|
|
25
|
+
|
|
26
|
+
Sprint numbering restarts at 1 in a new folder and collides with existing `Team.Sprints` rows, so a
|
|
27
|
+
repoint is a code + config change **plus** a data reset **plus** a manual seed row — not a one-line
|
|
28
|
+
constant edit. Done once on 2026-09-16 under TRUE-82052 (worker2 + dbchanges2).
|
|
29
|
+
|
|
30
|
+
## Steps
|
|
31
|
+
|
|
32
|
+
1. **Name the ClickUp lists `Sprint <n> (M/D/YY - M/D/YY)` — with the year.** Capture parses the list
|
|
33
|
+
name with a regex that requires the year; a list created as `Sprint 1 (9/16 - 9/30)` does not
|
|
34
|
+
match and the run fatals. See
|
|
35
|
+
[team-sprint-management → gotchas](../features/team-sprint-management.md#gotchas).
|
|
36
|
+
2. **Update all three copies of the folder id — they must move together**, or the tooling
|
|
37
|
+
split-brains:
|
|
38
|
+
- `CLICKUP_DEV_SPRINTS_FOLDER_ID` — `worker2/Worker/Team/Sprint.php` (~L10)
|
|
39
|
+
- `CLICKUP_SPRINTS_FOLDER_ID_FALLBACK` — `worker2/Worker/Monitor/Oneuptime.php` (~L25)
|
|
40
|
+
- `[clickup] sprint_folder_id` — `worker2/Config/production.ini` (~L270); the escalation cron
|
|
41
|
+
reads this and it **wins** over the Oneuptime fallback.
|
|
42
|
+
|
|
43
|
+
Do **not** touch `DESIGN_SPRINTS_FOLDER_ID` in `worker2/Worker/Clickup/Design.php` — Design
|
|
44
|
+
Sprints is a different folder with its own id.
|
|
45
|
+
3. **Run the reset migration alone, on a fresh connection**, against the `Team` database:
|
|
46
|
+
`dbchanges2/Team/2026-09-16a - Reset sprint tables for new ClickUp folder.sql`. It truncates
|
|
47
|
+
child → parent (`Tasks_Developers` → `Tasks` → `Sprints`) wrapped in
|
|
48
|
+
`SET FOREIGN_KEY_CHECKS = 0 / 1`, because MySQL refuses `TRUNCATE` on a table a foreign key
|
|
49
|
+
points at **even when the child is already empty**.
|
|
50
|
+
4. **Insert one `Sprints` row by hand** (`sprint`, `dateStart`, `dateEnd`). Required: the tooling
|
|
51
|
+
**cannot bootstrap from an empty `Sprints` table** — every entry point calls `getSprint()` before
|
|
52
|
+
the capture that would create the row. See
|
|
53
|
+
[team-sprint-management → gotchas](../features/team-sprint-management.md#gotchas).
|
|
54
|
+
5. **Deploy worker2, then run `Team/Sprint/SprintDaily` once** (manual POST — see
|
|
55
|
+
[creating-worker-actions](../features/creating-worker-actions.md)). From there
|
|
56
|
+
`CaptureSprintDaily`'s own "ensure the sprint record exists" block (~L3478) keeps `Sprints`
|
|
57
|
+
current on its own.
|
|
58
|
+
6. **Verify in the DB, not from the reply.** `SprintDaily` returns nothing on success, so a good run
|
|
59
|
+
reads `Successfully Executed (…): <no return message>`. Confirm `Sprints` / `Tasks` repopulated.
|
|
60
|
+
|
|
61
|
+
## Gotchas
|
|
62
|
+
|
|
63
|
+
- **`FOREIGN_KEY_CHECKS` is session-scoped.** Run nothing else on that connection, and if the file
|
|
64
|
+
stops part-way the flag stays **off** for the rest of that session — reconnect.
|
|
65
|
+
- **Do not use `SprintLock` to repopulate the tables.** It captures before it reads, so it looks
|
|
66
|
+
like a safe bootstrap, but its capture block **writes back to ClickUp** for every task. See
|
|
67
|
+
[team-sprint-management → gotchas](../features/team-sprint-management.md#gotchas).
|
|
68
|
+
- **Truncate throws away sprint history.** The alternative is renumbering the old rows. On
|
|
69
|
+
2026-09-16 the developer chose truncate and declined a backup — if history matters next time,
|
|
70
|
+
renumber, or back up `Sprints` / `Tasks` / `Tasks_Developers` first.
|
|
71
|
+
- **The cron rows are not in git.** No committed migration seeds the `Team/Sprint/%` `CronJobs`
|
|
72
|
+
rows, so after a repoint the live schedule can only be read from `Core.CronJobs` in the target
|
|
73
|
+
environment.
|
|
74
|
+
|
|
75
|
+
## Related
|
|
76
|
+
|
|
77
|
+
- [Team Sprint Management & Reporting](../features/team-sprint-management.md)
|
|
78
|
+
- [Creating Worker Actions](../features/creating-worker-actions.md)
|
|
79
|
+
- [dbchanges2 Architecture](../../dbchanges2/architecture.md)
|
package/knowledge/INDEX.md
CHANGED
|
@@ -20,7 +20,7 @@ _Auto-generated by `knowledge.js index`. Do not hand-edit._
|
|
|
20
20
|
## 2.0 framework
|
|
21
21
|
|
|
22
22
|
- **_underscore** (_Underscore) _(framework core)_ — 87 doc(s) → [2.0/apps/_underscore/INDEX.md](2.0/apps/_underscore/INDEX.md)
|
|
23
|
-
- **worker2** (Worker) —
|
|
23
|
+
- **worker2** (Worker) — 73 doc(s) → [2.0/apps/worker2/INDEX.md](2.0/apps/worker2/INDEX.md)
|
|
24
24
|
- **api2** (API) — 26 doc(s) → [2.0/apps/api2/INDEX.md](2.0/apps/api2/INDEX.md)
|
|
25
25
|
- **dbchanges2** (Database Changes) _(framework core)_ — 19 doc(s) → [2.0/apps/dbchanges2/INDEX.md](2.0/apps/dbchanges2/INDEX.md)
|
|
26
26
|
- **toga2-supply** (TOGa Supply) — 9 doc(s) → [2.0/apps/toga2-supply/INDEX.md](2.0/apps/toga2-supply/INDEX.md)
|
package/package.json
CHANGED