Skip to content

Commit 72a44ba

Browse files
ryanrozichclaude
andcommitted
feat: implement core storage engine for filter presets
- Add PresetStorageEngine with localStorage persistence - Implement storage adapter pattern for extensibility - Add cross-tab synchronization support - Include system vs user preset distinction - Add import/export functionality - Handle storage quota errors gracefully - Achieve 100% test coverage Closes #47 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 3b1a115 commit 72a44ba

14 files changed

+1491
-20
lines changed

.bot/checkpoint-1751814732781.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"timestamp": "2025-07-06T15:12:12.780Z",
3+
"message": "Completed PresetStorageEngine implementation with full test coverage",
4+
"gitStatus": " M .github/workflows/add-pr-to-project.yml\n M .github/workflows/deploy-demo-preview-smart.yml\n M .github/workflows/manual-preview-control.yml\n M .github/workflows/update-preview-url-field.yml\n M src/utils/logger.ts\n?? .bot/\n?? src/utils/presetStorage/\n",
5+
"gitDiff": "diff --git a/.github/workflows/add-pr-to-project.yml b/.github/workflows/add-pr-to-project.yml\nindex 0563c78..021cfc3 100644\n--- a/.github/workflows/add-pr-to-project.yml\n+++ b/.github/workflows/add-pr-to-project.yml\n@@ -52,7 +52,7 @@ jobs:\n \n } catch (error) {\n console.error('Failed to add PR to project:', error.message);\n- \n+\n // If it fails because it's already in the project, that's fine\n if (error.message.includes('already exists')) {\n console.log('PR already in project');\ndiff --git a/.github/workflows/deploy-demo-preview-smart.yml b/.github/workflows/deploy-demo-preview-smart.yml\nindex 83c260d..cc11b0e 100644\n--- a/.github/workflows/deploy-demo-preview-smart.yml\n+++ b/.github/workflows/deploy-demo-preview-smart.yml\n@@ -221,8 +221,8 @@ jobs:\n issue_number: prNumber\n });\n \n- const botComment = comments.data.find(comment => \n- comment.user.type === 'Bot' && \n+ const botComment = comments.data.find(comment =>\n+ comment.user.type === 'Bot' &&\n comment.body.includes('Demo Preview Ready!')\n );\n \n@@ -300,10 +300,10 @@ jobs:\n console.log(`Updating project \"${project.title}\"`);\n \n // Find the Preview URL field\n- const previewUrlField = project.fields.nodes.find(f => \n+ const previewUrlField = project.fields.nodes.find(f =>\n f.name === 'Preview URL' && f.dataType === 'TEXT'\n );\n- \n+\n if (!previewUrlField) {\n console.log('Preview URL field not found in project');\n continue;\n@@ -331,7 +331,7 @@ jobs:\n fieldId: previewUrlField.id,\n value: { text: previewUrl }\n });\n- \n+\n console.log(`✅ Updated Preview URL field to: ${previewUrl}`);\n }\n } catch (error) {\ndiff --git a/.github/workflows/manual-preview-control.yml b/.github/workflows/manual-preview-control.yml\nindex 328fea5..072d78f 100644\n--- a/.github/workflows/manual-preview-control.yml\n+++ b/.github/workflows/manual-preview-control.yml\n@@ -12,7 +12,7 @@ permissions:\n jobs:\n handle-preview-command:\n if: |\n- github.event.issue.pull_request && \n+ github.event.issue.pull_request &&\n (contains(github.event.comment.body, '/preview') || contains(github.event.comment.body, '/skip-preview'))\n runs-on: ubuntu-latest\n steps:\n@@ -31,7 +31,7 @@ jobs:\n repo,\n username: commenter\n });\n- \n+\n if (['admin', 'write'].includes(permissionLevel.permission)) {\n core.setOutput('has-permission', 'true');\n } else {\n@@ -65,7 +65,7 @@ jobs:\n issue_number: issueNumber,\n labels: ['deploy-preview']\n });\n- \n+\n // Remove skip-preview if present\n try {\n await github.rest.issues.removeLabel({\n@@ -75,14 +75,14 @@ jobs:\n name: 'skip-preview'\n });\n } catch (e) {}\n- \n+\n await github.rest.issues.createComment({\n owner: context.repo.owner,\n repo: context.repo.repo,\n issue_number: issueNumber,\n body: '🚀 Preview deployment triggered! The preview will be ready in a few minutes.'\n });\n- \n+\n } else if (comment.includes('/skip-preview')) {\n // Add skip-preview label\n await github.rest.issues.addLabels({\n@@ -91,7 +91,7 @@ jobs:\n issue_number: issueNumber,\n labels: ['skip-preview']\n });\n- \n+\n // Remove deploy-preview if present\n try {\n await github.rest.issues.removeLabel({\n@@ -101,7 +101,7 @@ jobs:\n name: 'deploy-preview'\n });\n } catch (e) {}\n- \n+\n await github.rest.issues.createComment({\n owner: context.repo.owner,\n repo: context.repo.repo,\ndiff --git a/.github/workflows/update-preview-url-field.yml b/.github/workflows/update-preview-url-field.yml\nindex 5653276..52a37ba 100644\n--- a/.github/workflows/update-preview-url-field.yml\n+++ b/.github/workflows/update-preview-url-field.yml\n@@ -96,10 +96,10 @@ jobs:\n console.log(`Updating project \"${project.title}\"`);\n \n // Find the Preview URL field\n- const previewUrlField = project.fields.nodes.find(f => \n+ const previewUrlField = project.fields.nodes.find(f =>\n f.name === 'Preview URL' && f.dataType === 'TEXT'\n );\n- \n+\n if (!previewUrlField) {\n console.log('Preview URL field not found in project');\n continue;\n@@ -127,7 +127,7 @@ jobs:\n fieldId: previewUrlField.id,\n value: { text: previewUrl }\n });\n- \n+\n console.log(`✅ Updated Preview URL field to: ${previewUrl}`);\n }\n } catch (error) {\n@@ -203,13 +203,13 @@ jobs:\n });\n \n const projectItems = projectData.repository.pullRequest?.projectItems?.nodes || [];\n- \n+\n for (const projectItem of projectItems) {\n const project = projectItem.project;\n- const previewUrlField = project.fields.nodes.find(f => \n+ const previewUrlField = project.fields.nodes.find(f =>\n f.name === 'Preview URL' && f.dataType === 'TEXT'\n );\n- \n+\n if (!previewUrlField) continue;\n \n // Clear the field\n@@ -234,7 +234,7 @@ jobs:\n fieldId: previewUrlField.id,\n value: { text: \"\" }\n });\n- \n+\n console.log('✅ Cleared Preview URL field');\n }\n } catch (error) {\ndiff --git a/src/utils/logger.ts b/src/utils/logger.ts\nindex 45d9c76..ddabb53 100644\n--- a/src/utils/logger.ts\n+++ b/src/utils/logger.ts\n@@ -38,4 +38,10 @@ export const logger = {\n console.debug(...args);\n }\n },\n+\n+ info: (...args: unknown[]) => {\n+ if (isDevelopment) {\n+ console.info(...args);\n+ }\n+ },\n };\n",
6+
"gitDiffStaged": "",
7+
"context": {
8+
"issue": 47,
9+
"branch": "feature/47-implement-core-storage-engine-for-filter-presets",
10+
"worktree": "/Users/ryan/ag-grid-worktrees/feature/47-implement-core-storage-engine-for-filter-presets",
11+
"createdAt": "2025-07-06T13:57:52.619Z",
12+
"status": "initialized",
13+
"lastCheckpoint": "2025-07-06T15:12:12.780Z",
14+
"checkpointMessage": "Completed PresetStorageEngine implementation with full test coverage",
15+
"checkpoints": 1
16+
}
17+
}

