toga-ai 1.0.24 → 1.0.25

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.
@@ -6,7 +6,7 @@ project: _Underscore
6
6
  client: shared
7
7
  type: architecture
8
8
  status: active
9
- updated: 2026-06-08
9
+ updated: 2026-06-09
10
10
  owners: [jcardinal]
11
11
  files:
12
12
  - _underscore/_underscore.php
@@ -73,6 +73,98 @@ multi-tenant client-DB lookup from Core. `Query.php` wraps MySQLi with read/writ
73
73
  auto-routing and result helpers: `fetchRows()`, `fetchRow()`, `fetchOne()`,
74
74
  `fetchRowsAssocArray()`, `fetchKeyValuePairs()`, `fetchValues()`.
75
75
 
76
+ ### Physical infrastructure
77
+
78
+ Each **environment** is one or more MySQL clusters. Every cluster has a single
79
+ **writer** host and three **reader** hosts, one per AWS region. The framework routes
80
+ reads to the reader nearest the request's origin and sends all writes to the writer:
81
+
82
+ | Region constant | AWS region | Reader role |
83
+ |---|---|---|
84
+ | region 1 | `us-east-1` | `reader1.*` |
85
+ | region 2 | `us-west-2` | `reader2.*` |
86
+ | region 3 | `eu-west-1` | `reader3.*` |
87
+
88
+ #### Production clusters
89
+
90
+ Production (`prod` / `production`) splits its databases across **four dedicated
91
+ clusters** by database family. Each has a writer + three regional readers under its own
92
+ DNS subdomain (`*.<family>.database.togahub.com`):
93
+
94
+ | Cluster | Schema group | Databases served | DNS host pattern |
95
+ |---|---|---|---|
96
+ | `prod-core` | platform | `Core`, `Forecast`, `Forecast_Archive`, `Team` | `writer.core…` / `reader{1,2,3}.core.database.togahub.com` |
97
+ | `prod-client` | tenants | `Client_<Tenant>` (active client data) | `writer.client…` / `reader{1,2,3}.client.database.togahub.com` |
98
+ | `prod-archive` | archive | `Archive_<Tenant>` (historical subset of `Client_`) | `writer.archive…` / `reader{1,2,3}.archive.database.togahub.com` |
99
+ | `prod-logs` | tenant_logs | `Logs_<Tenant>` + base `Logs` | `writer.logs…` / `reader{1,2,3}.logs.database.togahub.com` |
100
+
101
+ **`Core` is the most important database** — it holds the common tables shared across
102
+ the whole platform (clients, domains, environments, ACL, parameters, APIs, records,
103
+ record scripts, payload interceptors).
104
+
105
+ #### Database families & tenant resolution
106
+
107
+ Within an environment, databases follow a strict naming convention. The **tenant
108
+ string** has a single leading capital, rest lower-case (e.g. `Towfoundation`):
109
+
110
+ | Family | Pattern | Contents |
111
+ |---|---|---|
112
+ | Platform | `Core`, `Forecast`, `Team` | Shared infrastructure (not tenant-scoped). |
113
+ | Tenant (active) | `Client_<Tenant>` | Live working data for one client — e.g. `Client_Towfoundation`. |
114
+ | Archive | `Archive_<Tenant>` | Old archived rows; **same table schema** as the matching `Client_` DB. |
115
+ | Tenant logs | `Logs_<Tenant>` | Per-client activity/audit logs. |
116
+ | Framework logs | `Logs` | Generic 2.0 logs not tied to any client. |
117
+
118
+ **Resolving a tenant string from a client name:** query `Core.Clients`. The
119
+ `clientIdentifier` field **is** the exact suffix used in `Client_`, `Archive_`, and
120
+ `Logs_` database names; the `name` field is the human-readable label. Look up by either
121
+ to find the other:
122
+
123
+ ```sql
124
+ SELECT
125
+ name,
126
+ clientIdentifier
127
+ FROM Clients
128
+ WHERE
129
+ name LIKE '%<keyword>%'
130
+ ```
131
+
132
+ A client whose `clientIdentifier` is `Towfoundation` therefore lives in
133
+ `Client_Towfoundation`, `Archive_Towfoundation`, and `Logs_Towfoundation`.
134
+
135
+ #### Non-production environments
136
+
137
+ All non-production environments are **all-in-one**: a single cluster per environment
138
+ holds `Core`, `Client_<Tenant>`, `Archive_<Tenant>`, and `Logs_<Tenant>` together
139
+ (no family split). Region/reader routing still applies per cluster.
140
+
141
+ | Environment (aliases) | Host |
142
+ |---|---|
143
+ | `dev-sandbox` / `sandbox-dev` / developer sandbox | `dev.sandbox.database.togahub.com` |
144
+ | `client-sandbox` / `sandbox-client` | `client.sandbox.database.togahub.com` |
145
+ | `client-alpha` / `alpha-client` | `alpha.client.database.togahub.com` |
146
+ | `client-beta` / `beta-client` | `beta.client.database.togahub.com` |
147
+ | `client-gamma` / `gamma-client` | `gamma.client.database.togahub.com` |
148
+ | `qa-task` | `task.qa.database.togahub.com` |
149
+ | `qa-hotfix` | `hotfix.qa.database.togahub.com` |
150
+ | `qa-alpha` | `alpha.qa.database.togahub.com` |
151
+ | `qa-beta` | `beta.qa.database.togahub.com` |
152
+ | `qa-gamma` | `gamma.qa.database.togahub.com` |
153
+ | `qc-task` | `task.qc.database.togahub.com` |
154
+ | `qc-hotfix` | `hotfix.qc.database.togahub.com` |
155
+ | `qc-security` | `security.qc.database.togahub.com` |
156
+ | `qc-performance` | `performance.qc.database.togahub.com` |
157
+ | `qc-alpha` | `alpha.qc.database.togahub.com` |
158
+ | `qc-beta` | `beta.qc.database.togahub.com` |
159
+ | `qc-gamma` | `gamma.qc.database.togahub.com` |
160
+ | `stage` / `staging` | `stage.database.togahub.com` |
161
+ | `demo` | `demo.database.togahub.com` |
162
+
163
+ > **Credentials** are managed via the database/MCP environment config — **never stored
164
+ > in this repo or in any committed file** (per `rules/common/security.md` and
165
+ > `git-workflow.md`). Do not paste DB usernames or passwords into knowledge docs, code,
166
+ > or commits.
167
+
76
168
  ## Model layer
