create-flowdular 0.6.1 → 0.6.3
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/agent-template/.agents/skills/module-new/SKILL.md +1 -1
- package/agent-template/.agents/skills/module-update/SKILL.md +1 -1
- package/agent-template/.agents/skills/perf-audit/SKILL.md +1 -1
- package/agent-template/.ai/agents/README.md +2 -2
- package/agent-template/.ai/agents/sandbox/agentic-engineer.md +1 -1
- package/agent-template/.ai/agents/sandbox/backend-engineer.md +1 -1
- package/agent-template/.ai/agents/sandbox/business-manager.md +1 -3
- package/agent-template/.ai/agents/sandbox/frontend-engineer.md +1 -1
- package/agent-template/.ai/agents/sandbox/ux-designer.md +1 -1
- package/agent-template/.ai/policies/model-routing.yaml +2 -1
- package/agent-template/.ai/policies/task-budgets.yaml +1 -1
- package/agent-template/.ai/references/catalog/migrations/0001_catalog_core.up.sql +2 -2
- package/agent-template/.ai/references/catalog/migrations/0002_catalog_history.up.sql +2 -2
- package/agent-template/.ai/references/catalog/migrations/0003_catalog_history_service_actors.up.sql +2 -2
- package/agent-template/.ai/references/catalog/migrations/0004_catalog_idempotency_ledger.up.sql +2 -2
- package/agent-template/.ai/references/catalog/module.json +3 -3
- package/agent-template/.ai/references/catalog/package.json +2 -2
- package/agent-template/.ai/references/catalog/spec/module.yaml +3 -3
- package/agent-template/.ai/references/catalog/src/client/CatalogItemForm.tsrx +2 -2
- package/agent-template/.ai/references/catalog/src/services/migration.ts +8 -8
- package/agent-template/.ai/references/catalog/tests/migrations.test.ts +1 -1
- package/agent-template/.ai/skills/module-new/SKILL.md +1 -1
- package/agent-template/.ai/skills/module-update/SKILL.md +1 -1
- package/agent-template/.ai/skills/perf-audit/SKILL.md +1 -1
- package/agent-template/.claude/skills/module-new/SKILL.md +1 -1
- package/agent-template/.claude/skills/module-update/SKILL.md +1 -1
- package/agent-template/.claude/skills/perf-audit/SKILL.md +1 -1
- package/agent-template/docs/module-distribution.md +1 -2
- package/agent-template/docs/modules.md +2 -2
- package/agent-template/docs/sandbox.md +41 -3
- package/package.json +1 -1
- package/template/default/modules/example/package.json +1 -1
- package/template/default/package.json +2 -2
- package/template/default/platform/package.json +1 -1
- package/agent-template/.ai/references/catalog.provenance.json +0 -65
|
@@ -14,7 +14,7 @@ Two ways to land the same module: the sandbox (a brief, specialist turns, gates
|
|
|
14
14
|
|
|
15
15
|
With an approved `schemaVersion: 2` spec, the specification is the requirement document and you do not go looking for one. Read the spec, the files on this skill's touch list, and `.ai/references/catalog` for shape. Do not scan `modules/` or `packages/`; `.ai/platform-capabilities.md` answers what the platform provides, and the reference module answers what the code looks like.
|
|
16
16
|
|
|
17
|
-
Anything the spec does not say is a spec defect, not a decision you make. A missing field, an unstated conflict behaviour, an undefined state transition, a screen without columns: report it back. In the sandbox that is `
|
|
17
|
+
Anything the spec does not say is a spec defect, not a decision you make. A missing field, an unstated conflict behaviour, an undefined state transition, a screen without columns: report it back. In the sandbox that is a `questions` block the operator answers, and the business manager records an answer that changes the spec for a new approval before you continue; on a host it is a question to the user. Never fill the gap with a plausible guess, and never implement anything listed in `outOfScope[]`.
|
|
18
18
|
|
|
19
19
|
Every `acceptanceScenarios[]` entry maps to at least one test in `tests/`. A scenario with no test is unfinished work, and the scenario id belongs in the test name so the mapping is readable.
|
|
20
20
|
|
|
@@ -10,7 +10,7 @@ description: >-
|
|
|
10
10
|
|
|
11
11
|
With an approved `schemaVersion: 2` spec delta, the specification is the requirement document. Read the spec, the module itself, the touch list for the change class below, and `.ai/references/catalog` for shape. Do not scan `modules/` or `packages/`: `.ai/platform-capabilities.md` answers what the platform provides.
|
|
12
12
|
|
|
13
|
-
Anything the delta does not say is a spec defect, not your decision. Report it back (`
|
|
13
|
+
Anything the delta does not say is a spec defect, not your decision. Report it back (a `questions` block in the sandbox, which the business manager turns into a spec delta for a new approval when the answer changes the spec; a question to the user on a host) instead of guessing, and never implement an item the spec parks in `outOfScope[]`. Every new or changed `acceptanceScenarios[]` entry maps to at least one test, with the scenario id in the test name.
|
|
14
14
|
|
|
15
15
|
The spec-element to file mapping is the table in `module-new`; the change classes below are the same mapping arranged by what you are changing.
|
|
16
16
|
|
|
@@ -93,6 +93,6 @@ Complexity to state in the review: for each new data structure and loop on a req
|
|
|
93
93
|
## Pitfalls
|
|
94
94
|
|
|
95
95
|
- `LIKE` or `=` against `lower(column)` cannot use a plain `(tenant_id, column)` index; store a normalized column (`sku_normalized`) as `.ai/references/catalog` does, or add an expression index on `lower(column)`.
|
|
96
|
-
- `ORDER BY lower(name)`
|
|
96
|
+
- `ORDER BY lower(name)` cannot use a `(tenant_id, name, id)` index for the sort; acceptable at small sizes, name it once the table grows.
|
|
97
97
|
- A `Kpi` that shows `items.length` after loading the full list is O(rows) network per dashboard load.
|
|
98
98
|
- Never change behaviour in a performance commit; keep the functional tests green and add none that assert internal call counts.
|
|
@@ -8,9 +8,9 @@ Two families of role prompts live here. They share one front matter schema (`id`
|
|
|
8
8
|
|
|
9
9
|
What the front matter does at run time:
|
|
10
10
|
|
|
11
|
-
- `gates`: enforced. After a turn that changed files, the sandbox runs `dependencies` plus these gates (`packages/sandbox/src/server/turns.ts`, `runSessionGates`), workspace gates once and module gates per draft module. Ids must come from `packages/sandbox/src/server/gates.ts`: `spec-schema`, `module-schema`, `dependencies`, `typecheck`, `tests`, `format`. An unknown id is dropped silently.
|
|
11
|
+
- `gates`: enforced. After a turn that changed files, the sandbox runs `dependencies` plus these gates (`packages/sandbox/src/server/turns.ts`, `runSessionGates`), workspace gates once and module gates per draft module. Ids must come from `packages/sandbox/src/server/gates.ts`: `spec-schema`, `module-schema`, `dependencies`, `typecheck`, `tests`, `format`. An unknown id is dropped silently. A gate whose last result did not pass also runs after every turn until it passes, and every gate but `auto-review` runs after a turn that wrote a file it checks (`reads` in `gates.ts`) once the module has its `module.json`. A failure is repaired by a role whose `allowedPaths` cover the file the fix goes in (`packages/sandbox/src/server/gate-repair.ts`), with the reported errors in the fix prompt.
|
|
12
12
|
- `allowedPaths`: enforced after every turn. Globs relative to the active draft module are shown to the agent as "Paths you may write" and captured before the driver starts. A write outside that allowlist fails the turn, is quarantined as evidence and is restored before formatting, gates, checkpoints, preview or delivery can observe it (`packages/sandbox/src/server/path-guard.ts`, `turns.ts`).
|
|
13
|
-
- `handoff`: enforced. A `HANDOFF:` line is honoured only when it names a role in this list and not the role itself (`packages/sandbox/src/server/planning.ts`); otherwise the state routing decides and the transcript says why. The team list in the instruction is built from this list.
|
|
13
|
+
- `handoff`: enforced. A `HANDOFF:` line is honoured only when it names a role in this list and not the role itself (`packages/sandbox/src/server/planning.ts`); otherwise the state routing decides and the transcript says why. When the line names module files the finishing role may not write, the next turn goes to a role whose `allowedPaths` cover one of them, or the chain stops when no role's do. The team list in the instruction is built from this list.
|
|
14
14
|
- `id`, `name`, `purpose`: composed into the instruction after `SANDBOX_AGENT_CONTRACT`, before the session facts.
|
|
15
15
|
|
|
16
16
|
The five roles and who takes the first turn: `business-manager` for both a new module and a change to an existing module. For a change, it updates the copied specification first and leaves it as `draft` or `in-review`. The operator approval route changes the current text to `approved` and records its exact hash. Any later edit makes the hash stale and routes back to approval before `backend-engineer`, `ux-designer`, `frontend-engineer` or `agentic-engineer` may implement (`planSpecGateHandoff` in `planning.ts`, `isSpecApproved` in `spec.ts`).
|
|
@@ -29,4 +29,4 @@ The allowed tool list is a maximum. Effective authority also requires tenant bin
|
|
|
29
29
|
|
|
30
30
|
Module-owned agents require a tenant provider/model binding, retained definition revisions and an exact tool ceiling. Never pin provider credentials or use wildcard tools. Procedures stored by agents.core are business data, unrelated to coding skills.
|
|
31
31
|
|
|
32
|
-
If the requested surface needs a missing endpoint/service, hand off to backend. If a permission or acceptance scenario
|
|
32
|
+
If the requested surface needs a missing endpoint/service, hand off to backend. If a permission, tool or acceptance scenario the work needs is not in the approved spec, ask for it with a questions block (Session); never add it yourself. Never edit another module or platform package from this session.
|
|
@@ -43,4 +43,4 @@ Test observable behavior: successful operations, validation bounds, 401/403, uni
|
|
|
43
43
|
|
|
44
44
|
Operator sample data comes from the sample-data tool or reference/sample-data.json. Derive tests/fixtures/\*.json and preview/seed.json from its shape with invented names, contacts and identifiers. src/preview.ts exports an idempotent seed({ tenantId, accountId, data, databases }) that writes through the module repository. A spec research section reads research-fixtures.json and each adapter its adapters/<id>.recorded.json; never declare a live adapter.
|
|
45
45
|
|
|
46
|
-
Leave client files to the frontend engineer and tools/business-agent definitions to the agentic engineer. If their required service surface is missing, finish it here before handing off.
|
|
46
|
+
Leave client files to the frontend engineer and tools/business-agent definitions to the agentic engineer. If their required service surface is missing, finish it here before handing off. Implement only what the approved spec states. Never add an error code, field, permission, state or behaviour it does not define, not even as the cautious choice: ask for it with a questions block (Session) and leave it unbuilt.
|
|
@@ -16,12 +16,10 @@ You own specification decisions and locale terminology, never implementation. Us
|
|
|
16
16
|
|
|
17
17
|
Write schemaVersion 2: entities with typed fields (never id, tenantId or createdAt) and states, screens, actions, widgets, settings, agentTools, plus outOfScope and decisions. Fill decisions for every choice, including the platform defaults you proposed. The capability card is closed: anything it lists as missing goes to outOfScope with the business decision, never into a scenario. v1 specs stay valid.
|
|
18
18
|
|
|
19
|
-
When a decision is missing, end the reply with exactly one fenced block tagged questions holding {"questions":[{"id":"Q-1","question":"...","options":["..."],"recommended":"...","allowFreeText":true}]} and nothing after it. Stay within the limits the sandbox enforces: at most 12 questions, each 1 to 400 characters; at most 8 options per question, each 1 to 120 characters; recommended is one of the options; no line breaks inside a value; the whole block at most 8000 characters. A block outside them comes back to you once with the reason. The operator answers in a form and the replies arrive next turn as a Decisions section.
|
|
20
|
-
|
|
21
19
|
For an edit, compare against base/modules/<dir>/spec/module.yaml and make the smallest delta covering the brief. Start new specs as draft; change an existing approved spec to draft or in-review before editing requirements. Never set approved: only the operator records approval of the exact hash. Later edits invalidate it.
|
|
22
20
|
|
|
23
21
|
State actors, records, ownership, permissions, uniqueness, failure behavior and observable acceptance scenarios. Do not invent business facts. Include success, denial and cross-tenant cases. The schema rejects unknown keys: express navigation and failure decisions inside invariants and acceptanceScenarios.
|
|
24
22
|
|
|
25
23
|
Put the primary entity's read/manage permissions first: the scaffold builds that entity, while later permissions only become constants. Capability and dependency declarations must describe the approved module, not guessed future work. Define matching terminology for each declared locale.
|
|
26
24
|
|
|
27
|
-
Do not write TypeScript, module.json or package.json. Hand a complete specification to backend or UX, explicitly noting that implementation awaits exact-hash approval. If a business decision is missing, end with HANDOFF: none
|
|
25
|
+
Do not write TypeScript, module.json or package.json. Hand a complete specification to backend or UX, explicitly noting that implementation awaits exact-hash approval. If a business decision is missing, ask it with a questions block (Session) and end with HANDOFF: none.
|
|
@@ -25,4 +25,4 @@ Use the canonical createClientContribution entry. Navigation must point at an ex
|
|
|
25
25
|
|
|
26
26
|
Records own the page, with create/edit in a Drawer. Reuse TableCard and Table, including widths, loading and empty states. Use translated copy, all five states, and no hardcoded design values. Inspect the rendered screen before handoff.
|
|
27
27
|
|
|
28
|
-
For TSRX, loop keys can read only the loop item: precompute a key on each item if it needs props or local state. Test pure mapping/filtering logic in .ts helpers. Ask the backend engineer for
|
|
28
|
+
For TSRX, loop keys can read only the loop item: precompute a key on each item if it needs props or local state. Test pure mapping/filtering logic in .ts helpers. Ask the backend engineer for an endpoint or field the spec defines but the server lacks, or UX for an unresolved screen decision. Never invent a business decision the approved spec does not make (a field, state, permission or behaviour): ask for it with a questions block (Session).
|
|
@@ -20,4 +20,4 @@ Specify loading, empty, error, populated and denied states. Use TableCard with a
|
|
|
20
20
|
|
|
21
21
|
Use shared primitives and tokens. A missing primitive may be a small module-local component, flagged for possible promotion. Do not restyle ui-\* classes. Reference existing translation keys; hand missing locale terms to the business manager because translations/ is outside your write scope.
|
|
22
22
|
|
|
23
|
-
Inspect the rendered result for overflow, alignment and duplicate labels. Hand the skeleton to frontend for data wiring
|
|
23
|
+
Inspect the rendered result for overflow, alignment and duplicate labels. Hand the skeleton to frontend for data wiring. Ask a missing business decision with a questions block (Session), never in prose.
|
|
@@ -50,7 +50,8 @@ profiles:
|
|
|
50
50
|
# Who takes the first sandbox turn (planning.ts classifyByRules) and how the
|
|
51
51
|
# next role is chosen (planHandoff): the HANDOFF line when it names a
|
|
52
52
|
# registered role, otherwise routeRole by module state, and a failed gate
|
|
53
|
-
#
|
|
53
|
+
# goes to the role whose write paths cover the file its fix goes in
|
|
54
|
+
# (gate-repair.ts).
|
|
54
55
|
routing:
|
|
55
56
|
new-module: business-manager
|
|
56
57
|
edit-module: business-manager
|
|
@@ -33,7 +33,7 @@ sandbox:
|
|
|
33
33
|
messageLength: 1 to 20000 characters (packages/sandbox/src/server/turns.ts)
|
|
34
34
|
briefLength: at least 8 characters (planning.ts assertBrief)
|
|
35
35
|
gateTimeout: 5 minutes per gate, output capped at 12000 characters (gates.ts)
|
|
36
|
-
gateFailure: the same role
|
|
36
|
+
gateFailure: a role whose write paths cover the failing file repairs, a repair that changed nothing is not repeated by the same role, and a gate that failed runs after every turn until it passes; at most maxRepairLoops consecutive repair turns per chain, then the chain returns to the operator
|
|
37
37
|
byokReads: 400 listed files, 128 KB per read (packages/coding-agent/src/drivers/byok.ts)
|
|
38
38
|
review:
|
|
39
39
|
chainedTurns: stop and read the transcript after four automatic handoffs on one brief
|
|
@@ -17,5 +17,5 @@ CREATE INDEX IF NOT EXISTS catalog_items_tenant_sku_idx
|
|
|
17
17
|
ALTER TABLE catalog_items ENABLE ROW LEVEL SECURITY;
|
|
18
18
|
ALTER TABLE catalog_items FORCE ROW LEVEL SECURITY;
|
|
19
19
|
CREATE POLICY catalog_items_tenant_policy ON catalog_items
|
|
20
|
-
USING (tenant_id = current_setting('
|
|
21
|
-
WITH CHECK (tenant_id = current_setting('
|
|
20
|
+
USING (tenant_id = current_setting('flowdular.tenant_id', true))
|
|
21
|
+
WITH CHECK (tenant_id = current_setting('flowdular.tenant_id', true));
|
|
@@ -16,5 +16,5 @@ CREATE UNIQUE INDEX IF NOT EXISTS catalog_items_history_tenant_record_version_id
|
|
|
16
16
|
ALTER TABLE catalog_items_history ENABLE ROW LEVEL SECURITY;
|
|
17
17
|
ALTER TABLE catalog_items_history FORCE ROW LEVEL SECURITY;
|
|
18
18
|
CREATE POLICY catalog_items_history_tenant_policy ON catalog_items_history
|
|
19
|
-
USING (tenant_id = current_setting('
|
|
20
|
-
WITH CHECK (tenant_id = current_setting('
|
|
19
|
+
USING (tenant_id = current_setting('flowdular.tenant_id', true))
|
|
20
|
+
WITH CHECK (tenant_id = current_setting('flowdular.tenant_id', true));
|
package/agent-template/.ai/references/catalog/migrations/0003_catalog_history_service_actors.up.sql
CHANGED
|
@@ -32,5 +32,5 @@ ON CONFLICT DO NOTHING;
|
|
|
32
32
|
ALTER TABLE catalog_items_history_v2 ENABLE ROW LEVEL SECURITY;
|
|
33
33
|
ALTER TABLE catalog_items_history_v2 FORCE ROW LEVEL SECURITY;
|
|
34
34
|
CREATE POLICY catalog_items_history_v2_tenant_policy ON catalog_items_history_v2
|
|
35
|
-
USING (tenant_id = current_setting('
|
|
36
|
-
WITH CHECK (tenant_id = current_setting('
|
|
35
|
+
USING (tenant_id = current_setting('flowdular.tenant_id', true))
|
|
36
|
+
WITH CHECK (tenant_id = current_setting('flowdular.tenant_id', true));
|
package/agent-template/.ai/references/catalog/migrations/0004_catalog_idempotency_ledger.up.sql
CHANGED
|
@@ -15,5 +15,5 @@ CREATE INDEX IF NOT EXISTS catalog_idempotency_ledger_tenant_operation_idx
|
|
|
15
15
|
ALTER TABLE catalog_idempotency_ledger ENABLE ROW LEVEL SECURITY;
|
|
16
16
|
ALTER TABLE catalog_idempotency_ledger FORCE ROW LEVEL SECURITY;
|
|
17
17
|
CREATE POLICY catalog_idempotency_ledger_tenant_policy ON catalog_idempotency_ledger
|
|
18
|
-
USING (tenant_id = current_setting('
|
|
19
|
-
WITH CHECK (tenant_id = current_setting('
|
|
18
|
+
USING (tenant_id = current_setting('flowdular.tenant_id', true))
|
|
19
|
+
WITH CHECK (tenant_id = current_setting('flowdular.tenant_id', true));
|
|
@@ -13,11 +13,11 @@
|
|
|
13
13
|
"dependencies": [
|
|
14
14
|
{
|
|
15
15
|
"id": "system.core",
|
|
16
|
-
"range": "^0.
|
|
16
|
+
"range": "^0.9.0"
|
|
17
17
|
},
|
|
18
18
|
{
|
|
19
19
|
"id": "auth.core",
|
|
20
|
-
"range": "^0.
|
|
20
|
+
"range": "^0.14.0"
|
|
21
21
|
},
|
|
22
22
|
{
|
|
23
23
|
"id": "exports.core",
|
|
@@ -33,5 +33,5 @@
|
|
|
33
33
|
"tenancy": "required",
|
|
34
34
|
"locales": ["en", "pl"],
|
|
35
35
|
"stability": "experimental",
|
|
36
|
-
"platformApi": "^0.
|
|
36
|
+
"platformApi": "^0.2.0"
|
|
37
37
|
}
|
|
@@ -30,8 +30,8 @@
|
|
|
30
30
|
},
|
|
31
31
|
"repository": {
|
|
32
32
|
"type": "git",
|
|
33
|
-
"url": "git+https://github.com/Flowdular/
|
|
34
|
-
"directory": "
|
|
33
|
+
"url": "git+https://github.com/Flowdular/flowdular.git",
|
|
34
|
+
"directory": ".ai/references/catalog"
|
|
35
35
|
},
|
|
36
36
|
"files": [
|
|
37
37
|
"src",
|
|
@@ -12,9 +12,9 @@ capabilities:
|
|
|
12
12
|
- translations
|
|
13
13
|
dependencies:
|
|
14
14
|
- id: system.core
|
|
15
|
-
range: ^0.
|
|
15
|
+
range: ^0.9.0
|
|
16
16
|
- id: auth.core
|
|
17
|
-
range: ^0.
|
|
17
|
+
range: ^0.14.0
|
|
18
18
|
- id: exports.core
|
|
19
19
|
range: ^0.2.0
|
|
20
20
|
requires:
|
|
@@ -26,7 +26,7 @@ locales:
|
|
|
26
26
|
- pl
|
|
27
27
|
invariants:
|
|
28
28
|
- Persistence runs on the shared asynchronous database contract. The module receives a leased PostgreSQL handle from platform composition, never a driver or a connection string, and declares explicit PostgreSQL SQL for every statement and migration.
|
|
29
|
-
- PostgreSQL item, history, and idempotency ledger tables enable and force row-level security with USING and WITH CHECK policies bound to transaction-local
|
|
29
|
+
- PostgreSQL item, history, and idempotency ledger tables enable and force row-level security with USING and WITH CHECK policies bound to transaction-local flowdular.tenant_id, and the runtime role holds neither SUPERUSER nor BYPASSRLS. Migrations use a separate lease.
|
|
30
30
|
- Every catalog item is owned by exactly one tenant and every query uses the trusted tenant identifier.
|
|
31
31
|
- SKU is unique inside a tenant and is never used as tenancy authority.
|
|
32
32
|
- Monetary values are stored as integer minor units with an explicit ISO currency code.
|
|
@@ -47,7 +47,7 @@ export function CatalogItemForm(props: CatalogItemFormProps) @{
|
|
|
47
47
|
name="name"
|
|
48
48
|
value={name}
|
|
49
49
|
onInput={(event) => setName(event.currentTarget.value)}
|
|
50
|
-
|
|
50
|
+
minLength={2}
|
|
51
51
|
maxLength={160}
|
|
52
52
|
autoFocus
|
|
53
53
|
required
|
|
@@ -113,7 +113,7 @@ export function CatalogItemForm(props: CatalogItemFormProps) @{
|
|
|
113
113
|
name="currency"
|
|
114
114
|
value={currency}
|
|
115
115
|
onInput={(event) => setCurrency(event.currentTarget.value)}
|
|
116
|
-
|
|
116
|
+
minLength={3}
|
|
117
117
|
maxLength={3}
|
|
118
118
|
required
|
|
119
119
|
/>
|
|
@@ -26,8 +26,8 @@ CREATE INDEX IF NOT EXISTS catalog_items_tenant_sku_idx
|
|
|
26
26
|
ALTER TABLE catalog_items ENABLE ROW LEVEL SECURITY;
|
|
27
27
|
ALTER TABLE catalog_items FORCE ROW LEVEL SECURITY;
|
|
28
28
|
CREATE POLICY catalog_items_tenant_policy ON catalog_items
|
|
29
|
-
USING (tenant_id = current_setting('
|
|
30
|
-
WITH CHECK (tenant_id = current_setting('
|
|
29
|
+
USING (tenant_id = current_setting('flowdular.tenant_id', true))
|
|
30
|
+
WITH CHECK (tenant_id = current_setting('flowdular.tenant_id', true));
|
|
31
31
|
`;
|
|
32
32
|
|
|
33
33
|
export const CATALOG_MIGRATION_002_HISTORY = `CREATE TABLE IF NOT EXISTS catalog_items_history (
|
|
@@ -48,8 +48,8 @@ CREATE UNIQUE INDEX IF NOT EXISTS catalog_items_history_tenant_record_version_id
|
|
|
48
48
|
ALTER TABLE catalog_items_history ENABLE ROW LEVEL SECURITY;
|
|
49
49
|
ALTER TABLE catalog_items_history FORCE ROW LEVEL SECURITY;
|
|
50
50
|
CREATE POLICY catalog_items_history_tenant_policy ON catalog_items_history
|
|
51
|
-
USING (tenant_id = current_setting('
|
|
52
|
-
WITH CHECK (tenant_id = current_setting('
|
|
51
|
+
USING (tenant_id = current_setting('flowdular.tenant_id', true))
|
|
52
|
+
WITH CHECK (tenant_id = current_setting('flowdular.tenant_id', true));
|
|
53
53
|
`;
|
|
54
54
|
|
|
55
55
|
export const CATALOG_MIGRATION_003_HISTORY_SERVICE_ACTORS = `CREATE TABLE IF NOT EXISTS catalog_items_history_v2 (
|
|
@@ -86,8 +86,8 @@ ON CONFLICT DO NOTHING;
|
|
|
86
86
|
ALTER TABLE catalog_items_history_v2 ENABLE ROW LEVEL SECURITY;
|
|
87
87
|
ALTER TABLE catalog_items_history_v2 FORCE ROW LEVEL SECURITY;
|
|
88
88
|
CREATE POLICY catalog_items_history_v2_tenant_policy ON catalog_items_history_v2
|
|
89
|
-
USING (tenant_id = current_setting('
|
|
90
|
-
WITH CHECK (tenant_id = current_setting('
|
|
89
|
+
USING (tenant_id = current_setting('flowdular.tenant_id', true))
|
|
90
|
+
WITH CHECK (tenant_id = current_setting('flowdular.tenant_id', true));
|
|
91
91
|
`;
|
|
92
92
|
|
|
93
93
|
export const CATALOG_MIGRATION_004_IDEMPOTENCY_LEDGER = `CREATE TABLE IF NOT EXISTS catalog_idempotency_ledger (
|
|
@@ -107,8 +107,8 @@ CREATE INDEX IF NOT EXISTS catalog_idempotency_ledger_tenant_operation_idx
|
|
|
107
107
|
ALTER TABLE catalog_idempotency_ledger ENABLE ROW LEVEL SECURITY;
|
|
108
108
|
ALTER TABLE catalog_idempotency_ledger FORCE ROW LEVEL SECURITY;
|
|
109
109
|
CREATE POLICY catalog_idempotency_ledger_tenant_policy ON catalog_idempotency_ledger
|
|
110
|
-
USING (tenant_id = current_setting('
|
|
111
|
-
WITH CHECK (tenant_id = current_setting('
|
|
110
|
+
USING (tenant_id = current_setting('flowdular.tenant_id', true))
|
|
111
|
+
WITH CHECK (tenant_id = current_setting('flowdular.tenant_id', true));
|
|
112
112
|
`;
|
|
113
113
|
|
|
114
114
|
export const CATALOG_MIGRATION_005_LIST_INDEXES = `ALTER TABLE catalog_items ADD COLUMN IF NOT EXISTS updated_at BIGINT NOT NULL DEFAULT 0;
|
|
@@ -90,7 +90,7 @@ describe('catalog migrations', () => {
|
|
|
90
90
|
if (!sql.includes('CREATE TABLE')) continue;
|
|
91
91
|
expect(sql).toContain('ENABLE ROW LEVEL SECURITY');
|
|
92
92
|
expect(sql).toContain('FORCE ROW LEVEL SECURITY');
|
|
93
|
-
expect(sql).toContain("current_setting('
|
|
93
|
+
expect(sql).toContain("current_setting('flowdular.tenant_id', true)");
|
|
94
94
|
expect(sql).toContain('WITH CHECK');
|
|
95
95
|
}
|
|
96
96
|
});
|
|
@@ -20,7 +20,7 @@ Two ways to land the same module: the sandbox (a brief, specialist turns, gates
|
|
|
20
20
|
|
|
21
21
|
With an approved `schemaVersion: 2` spec, the specification is the requirement document and you do not go looking for one. Read the spec, the files on this skill's touch list, and `.ai/references/catalog` for shape. Do not scan `modules/` or `packages/`; `.ai/platform-capabilities.md` answers what the platform provides, and the reference module answers what the code looks like.
|
|
22
22
|
|
|
23
|
-
Anything the spec does not say is a spec defect, not a decision you make. A missing field, an unstated conflict behaviour, an undefined state transition, a screen without columns: report it back. In the sandbox that is `
|
|
23
|
+
Anything the spec does not say is a spec defect, not a decision you make. A missing field, an unstated conflict behaviour, an undefined state transition, a screen without columns: report it back. In the sandbox that is a `questions` block the operator answers, and the business manager records an answer that changes the spec for a new approval before you continue; on a host it is a question to the user. Never fill the gap with a plausible guess, and never implement anything listed in `outOfScope[]`.
|
|
24
24
|
|
|
25
25
|
Every `acceptanceScenarios[]` entry maps to at least one test in `tests/`. A scenario with no test is unfinished work, and the scenario id belongs in the test name so the mapping is readable.
|
|
26
26
|
|
|
@@ -17,7 +17,7 @@ when: A brief names an existing module, or a sandbox session is labelled edit-mo
|
|
|
17
17
|
|
|
18
18
|
With an approved `schemaVersion: 2` spec delta, the specification is the requirement document. Read the spec, the module itself, the touch list for the change class below, and `.ai/references/catalog` for shape. Do not scan `modules/` or `packages/`: `.ai/platform-capabilities.md` answers what the platform provides.
|
|
19
19
|
|
|
20
|
-
Anything the delta does not say is a spec defect, not your decision. Report it back (`
|
|
20
|
+
Anything the delta does not say is a spec defect, not your decision. Report it back (a `questions` block in the sandbox, which the business manager turns into a spec delta for a new approval when the answer changes the spec; a question to the user on a host) instead of guessing, and never implement an item the spec parks in `outOfScope[]`. Every new or changed `acceptanceScenarios[]` entry maps to at least one test, with the scenario id in the test name.
|
|
21
21
|
|
|
22
22
|
The spec-element to file mapping is the table in `module-new`; the change classes below are the same mapping arranged by what you are changing.
|
|
23
23
|
|
|
@@ -99,6 +99,6 @@ Complexity to state in the review: for each new data structure and loop on a req
|
|
|
99
99
|
## Pitfalls
|
|
100
100
|
|
|
101
101
|
- `LIKE` or `=` against `lower(column)` cannot use a plain `(tenant_id, column)` index; store a normalized column (`sku_normalized`) as `.ai/references/catalog` does, or add an expression index on `lower(column)`.
|
|
102
|
-
- `ORDER BY lower(name)`
|
|
102
|
+
- `ORDER BY lower(name)` cannot use a `(tenant_id, name, id)` index for the sort; acceptable at small sizes, name it once the table grows.
|
|
103
103
|
- A `Kpi` that shows `items.length` after loading the full list is O(rows) network per dashboard load.
|
|
104
104
|
- Never change behaviour in a performance commit; keep the functional tests green and add none that assert internal call counts.
|
|
@@ -14,7 +14,7 @@ Two ways to land the same module: the sandbox (a brief, specialist turns, gates
|
|
|
14
14
|
|
|
15
15
|
With an approved `schemaVersion: 2` spec, the specification is the requirement document and you do not go looking for one. Read the spec, the files on this skill's touch list, and `.ai/references/catalog` for shape. Do not scan `modules/` or `packages/`; `.ai/platform-capabilities.md` answers what the platform provides, and the reference module answers what the code looks like.
|
|
16
16
|
|
|
17
|
-
Anything the spec does not say is a spec defect, not a decision you make. A missing field, an unstated conflict behaviour, an undefined state transition, a screen without columns: report it back. In the sandbox that is `
|
|
17
|
+
Anything the spec does not say is a spec defect, not a decision you make. A missing field, an unstated conflict behaviour, an undefined state transition, a screen without columns: report it back. In the sandbox that is a `questions` block the operator answers, and the business manager records an answer that changes the spec for a new approval before you continue; on a host it is a question to the user. Never fill the gap with a plausible guess, and never implement anything listed in `outOfScope[]`.
|
|
18
18
|
|
|
19
19
|
Every `acceptanceScenarios[]` entry maps to at least one test in `tests/`. A scenario with no test is unfinished work, and the scenario id belongs in the test name so the mapping is readable.
|
|
20
20
|
|
|
@@ -10,7 +10,7 @@ description: >-
|
|
|
10
10
|
|
|
11
11
|
With an approved `schemaVersion: 2` spec delta, the specification is the requirement document. Read the spec, the module itself, the touch list for the change class below, and `.ai/references/catalog` for shape. Do not scan `modules/` or `packages/`: `.ai/platform-capabilities.md` answers what the platform provides.
|
|
12
12
|
|
|
13
|
-
Anything the delta does not say is a spec defect, not your decision. Report it back (`
|
|
13
|
+
Anything the delta does not say is a spec defect, not your decision. Report it back (a `questions` block in the sandbox, which the business manager turns into a spec delta for a new approval when the answer changes the spec; a question to the user on a host) instead of guessing, and never implement an item the spec parks in `outOfScope[]`. Every new or changed `acceptanceScenarios[]` entry maps to at least one test, with the scenario id in the test name.
|
|
14
14
|
|
|
15
15
|
The spec-element to file mapping is the table in `module-new`; the change classes below are the same mapping arranged by what you are changing.
|
|
16
16
|
|
|
@@ -93,6 +93,6 @@ Complexity to state in the review: for each new data structure and loop on a req
|
|
|
93
93
|
## Pitfalls
|
|
94
94
|
|
|
95
95
|
- `LIKE` or `=` against `lower(column)` cannot use a plain `(tenant_id, column)` index; store a normalized column (`sku_normalized`) as `.ai/references/catalog` does, or add an expression index on `lower(column)`.
|
|
96
|
-
- `ORDER BY lower(name)`
|
|
96
|
+
- `ORDER BY lower(name)` cannot use a `(tenant_id, name, id)` index for the sort; acceptable at small sizes, name it once the table grows.
|
|
97
97
|
- A `Kpi` that shows `items.length` after loading the full list is O(rows) network per dashboard load.
|
|
98
98
|
- Never change behaviour in a performance commit; keep the functional tests green and add none that assert internal call counts.
|
|
@@ -77,8 +77,7 @@ release. No direct registry installation path remains.
|
|
|
77
77
|
Automation that imported `installModule` from `flowdular/distribution` must use
|
|
78
78
|
the host CLI plan and apply commands; that direct install export was removed.
|
|
79
79
|
|
|
80
|
-
|
|
81
|
-
`sandbox.delivery.targets` to `workspace` or `git-pr`; `git-pr` points to the
|
|
80
|
+
Sandbox delivery targets are `workspace` and `git-pr`; `git-pr` points to the
|
|
82
81
|
platform repository configured in `flowdular.json`. A catalog publisher can
|
|
83
82
|
use any Git repository and publish immutable artifacts independently. Historical
|
|
84
83
|
review and RFC documents retain the old project name as provenance.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
A module is a self-contained slice of the product: its own permissions,
|
|
4
4
|
endpoints, migrations, services, screens, translations and tests, wired into the
|
|
5
|
-
platform without touching a core file. `.ai/references/catalog` is the
|
|
5
|
+
platform without touching a core file. `.ai/references/catalog` is the reference
|
|
6
6
|
implementation; copy its shape.
|
|
7
7
|
|
|
8
8
|
## Lifecycle
|
|
@@ -419,4 +419,4 @@ RuleSync generates the discovery copies for supported coding agents:
|
|
|
419
419
|
`test-hardening`, `cli-extension`, `agent-tool-design`,
|
|
420
420
|
`business-agent-design`, `workflow-development`, `release-eject-pr`.
|
|
421
421
|
|
|
422
|
-
|
|
422
|
+
Business modules kept outside this repository install through [module distribution](module-distribution.md), which covers install, update, lock verification and release checks.
|
|
@@ -336,7 +336,13 @@ and a human review remain the repository's own gate.
|
|
|
336
336
|
## Decisions the specialist needs
|
|
337
337
|
|
|
338
338
|
A specialist that cannot continue without a business decision ends its reply
|
|
339
|
-
with one fenced block tagged `questions` holding a single JSON object
|
|
339
|
+
with one fenced block tagged `questions` holding a single JSON object. An
|
|
340
|
+
implementer (every role but the business manager) asks this way for anything
|
|
341
|
+
the approved specification does not decide, such as a new error code, field,
|
|
342
|
+
permission, state or changed behaviour, and leaves that part unbuilt instead of
|
|
343
|
+
deciding it and mentioning it in prose. Every turn's instruction carries the
|
|
344
|
+
format and the limits below from `questions.ts`, the module that parses the
|
|
345
|
+
block.
|
|
340
346
|
|
|
341
347
|
````
|
|
342
348
|
```questions
|
|
@@ -389,8 +395,11 @@ POST /sandbox/api/sessions/:id/answers
|
|
|
389
395
|
```
|
|
390
396
|
|
|
391
397
|
behind the same origin, header and ownership checks as every other mutation. It
|
|
392
|
-
clears `pendingQuestions` and starts the next turn in the
|
|
393
|
-
|
|
398
|
+
clears `pendingQuestions` and starts the next turn in the module the questions
|
|
399
|
+
were about, with the decisions leading the request text. The business manager's
|
|
400
|
+
own questions go back to it. An implementer's questions go to the business
|
|
401
|
+
manager first (`answeringRole` in `planning.ts`), and so does an answer the
|
|
402
|
+
operator types in the message box instead:
|
|
394
403
|
|
|
395
404
|
```
|
|
396
405
|
Decisions:
|
|
@@ -406,6 +415,35 @@ INVALID_INPUT` for a body that leaves a question unanswered, names a question
|
|
|
406
415
|
the session did not ask, exceeds 400 characters, or gives an answer that is not
|
|
407
416
|
one of the offered options when the specialist allowed no free text.
|
|
408
417
|
|
|
418
|
+
### Answers to an implementer's questions
|
|
419
|
+
|
|
420
|
+
The business manager applies the answers to `spec/module.yaml`, and the text it
|
|
421
|
+
leaves behind decides what happens next:
|
|
422
|
+
|
|
423
|
+
- An answer that changes what the module must do is recorded in the
|
|
424
|
+
specification, which goes back to `draft`. Its hash no longer matches the
|
|
425
|
+
approval, so the session waits in `awaiting-approval` with the implementer
|
|
426
|
+
that asked as the next role, and implementation is refused until the operator
|
|
427
|
+
approves the new hash. Approving resumes that implementer with its decisions.
|
|
428
|
+
- An answer the approved text already decides leaves the file untouched. The
|
|
429
|
+
approval still holds, and the implementer that asked continues at once with
|
|
430
|
+
its decisions.
|
|
431
|
+
|
|
432
|
+
The wait is read from the transcript (`specFollowUp` in `planning.ts`): the
|
|
433
|
+
newest handoff that is not the business manager's own is the implementer's
|
|
434
|
+
question, so the implementer still resumes when the business manager asks a
|
|
435
|
+
question of its own in between. A gate the implementer left failing runs again
|
|
436
|
+
on the business manager's turn. When it still fails, only a repair the business
|
|
437
|
+
manager takes in that module runs first; any other waits until the implementer
|
|
438
|
+
has resumed with its decisions, and the gates run again after that turn.
|
|
439
|
+
|
|
440
|
+
The `module-rules` gate backs the rule for permissions: `permissions-specified`
|
|
441
|
+
fails a module whose `src/acl/permissions.ts`, or an inline `permission:`
|
|
442
|
+
value, names a permission the specification does not list. Error codes have no
|
|
443
|
+
structured list in a specification and the shipped modules throw many codes
|
|
444
|
+
their specifications never name, so a matching rule for them would fail correct
|
|
445
|
+
modules; the instruction and the question card cover them.
|
|
446
|
+
|
|
409
447
|
## Operator commands
|
|
410
448
|
|
|
411
449
|
```bash
|
package/package.json
CHANGED
|
@@ -22,10 +22,10 @@
|
|
|
22
22
|
"build": "flowdular module sync --apply && pnpm --filter @app/platform build"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
|
-
"@flowdular/sandbox": "0.6.
|
|
25
|
+
"@flowdular/sandbox": "0.6.3",
|
|
26
26
|
"@tsrx/prettier-plugin": "0.3.120",
|
|
27
27
|
"prettier": "3.6.2",
|
|
28
|
-
"flowdular": "0.6.
|
|
28
|
+
"flowdular": "0.6.3",
|
|
29
29
|
"rulesync": "16.21.0"
|
|
30
30
|
}
|
|
31
31
|
}
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"id": "catalog.core",
|
|
3
|
-
"version": "0.8.2",
|
|
4
|
-
"repository": "Flowdular/official-modules",
|
|
5
|
-
"sourceCommit": "f38a67718c5a29aba5b5d37c0504430a3c7f565b",
|
|
6
|
-
"artifactSha256": "149808831d620ac0ebc50abb6b0fb2caef6bec66b5d7821c752ec811e5d9219f",
|
|
7
|
-
"files": {
|
|
8
|
-
"LICENSE": "155d722071bad9d0d832482e06fd5a47f7034389cb63aabcb39f4282aa3499fc",
|
|
9
|
-
"migrations/0001_catalog_core.down.sql": "0962a1edf0bde959cd4facccf77bd5b634d6cc25f125a0c79a61770c8871093f",
|
|
10
|
-
"migrations/0001_catalog_core.up.sql": "602ed9c1852b729cf278cf8536f79e3f7432f23a5a60c50d8826f5c1b9442d18",
|
|
11
|
-
"migrations/0002_catalog_history.down.sql": "7f163e11ca9033101e3bb1de61481b1a8043c204e65aa2bb508a13b065e98c78",
|
|
12
|
-
"migrations/0002_catalog_history.up.sql": "3aa30993b1676cf357c2ef87f19a7d4b64b77041c0e4bc743fced04521471c28",
|
|
13
|
-
"migrations/0003_catalog_history_service_actors.down.sql": "f20ecc8d7d753af3d2b6fdbff9d637fd938884cfbd88b08a30958e6aa000132b",
|
|
14
|
-
"migrations/0003_catalog_history_service_actors.up.sql": "7caae787ca2fc1e331ccbfda4df5982beec76136e8dc486aab5532ccd338a722",
|
|
15
|
-
"migrations/0004_catalog_idempotency_ledger.down.sql": "8ba72d8edc4d25ecf6d041888cf321690c25afdaf3723812ddd7d391d75370aa",
|
|
16
|
-
"migrations/0004_catalog_idempotency_ledger.up.sql": "41e86ba2051159c6cc9672bfae17c1d02051da975f1c43c566a2b66592673cb0",
|
|
17
|
-
"migrations/0005_catalog_list_indexes.down.sql": "3dd547d738e75513abef502afc4bf9b51851ec9405b6b719c6134b897c5b1776",
|
|
18
|
-
"migrations/0005_catalog_list_indexes.up.sql": "dc3ece30b93fba0c91be58f772d1ae421cfbba49439e8c72a06aead6720f5db5",
|
|
19
|
-
"migrations/README.md": "2a15fd001713c2552a3c82b186246aa5fec136f43143cc2d9aa15bd491a09d41",
|
|
20
|
-
"module.json": "d2a98b70d60a433e1b3b6547352781048d562b996e3ee961f519d61ee1b623b9",
|
|
21
|
-
"package.json": "c23a99016f974d183189a05e4cfc4929788a46ae1ad65c623d66513e0880cdbd",
|
|
22
|
-
"spec/module.yaml": "992953d002574e83374c21e1ee7bef1d451c04b0180892856838d7c67404ce66",
|
|
23
|
-
"src/acl/permissions.ts": "3375521a5a229736ffac5a948140ec347dc7a7e4fba80e778c0baaf9e0622590",
|
|
24
|
-
"src/agent/tools.ts": "3403db7954906dc2c79227ba0420b5cb4bfb57063b7cfc285e6e556f16be9266",
|
|
25
|
-
"src/api/endpoints.ts": "205ef36d058f246f99b77336e7246a23aaca611c696a1f6f09758f66e8a93a29",
|
|
26
|
-
"src/api/list-cursor.ts": "dcb763edc0128a3aac95e9ca3c5158611a7f2c6a4c71484438c89b7f4d79bb0d",
|
|
27
|
-
"src/client/CatalogHistoryDrawer.tsrx": "6cdba5249be81e70da703cb34c1a2210943ce5e5fb596ee77cf7952e2acf3ee3",
|
|
28
|
-
"src/client/CatalogItemForm.tsrx": "d621ac2a513635a5e38ee44726c07926bf035ec5e0dddca487c462cc7913d040",
|
|
29
|
-
"src/client/CatalogView.tsrx": "2c3e49bb1e54b58d636de0ddbb6ece429acf6aeadb6a0515ab52fca3baabec21",
|
|
30
|
-
"src/client/api.ts": "eaa55af81d26aa0190d19b3102c363c1ee25b2bdc05436446ac95dcde62aea75",
|
|
31
|
-
"src/client/contribution.tsrx": "6cbf79e6188bdf24b9cec4a06ae621e03efd5d0c76ad72b28828eee9155ab893",
|
|
32
|
-
"src/client/index.ts": "03eb0664cdafccb66cb25f2e1b07e6959c2dfa9bdbfffc3e7edf9b535ba4949a",
|
|
33
|
-
"src/client/navigation-copy.ts": "9a8757e64f4001a93e2bc2861c686a19f791f9d67a396d9e658023b1ec4cea8f",
|
|
34
|
-
"src/client/state.ts": "61601f6037c4bb8a709b69b10c1a37e59b45b0c941240c436f7861c2b034dcc1",
|
|
35
|
-
"src/domain/lists.ts": "83749967f99fa0c4f44abc0c614108b844321e50ce6408553215e6233ad6e350",
|
|
36
|
-
"src/domain/types.ts": "374efeb24c4f7d41e3c660336e721fa362418579837d44a46724076d03287a0b",
|
|
37
|
-
"src/domain/variables.ts": "131130e57838235b1f3fcb799da44baeae16522bb346d522827e022305c110b5",
|
|
38
|
-
"src/index.ts": "5b27943018db9a18651d62add7d6f8397d7c492a204381fae74547b99b91990d",
|
|
39
|
-
"src/platform.ts": "f048082a33c1c688e4952750c762c8b65a4626ff52cc9c4eaca2156014bac631",
|
|
40
|
-
"src/server/index.ts": "90eae107d863418124e5d10c4d1fe8a119bd14da605b36de708c18d8500c4b5e",
|
|
41
|
-
"src/server/runtime.ts": "5f4389a6adf8265f6737c489baf686f63cc3550662103d28b2da9800dd9f5b63",
|
|
42
|
-
"src/services/catalog-service.ts": "66e61dfbd9797d31e6814c18efcd21cfcb7b220f7df22677868f486f3fa0e9d1",
|
|
43
|
-
"src/services/data-classes.ts": "ea09b1a7def59fee43d57ca7dab6fdb4d646b51df2cacb60af96676c43602b33",
|
|
44
|
-
"src/services/database-repository.ts": "1b72ce91a2f85f6572825766781a806d94fe0d2abb91872ee9acae3b1e70db2e",
|
|
45
|
-
"src/services/index.ts": "a08aefe5101814538666f861536287fc382e6c655d62ba9b9ef4bbfbc6ede4af",
|
|
46
|
-
"src/services/item-export.ts": "b2a4613b43a98d0d41699481bb5e85a770f9a60cb2241579b065effb6936c80b",
|
|
47
|
-
"src/services/migration.ts": "57c9a857d4074973e14b5e3a1c4548a92ad0faca371419e7daf2334f3ef701ab",
|
|
48
|
-
"src/services/repository.ts": "9f560033875d05654148b4a11897465ee4eefa0d7fa701439e8f562da9fba1db",
|
|
49
|
-
"src/services/target-idempotency.ts": "7111b56a30b691eaaaa64f5691895ac94b6e0735b0079794835bbbeba5102cb0",
|
|
50
|
-
"tests/agent-tools.test.ts": "7762c14bc353ee3085df46a91cf370eb5c25b2edb7096f0a4b0e033f220ea726",
|
|
51
|
-
"tests/client-state.test.ts": "ea146c793b14d0f9bc5e36d92e92894ced6531b8fcbd11c8be1486b62313b8c3",
|
|
52
|
-
"tests/data-classes.test.ts": "bea08e4d1d7380ccdebc211374b74a6034714b192fd98bfb90a2218067b35658",
|
|
53
|
-
"tests/endpoints.test.ts": "a2d700f4c3eb6fbbef5c57ed5591017a27c98e17fe84fba8426fcd3a2820b210",
|
|
54
|
-
"tests/export.test.ts": "de83066272cee5f7f5736d636d7b9b97dab09778ba661816e401bf926b826402",
|
|
55
|
-
"tests/idempotency.test.ts": "faea4a2cfa04e81b7155399cba807af4c1ba4448cdfeab733d1afe801d27734f",
|
|
56
|
-
"tests/list.test.ts": "97605b50020841cbdac62f9d44b65f0f7dce9c4c4972af6409afeb6b9b66e59a",
|
|
57
|
-
"tests/migrations.test.ts": "fb796aecedb997f6395c2c15e45bf4abfae4677953fa8cb420c94e9cfba8222f",
|
|
58
|
-
"tests/module.test.ts": "af961a5bcddc41d304d14841f8810976f43f46b46ab7814142fdb921a773e92a",
|
|
59
|
-
"tests/support/database.ts": "4ff6d093ca2e80baab3dea476018661473d6474db63d67655f1edc667b8472ac",
|
|
60
|
-
"translations/en.json": "a86d70e02ccf46a2a132d5bee0de7c528c0eb56a85c269a78e0c2e7e0de24e37",
|
|
61
|
-
"translations/pl.json": "8157d83467e9dd8d9700e2fb188f1a730073f805d2a8b3f0ba98f02f2ca9a264",
|
|
62
|
-
"tsconfig.json": "140bb4775df421146563d13d2f78ff74cb3c2decab6737db32938339248a92ba",
|
|
63
|
-
"vitest.config.ts": "d13725b13c3712ec91c1646e9226fb172eec2599f72f4e6608bece9912e2bd81"
|
|
64
|
-
}
|
|
65
|
-
}
|