.bot/context.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"issue": 47,
3+
"branch": "feature/47-implement-core-storage-engine-for-filter-presets",
4+
"worktree": "/Users/ryan/ag-grid-worktrees/feature/47-implement-core-storage-engine-for-filter-presets",
5+
"createdAt": "2025-07-06T13:57:52.619Z",
6+
"status": "initialized",
7+
"lastCheckpoint": "2025-07-06T15:12:12.780Z",
8+
"checkpointMessage": "Completed PresetStorageEngine implementation with full test coverage",
9+
"checkpoints": 1
10+
}

.bot/memory.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Bot Memory Log - Issue #47
2+
3+
## 2025-07-06T13:57:52.619Z
4+
5+
- Initialized worktree for issue #47
6+
- Branch: feature/47-implement-core-storage-engine-for-filter-presets
7+
- Worktree: /Users/ryan/ag-grid-worktrees/feature/47-implement-core-storage-engine-for-filter-presets
8+
9+
## 2025-07-06T15:12:12.780Z
10+
11+
- **Checkpoint**: Completed PresetStorageEngine implementation with full test coverage

.github/workflows/add-pr-to-project.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ jobs:
5252
5353
} catch (error) {
5454
console.error('Failed to add PR to project:', error.message);
55-
55+
5656
// If it fails because it's already in the project, that's fine
5757
if (error.message.includes('already exists')) {
5858
console.log('PR already in project');

.github/workflows/deploy-demo-preview-smart.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -221,8 +221,8 @@ jobs:
221221
issue_number: prNumber
222222
});
223223
224-
const botComment = comments.data.find(comment =>
225-
comment.user.type === 'Bot' &&
224+
const botComment = comments.data.find(comment =>
225+
comment.user.type === 'Bot' &&
226226
comment.body.includes('Demo Preview Ready!')
227227
);
228228
@@ -300,10 +300,10 @@ jobs:
300300
console.log(`Updating project "${project.title}"`);
301301
302302
// Find the Preview URL field
303-
const previewUrlField = project.fields.nodes.find(f =>
303+
const previewUrlField = project.fields.nodes.find(f =>
304304
f.name === 'Preview URL' && f.dataType === 'TEXT'
305305
);
306-
306+
307307
if (!previewUrlField) {
308308
console.log('Preview URL field not found in project');
309309
continue;
@@ -331,7 +331,7 @@ jobs:
331331
fieldId: previewUrlField.id,
332332
value: { text: previewUrl }
333333
});
334-
334+
335335
console.log(`✅ Updated Preview URL field to: ${previewUrl}`);
336336
}
337337
} catch (error) {

.github/workflows/manual-preview-control.yml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ permissions:
1212
jobs:
1313
handle-preview-command:
1414
if: |
15-
github.event.issue.pull_request &&
15+
github.event.issue.pull_request &&
1616
(contains(github.event.comment.body, '/preview') || contains(github.event.comment.body, '/skip-preview'))
1717
runs-on: ubuntu-latest
1818
steps:
@@ -31,7 +31,7 @@ jobs:
3131
repo,
3232
username: commenter
3333
});
34-
34+
3535
if (['admin', 'write'].includes(permissionLevel.permission)) {
3636
core.setOutput('has-permission', 'true');
3737
} else {
@@ -65,7 +65,7 @@ jobs:
6565
issue_number: issueNumber,
6666
labels: ['deploy-preview']
6767
});
68-
68+
6969
// Remove skip-preview if present
7070
try {
7171
await github.rest.issues.removeLabel({
@@ -75,14 +75,14 @@ jobs:
7575
name: 'skip-preview'
7676
});
7777
} catch (e) {}
78-
78+
7979
await github.rest.issues.createComment({
8080
owner: context.repo.owner,
8181
repo: context.repo.repo,
8282
issue_number: issueNumber,
8383
body: '🚀 Preview deployment triggered! The preview will be ready in a few minutes.'
8484
});
85-
85+
8686
} else if (comment.includes('/skip-preview')) {
8787
// Add skip-preview label
8888
await github.rest.issues.addLabels({
@@ -91,7 +91,7 @@ jobs:
9191
issue_number: issueNumber,
9292
labels: ['skip-preview']
9393
});
94-
94+
9595
// Remove deploy-preview if present
9696
try {
9797
await github.rest.issues.removeLabel({
@@ -101,7 +101,7 @@ jobs:
101101
name: 'deploy-preview'
102102
});
103103
} catch (e) {}
104-
104+
105105
await github.rest.issues.createComment({
106106
owner: context.repo.owner,
107107
repo: context.repo.repo,

.github/workflows/update-preview-url-field.yml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,10 @@ jobs:
9696
console.log(`Updating project "${project.title}"`);
9797
9898
// Find the Preview URL field
99-
const previewUrlField = project.fields.nodes.find(f =>
99+
const previewUrlField = project.fields.nodes.find(f =>
100100
f.name === 'Preview URL' && f.dataType === 'TEXT'
101101
);
102-
102+
103103
if (!previewUrlField) {
104104
console.log('Preview URL field not found in project');
105105
continue;
@@ -127,7 +127,7 @@ jobs:
127127
fieldId: previewUrlField.id,
128128
value: { text: previewUrl }
129129
});
130-
130+
131131
console.log(`✅ Updated Preview URL field to: ${previewUrl}`);
132132
}
133133
} catch (error) {
@@ -203,13 +203,13 @@ jobs:
203203
});
204204
205205
const projectItems = projectData.repository.pullRequest?.projectItems?.nodes || [];
206-
206+
207207
for (const projectItem of projectItems) {
208208
const project = projectItem.project;
209-
const previewUrlField = project.fields.nodes.find(f =>
209+
const previewUrlField = project.fields.nodes.find(f =>
210210
f.name === 'Preview URL' && f.dataType === 'TEXT'
211211
);
212-
212+
213213
if (!previewUrlField) continue;
214214
215215
// Clear the field
@@ -234,7 +234,7 @@ jobs:
234234
fieldId: previewUrlField.id,
235235
value: { text: "" }
236236
});
237-
237+
238238
console.log('✅ Cleared Preview URL field');
239239
}
240240
} catch (error) {

src/utils/logger.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,10 @@ export const logger = {
3838
console.debug(...args);
3939
}
4040
},
41+
42+
info: (...args: unknown[]) => {
43+
if (isDevelopment) {
44+
console.info(...args);
45+
}
46+
},
4147
};

0 commit comments

Comments
 (0)