Skip to content

Commit d8c2c02

Browse files
committed
Add best practices section to AGENTS.md for env config and testing
- Environment Configuration: documents the unified env config system (@pgpmjs/env and @constructive-io/graphql-env) with which-to-import guide - Testing: documents the framework hierarchy (pgsql-test → graphile-test → graphql-test → server-test), required beforeEach/afterEach hooks, and anti-patterns to avoid (manual pg.Pool, pg-cache in tests, etc.)
1 parent 1fbcc65 commit d8c2c02

1 file changed

Lines changed: 76 additions & 1 deletion

File tree

AGENTS.md

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,83 @@ This guide helps AI agents quickly navigate the Constructive monorepo. Construct
6262
- Generate types/SDK: `cnc codegen`
6363
- Export schema SDL: `cnc get-graphql-schema`
6464

65+
## Best Practices
66+
67+
### Environment Configuration
68+
69+
Always use the unified environment configuration system — never read `process.env` directly for config values.
70+
71+
- **PGPM packages** (`pgpm/*`): `import { getEnvOptions } from '@pgpmjs/env'`
72+
- **GraphQL/Constructive packages** (`graphql/*`, `packages/cli`): `import { getEnvOptions } from '@constructive-io/graphql-env'`
73+
- **PostgreSQL tools** (`postgres/*`): `import { getPgEnvOptions } from 'pg-env'` or `@pgpmjs/env`
74+
75+
The system provides typed defaults, config file discovery (`pgpm.json`), env var parsing, and a clean merge hierarchy: **defaults → config file → env vars → runtime overrides**.
76+
77+
```typescript
78+
// GOOD
79+
import { getEnvOptions } from '@pgpmjs/env';
80+
const opts = getEnvOptions({ pg: { database: 'mydb' } });
81+
82+
// BAD — scattered, untyped, no defaults
83+
const host = process.env.PGHOST || 'localhost';
84+
const port = parseInt(process.env.PGPORT || '5432');
85+
```
86+
87+
### Testing
88+
89+
Constructive provides a layered testing framework stack. **Always use the appropriate framework** — never manually create `pg.Pool` or `pg.Client` instances in tests.
90+
91+
#### Which Framework to Use
92+
93+
| Scenario | Framework | Import |
94+
|----------|-----------|--------|
95+
| Raw SQL, RLS policies, database functions | `pgsql-test` | `import { getConnections } from 'pgsql-test'` |
96+
| PostGraphile schema, basic GraphQL queries | `graphile-test` | `import { getConnections } from 'graphile-test'` |
97+
| GraphQL with Constructive plugins (search, pgvector, etc.) | `@constructive-io/graphql-test` | `import { getConnections } from '@constructive-io/graphql-test'` |
98+
| HTTP endpoints, auth headers, middleware | `@constructive-io/graphql-server-test` | `import { getConnections } from '@constructive-io/graphql-server-test'` |
99+
100+
Each layer builds on `pgsql-test` underneath — they all create isolated test databases with proper teardown.
101+
102+
#### Required Test Hooks
103+
104+
Always include `beforeEach`/`afterEach` hooks to ensure test isolation via savepoints:
105+
106+
```typescript
107+
import { getConnections, PgTestClient } from 'pgsql-test';
108+
109+
let pg: PgTestClient;
110+
let db: PgTestClient;
111+
let teardown: () => Promise<void>;
112+
113+
beforeAll(async () => {
114+
({ pg, db, teardown } = await getConnections());
115+
});
116+
117+
afterAll(async () => {
118+
await teardown();
119+
});
120+
121+
beforeEach(async () => {
122+
await pg.beforeEach();
123+
await db.beforeEach();
124+
});
125+
126+
afterEach(async () => {
127+
await db.afterEach();
128+
await pg.afterEach();
129+
});
130+
```
131+
132+
#### Anti-Patterns to Avoid
133+
134+
- **Never** create `new pg.Pool()` or `new pg.Client()` in tests — use `getConnections()` from the appropriate framework
135+
- **Never** use `getPgPool()` from `pg-cache` in tests — that's for production connection pooling
136+
- **Never** manually create/drop databases in tests — `pgsql-test` handles this automatically
137+
- **Never** skip `beforeEach`/`afterEach` hooks — tests will leak state to each other
138+
- **Never** construct connection strings manually — use the env configuration system
139+
65140
## Tips
66141

67142
1. Start with `pgpm/core/AGENTS.md` to understand the migration and plan model.
68-
2. Use `packages/cli/AGENTS.md` to understand Constructives command routing.
143+
2. Use `packages/cli/AGENTS.md` to understand Constructive's command routing.
69144
3. Use `postgres/pgsql-test/AGENTS.md` for patterns around isolated test DBs and seeding.

0 commit comments

Comments
 (0)