@vanshbhardwaj/worklog 1.0.0
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/.github/ISSUE_TEMPLATE/bug_report.md +28 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +19 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +19 -0
- package/.github/workflows/release.yml +63 -0
- package/.github/workflows/validate.yml +103 -0
- package/.prettierrc +8 -0
- package/ARCHITECTURE.md +82 -0
- package/CODE_OF_CONDUCT.md +65 -0
- package/CONTRIBUTING.md +74 -0
- package/INSTALLATION.md +98 -0
- package/LICENSE +21 -0
- package/README.md +246 -0
- package/SECURITY.md +18 -0
- package/benchmarks/benchmark.ts +149 -0
- package/benchmarks/vitest.bench.config.ts +9 -0
- package/dist/database/migrations/001_initial.sql +60 -0
- package/dist/database/migrations/002_relational_tables.sql +22 -0
- package/dist/index.cjs +31007 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1873 -0
- package/dist/index.js.map +1 -0
- package/eslint.config.js +38 -0
- package/package.json +49 -0
- package/pnpm-workspace.yaml +6 -0
- package/scripts/build-bin.js +75 -0
- package/sea-config.json +5 -0
- package/src/cli/commands/add.ts +176 -0
- package/src/cli/commands/continue.ts +80 -0
- package/src/cli/commands/dashboard.ts +30 -0
- package/src/cli/commands/export.ts +72 -0
- package/src/cli/commands/init.ts +52 -0
- package/src/cli/commands/list.ts +33 -0
- package/src/cli/commands/search.ts +33 -0
- package/src/cli/commands/show.ts +42 -0
- package/src/cli/commands/stats.ts +23 -0
- package/src/cli/commands/today.ts +27 -0
- package/src/cli/commands/week.ts +93 -0
- package/src/cli/index.ts +294 -0
- package/src/cli/ui.ts +323 -0
- package/src/core/config.ts +69 -0
- package/src/core/discovery.ts +38 -0
- package/src/core/logger.ts +53 -0
- package/src/database/connection.ts +95 -0
- package/src/database/migration-data.ts +71 -0
- package/src/database/migrations/001_initial.sql +60 -0
- package/src/database/migrations/002_relational_tables.sql +22 -0
- package/src/database/migrations.ts +65 -0
- package/src/errors/index.ts +51 -0
- package/src/exporters/csv.ts +59 -0
- package/src/exporters/json.ts +8 -0
- package/src/exporters/markdown.ts +71 -0
- package/src/models/work-unit.ts +38 -0
- package/src/repositories/work-unit.ts +466 -0
- package/src/services/work-unit.ts +131 -0
- package/src/tests/cli/__snapshots__/cli-productivity.test.ts.snap +37 -0
- package/src/tests/cli/__snapshots__/cli.test.ts.snap +20 -0
- package/src/tests/cli/cli-productivity.test.ts +167 -0
- package/src/tests/cli/cli.test.ts +171 -0
- package/src/tests/core/config.test.ts +53 -0
- package/src/tests/core/discovery.test.ts +46 -0
- package/src/tests/database/migrations.test.ts +75 -0
- package/src/tests/repositories/work-unit.test.ts +243 -0
- package/src/tests/services/work-unit.test.ts +87 -0
- package/src/validators/work-unit.ts +63 -0
- package/tsconfig.json +16 -0
- package/tsup.config.ts +50 -0
- package/vitest.config.ts +8 -0
package/README.md
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
# WorkLog
|
|
2
|
+
|
|
3
|
+
> **Engineering Context Manager** — *Git stores code. WorkLog stores engineering context.*
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
### Links:
|
|
7
|
+
- 📖 [Architecture Design Manual](ARCHITECTURE.md)
|
|
8
|
+
- 💾 [Advanced Installation Guide](INSTALLATION.md)
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
WorkLog is a local-first, offline-first command-line tool designed to capture the **why**, the **blockers**, the **decisions**, and the **meaningful progress** of your daily engineering work. It helps you keep track of what you are doing so you never have to ask yourself, *"What was I doing yesterday?"*
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Technical Stack
|
|
16
|
+
|
|
17
|
+
- **Language:** TypeScript
|
|
18
|
+
- **Runtime:** Node.js (v20+ recommended)
|
|
19
|
+
- **CLI Framework:** Commander.js
|
|
20
|
+
- **Database:** SQLite (via `better-sqlite3` native drivers)
|
|
21
|
+
- **Validation:** Zod
|
|
22
|
+
- **Logging:** Pino (saved to `.worklog/worklog.log`)
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Installation
|
|
27
|
+
|
|
28
|
+
WorkLog is configured to install and run locally.
|
|
29
|
+
|
|
30
|
+
1. Ensure you have **pnpm** and Node.js installed.
|
|
31
|
+
2. Clone this repository.
|
|
32
|
+
3. Install dependencies:
|
|
33
|
+
```bash
|
|
34
|
+
pnpm install
|
|
35
|
+
```
|
|
36
|
+
4. Build the application:
|
|
37
|
+
```bash
|
|
38
|
+
pnpm build
|
|
39
|
+
```
|
|
40
|
+
5. Link the command globally (optional):
|
|
41
|
+
```bash
|
|
42
|
+
pnpm link --global
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Now you can invoke WorkLog with:
|
|
46
|
+
```bash
|
|
47
|
+
worklog --help
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Core Philosophy
|
|
53
|
+
|
|
54
|
+
- **Local Scope:** Every project initializes its own database in a `.worklog/` directory (just like `.git` in Git).
|
|
55
|
+
- **Fast Interactive Prompts:** If you omit arguments, `worklog add` automatically prompts you through choices.
|
|
56
|
+
- **Machine Readable:** Add the `--json` flag to print structured data for IDE plugins or scripts.
|
|
57
|
+
- **Dedicated Exporters:** Supports Markdown, CSV, and JSON outputs for clean copy-pasting.
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## CLI Usage & Reference
|
|
62
|
+
|
|
63
|
+
### 1. Initialize a Project (`init` / `i`)
|
|
64
|
+
Initializes a new context tracker in the current directory.
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
worklog init
|
|
68
|
+
# or
|
|
69
|
+
worklog i
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
**Output:**
|
|
73
|
+
```
|
|
74
|
+
Initialized empty WorkLog repository in /path/to/project/.worklog/
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
### 2. Create a Work Unit (`add` / `a`)
|
|
80
|
+
Create an entry representing a Feature, Bug, Refactor, Spike, Research, or Decision.
|
|
81
|
+
|
|
82
|
+
**Non-Interactive Mode:**
|
|
83
|
+
```bash
|
|
84
|
+
worklog add --title "Setup authentication endpoint" --type Feature --status "In Progress" --module Auth --tags backend,security
|
|
85
|
+
# or
|
|
86
|
+
worklog a -t "Fix connection leak" --type Bug --status Completed
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
**Interactive Mode:**
|
|
90
|
+
Simply run `worklog add` (or `worklog a`) without flags in a TTY terminal, and it will guide you:
|
|
91
|
+
```
|
|
92
|
+
? Title: › Setup auth
|
|
93
|
+
? Type: › Feature
|
|
94
|
+
? Status: › Planned
|
|
95
|
+
? Description (optional): › Initial JWT setup
|
|
96
|
+
? Module (optional): › auth
|
|
97
|
+
? Tags (comma-separated, optional): › backend,security
|
|
98
|
+
? Next Step (optional): › write unit tests
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
### 3. List Work Units (`list` / `ls`)
|
|
104
|
+
Lists recent entries.
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
worklog list
|
|
108
|
+
# or
|
|
109
|
+
worklog ls
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
**Output:**
|
|
113
|
+
```
|
|
114
|
+
ID Title Type Status Module Priority Created At
|
|
115
|
+
#2 Fix connection leak Bug Completed - - Jul 26
|
|
116
|
+
#1 Setup authentication... Feature In Progress Auth - Jul 26
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
**Options:**
|
|
120
|
+
- `-l, --limit <count>`: Limit output (default is 20).
|
|
121
|
+
- `-s, --status <status>`: Filter list by status.
|
|
122
|
+
- `-t, --type <type>`: Filter list by type.
|
|
123
|
+
- `--json`: Output machine-readable JSON array.
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
### 4. Show Details (`show` / `sh`)
|
|
128
|
+
Displays detailed card information for a single Work Unit.
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
worklog show 1
|
|
132
|
+
# or
|
|
133
|
+
worklog sh 1
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
### 5. Multi-criteria Search (`search` / `s`)
|
|
139
|
+
Perform case-insensitive text search querying the SQLite FTS5 virtual table, combined with category filters.
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
# Search text
|
|
143
|
+
worklog search "connection leak"
|
|
144
|
+
|
|
145
|
+
# Search by tags and module
|
|
146
|
+
worklog search --tag backend --module auth
|
|
147
|
+
|
|
148
|
+
# Combined keyword and status query
|
|
149
|
+
worklog search "setup" --status "In Progress"
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
**Options:**
|
|
153
|
+
- `--tag <tag>`: Filter results by tag.
|
|
154
|
+
- `--module <module>`: Filter results by module.
|
|
155
|
+
- `--status <status>`: Filter results by status.
|
|
156
|
+
- `--type <type>`: Filter results by type.
|
|
157
|
+
- `--json`: Return structured matches as JSON.
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
### 6. Today's Progress (`today` / `t`)
|
|
162
|
+
Display work units created or updated today since midnight.
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
worklog today
|
|
166
|
+
# or
|
|
167
|
+
worklog t
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
### 7. Weekly Summary (`week` / `w`)
|
|
173
|
+
Provides a weekly summary of progress grouped by engineering categories (features completed, bugs fixed, decisions made, blockers encountered, research performed) and prints status/type distribution counts.
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
worklog week
|
|
177
|
+
# or
|
|
178
|
+
worklog w
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
### 8. Project Dashboard (`dashboard` / `db`)
|
|
184
|
+
Displays a focused overview answering three core developer questions:
|
|
185
|
+
1. *What am I currently working on?* (In Progress items)
|
|
186
|
+
2. *What needs attention?* (Blocked or Planned items)
|
|
187
|
+
3. *What changed recently?* (Recently updated items)
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
worklog dashboard
|
|
191
|
+
# or
|
|
192
|
+
worklog db
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
### 9. Resume Last Work (`continue` / `co`)
|
|
198
|
+
Resumes the most recently touched unfinished task (Planned, In Progress, Blocked), shifting its status to `In Progress` and updating its time marker.
|
|
199
|
+
If multiple unfinished units exist, it prompts you to select one (sorted by update date, most recent first).
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
worklog continue
|
|
203
|
+
# or
|
|
204
|
+
worklog co
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
### 10. Analytical Insights (`stats` / `st`)
|
|
210
|
+
Shows high-level metrics (totals, category distributions, and daily activity logs over the past 7 days) in clean text bars.
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
worklog stats
|
|
214
|
+
# or
|
|
215
|
+
worklog st
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
### 11. Export Context (`export` / `ex`)
|
|
221
|
+
Exports log entries to Markdown, CSV, or JSON. Supports writing directly to files or stdout piping.
|
|
222
|
+
|
|
223
|
+
```bash
|
|
224
|
+
# Export everything to markdown file
|
|
225
|
+
worklog export --format markdown --output docs/summary.md
|
|
226
|
+
|
|
227
|
+
# Pipe CSV data
|
|
228
|
+
worklog export --format csv > data_export.csv
|
|
229
|
+
|
|
230
|
+
# Export a single work unit
|
|
231
|
+
worklog export --id 1 --format markdown
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
**Options:**
|
|
235
|
+
- `-f, --format <format>`: Output format (`markdown` / `md`, `csv`, `json`). Defaults to `markdown`.
|
|
236
|
+
- `-o, --output <file>`: Writes data to a physical file.
|
|
237
|
+
- `--id <id>`: Exports only the unit matching this ID.
|
|
238
|
+
|
|
239
|
+
---
|
|
240
|
+
|
|
241
|
+
## Error Codes
|
|
242
|
+
|
|
243
|
+
The CLI will exit with:
|
|
244
|
+
- `0` on successful operation execution.
|
|
245
|
+
- `1` on user/validation errors (e.g. invalid arguments, missing fields, not in a repository).
|
|
246
|
+
- `2` on system/database failures (e.g. SQLite corruption, unhandled crashes).
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## Supported Versions
|
|
4
|
+
|
|
5
|
+
Only the latest release of WorkLog is actively supported for security updates.
|
|
6
|
+
|
|
7
|
+
| Version | Supported |
|
|
8
|
+
| ------- | ------------------ |
|
|
9
|
+
| v0.1.x | :white_check_mark: |
|
|
10
|
+
|
|
11
|
+
## Reporting a Vulnerability
|
|
12
|
+
|
|
13
|
+
If you discover a security vulnerability in this project, please **do not** open a public issue. Instead, report it privately to the maintainers.
|
|
14
|
+
|
|
15
|
+
Please send security disclosures and details of the vulnerability to:
|
|
16
|
+
- **Email:** security@worklog.local (placeholder, replace with actual security contact)
|
|
17
|
+
|
|
18
|
+
We will endeavor to respond to your report within 48 hours and outline a plan for remediation.
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { describe, it } from 'vitest';
|
|
2
|
+
import * as fs from 'fs';
|
|
3
|
+
import * as path from 'path';
|
|
4
|
+
import Database from 'better-sqlite3';
|
|
5
|
+
import { runMigrations } from '../src/database/migrations.js';
|
|
6
|
+
import { WorkUnitRepository } from '../src/repositories/work-unit.js';
|
|
7
|
+
import { WorkUnitService } from '../src/services/work-unit.js';
|
|
8
|
+
import { exportToMarkdown } from '../src/exporters/markdown.js';
|
|
9
|
+
import { exportToCSV } from '../src/exporters/csv.js';
|
|
10
|
+
import { exportToJSON } from '../src/exporters/json.js';
|
|
11
|
+
|
|
12
|
+
describe('WorkLog Performance Benchmark', () => {
|
|
13
|
+
const benchDir = path.join(process.cwd(), 'benchmarks', 'temp-bench-db');
|
|
14
|
+
|
|
15
|
+
it('should run performance metrics with 10,000 work units', () => {
|
|
16
|
+
if (fs.existsSync(benchDir)) {
|
|
17
|
+
fs.rmSync(benchDir, { recursive: true, force: true });
|
|
18
|
+
}
|
|
19
|
+
fs.mkdirSync(benchDir, { recursive: true });
|
|
20
|
+
|
|
21
|
+
console.log('\n--- STARTING WORKLOG BENCHMARK ---');
|
|
22
|
+
|
|
23
|
+
// 1. Connection & Migration Benchmark
|
|
24
|
+
const startConn = performance.now();
|
|
25
|
+
const db = new Database(path.join(benchDir, 'bench.db'));
|
|
26
|
+
runMigrations(db);
|
|
27
|
+
const endConn = performance.now();
|
|
28
|
+
const connTime = endConn - startConn;
|
|
29
|
+
console.log(`Database Connection & Migrations: ${connTime.toFixed(2)}ms`);
|
|
30
|
+
|
|
31
|
+
const repo = new WorkUnitRepository(db);
|
|
32
|
+
const service = new WorkUnitService(repo);
|
|
33
|
+
|
|
34
|
+
// 2. Seeding 10,000 work units
|
|
35
|
+
console.log('Seeding 10,000 work units...');
|
|
36
|
+
const startSeed = performance.now();
|
|
37
|
+
|
|
38
|
+
// Seed using a transaction to run extremely fast
|
|
39
|
+
const seedTx = db.transaction(() => {
|
|
40
|
+
const types = [
|
|
41
|
+
'Feature',
|
|
42
|
+
'Bug',
|
|
43
|
+
'Spike',
|
|
44
|
+
'Refactor',
|
|
45
|
+
'Improvement',
|
|
46
|
+
'Research',
|
|
47
|
+
'Decision',
|
|
48
|
+
'Blocker',
|
|
49
|
+
'Review',
|
|
50
|
+
'Idea',
|
|
51
|
+
];
|
|
52
|
+
const statuses = ['Planned', 'In Progress', 'Blocked', 'Completed', 'Cancelled'];
|
|
53
|
+
const priorities = ['Low', 'Medium', 'High', null];
|
|
54
|
+
const modules = ['auth', 'billing', 'gateway', 'core', 'ui', null];
|
|
55
|
+
|
|
56
|
+
const insertStmt = db.prepare(`
|
|
57
|
+
INSERT INTO work_units (
|
|
58
|
+
title, type, status, priority, module, description, next_step, decision, blocker, notes, created_at, updated_at
|
|
59
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
60
|
+
`);
|
|
61
|
+
|
|
62
|
+
const insertTag = db.prepare('INSERT INTO work_unit_tags (work_unit_id, tag) VALUES (?, ?)');
|
|
63
|
+
|
|
64
|
+
for (let i = 1; i <= 10000; i++) {
|
|
65
|
+
const type = types[i % types.length];
|
|
66
|
+
const status = statuses[i % statuses.length];
|
|
67
|
+
const priority = priorities[i % priorities.length];
|
|
68
|
+
const mod = modules[i % modules.length];
|
|
69
|
+
|
|
70
|
+
const now = new Date().toISOString();
|
|
71
|
+
|
|
72
|
+
insertStmt.run(
|
|
73
|
+
`Work Unit Title Number ${i} is long and descriptive`,
|
|
74
|
+
type,
|
|
75
|
+
status,
|
|
76
|
+
priority,
|
|
77
|
+
mod,
|
|
78
|
+
`Detailed description of work unit ${i} containing some sample logs.`,
|
|
79
|
+
i % 3 === 0 ? 'Review next milestone tasks' : null,
|
|
80
|
+
type === 'Decision' ? `Decision approved for item ${i}` : null,
|
|
81
|
+
status === 'Blocked' ? `Blocked by gateway API down for item ${i}` : null,
|
|
82
|
+
`Some private developer notes for unit ${i}`,
|
|
83
|
+
now,
|
|
84
|
+
now,
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
if (i % 2 === 0) {
|
|
88
|
+
insertTag.run(i, 'backend');
|
|
89
|
+
insertTag.run(i, `tag-${i % 20}`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
seedTx();
|
|
95
|
+
const endSeed = performance.now();
|
|
96
|
+
console.log(`Seeding 10,000 units: ${(endSeed - startSeed).toFixed(2)}ms`);
|
|
97
|
+
|
|
98
|
+
// 3. Stats Query Speed
|
|
99
|
+
const startStats = performance.now();
|
|
100
|
+
service.getStats(new Date(Date.now() - 7 * 24 * 3600 * 1000).toISOString());
|
|
101
|
+
const endStats = performance.now();
|
|
102
|
+
console.log(`Stats Aggregation (10k items): ${(endStats - startStats).toFixed(2)}ms`);
|
|
103
|
+
|
|
104
|
+
// 4. Search Filter Speed
|
|
105
|
+
const startSearch = performance.now();
|
|
106
|
+
const searchResult = service.searchWorkUnits('descriptive', {
|
|
107
|
+
status: 'In Progress',
|
|
108
|
+
tag: 'backend',
|
|
109
|
+
});
|
|
110
|
+
const endSearch = performance.now();
|
|
111
|
+
console.log(
|
|
112
|
+
`Case-insensitive Multi-criteria Search (10k items, matching ${searchResult.length} units): ${(endSearch - startSearch).toFixed(2)}ms`,
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
// 5. Dashboard Generation Speed
|
|
116
|
+
const startDash = performance.now();
|
|
117
|
+
const inProgress = service.getWorkUnitsByStatus('In Progress');
|
|
118
|
+
const recentlyUpdated = service.getRecentWorkUnits(5);
|
|
119
|
+
const blocked = service.getWorkUnitsByStatus('Blocked');
|
|
120
|
+
const planned = service.getWorkUnitsByStatus('Planned');
|
|
121
|
+
const needsAttention = [...blocked, ...planned].slice(0, 5);
|
|
122
|
+
const endDash = performance.now();
|
|
123
|
+
console.log(
|
|
124
|
+
`Dashboard Query Speed (10k items, loading ${inProgress.length + recentlyUpdated.length + needsAttention.length} visual links): ${(endDash - startDash).toFixed(2)}ms`,
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
// 6. Exports Formatting Speed
|
|
128
|
+
const allUnits = service.getRecentWorkUnits(10000);
|
|
129
|
+
|
|
130
|
+
const startMd = performance.now();
|
|
131
|
+
exportToMarkdown(allUnits);
|
|
132
|
+
const endMd = performance.now();
|
|
133
|
+
console.log(`Markdown Export format (10k items): ${(endMd - startMd).toFixed(2)}ms`);
|
|
134
|
+
|
|
135
|
+
const startCSV = performance.now();
|
|
136
|
+
exportToCSV(allUnits);
|
|
137
|
+
const endCSV = performance.now();
|
|
138
|
+
console.log(`CSV Export format (10k items): ${(endCSV - startCSV).toFixed(2)}ms`);
|
|
139
|
+
|
|
140
|
+
const startJSON = performance.now();
|
|
141
|
+
exportToJSON(allUnits);
|
|
142
|
+
const endJSON = performance.now();
|
|
143
|
+
console.log(`JSON Export format (10k items): ${(endJSON - startJSON).toFixed(2)}ms`);
|
|
144
|
+
|
|
145
|
+
db.close();
|
|
146
|
+
fs.rmSync(benchDir, { recursive: true, force: true });
|
|
147
|
+
console.log('--- BENCHMARK COMPLETE ---\n');
|
|
148
|
+
});
|
|
149
|
+
});
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
-- Table to track database migrations
|
|
2
|
+
CREATE TABLE IF NOT EXISTS schema_migrations (
|
|
3
|
+
version TEXT PRIMARY KEY,
|
|
4
|
+
applied_at TEXT NOT NULL
|
|
5
|
+
);
|
|
6
|
+
|
|
7
|
+
-- Core work_units table
|
|
8
|
+
CREATE TABLE IF NOT EXISTS work_units (
|
|
9
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
10
|
+
title TEXT NOT NULL,
|
|
11
|
+
type TEXT NOT NULL,
|
|
12
|
+
status TEXT NOT NULL,
|
|
13
|
+
priority TEXT,
|
|
14
|
+
module TEXT,
|
|
15
|
+
description TEXT,
|
|
16
|
+
next_step TEXT,
|
|
17
|
+
decision TEXT,
|
|
18
|
+
blocker TEXT,
|
|
19
|
+
tags TEXT, -- JSON array of strings
|
|
20
|
+
related_work_units TEXT, -- JSON array of integers
|
|
21
|
+
notes TEXT,
|
|
22
|
+
created_at TEXT NOT NULL,
|
|
23
|
+
updated_at TEXT NOT NULL
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
-- Performance indexes for status, type, and dates
|
|
27
|
+
CREATE INDEX IF NOT EXISTS idx_work_units_status ON work_units(status);
|
|
28
|
+
CREATE INDEX IF NOT EXISTS idx_work_units_type ON work_units(type);
|
|
29
|
+
CREATE INDEX IF NOT EXISTS idx_work_units_created_at ON work_units(created_at);
|
|
30
|
+
|
|
31
|
+
-- SQLite FTS5 Search Index Table using work_units as external content
|
|
32
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS work_units_fts USING fts5(
|
|
33
|
+
title,
|
|
34
|
+
description,
|
|
35
|
+
decision,
|
|
36
|
+
blocker,
|
|
37
|
+
notes,
|
|
38
|
+
content='work_units',
|
|
39
|
+
content_rowid='id'
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
-- Trigger to sync insert events to FTS
|
|
43
|
+
CREATE TRIGGER IF NOT EXISTS work_units_ai AFTER INSERT ON work_units BEGIN
|
|
44
|
+
INSERT INTO work_units_fts(rowid, title, description, decision, blocker, notes)
|
|
45
|
+
VALUES (new.id, new.title, new.description, new.decision, new.blocker, new.notes);
|
|
46
|
+
END;
|
|
47
|
+
|
|
48
|
+
-- Trigger to sync delete events to FTS
|
|
49
|
+
CREATE TRIGGER IF NOT EXISTS work_units_ad AFTER DELETE ON work_units BEGIN
|
|
50
|
+
INSERT INTO work_units_fts(work_units_fts, rowid, title, description, decision, blocker, notes)
|
|
51
|
+
VALUES('delete', old.id, old.title, old.description, old.decision, old.blocker, old.notes);
|
|
52
|
+
END;
|
|
53
|
+
|
|
54
|
+
-- Trigger to sync update events to FTS
|
|
55
|
+
CREATE TRIGGER IF NOT EXISTS work_units_au AFTER UPDATE ON work_units BEGIN
|
|
56
|
+
INSERT INTO work_units_fts(work_units_fts, rowid, title, description, decision, blocker, notes)
|
|
57
|
+
VALUES('delete', old.id, old.title, old.description, old.decision, old.blocker, old.notes);
|
|
58
|
+
INSERT INTO work_units_fts(rowid, title, description, decision, blocker, notes)
|
|
59
|
+
VALUES (new.id, new.title, new.description, new.decision, new.blocker, new.notes);
|
|
60
|
+
END;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
-- Create work_unit_tags table for indexing and querying tags
|
|
2
|
+
CREATE TABLE IF NOT EXISTS work_unit_tags (
|
|
3
|
+
work_unit_id INTEGER NOT NULL,
|
|
4
|
+
tag TEXT NOT NULL,
|
|
5
|
+
PRIMARY KEY (work_unit_id, tag),
|
|
6
|
+
FOREIGN KEY (work_unit_id) REFERENCES work_units(id) ON DELETE CASCADE
|
|
7
|
+
);
|
|
8
|
+
|
|
9
|
+
CREATE INDEX IF NOT EXISTS idx_work_unit_tags_tag ON work_unit_tags(tag);
|
|
10
|
+
|
|
11
|
+
-- Create work_unit_relations table for modeling links between work units
|
|
12
|
+
CREATE TABLE IF NOT EXISTS work_unit_relations (
|
|
13
|
+
work_unit_id INTEGER NOT NULL,
|
|
14
|
+
related_work_unit_id INTEGER NOT NULL,
|
|
15
|
+
PRIMARY KEY (work_unit_id, related_work_unit_id),
|
|
16
|
+
FOREIGN KEY (work_unit_id) REFERENCES work_units(id) ON DELETE CASCADE,
|
|
17
|
+
FOREIGN KEY (related_work_unit_id) REFERENCES work_units(id) ON DELETE CASCADE
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
-- Drop unused JSON columns from the main work_units table
|
|
21
|
+
ALTER TABLE work_units DROP COLUMN tags;
|
|
22
|
+
ALTER TABLE work_units DROP COLUMN related_work_units;
|