← Corpus / lost-in-public / other
Refactor Plan: Consolidate Callout Processing to Pipeline Architecture
- Path
- refactors/Extended-Markdown-Rendering-Consolidation.md
Non-Destructive Refactor Plan: Callout Processing Consolidation
Goal
Consolidate callout processing into the four-phase pipeline architecture while preserving existing code for reference and rollback capability.
Current State
We have two parallel implementations:
- Monolithic approach in
remark-callout.ts - Four-phase pipeline in
callouts/directory
Refactor Steps
1. Archive Current Implementation
# Create archive directory in site-archive submodule
mkdir -p site-archive/2025-04-03/markdown-processing/
# Copy files to archive with clear documentation
cp site/src/utils/markdown/plugins/remark-callout.ts \
site-archive/2025-04-03/markdown-processing/remark-callout.original.ts
cp site/src/types/remark-callout-handler.d.ts \
site-archive/2025-04-03/markdown-processing/remark-callout-handler.original.d.ts
# Add README explaining the archived code
touch site-archive/2025-04-03/markdown-processing/README.md
2. Extract Reusable Components
Before removing any code, extract valuable patterns from the monolithic implementation:
- Detection Pattern:
// Copy regex pattern to calloutCases.ts
const CALLOUT_PATTERN = /^\[!(\w+)\](?:\s+(.+))?/;
- Type Definitions:
// Merge relevant types into calloutTypes.ts
export interface CalloutNode {
type: 'callout';
calloutType: string;
title?: string;
children: Array<any>;
data: {
hName: string;
hProperties: {
className: string[];
'data-type': string;
'data-title': string;
};
};
}
3. Enhance Pipeline Implementation
- Update Detection Phase:
// In detectMarkdownCallouts.ts
import { CALLOUT_PATTERN } from './calloutCases';
export function detectCallouts(tree: Node): CalloutCandidate[] {
const candidates: CalloutCandidate[] = [];
visit(tree, 'blockquote', (node: Blockquote) => {
const match = CALLOUT_PATTERN.exec(/* ... */);
if (match) {
candidates.push({
node,
type: match[1],
title: match[2]
});
}
});
return candidates;
}
- Add Debug Points:
// In processCalloutPipeline.ts
astDebugger.writeDebugFile('callouts-detection', {
phase: 'detect',
candidates: detected.length,
patterns: detected.map(d => d.type)
});
4. Create Deprecation Notice
// In remark-callout.ts
/**
* @deprecated This monolithic implementation has been replaced by the
* four-phase pipeline in ../callouts/. See processCalloutPipeline.ts
* for the new implementation.
*
* Original code archived in site-archive/2025-04-03/markdown-processing/
*/
5. Update Documentation
- Add Migration Guide:
# Callout Processing Migration
- Previous: Single-pass transformation in remark-callout.ts
- New: Four-phase pipeline in callouts/
1. Detection (detectMarkdownCallouts.ts)
2. Isolation (isolateCalloutContent.ts)
3. Transform (transformCalloutStructure.ts)
4. Embed (embedCalloutNodes.ts)
- Update Debug Documentation:
Debug output points:
1. callouts-detection.json
2. callouts-isolation.json
3. callouts-transform.json
4. callouts-embed.json
5. callouts-complete.json
Benefits
- Single source of truth in pipeline architecture
- Better debugging through phase isolation
- Clearer separation of concerns
- Original code preserved in archive
- Non-destructive transition path
Validation Steps
- Run existing test suite against pipeline
- Compare debug output between implementations
- Verify all callout types are handled
- Check HTML output matches original
Rollback Plan
- Code preserved in site-archive
- Deprecation notice includes migration path
- Types and patterns extracted for reuse
Post-Mortem: Breaking Change
[!ERROR] Failed to Follow Plan We deviated from our own refactoring plan by:
- Deleting files immediately without archiving
- Not adding deprecation notices
- Making breaking changes to
astro.config.mjswithout testing
Impact
- Build failed due to missing
remark-callout-handler.ts - No rollback path available
- Lost original implementation reference
Recovery Steps
- Restored proper pipeline implementation in
detectMarkdownCallouts.ts - Updated Astro config to use new pipeline
- Documented failure in this log
Lessons Learned
- ALWAYS FOLLOW THE REFACTOR PLAN
- Never delete files without archiving
- Use deprecation notices for breaking changes
- Test configuration changes before removing old code
Next Steps
- Create proper archive in
site-archive - Add comprehensive tests for new pipeline
- Document the new implementation thoroughly