77
169
 
78
170
  Each DB table has a model. Every model must define:
@@ -3,5 +3,3 @@
3
3
  | Doc | Summary | Files |
4
4
  |-----|---------|-------|
5
5
  | [API (api2 / TOGa API v2) Architecture](architecture.md) | `api2` is the backend powering the public **TOGa 2.0 API**. | api2/Controller/Index.php, api2/Component/Api/V2/V2.php, api2/Component/Api/Cxml/Cxml.php, api2/Component/Api/V2/Response/Response.php, api2/Config/ |
6
- | [Error Response Envelope](features/error-response.md) | Every api2 action method returns the same three-key envelope. | api2/Controller/Index.php |
7
- | [Health Check Endpoint](features/health-endpoint.md) | `GET /health` returns HTTP 200 with an empty JSON object (`{}`). | api2/Controller/Index.php |
@@ -11,7 +11,7 @@ _Auto-generated by `knowledge.js index`. Do not hand-edit._
11
11
 
12
12
  - **_underscore** (_Underscore) _(framework core)_ — 2 doc(s) → [2.0/apps/_underscore/INDEX.md](2.0/apps/_underscore/INDEX.md)
13
13
  - **worker2** (Worker) — 3 doc(s) → [2.0/apps/worker2/INDEX.md](2.0/apps/worker2/INDEX.md)
14
- - **api2** (API) — 3 doc(s) → [2.0/apps/api2/INDEX.md](2.0/apps/api2/INDEX.md)
14
+ - **api2** (API) — 1 doc(s) → [2.0/apps/api2/INDEX.md](2.0/apps/api2/INDEX.md)
15
15
 
16
16
  ## Clients
17
17
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "toga-ai",
3
- "version": "1.0.24",
3
+ "version": "1.0.25",
4
4
  "description": "TOGA Technology Team Claude Knowledge System — shared AI coding harness with skills, knowledge base CLI, and project installer for Claude Code.",
5
5
  "keywords": [
6
6
  "claude",