@regardio/dev 1.24.0 → 2.0.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/README.md +2 -2
- package/dist/bin/ship/hotfix.bin.mjs +140 -0
- package/dist/bin/ship/production.bin.mjs +120 -0
- package/dist/bin/ship/staging.bin.mjs +70 -0
- package/dist/bin/ship/utils-BQ-JZ2D5.mjs +45 -0
- package/dist/playwright/index.d.mts +24 -0
- package/dist/playwright/index.mjs +61 -0
- package/dist/vitest/node.d.mts +22 -0
- package/dist/vitest/node.mjs +28 -0
- package/dist/vitest/react.d.mts +22 -0
- package/dist/vitest/react.mjs +28 -0
- package/docs/en/README.md +95 -0
- package/docs/en/agents.md +57 -0
- package/docs/en/standards/api.md +324 -0
- package/docs/en/standards/coding.md +144 -0
- package/docs/en/standards/commits.md +111 -0
- package/docs/en/standards/documentation.md +173 -0
- package/docs/en/standards/naming.md +180 -0
- package/docs/en/standards/principles.md +84 -0
- package/docs/en/standards/react.md +246 -0
- package/docs/en/standards/sql.md +258 -0
- package/docs/en/standards/testing.md +139 -0
- package/docs/en/standards/writing.md +119 -0
- package/docs/en/tools/biome.md +89 -0
- package/docs/en/tools/commitlint.md +92 -0
- package/docs/en/tools/dependencies.md +116 -0
- package/docs/en/tools/husky.md +90 -0
- package/docs/en/tools/markdownlint.md +84 -0
- package/docs/en/tools/playwright.md +117 -0
- package/docs/en/tools/releases.md +242 -0
- package/docs/en/tools/typescript.md +89 -0
- package/docs/en/tools/vitest.md +146 -0
- package/package.json +57 -70
- package/src/biome/preset.json +3 -0
- package/templates/changeset/README.md +14 -0
- package/templates/changeset/config.json +11 -0
- package/templates/github/release.yml +77 -0
- package/dist/bin/exec/clean.d.ts +0 -3
- package/dist/bin/exec/clean.d.ts.map +0 -1
- package/dist/bin/exec/clean.js +0 -25
- package/dist/bin/exec/clean.test.d.ts +0 -2
- package/dist/bin/exec/clean.test.d.ts.map +0 -1
- package/dist/bin/exec/clean.test.js +0 -45
- package/dist/bin/exec/husky.d.ts +0 -3
- package/dist/bin/exec/husky.d.ts.map +0 -1
- package/dist/bin/exec/husky.js +0 -9
- package/dist/bin/exec/p.d.ts +0 -3
- package/dist/bin/exec/p.d.ts.map +0 -1
- package/dist/bin/exec/p.js +0 -8
- package/dist/bin/exec/s.d.ts +0 -3
- package/dist/bin/exec/s.d.ts.map +0 -1
- package/dist/bin/exec/s.js +0 -8
- package/dist/bin/exec/tsc.d.ts +0 -3
- package/dist/bin/exec/tsc.d.ts.map +0 -1
- package/dist/bin/exec/tsc.js +0 -8
- package/dist/bin/lint/biome.d.ts +0 -3
- package/dist/bin/lint/biome.d.ts.map +0 -1
- package/dist/bin/lint/biome.js +0 -8
- package/dist/bin/lint/commit.d.ts +0 -3
- package/dist/bin/lint/commit.d.ts.map +0 -1
- package/dist/bin/lint/commit.js +0 -8
- package/dist/bin/lint/md.d.ts +0 -3
- package/dist/bin/lint/md.d.ts.map +0 -1
- package/dist/bin/lint/md.js +0 -16
- package/dist/bin/lint/package.d.ts +0 -4
- package/dist/bin/lint/package.d.ts.map +0 -1
- package/dist/bin/lint/package.js +0 -81
- package/dist/bin/lint/package.test.d.ts +0 -2
- package/dist/bin/lint/package.test.d.ts.map +0 -1
- package/dist/bin/lint/package.test.js +0 -65
- package/dist/bin/ship/hotfix.d.ts +0 -3
- package/dist/bin/ship/hotfix.d.ts.map +0 -1
- package/dist/bin/ship/hotfix.js +0 -141
- package/dist/bin/ship/production.d.ts +0 -3
- package/dist/bin/ship/production.d.ts.map +0 -1
- package/dist/bin/ship/production.js +0 -124
- package/dist/bin/ship/staging.d.ts +0 -3
- package/dist/bin/ship/staging.d.ts.map +0 -1
- package/dist/bin/ship/staging.js +0 -51
- package/dist/bin/ship/utils.d.ts +0 -9
- package/dist/bin/ship/utils.d.ts.map +0 -1
- package/dist/bin/ship/utils.js +0 -63
- package/dist/bin/ship/utils.test.d.ts +0 -2
- package/dist/bin/ship/utils.test.d.ts.map +0 -1
- package/dist/bin/ship/utils.test.js +0 -127
- package/dist/config.test.d.ts +0 -2
- package/dist/config.test.d.ts.map +0 -1
- package/dist/config.test.js +0 -101
- package/dist/playwright/index.d.ts +0 -10
- package/dist/playwright/index.d.ts.map +0 -1
- package/dist/playwright/index.js +0 -42
- package/dist/playwright/index.test.d.ts +0 -2
- package/dist/playwright/index.test.d.ts.map +0 -1
- package/dist/playwright/index.test.js +0 -55
- package/dist/testing/setup-react.d.ts +0 -2
- package/dist/testing/setup-react.d.ts.map +0 -1
- package/dist/testing/setup-react.js +0 -1
- package/dist/vitest/node.d.ts +0 -22
- package/dist/vitest/node.d.ts.map +0 -1
- package/dist/vitest/node.js +0 -16
- package/dist/vitest/react.d.ts +0 -17
- package/dist/vitest/react.d.ts.map +0 -1
- package/dist/vitest/react.js +0 -12
- package/src/bin/exec/clean.test.ts +0 -63
- package/src/bin/exec/clean.ts +0 -36
- package/src/bin/exec/husky.ts +0 -14
- package/src/bin/exec/p.ts +0 -13
- package/src/bin/exec/s.ts +0 -13
- package/src/bin/exec/tsc.ts +0 -13
- package/src/bin/lint/biome.ts +0 -13
- package/src/bin/lint/commit.ts +0 -13
- package/src/bin/lint/md.ts +0 -28
- package/src/bin/lint/package.test.ts +0 -83
- package/src/bin/lint/package.ts +0 -108
- package/src/bin/ship/hotfix.ts +0 -241
- package/src/bin/ship/production.ts +0 -240
- package/src/bin/ship/staging.ts +0 -108
- package/src/bin/ship/utils.test.ts +0 -178
- package/src/bin/ship/utils.ts +0 -109
- package/src/config.test.ts +0 -129
- package/src/markdownlint/markdownlint-cli2.jsonc +0 -9
- package/src/playwright/index.test.ts +0 -73
- package/src/playwright/index.ts +0 -63
- package/src/templates/release.yml +0 -128
- package/src/testing/setup-react.ts +0 -8
- package/src/vitest/node.ts +0 -25
- package/src/vitest/react.ts +0 -19
- /package/{src → templates}/sqlfluff/setup.cfg +0 -0
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
---
|
|
2
|
+
|
|
3
|
+
title: "SQL"
|
|
4
|
+
description: "PostgreSQL file organisation, formatting, naming, functions, and access control for Regardio schemas."
|
|
5
|
+
publishedAt: 2026-04-17
|
|
6
|
+
order: 7
|
|
7
|
+
language: "en"
|
|
8
|
+
status: "published"
|
|
9
|
+
kind: "reference"
|
|
10
|
+
area: "dev"
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
All SQL in Regardio is lowercase, schemas are organised by numbered files, SQLFluff enforces formatting, and RLS is on for every public table. This page catalogues the conventions. The reasoning behind the access pattern lives with the schema it protects — the standards here describe the form.
|
|
14
|
+
|
|
15
|
+
## Formatting
|
|
16
|
+
|
|
17
|
+
Keywords, identifiers, data types, function names, and casts are lowercase.
|
|
18
|
+
|
|
19
|
+
```sql
|
|
20
|
+
create table public.task (
|
|
21
|
+
id uuid primary key default gen_random_uuid(),
|
|
22
|
+
title text not null,
|
|
23
|
+
created_at timestamptz not null default now(),
|
|
24
|
+
updated_at timestamptz null
|
|
25
|
+
);
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
- 2-space indentation
|
|
29
|
+
- Leading binary operators (`and`, `or`)
|
|
30
|
+
- Trailing commas
|
|
31
|
+
- Single quotes for string literals
|
|
32
|
+
- Shorthand casting (`::type`)
|
|
33
|
+
- `!=` for not-equal (`<>` is not used)
|
|
34
|
+
- Line length capped at 100
|
|
35
|
+
- One statement per semicolon
|
|
36
|
+
|
|
37
|
+
## Linting
|
|
38
|
+
|
|
39
|
+
SQLFluff is the linter. Configuration lives in `.sqlfluff` at the project root. A blueprint ships with `@regardio/dev/sqlfluff/setup.cfg` — projects copy it and adjust (SQLFluff does not support config inheritance).
|
|
40
|
+
|
|
41
|
+
Key settings:
|
|
42
|
+
|
|
43
|
+
```ini
|
|
44
|
+
[sqlfluff]
|
|
45
|
+
dialect = postgres
|
|
46
|
+
max_line_length = 100
|
|
47
|
+
|
|
48
|
+
[sqlfluff:rules:capitalisation.keywords]
|
|
49
|
+
capitalisation_policy = lower
|
|
50
|
+
|
|
51
|
+
[sqlfluff:rules:capitalisation.identifiers]
|
|
52
|
+
extended_capitalisation_policy = lower
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
sqlfluff lint schemas/
|
|
57
|
+
sqlfluff fix schemas/
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## File organisation
|
|
61
|
+
|
|
62
|
+
Schema files live in `schemas/` and are numbered to control load order. Each file owns one domain or object group.
|
|
63
|
+
|
|
64
|
+
### Naming pattern
|
|
65
|
+
|
|
66
|
+
```text
|
|
67
|
+
{nn}_{category}_{name}.sql
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Examples: `00_schema_setup.sql`, `15_function_util.sql`, `30_core_task.sql`.
|
|
71
|
+
|
|
72
|
+
### Number ranges
|
|
73
|
+
|
|
74
|
+
- `00–09` — schema setup, enums
|
|
75
|
+
- `10–19` — functions (auth, jsonb, model, storage)
|
|
76
|
+
- `20–29` — reference tables (locale, timezone, country)
|
|
77
|
+
- `30–39` — core tables (member, task, tag)
|
|
78
|
+
- `40+` — domain tables
|
|
79
|
+
|
|
80
|
+
A file with a lower number does not depend on a file with a higher number.
|
|
81
|
+
|
|
82
|
+
### File header
|
|
83
|
+
|
|
84
|
+
Every file opens with a banner naming its number, title, purpose, and sections:
|
|
85
|
+
|
|
86
|
+
```sql
|
|
87
|
+
--------------------------------------------------------------------------------
|
|
88
|
+
-- {nn}. {Title}
|
|
89
|
+
--
|
|
90
|
+
-- {One-line purpose description.}
|
|
91
|
+
--
|
|
92
|
+
-- Provides:
|
|
93
|
+
-- 1. {First section}
|
|
94
|
+
-- 2. {Second section}
|
|
95
|
+
--------------------------------------------------------------------------------
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Section dividers
|
|
99
|
+
|
|
100
|
+
Within a file, sections separate by labelled dividers in a fixed order:
|
|
101
|
+
|
|
102
|
+
```sql
|
|
103
|
+
--[ 1. Table ]------------------------------------------------------------------
|
|
104
|
+
|
|
105
|
+
--[ 2. Indexes ]----------------------------------------------------------------
|
|
106
|
+
|
|
107
|
+
--[ 3. Functions ]--------------------------------------------------------------
|
|
108
|
+
|
|
109
|
+
--[ 4. Constraints ]------------------------------------------------------------
|
|
110
|
+
|
|
111
|
+
--[ 5. Triggers ]---------------------------------------------------------------
|
|
112
|
+
|
|
113
|
+
--[ 6. Permissions ]------------------------------------------------------------
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Schema structure
|
|
117
|
+
|
|
118
|
+
- `public` — user-facing tables, views, and API functions (exposed to PostgREST)
|
|
119
|
+
- `private` — server-internal tables and helpers (not exposed to PostgREST)
|
|
120
|
+
- `extensions` — third-party PostgreSQL extensions
|
|
121
|
+
- `auth` — Supabase auth schema; not modified
|
|
122
|
+
|
|
123
|
+
## Naming
|
|
124
|
+
|
|
125
|
+
Every identifier is `snake_case`.
|
|
126
|
+
|
|
127
|
+
### Tables
|
|
128
|
+
|
|
129
|
+
Singular: `member`, `task`, `project` — not `members`, `tasks`.
|
|
130
|
+
|
|
131
|
+
### Columns
|
|
132
|
+
|
|
133
|
+
- `id uuid` — primary key
|
|
134
|
+
- `{referenced_table}_id` — foreign key
|
|
135
|
+
- `{field}_intl jsonb` — internationalised content
|
|
136
|
+
- `created_at`, `updated_at`, `deleted_at`, `{event}_at` — timestamps
|
|
137
|
+
- `deleted_at timestamptz null` — soft-delete marker
|
|
138
|
+
|
|
139
|
+
Active-record queries use partial indexes filtered by `deleted_at is null`.
|
|
140
|
+
|
|
141
|
+
### Column grouping
|
|
142
|
+
|
|
143
|
+
Inline `--- SECTION` markers group related columns:
|
|
144
|
+
|
|
145
|
+
```sql
|
|
146
|
+
create table public.task (
|
|
147
|
+
id uuid primary key default gen_random_uuid(),
|
|
148
|
+
project_id uuid not null references public.project (id),
|
|
149
|
+
|
|
150
|
+
--- CONTENT
|
|
151
|
+
title text not null,
|
|
152
|
+
description text null,
|
|
153
|
+
|
|
154
|
+
--- STATUS
|
|
155
|
+
status public.task_status not null,
|
|
156
|
+
due_at timestamptz null,
|
|
157
|
+
deleted_at timestamptz null,
|
|
158
|
+
|
|
159
|
+
created_at timestamptz not null default now(),
|
|
160
|
+
updated_at timestamptz null
|
|
161
|
+
);
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Functions
|
|
165
|
+
|
|
166
|
+
Pattern: `{domain}_{verb}` or `{domain}_{verb}_{target}`.
|
|
167
|
+
|
|
168
|
+
- `util_generate_slug`, `util_generate_code`
|
|
169
|
+
- `jsonb_is_boolean`, `jsonb_deep_merge`
|
|
170
|
+
- `task_get_status`, `task_check_ownership`
|
|
171
|
+
- `access_check_permissions`, `user_get_role`
|
|
172
|
+
|
|
173
|
+
Parameters are prefixed `_` (`_input`, `_task_id`); local variables are prefixed `v_` (`v_result`, `v_count`).
|
|
174
|
+
|
|
175
|
+
Standard verbs: `get`, `list`, `create`, `update`, `delete`, `check`, `is`, `has`, `set`, `generate`.
|
|
176
|
+
|
|
177
|
+
### Objects bound to a table
|
|
178
|
+
|
|
179
|
+
- Check constraints — `chk_{table}_{field}_{purpose}`
|
|
180
|
+
- Unique constraints — `uq_{table}_{field}`
|
|
181
|
+
- Indexes — `idx_{table}_{field}`; unique as `idx_unique_{table}_{field}`
|
|
182
|
+
- Triggers — `trg_{table}_{purpose}`
|
|
183
|
+
- RLS policies — `pol_{table}_{operation}`
|
|
184
|
+
|
|
185
|
+
## Functions
|
|
186
|
+
|
|
187
|
+
Every function declares volatility, security context, language, and a pinned empty search path:
|
|
188
|
+
|
|
189
|
+
```sql
|
|
190
|
+
create or replace function public.util_generate_slug(
|
|
191
|
+
_input text
|
|
192
|
+
) returns text
|
|
193
|
+
language plpgsql
|
|
194
|
+
immutable
|
|
195
|
+
security invoker
|
|
196
|
+
set search_path = ''
|
|
197
|
+
as $func$
|
|
198
|
+
declare
|
|
199
|
+
v_result text;
|
|
200
|
+
begin
|
|
201
|
+
-- body
|
|
202
|
+
return v_result;
|
|
203
|
+
end;
|
|
204
|
+
$func$;
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
- `security invoker` is the default
|
|
208
|
+
- `security definer` is chosen only when the function needs to act beyond the caller's grants
|
|
209
|
+
- `set search_path = ''` always; schema-qualified names are used throughout
|
|
210
|
+
|
|
211
|
+
## Documentation
|
|
212
|
+
|
|
213
|
+
Tables, columns, and functions carry `comment on` entries using dollar-quoted `$doc$` strings, placed immediately after the definition. The comment describes what the object is and what callers can assume about it — not how it is implemented.
|
|
214
|
+
|
|
215
|
+
```sql
|
|
216
|
+
comment on table public.task is $doc$A unit of work within a project.$doc$;
|
|
217
|
+
|
|
218
|
+
comment on column public.task.title is $doc$Short description of the task.$doc$;
|
|
219
|
+
|
|
220
|
+
comment on function public.util_generate_slug is $doc$
|
|
221
|
+
Converts a text input into a URL-safe slug.
|
|
222
|
+
|
|
223
|
+
Parameters:
|
|
224
|
+
- _input text: Source text to slugify
|
|
225
|
+
|
|
226
|
+
Returns text: Lowercase hyphenated slug.
|
|
227
|
+
$doc$;
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
## Access control
|
|
231
|
+
|
|
232
|
+
RLS is on and forced for every table in `public`. Grants revoke everything first, then grant only what is needed. Write paths prefer `security definer` functions over direct table grants.
|
|
233
|
+
|
|
234
|
+
```sql
|
|
235
|
+
alter table public.task enable row level security;
|
|
236
|
+
alter table public.task force row level security;
|
|
237
|
+
|
|
238
|
+
revoke all on table public.task from anon, authenticated;
|
|
239
|
+
grant select on table public.task to authenticated;
|
|
240
|
+
|
|
241
|
+
create policy pol_task_select on public.task
|
|
242
|
+
for select using (owner_id = (select auth.uid()));
|
|
243
|
+
|
|
244
|
+
create policy pol_task_update on public.task
|
|
245
|
+
for update using (owner_id = (select auth.uid()))
|
|
246
|
+
with check (owner_id = (select auth.uid()));
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
## Related
|
|
250
|
+
|
|
251
|
+
- [Naming](./naming.md) — Names across languages
|
|
252
|
+
- [API](./api.md) — How the schema is consumed
|
|
253
|
+
- [Principles](./principles.md) — Shared principles
|
|
254
|
+
- [Writing](./writing.md) — Voice, tone, language
|
|
255
|
+
|
|
256
|
+
---
|
|
257
|
+
|
|
258
|
+
**License**: [CC-BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/) © Regardio
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
---
|
|
2
|
+
|
|
3
|
+
title: "Testing"
|
|
4
|
+
description: "How Regardio tests its code — layered, behaviour-first, and written as specification."
|
|
5
|
+
publishedAt: 2026-04-17
|
|
6
|
+
order: 9
|
|
7
|
+
language: "en"
|
|
8
|
+
status: "published"
|
|
9
|
+
kind: "reference"
|
|
10
|
+
area: "dev"
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
Tests are the bridge between the prose that describes behaviour and the code that produces it. A test quotes what the docs say the system does and checks that the code holds to it. When the bridge stays honest, refactors are safe because tests describe behaviour rather than shape; when it slips, tests break on every refactor and pass through every regression that preserves the shape they pinned.
|
|
14
|
+
|
|
15
|
+
## Core principles
|
|
16
|
+
|
|
17
|
+
- Test what the caller observes, not how the code achieves it
|
|
18
|
+
- Fast feedback on the lowest layer that can verify a behaviour
|
|
19
|
+
- Deterministic runs; no reliance on time-of-day, order, or shared state
|
|
20
|
+
- Readable as specifications in their own right
|
|
21
|
+
- Cover the success path, the edges, and the errors
|
|
22
|
+
|
|
23
|
+
## Layers
|
|
24
|
+
|
|
25
|
+
| Level | Share | Purpose | Tool |
|
|
26
|
+
|-------|-------|---------|------|
|
|
27
|
+
| **Unit** | ~70% | Functions, components, small pieces of business logic | Vitest |
|
|
28
|
+
| **Integration** | ~20% | Modules together, API contracts, database behaviour | Vitest |
|
|
29
|
+
| **End-to-end** | ~10% | Critical user flows across the stack | Playwright |
|
|
30
|
+
|
|
31
|
+
The distribution follows cost and signal. Unit tests give the fastest feedback and the clearest error; integration tests catch contract mistakes between modules; end-to-end tests protect the flows users actually feel, and are too expensive to carry for everything else.
|
|
32
|
+
|
|
33
|
+
## Writing tests
|
|
34
|
+
|
|
35
|
+
### Arrange, Act, Assert
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
it('calculates total with discount', () => {
|
|
39
|
+
// Arrange
|
|
40
|
+
const items = [{ price: 100 }, { price: 50 }];
|
|
41
|
+
const discount = 0.1;
|
|
42
|
+
// Act
|
|
43
|
+
const total = calculateTotal(items, discount);
|
|
44
|
+
// Assert
|
|
45
|
+
expect(total).toBe(135);
|
|
46
|
+
});
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Names describe behaviour
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
// Good
|
|
53
|
+
it('returns an empty array when no items match the filter', () => {});
|
|
54
|
+
it('throws ValidationError when the email is invalid', () => {});
|
|
55
|
+
|
|
56
|
+
// Not good
|
|
57
|
+
it('test1', () => {});
|
|
58
|
+
it('sets isError to true', () => {});
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Independence
|
|
62
|
+
|
|
63
|
+
- Each test sets up its own state
|
|
64
|
+
- No dependency on the order other tests ran in
|
|
65
|
+
- Cleanup leaves nothing behind
|
|
66
|
+
|
|
67
|
+
## Frontend testing
|
|
68
|
+
|
|
69
|
+
Components are tested through the interface a user reaches — roles, labels, visible text, keyboard:
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
it('displays an error when submission fails', async () => {
|
|
73
|
+
render(<ContactForm />);
|
|
74
|
+
await user.click(screen.getByRole('button', { name: /submit/i }));
|
|
75
|
+
expect(screen.getByRole('alert')).toHaveTextContent(/failed/i);
|
|
76
|
+
});
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Implementation-detail assertions (`isError` flags, render counts, private method calls) do not appear.
|
|
80
|
+
|
|
81
|
+
### Accessibility
|
|
82
|
+
|
|
83
|
+
- Keyboard navigation verified
|
|
84
|
+
- Screen-reader access through roles and labels
|
|
85
|
+
- Colour contrast checked where it matters
|
|
86
|
+
- Focus management correct on interactive flows
|
|
87
|
+
|
|
88
|
+
## Database testing
|
|
89
|
+
|
|
90
|
+
Schema tests run against a real Postgres so policies and triggers behave as they do in production:
|
|
91
|
+
|
|
92
|
+
- Business rules held
|
|
93
|
+
- RLS boundaries enforced
|
|
94
|
+
- Validation errors return the expected shape
|
|
95
|
+
- Queries use the indexes they are meant to
|
|
96
|
+
- Error paths are reached and handled
|
|
97
|
+
|
|
98
|
+
## Coverage
|
|
99
|
+
|
|
100
|
+
Library packages hold a floor around 80% for statements, branches, functions, and lines. The floor is a minimum, not a target — the goal is meaningful tests, not arithmetic.
|
|
101
|
+
|
|
102
|
+
Enforced at:
|
|
103
|
+
|
|
104
|
+
- Local development — `pnpm test`
|
|
105
|
+
- Release preparation — `ship-staging`
|
|
106
|
+
- CI — GitHub Actions
|
|
107
|
+
|
|
108
|
+
## Quality gates
|
|
109
|
+
|
|
110
|
+
Before a package publishes:
|
|
111
|
+
|
|
112
|
+
1. Build succeeds
|
|
113
|
+
2. Type check passes
|
|
114
|
+
3. Coverage meets the floor
|
|
115
|
+
4. Tests pass — no skipped or failing
|
|
116
|
+
|
|
117
|
+
## Continuous integration
|
|
118
|
+
|
|
119
|
+
- Pre-commit hooks run linting (Biome)
|
|
120
|
+
- CI runs build, typecheck, and the test suite with coverage
|
|
121
|
+
- Release workflow blocks publishing on any failure
|
|
122
|
+
|
|
123
|
+
## Test maintenance
|
|
124
|
+
|
|
125
|
+
- Tests that no longer describe current behaviour are updated or deleted
|
|
126
|
+
- Tests are refactored alongside the production code they accompany
|
|
127
|
+
- A suite with failing or skipped tests is a broken suite
|
|
128
|
+
|
|
129
|
+
## Related
|
|
130
|
+
|
|
131
|
+
- [Principles](./principles.md) — Shared principles, including specification-led workflow
|
|
132
|
+
- [React](./react.md) — How components are shaped to be testable
|
|
133
|
+
- [API](./api.md) — Testing API endpoints and contracts
|
|
134
|
+
- [Vitest](../tools/vitest.md) — Unit and integration testing
|
|
135
|
+
- [Playwright](../tools/playwright.md) — End-to-end testing
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
**License**: [CC-BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/) © Regardio
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
---
|
|
2
|
+
|
|
3
|
+
title: "Writing"
|
|
4
|
+
description: "Voice, tone, and language Regardio content carries, in English and German."
|
|
5
|
+
publishedAt: 2026-04-17
|
|
6
|
+
order: 2
|
|
7
|
+
language: "en"
|
|
8
|
+
status: "published"
|
|
9
|
+
kind: "concept"
|
|
10
|
+
area: "dev"
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
The voice in which Regardio writes about itself and its tools.
|
|
14
|
+
|
|
15
|
+
## What you are doing
|
|
16
|
+
|
|
17
|
+
You write *from within* the System, not *about* it. Your aim is to trigger recognition. The reader you are writing for should be able to think *Yes, that's how it is.*
|
|
18
|
+
|
|
19
|
+
Two trains of thought carry everything the System does — and everything you write about it.
|
|
20
|
+
|
|
21
|
+
**Any one object can be observed from two sides.** Front and back, inside and outside, past and future, still and moving, question and answer, start and finish. A thing that looks complete from one angle shows something new from the other. Writing that only shows one side flattens what it describes. Writing that acknowledges both gives the reader room to stand where they already stand.
|
|
22
|
+
|
|
23
|
+
**A whole becomes graspable when it is cut into a few distinct parts.** Six is the number to return to: enough variety to cover what matters, few enough to hold in the head at once, clear enough to name and locate each piece. A pie cut into six slices is something anyone can picture. When a subject resists clarity, the move is not more words — it is better cuts.
|
|
24
|
+
|
|
25
|
+
These two habits are the grammar underneath the System. Carry them quietly. You rarely name them. They are just the shape of the thinking.
|
|
26
|
+
|
|
27
|
+
## How to meet the reader
|
|
28
|
+
|
|
29
|
+
Every reader comes with their own life and their own pursuit. Assume they notice things for themselves. Trust them to do their own connecting. Address them directly, without talking up or down.
|
|
30
|
+
|
|
31
|
+
The ground under the writing is careful observation of how people actually feel, think, and act — not advice about how they should. When an idea becomes personally recognizable while staying broadly true, it has landed. When it only flatters or only instructs, it hasn't.
|
|
32
|
+
|
|
33
|
+
## Stance
|
|
34
|
+
|
|
35
|
+
Six movements carry every piece.
|
|
36
|
+
|
|
37
|
+
1. **Derive, don't declare.** One thought leads to the next. "The System recognizes…" speaks from above. Better: the observation that leads to the structure. Readers follow a line of thought, not an instruction.
|
|
38
|
+
2. **Observe, don't instruct.** Write like someone who has listened carefully and is sharing an observation, not like someone explaining a method.
|
|
39
|
+
3. **Structure offers freedom, not rules.** The cuts exist to widen a view that has become too narrow, not to discipline one that is already broad.
|
|
40
|
+
4. **Suggest possibilities to choose from.** Offer angles, not answers. Let the reader decide what fits. Suggest questions that people have, not riddles to solve.
|
|
41
|
+
5. **Turned toward what could be, without promises.** Warm, attentive, spacious. Curious about people rather than diagnostic. No salvation talk, no coaching register.
|
|
42
|
+
6. **Good humor makes the deepest thought approachable.** Lightness when it fits. Not forced, not absent. When the moment is right, a small wink can carry weight without claiming it.
|
|
43
|
+
|
|
44
|
+
## Before and after
|
|
45
|
+
|
|
46
|
+
**Instead of:** *"Apply this framework to align your team."*
|
|
47
|
+
**Try:** *"What does the decision we made last week have to do with what's slowing us down now?"*
|
|
48
|
+
|
|
49
|
+
**Instead of:** *"The System helps you gain clarity."*
|
|
50
|
+
**Try:** *"A few angles worth looking at, whatever the pursuit."*
|
|
51
|
+
|
|
52
|
+
**Instead of:** *"Pursuits flourish with a clear core."*
|
|
53
|
+
**Try:** *"How will we know when we've arrived?"*
|
|
54
|
+
|
|
55
|
+
The System's questions are not headers. They are real questions, worth sitting with.
|
|
56
|
+
|
|
57
|
+
## Language
|
|
58
|
+
|
|
59
|
+
Language that leaves room lets readers think. Language that pushes does the thinking for them. Given the choice, choose room.
|
|
60
|
+
|
|
61
|
+
**Favor:** notice, explore, find, might, could, pattern, rhythm, carry, hold — words that leave room.
|
|
62
|
+
|
|
63
|
+
**Avoid:** must, potential, resources, values, purpose, sustainability, growth, leverage, empower, ownership, good, bad. These either push or have been worn down to noise.
|
|
64
|
+
|
|
65
|
+
**No method jargon.** Not from business, not from coaching, not from therapy, not from spirituality. If a term has a clear everyday word behind it, use the everyday word.
|
|
66
|
+
|
|
67
|
+
**People are not categories.** Describe what people do and bring about, not what they are. This is also how gendered forms are handled — name actions, not groups.
|
|
68
|
+
|
|
69
|
+
**The System is humane.** Equal, free cooperation is built in. Avoid connotations of hierarchy, ownership, dominance, control, or force. Reflect that without announcing it.
|
|
70
|
+
|
|
71
|
+
**Complexity earns its place or goes.** Make hard ideas reachable without flattening them. If a sentence has to be read twice, shorten it. If an idea has been reduced past recognition, let it breathe again.
|
|
72
|
+
|
|
73
|
+
## System terms
|
|
74
|
+
|
|
75
|
+
System terms carry precisely defined concepts. Use them as they are; don't swap in synonyms for variety. When tempted to reach for a buzzword, reach for a System term instead — if it fits. If no System term fits, the buzzword probably isn't earning its place either.
|
|
76
|
+
|
|
77
|
+
In every language the System is written in, the terms are chosen to capture the spirit of each concept in that language — not to translate literally from another. Don't import words from other languages into the prose. Let each language stand on its own.
|
|
78
|
+
|
|
79
|
+
## Roots, kept in the background
|
|
80
|
+
|
|
81
|
+
The System draws from many traditions of thought. Reference intents and ideas, not names or schools. The sources show themselves in the structure, not in citation. This is working craft carried by collective intelligence, not an elaborate treatise.
|
|
82
|
+
|
|
83
|
+
## Format and craft
|
|
84
|
+
|
|
85
|
+
**Headers** for orientation. **Prose** for connected thought. **Bold** for System terms at first introduction. *Italics* for genuine emphasis. No emojis. Lists only when the content is genuinely a list — bullets never replace a thought.
|
|
86
|
+
|
|
87
|
+
## Language-specific caveats
|
|
88
|
+
|
|
89
|
+
### German
|
|
90
|
+
|
|
91
|
+
- Address the reader with *du* unless the context clearly calls for *Sie* (formal contracts, legal notices). Keep it direct, without affectation.
|
|
92
|
+
- No gendering artifacts: no *:innen*, no asterisks, no *(m/w/d)*. Prefer action-based descriptions over group labels: *wer etwas vorhat*, *ein Mensch, der …*, *die Person, die …*, *Mitwirkende*, *Beteiligte*.
|
|
93
|
+
- Quotation marks: German low-high („…") in body text.
|
|
94
|
+
|
|
95
|
+
### English
|
|
96
|
+
|
|
97
|
+
- American English: *organize*, *color*, *toward*, *behavior*, *center*. Periods and commas inside quotation marks.
|
|
98
|
+
- No gendered forms. Name actions: *the person pursuing this*, *contributors*, *those involved*. Singular *they* is fine where a pronoun is unavoidable.
|
|
99
|
+
- Quotation marks: straight double quotes (") in Markdown source; typographic quotes ("…") in rendered prose.
|
|
100
|
+
|
|
101
|
+
## Check before publishing
|
|
102
|
+
|
|
103
|
+
- Does it sound like a conversation the reader would want to be in?
|
|
104
|
+
- Does the text derive rather than declare?
|
|
105
|
+
- Are abstract thoughts grounded in concrete examples?
|
|
106
|
+
- Are System terms used consistently, in their precise meaning?
|
|
107
|
+
- Is it free of coaching register, pigeonholing, and tired buzzwords?
|
|
108
|
+
- Could the honest response be *"Yes, that's how it is"*?
|
|
109
|
+
|
|
110
|
+
*This guide is itself a living text. When in doubt: would you enjoy reading this?*
|
|
111
|
+
|
|
112
|
+
## Related
|
|
113
|
+
|
|
114
|
+
- [Documentation Standard](./documentation.md) — How Regardio shapes its documents
|
|
115
|
+
- [Principles](./principles.md) — Shared development principles
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
**License**: [CC-BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/) © Regardio
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
---
|
|
2
|
+
|
|
3
|
+
title: Biome
|
|
4
|
+
type: guide
|
|
5
|
+
status: published
|
|
6
|
+
summary: Fast, unified linting and formatting for JavaScript and TypeScript
|
|
7
|
+
related: [typescript, markdownlint]
|
|
8
|
+
locale: en-US
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Biome
|
|
12
|
+
|
|
13
|
+
Fast, unified linting and formatting for JavaScript and TypeScript. Single tool replacing ESLint + Prettier. Configuration is centralized through `@regardio/dev`; use wrapper commands so all packages behave consistently.
|
|
14
|
+
|
|
15
|
+
## Configuration
|
|
16
|
+
|
|
17
|
+
Create `biome.jsonc` in your package root:
|
|
18
|
+
|
|
19
|
+
```jsonc
|
|
20
|
+
{
|
|
21
|
+
"$schema": "https://biomejs.dev/schemas/latest/schema.json",
|
|
22
|
+
"extends": ["@regardio/dev/biome"]
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Scripts
|
|
27
|
+
|
|
28
|
+
```json
|
|
29
|
+
{
|
|
30
|
+
"scripts": {
|
|
31
|
+
"fix": "exec-s fix:pkg fix:md fix:biome",
|
|
32
|
+
"fix:biome": "lint-biome check --write --unsafe .",
|
|
33
|
+
"lint": "exec-s lint:md lint:biome",
|
|
34
|
+
"lint:biome": "lint-biome check ."
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## CLI Wrapper
|
|
40
|
+
|
|
41
|
+
Use `lint-biome` instead of `biome` directly. This wrapper ensures consistent behavior across the monorepo.
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
lint-biome check . # Check for issues
|
|
45
|
+
lint-biome check --write . # Fix auto-fixable issues
|
|
46
|
+
lint-biome format . # Format only
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Package.json Handling
|
|
50
|
+
|
|
51
|
+
The Biome preset excludes `package.json` files from processing. Instead, use `lint-package` which:
|
|
52
|
+
|
|
53
|
+
1. Sorts package.json using the well-known field order
|
|
54
|
+
2. Fixes exports condition order (`types` before `default` for TypeScript)
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
lint-package # Sort package.json in current directory
|
|
58
|
+
lint-package path/to/pkg # Sort specific package.json
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
This is automatically run as part of `pnpm fix`.
|
|
62
|
+
|
|
63
|
+
## Rule Categories
|
|
64
|
+
|
|
65
|
+
The preset enables rules across categories:
|
|
66
|
+
|
|
67
|
+
- **Correctness** - Catch bugs and incorrect code
|
|
68
|
+
- **Style** - Consistent code formatting
|
|
69
|
+
- **Complexity** - Prevent overly complex code
|
|
70
|
+
- **Performance** - Identify performance issues
|
|
71
|
+
- **Security** - Flag potential security vulnerabilities
|
|
72
|
+
|
|
73
|
+
## Ignoring Rules
|
|
74
|
+
|
|
75
|
+
When a rule genuinely doesn't apply, use inline comments:
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
// biome-ignore lint/complexity/noForEach: forEach is clearer here for side effects
|
|
79
|
+
items.forEach(item => process(item));
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Always include a reason explaining why the exception is necessary.
|
|
83
|
+
|
|
84
|
+
## Editor Setup
|
|
85
|
+
|
|
86
|
+
- **VS Code**: [Biome extension](https://marketplace.visualstudio.com/items?itemName=biomejs.biome)
|
|
87
|
+
- **JetBrains**: Built-in support via settings
|
|
88
|
+
|
|
89
|
+
Resources: [Biome Documentation](https://biomejs.dev/) · [Rules Reference](https://biomejs.dev/linter/rules/)
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
---
|
|
2
|
+
|
|
3
|
+
title: Commitlint
|
|
4
|
+
type: guide
|
|
5
|
+
status: published
|
|
6
|
+
summary: Enforce conventional commit messages
|
|
7
|
+
related: [husky]
|
|
8
|
+
locale: en-US
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Commitlint
|
|
12
|
+
|
|
13
|
+
Validates commit messages against the conventional format via Git hooks. Rules are centralized in `@regardio/dev`.
|
|
14
|
+
|
|
15
|
+
## Configuration
|
|
16
|
+
|
|
17
|
+
At the workspace root, create `.commitlintrc.json`:
|
|
18
|
+
|
|
19
|
+
```json
|
|
20
|
+
{
|
|
21
|
+
"extends": ["@regardio/dev/commitlint"]
|
|
22
|
+
}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Or use a JavaScript config:
|
|
26
|
+
|
|
27
|
+
```javascript
|
|
28
|
+
// commitlint.config.cjs
|
|
29
|
+
module.exports = require('@regardio/dev/commitlint');
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Commit Format
|
|
33
|
+
|
|
34
|
+
```text
|
|
35
|
+
<type>(<scope>): <subject>
|
|
36
|
+
|
|
37
|
+
[optional body]
|
|
38
|
+
|
|
39
|
+
[optional footer]
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Types
|
|
43
|
+
|
|
44
|
+
| Type | Description |
|
|
45
|
+
|------|-------------|
|
|
46
|
+
| `feat` | New feature |
|
|
47
|
+
| `fix` | Bug fix |
|
|
48
|
+
| `docs` | Documentation only |
|
|
49
|
+
| `style` | Formatting, no code change |
|
|
50
|
+
| `refactor` | Code change that neither fixes nor adds |
|
|
51
|
+
| `perf` | Performance improvement |
|
|
52
|
+
| `test` | Adding or updating tests |
|
|
53
|
+
| `build` | Build system or dependencies |
|
|
54
|
+
| `ci` | CI configuration |
|
|
55
|
+
| `chore` | Other changes (tooling, etc.) |
|
|
56
|
+
| `revert` | Revert a previous commit |
|
|
57
|
+
|
|
58
|
+
### Examples
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
feat: add user authentication
|
|
62
|
+
fix: resolve login redirect loop
|
|
63
|
+
docs: update API documentation
|
|
64
|
+
refactor: simplify payment processing
|
|
65
|
+
test: add unit tests for date utilities
|
|
66
|
+
chore: update dependencies
|
|
67
|
+
feat(auth): implement OAuth2 flow
|
|
68
|
+
fix(api): handle null response gracefully
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Rules
|
|
72
|
+
|
|
73
|
+
The preset enforces:
|
|
74
|
+
|
|
75
|
+
- **Header max length**: 100 characters
|
|
76
|
+
- **Body leading blank**: Blank line before body
|
|
77
|
+
- **Footer leading blank**: Blank line before footer
|
|
78
|
+
- **Type enum**: Must be one of the allowed types
|
|
79
|
+
|
|
80
|
+
## Git Hooks
|
|
81
|
+
|
|
82
|
+
Commitlint runs automatically via Husky on commit. See [Husky](./husky.md) for setup.
|
|
83
|
+
|
|
84
|
+
Related documents:
|
|
85
|
+
|
|
86
|
+
- [Commit Conventions](../standards/commits.md) — Conventional commits and changelog generation
|
|
87
|
+
- [Husky](./husky.md) — Git hooks for quality gates
|
|
88
|
+
|
|
89
|
+
### Resources
|
|
90
|
+
|
|
91
|
+
- [Conventional Commits](https://www.conventionalcommits.org/)
|
|
92
|
+
- [Commitlint Documentation](https://commitlint.js.org/)
|