52 lines
2.5 KiB
Markdown
52 lines
2.5 KiB
Markdown
# Project Context Model Design
|
|
|
|
## Summary
|
|
Aggregate views need stable project identity attached to each issue so cross-project Kanban, timeline, and session views can filter and display project metadata consistently. This design adds a normalized `ProjectContext` payload to every issue returned from read flows while keeping the raw JSONL format untouched.
|
|
|
|
## Requirements
|
|
- Use existing Windows-safe path normalization for stable identity.
|
|
- Attach project identity on every issue returned from read services.
|
|
- Include fields: `key`, `root`, `displayPath`, `name`, `source`, `addedAt`.
|
|
- Default single-project reads to `source="local"` and `addedAt=null`.
|
|
|
|
## Data Model
|
|
```ts
|
|
export type ProjectSource = 'local' | 'registry' | 'scanner';
|
|
|
|
export interface ProjectContext {
|
|
key: string; // windowsPathKey(root)
|
|
root: string; // canonicalizeWindowsPath(root)
|
|
displayPath: string; // toDisplayPath(root)
|
|
name: string; // path.basename(root)
|
|
source: ProjectSource;
|
|
addedAt: string | null;
|
|
}
|
|
|
|
export type BeadIssueWithProject = BeadIssue & { project: ProjectContext };
|
|
```
|
|
|
|
## Construction
|
|
- Add a helper (e.g., `buildProjectContext`) that accepts `projectRoot`, `source`, and `addedAt`.
|
|
- Normalize the root with `canonicalizeWindowsPath`, compute the key with `windowsPathKey`, display path with `toDisplayPath`, and name from `path.basename`.
|
|
- No filesystem checks are required; this is identity metadata only.
|
|
|
|
## Read Flow Integration
|
|
- Update `readIssuesFromDisk` to attach `project` to each parsed issue.
|
|
- Default `projectRoot` to `process.cwd()` when not provided.
|
|
- Keep the existing `BeadIssue` shape for raw parsing; project context is added in read services only.
|
|
|
|
## Error Handling
|
|
- If `projectRoot` is empty, throw a clear error early in `buildProjectContext`.
|
|
- Otherwise, treat normalization as pure string ops and do not swallow exceptions.
|
|
|
|
## Tests
|
|
- Add unit tests for `buildProjectContext` field derivation (key/root/displayPath/name/source/addedAt).
|
|
- Update `readIssuesFromDisk` tests to assert `project` is attached with expected fields.
|
|
|
|
## Alternatives Considered
|
|
1. **Wrapper object `{ project, issue }`**
|
|
Pro: explicit separation; Con: more refactors across UI filtering and query shapes.
|
|
2. **`metadata.project` on issues**
|
|
Pro: zero type changes; Con: weak typing and harder discoverability.
|
|
3. **Chosen: `issue.project` field**
|
|
Clear typing, predictable access, and minimal friction for UI + aggregate queries.
|