Skip to content

Commit 0fed474

Browse files
PaulJPhilpclaude
andcommitted
refactor: adopt toolkit DatabaseLayer across ep-cli, ep-admin, and MCP server
Replace manual createDatabase() + createXyzRepository() + addFinalizer() boilerplate with toolkit's EffectPatternRepositoryService, ApplicationPatternRepositoryService, and new SkillRepositoryService. - Add SkillRepositoryService + SkillRepositoryLive to toolkit - Update DatabaseLayer to include all 3 repository services - Migrate 5 ep-admin command files (search, lock, install, show, skills) - Migrate ep-cli pattern-repo-commands and install service - Delete unused ep-cli utils/database.ts helper - Fix helpers.test.ts to match REQUIRED_TABLES after jobs removal - Update DATABASE_ARCHITECTURE.md for v0.12.3 stats Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 7d357ac commit 0fed474

13 files changed

Lines changed: 281 additions & 464 deletions

File tree

docs/DATABASE_ARCHITECTURE.md

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -298,14 +298,21 @@ These files enumerate columns explicitly in raw SQL INSERT statements. They don'
298298

299299
## Current State
300300

301-
As of v0.12.1 (2026-02-11):
301+
As of v0.12.3 (2026-02-11):
302302

303303
| Table | Row count | Notes |
304304
|---|---|---|
305-
| `effect_patterns` | 309 | All linked to `application_patterns`, all have `rule` |
305+
| `effect_patterns` | 304 | All linked to `application_patterns`, all have `rule` and `summary` |
306306
| `application_patterns` | 16 | 16 top-level categories |
307-
| `pattern_relations` | 455 | Populated from MDX `related:` frontmatter |
307+
| `pattern_relations` | 445 | Populated from MDX `related:` frontmatter |
308308
| `skills` | 16 | One per application pattern category |
309309
| `skill_patterns` | 309 | All patterns assigned to a skill |
310310

311311
All 5 tables are actively populated. The `jobs` and `pattern_jobs` tables were removed in migration 0004.
312+
313+
### v0.12.3 changes
314+
315+
- Deleted 5 duplicate patterns (`data-chunk`, `data-duration`, `observability-custom-metrics`, `observability-tracing-spans`, `leverage-structured-logging`) — row count dropped from 309 to 304
316+
- All 77 schema patterns now have `summary` populated from frontmatter (previously extracted from body at sync time)
317+
- 4 core-concepts patterns renamed to disambiguate duplicate titles
318+
- `pattern_relations` rebuilt with updated `related:` slugs (445 rows, down from 455 due to removed patterns)

packages/ep-admin/src/install-commands.ts

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
/**
22
* Install and rules commands for AI tool integration
3-
*
3+
*
44
* Commands for installing Effect patterns into AI tools and generating skills
55
*/
66

77
import {
8-
createApplicationPatternRepository,
9-
createDatabase,
10-
createEffectPatternRepository,
8+
ApplicationPatternRepositoryService,
9+
DatabaseLayer,
10+
EffectPatternRepositoryLive,
11+
EffectPatternRepositoryService,
1112
type SkillLevel,
1213
} from "@effect-patterns/toolkit";
1314
import { Command, Options } from "@effect/cli";
@@ -162,18 +163,7 @@ export const installAddCommand = Command.make("add", {
162163
return yield* Effect.fail(new Error(`Unsupported tool: ${tool}`));
163164
}
164165

165-
const conn = yield* Effect.try({
166-
try: () => createDatabase(),
167-
catch: (error) =>
168-
new Error(
169-
`Failed to create database connection: ${error instanceof Error ? error.message : String(error)}`
170-
),
171-
});
172-
yield* Effect.addFinalizer(() =>
173-
Effect.promise(() => conn.close())
174-
);
175-
176-
const repo = createEffectPatternRepository(conn.db);
166+
const repo = yield* EffectPatternRepositoryService;
177167
const searchParams: {
178168
query?: string;
179169
skillLevel?: SkillLevel;
@@ -287,6 +277,8 @@ Your AI tool configuration has been updated with Effect patterns!`,
287277
{ type: "success" }
288278
);
289279
})
280+
).pipe(
281+
Effect.provide(EffectPatternRepositoryLive),
290282
) as any
291283
)
292284
);
@@ -415,10 +407,8 @@ export const installSkillsCommand = Command.make("skills", {
415407
colorize("\n🎓 Generating Skills from Effect Patterns\n", "BRIGHT")
416408
);
417409

418-
const conn = createDatabase();
419-
yield* Effect.addFinalizer(() => Effect.promise(() => conn.close()));
420-
const apRepo = createApplicationPatternRepository(conn.db);
421-
const epRepo = createEffectPatternRepository(conn.db);
410+
const epRepo = yield* EffectPatternRepositoryService;
411+
const apRepo = yield* ApplicationPatternRepositoryService;
422412

423413
yield* Console.log(
424414
colorize("📖 Loading patterns from database...", "CYAN")
@@ -681,7 +671,9 @@ export const installSkillsCommand = Command.make("skills", {
681671
"✨ Skills Generation Complete!",
682672
{ type: "success" }
683673
);
684-
})) as any;
674+
})).pipe(
675+
Effect.provide(DatabaseLayer),
676+
) as any;
685677
})
686678
);
687679

packages/ep-admin/src/lock-commands.ts

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
*/
66

77
import {
8-
createApplicationPatternRepository,
9-
createDatabase,
10-
createEffectPatternRepository,
8+
ApplicationPatternRepositoryService,
9+
DatabaseLayer,
10+
EffectPatternRepositoryService,
1111
} from "@effect-patterns/toolkit";
1212
import { Args, Command, Options } from "@effect/cli";
1313
import { Effect } from "effect";
@@ -89,16 +89,20 @@ const performEntityOperation = (
8989
});
9090

9191
/**
92-
* Get repository for entity type
92+
* Get repository for entity type from pre-constructed services
9393
*/
94-
const getRepository = (db: any, entityType: string): Repository | null => {
94+
const getRepository = (
95+
epRepo: Repository,
96+
apRepo: Repository,
97+
entityType: string
98+
): Repository | null => {
9599
switch (entityType) {
96100
case "pattern":
97101
case "effect-pattern":
98-
return createEffectPatternRepository(db);
102+
return epRepo;
99103
case "application-pattern":
100104
case "ap":
101-
return createApplicationPatternRepository(db);
105+
return apRepo;
102106
default:
103107
return null;
104108
}
@@ -130,17 +134,11 @@ export const handleEntityOperation = (
130134
) =>
131135
Effect.scoped(
132136
Effect.gen(function* () {
133-
const db = yield* Effect.try({
134-
try: () => createDatabase(),
135-
catch: (error) =>
136-
new Error(
137-
`Failed to create database connection: ${error instanceof Error ? error.message : String(error)}`
138-
),
139-
});
140-
yield* Effect.addFinalizer(() => Effect.promise(() => db.close()));
137+
const epRepo = yield* EffectPatternRepositoryService;
138+
const apRepo = yield* ApplicationPatternRepositoryService;
141139

142140
const entityType = options.type.toLowerCase();
143-
const repo = getRepository(db.db, entityType);
141+
const repo = getRepository(epRepo, apRepo, entityType);
144142

145143
if (!repo) {
146144
yield* Display.showError(
@@ -163,6 +161,7 @@ export const handleEntityOperation = (
163161
yield* Display.showSuccess(`${entityName} has been ${actionText}`);
164162
})
165163
).pipe(
164+
Effect.provide(DatabaseLayer),
166165
Effect.catchAll((error) =>
167166
Effect.gen(function* () {
168167
yield* Display.showError(

packages/ep-admin/src/search-commands.ts

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
*/
44

55
import {
6-
createDatabase,
7-
createEffectPatternRepository,
6+
EffectPatternRepositoryLive,
7+
EffectPatternRepositoryService,
88
} from "@effect-patterns/toolkit";
99
import { Args, Command } from "@effect/cli";
1010
import { Console, Effect } from "effect";
@@ -28,18 +28,7 @@ export const searchCommand = Command.make("search", {
2828
`\n🔍 Searching for patterns matching "${args.query}"...\n`
2929
);
3030

31-
const db = yield* Effect.try({
32-
try: () => createDatabase(),
33-
catch: (error) =>
34-
new Error(
35-
`Failed to create database connection: ${error instanceof Error ? error.message : String(error)}`
36-
),
37-
});
38-
yield* Effect.addFinalizer(() =>
39-
Effect.promise(() => db.close())
40-
);
41-
42-
const repo = createEffectPatternRepository(db.db);
31+
const repo = yield* EffectPatternRepositoryService;
4332
const dbPatterns = yield* Effect.tryPromise({
4433
try: () =>
4534
repo.search({
@@ -106,6 +95,7 @@ export const searchCommand = Command.make("search", {
10695
}
10796
})
10897
).pipe(
98+
Effect.provide(EffectPatternRepositoryLive),
10999
Effect.catchAll((error) =>
110100
Effect.gen(function* () {
111101
yield* Display.showError(

packages/ep-admin/src/services/db/__tests__/helpers.test.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@ describe("Database Service Helpers", () => {
2020
expect(REQUIRED_TABLES).toEqual([
2121
"application_patterns",
2222
"effect_patterns",
23-
"jobs",
24-
"pattern_jobs",
2523
"pattern_relations",
2624
]);
2725
});

0 commit comments

Comments
 (0)