@happyvertical/smrt-projects 0.57.19 → 0.57.21

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.
Files changed (57) hide show
  1. package/AGENTS.md +3 -0
  2. package/README.md +68 -0
  3. package/dist/collections/DevelopmentRequests.d.ts.map +1 -1
  4. package/dist/collections/ProjectDecisions.d.ts +9 -0
  5. package/dist/collections/ProjectDecisions.d.ts.map +1 -0
  6. package/dist/collections/ProjectGovernanceEvents.d.ts +11 -0
  7. package/dist/collections/ProjectGovernanceEvents.d.ts.map +1 -0
  8. package/dist/collections/ProjectQuestions.d.ts +9 -0
  9. package/dist/collections/ProjectQuestions.d.ts.map +1 -0
  10. package/dist/collections/ProjectSpecifications.d.ts +8 -0
  11. package/dist/collections/ProjectSpecifications.d.ts.map +1 -0
  12. package/dist/collections/index.d.ts +4 -0
  13. package/dist/collections/index.d.ts.map +1 -1
  14. package/dist/index.d.ts +11 -0
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +1120 -51
  17. package/dist/index.js.map +1 -1
  18. package/dist/manifest.json +4604 -2323
  19. package/dist/models/DevelopmentRequest.d.ts +2 -2
  20. package/dist/models/DevelopmentRequest.d.ts.map +1 -1
  21. package/dist/models/ProjectDecision.d.ts +39 -0
  22. package/dist/models/ProjectDecision.d.ts.map +1 -0
  23. package/dist/models/ProjectGovernanceEvent.d.ts +40 -0
  24. package/dist/models/ProjectGovernanceEvent.d.ts.map +1 -0
  25. package/dist/models/ProjectQuestion.d.ts +32 -0
  26. package/dist/models/ProjectQuestion.d.ts.map +1 -0
  27. package/dist/models/ProjectSpecification.d.ts +26 -0
  28. package/dist/models/ProjectSpecification.d.ts.map +1 -0
  29. package/dist/models/index.d.ts +4 -0
  30. package/dist/models/index.d.ts.map +1 -1
  31. package/dist/models/project-governance-validation.d.ts +6 -0
  32. package/dist/models/project-governance-validation.d.ts.map +1 -0
  33. package/dist/project-governance-types.d.ts +49 -0
  34. package/dist/project-governance-types.d.ts.map +1 -0
  35. package/dist/services/development-request-service.d.ts.map +1 -1
  36. package/dist/services/index.d.ts +3 -0
  37. package/dist/services/index.d.ts.map +1 -1
  38. package/dist/services/participant-development-request-service.d.ts +34 -0
  39. package/dist/services/participant-development-request-service.d.ts.map +1 -0
  40. package/dist/services/project-governance-service.d.ts +106 -0
  41. package/dist/services/project-governance-service.d.ts.map +1 -0
  42. package/dist/services/project-specification-service.d.ts +30 -0
  43. package/dist/services/project-specification-service.d.ts.map +1 -0
  44. package/dist/smrt-knowledge.json +915 -49
  45. package/dist/svelte/ProjectQuestionsAndDecisions.svelte +183 -0
  46. package/dist/svelte/ProjectQuestionsAndDecisions.svelte.d.ts +17 -0
  47. package/dist/svelte/ProjectQuestionsAndDecisions.svelte.d.ts.map +1 -0
  48. package/dist/svelte/i18n.d.ts +16 -0
  49. package/dist/svelte/i18n.d.ts.map +1 -1
  50. package/dist/svelte/i18n.js +16 -0
  51. package/dist/svelte/index.d.ts +4 -1
  52. package/dist/svelte/index.d.ts.map +1 -1
  53. package/dist/svelte/index.js +3 -1
  54. package/dist/svelte/project-governance-types.d.ts +35 -0
  55. package/dist/svelte/project-governance-types.d.ts.map +1 -0
  56. package/dist/svelte/project-governance-types.js +1 -0
  57. package/package.json +14 -13
@@ -0,0 +1,183 @@
1
+ <script lang="ts">
2
+ import { Form, Input, Select, Textarea } from '@happyvertical/smrt-ui/forms';
3
+ import { useI18n } from '@happyvertical/smrt-ui/i18n';
4
+ import { Button } from '@happyvertical/smrt-ui/ui';
5
+ import { M } from './i18n.js';
6
+ import type {
7
+ ProjectDecisionResolveInput,
8
+ ProjectDecisionView,
9
+ ProjectQuestionAnswerInput,
10
+ ProjectQuestionView,
11
+ } from './project-governance-types.js';
12
+
13
+ export interface Props {
14
+ /** Authorized question projections to display and resolve. */
15
+ questions?: ProjectQuestionView[];
16
+ /** Authorized decision projections with their available choices. */
17
+ decisions?: ProjectDecisionView[];
18
+ /** Disable resolution submissions while the host saves a change. */
19
+ busy?: boolean;
20
+ /** Save an explicit owner answer with the observed revision. */
21
+ onanswer?: (input: ProjectQuestionAnswerInput) => void | Promise<void>;
22
+ /** Save a selected outcome and rationale with the observed revision. */
23
+ ondecide?: (input: ProjectDecisionResolveInput) => void | Promise<void>;
24
+ }
25
+
26
+ let {
27
+ questions = [],
28
+ decisions = [],
29
+ busy = false,
30
+ onanswer,
31
+ ondecide,
32
+ }: Props = $props();
33
+
34
+ const { t } = useI18n();
35
+
36
+ function submitAnswer(event: SubmitEvent, question: ProjectQuestionView) {
37
+ event.preventDefault();
38
+ const form = new FormData(event.currentTarget as HTMLFormElement);
39
+ const answer = String(form.get('answer') ?? '').trim();
40
+ if (answer)
41
+ onanswer?.({
42
+ id: question.id,
43
+ answer,
44
+ expectedRevision: question.revision,
45
+ });
46
+ }
47
+
48
+ function submitDecision(event: SubmitEvent, decision: ProjectDecisionView) {
49
+ event.preventDefault();
50
+ const form = new FormData(event.currentTarget as HTMLFormElement);
51
+ const outcome = String(form.get('outcome') ?? '').trim();
52
+ if (!outcome) return;
53
+ ondecide?.({
54
+ id: decision.id,
55
+ outcome,
56
+ rationale: String(form.get('rationale') ?? '').trim(),
57
+ expectedRevision: decision.revision,
58
+ });
59
+ }
60
+ </script>
61
+
62
+ <section class="governance" data-smrt-component="ProjectQuestionsAndDecisions">
63
+ <div class="section-heading">
64
+ <div>
65
+ <h2>{t(M['projects.governance.questions'])}</h2>
66
+ <p>{t(M['projects.governance.questions_description'])}</p>
67
+ </div>
68
+ <span>{t(M['projects.governance.open_count'], { count: questions.filter((item) => item.status === 'open').length })}</span>
69
+ </div>
70
+
71
+ {#if questions.length === 0}
72
+ <p class="empty">{t(M['projects.governance.questions_empty'])}</p>
73
+ {:else}
74
+ <div class="items">
75
+ {#each questions as question (question.id)}
76
+ <article id={`question-${question.id}`}>
77
+ <header>
78
+ <div>
79
+ <h3>{question.prompt}</h3>
80
+ {#if question.ownerLabel}<small>{t(M['projects.governance.owner'])} {question.ownerLabel}</small>{/if}
81
+ </div>
82
+ <span class="status">{question.status}</span>
83
+ </header>
84
+ {#if question.answer}<p class="response">{question.answer}</p>{/if}
85
+ {#if question.contextReferences?.length}
86
+ <ul class="references" aria-label={t(M['projects.governance.question_context'])}>
87
+ {#each question.contextReferences as reference (`${reference.kind}:${reference.ref}`)}
88
+ <li>{reference.label ?? reference.ref} <small>{reference.kind}</small></li>
89
+ {/each}
90
+ </ul>
91
+ {/if}
92
+ {#if question.status === 'open' && question.canResolve}
93
+ <Form onsubmit={(event) => submitAnswer(event, question)}>
94
+ <label for={`answer-${question.id}`}>{t(M['projects.governance.answer'])}</label>
95
+ <Textarea id={`answer-${question.id}`} name="answer" required></Textarea>
96
+ <Button type="submit" disabled={busy}>{t(M['projects.governance.save_answer'])}</Button>
97
+ </Form>
98
+ {/if}
99
+ </article>
100
+ {/each}
101
+ </div>
102
+ {/if}
103
+
104
+ <div class="section-heading decisions-heading">
105
+ <div>
106
+ <h2>{t(M['projects.governance.decisions'])}</h2>
107
+ <p>{t(M['projects.governance.decisions_description'])}</p>
108
+ </div>
109
+ <span>{t(M['projects.governance.open_count'], { count: decisions.filter((item) => item.status === 'open').length })}</span>
110
+ </div>
111
+
112
+ {#if decisions.length === 0}
113
+ <p class="empty">{t(M['projects.governance.decisions_empty'])}</p>
114
+ {:else}
115
+ <div class="items">
116
+ {#each decisions as decision (decision.id)}
117
+ <article id={`decision-${decision.id}`}>
118
+ <header>
119
+ <div>
120
+ <h3>{decision.question}</h3>
121
+ {#if decision.ownerLabel}<small>{t(M['projects.governance.owner'])} {decision.ownerLabel}</small>{/if}
122
+ </div>
123
+ <span class="status">{decision.status}</span>
124
+ </header>
125
+ {#if decision.outcome}
126
+ <p class="response">
127
+ <strong>{decision.options?.find((option) => option.id === decision.outcome)?.label ?? decision.outcome}</strong>
128
+ {#if decision.rationale}<span>{decision.rationale}</span>{/if}
129
+ </p>
130
+ {/if}
131
+ {#if decision.contextReferences?.length}
132
+ <ul class="references" aria-label={t(M['projects.governance.decision_context'])}>
133
+ {#each decision.contextReferences as reference (`${reference.kind}:${reference.ref}`)}
134
+ <li>{reference.label ?? reference.ref} <small>{reference.kind}</small></li>
135
+ {/each}
136
+ </ul>
137
+ {/if}
138
+ {#if decision.status === 'open' && decision.canResolve}
139
+ <Form onsubmit={(event) => submitDecision(event, decision)}>
140
+ {#if decision.options?.length}
141
+ <label for={`outcome-${decision.id}`}>{t(M['projects.governance.outcome'])}</label>
142
+ <Select id={`outcome-${decision.id}`} name="outcome" required>
143
+ <option value="">{t(M['projects.governance.choose_option'])}</option>
144
+ {#each decision.options as option (option.id)}
145
+ <option value={option.id}>{option.label}</option>
146
+ {/each}
147
+ </Select>
148
+ {:else}
149
+ <label for={`outcome-${decision.id}`}>{t(M['projects.governance.outcome'])}</label>
150
+ <Input id={`outcome-${decision.id}`} name="outcome" required />
151
+ {/if}
152
+ <label for={`rationale-${decision.id}`}>{t(M['projects.governance.rationale'])}</label>
153
+ <Textarea id={`rationale-${decision.id}`} name="rationale"></Textarea>
154
+ <Button type="submit" disabled={busy}>{t(M['projects.governance.record_decision'])}</Button>
155
+ </Form>
156
+ {/if}
157
+ </article>
158
+ {/each}
159
+ </div>
160
+ {/if}
161
+ </section>
162
+
163
+ <style>
164
+ @layer smrt.reset, smrt.structure, smrt.theme;
165
+ @layer smrt.theme {
166
+ .governance { display: grid; gap: var(--smrt-spacing-4); }
167
+ .section-heading { align-items: end; display: flex; justify-content: space-between; gap: var(--smrt-spacing-4); }
168
+ .section-heading h2, .section-heading p, article h3, .response { margin: 0; }
169
+ .section-heading p, article small, .empty { color: var(--smrt-color-on-surface-variant); }
170
+ .section-heading > span, .status { border: var(--smrt-hairline); border-radius: var(--smrt-radius-full); padding: var(--smrt-spacing-1) var(--smrt-spacing-3); white-space: nowrap; }
171
+ .decisions-heading { margin-top: var(--smrt-spacing-5); }
172
+ .items { display: grid; gap: var(--smrt-spacing-3); }
173
+ article { border: var(--smrt-hairline); border-radius: var(--smrt-radius-medium); display: grid; gap: var(--smrt-spacing-3); padding: var(--smrt-spacing-4); }
174
+ article header { align-items: start; display: flex; justify-content: space-between; gap: var(--smrt-spacing-3); }
175
+ article header > div, article :global(form), .response { display: grid; gap: var(--smrt-spacing-2); }
176
+ .status { font-size: var(--smrt-typography-label-medium-size); text-transform: capitalize; }
177
+ .references { display: flex; flex-wrap: wrap; gap: var(--smrt-spacing-2); list-style: none; margin: 0; padding: 0; }
178
+ .references li { background: var(--smrt-color-surface-container); border-radius: var(--smrt-radius-small); padding: var(--smrt-spacing-1) var(--smrt-spacing-2); }
179
+ article :global(form) { border-top: var(--smrt-hairline); padding-top: var(--smrt-spacing-3); }
180
+ article :global(form button) { justify-self: end; }
181
+ @media (max-width: 40rem) { .section-heading, article header { align-items: stretch; flex-direction: column; } .section-heading > span, .status { align-self: start; } }
182
+ }
183
+ </style>
@@ -0,0 +1,17 @@
1
+ import type { ProjectDecisionResolveInput, ProjectDecisionView, ProjectQuestionAnswerInput, ProjectQuestionView } from './project-governance-types.js';
2
+ export interface Props {
3
+ /** Authorized question projections to display and resolve. */
4
+ questions?: ProjectQuestionView[];
5
+ /** Authorized decision projections with their available choices. */
6
+ decisions?: ProjectDecisionView[];
7
+ /** Disable resolution submissions while the host saves a change. */
8
+ busy?: boolean;
9
+ /** Save an explicit owner answer with the observed revision. */
10
+ onanswer?: (input: ProjectQuestionAnswerInput) => void | Promise<void>;
11
+ /** Save a selected outcome and rationale with the observed revision. */
12
+ ondecide?: (input: ProjectDecisionResolveInput) => void | Promise<void>;
13
+ }
14
+ declare const ProjectQuestionsAndDecisions: import("svelte").Component<Props, {}, "">;
15
+ type ProjectQuestionsAndDecisions = ReturnType<typeof ProjectQuestionsAndDecisions>;
16
+ export default ProjectQuestionsAndDecisions;
17
+ //# sourceMappingURL=ProjectQuestionsAndDecisions.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProjectQuestionsAndDecisions.svelte.d.ts","sourceRoot":"","sources":["../../src/svelte/ProjectQuestionsAndDecisions.svelte.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,2BAA2B,EAC3B,mBAAmB,EACnB,0BAA0B,EAC1B,mBAAmB,EACpB,MAAM,+BAA+B,CAAC;AAGvC,MAAM,WAAW,KAAK;IACpB,8DAA8D;IAC9D,SAAS,CAAC,EAAE,mBAAmB,EAAE,CAAC;IAClC,oEAAoE;IACpE,SAAS,CAAC,EAAE,mBAAmB,EAAE,CAAC;IAClC,oEAAoE;IACpE,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,gEAAgE;IAChE,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,0BAA0B,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvE,wEAAwE;IACxE,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,2BAA2B,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACzE;AAsJD,QAAA,MAAM,4BAA4B,2CAAwC,CAAC;AAC3E,KAAK,4BAA4B,GAAG,UAAU,CAAC,OAAO,4BAA4B,CAAC,CAAC;AACpF,eAAe,4BAA4B,CAAC"}
@@ -1,4 +1,20 @@
1
1
  export declare const M: {
2
+ readonly 'projects.governance.questions': "projects.governance.questions";
3
+ readonly 'projects.governance.questions_description': "projects.governance.questions_description";
4
+ readonly 'projects.governance.questions_empty': "projects.governance.questions_empty";
5
+ readonly 'projects.governance.decisions': "projects.governance.decisions";
6
+ readonly 'projects.governance.decisions_description': "projects.governance.decisions_description";
7
+ readonly 'projects.governance.decisions_empty': "projects.governance.decisions_empty";
8
+ readonly 'projects.governance.open_count': "projects.governance.open_count";
9
+ readonly 'projects.governance.owner': "projects.governance.owner";
10
+ readonly 'projects.governance.question_context': "projects.governance.question_context";
11
+ readonly 'projects.governance.decision_context': "projects.governance.decision_context";
12
+ readonly 'projects.governance.answer': "projects.governance.answer";
13
+ readonly 'projects.governance.save_answer': "projects.governance.save_answer";
14
+ readonly 'projects.governance.outcome': "projects.governance.outcome";
15
+ readonly 'projects.governance.choose_option': "projects.governance.choose_option";
16
+ readonly 'projects.governance.rationale': "projects.governance.rationale";
17
+ readonly 'projects.governance.record_decision': "projects.governance.record_decision";
2
18
  readonly 'projects.development_request.type': "projects.development_request.type";
3
19
  readonly 'projects.development_request.feature': "projects.development_request.feature";
4
20
  readonly 'projects.development_request.bug': "projects.development_request.bug";
@@ -1 +1 @@
1
- {"version":3,"file":"i18n.d.ts","sourceRoot":"","sources":["../../src/svelte/i18n.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwCZ,CAAC"}
1
+ {"version":3,"file":"i18n.d.ts","sourceRoot":"","sources":["../../src/svelte/i18n.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2DZ,CAAC"}
@@ -1,5 +1,21 @@
1
1
  import { defineMessages } from '@happyvertical/smrt-ui/i18n';
2
2
  export const M = defineMessages({
3
+ 'projects.governance.questions': 'Questions',
4
+ 'projects.governance.questions_description': 'Facts the project still needs from its owners.',
5
+ 'projects.governance.questions_empty': 'No project questions are waiting.',
6
+ 'projects.governance.decisions': 'Decisions',
7
+ 'projects.governance.decisions_description': 'Choices that need an owner and a recorded outcome.',
8
+ 'projects.governance.decisions_empty': 'No project decisions are waiting.',
9
+ 'projects.governance.open_count': '{count} open',
10
+ 'projects.governance.owner': 'Owner:',
11
+ 'projects.governance.question_context': 'Question context',
12
+ 'projects.governance.decision_context': 'Decision context',
13
+ 'projects.governance.answer': 'Answer',
14
+ 'projects.governance.save_answer': 'Save answer',
15
+ 'projects.governance.outcome': 'Outcome',
16
+ 'projects.governance.choose_option': 'Select an option',
17
+ 'projects.governance.rationale': 'Rationale',
18
+ 'projects.governance.record_decision': 'Record decision',
3
19
  'projects.development_request.type': 'Request type',
4
20
  'projects.development_request.feature': 'Feature',
5
21
  'projects.development_request.bug': 'Bug',
@@ -19,8 +19,9 @@ import DevelopmentBoard from './DevelopmentBoard.svelte';
19
19
  import DevelopmentRequestDetail from './DevelopmentRequestDetail.svelte';
20
20
  import PreviewApprovalPanel from './PreviewApprovalPanel.svelte';
21
21
  import ProjectBoard from './ProjectBoard.svelte';
22
+ import ProjectQuestionsAndDecisions from './ProjectQuestionsAndDecisions.svelte';
22
23
  import ServiceEvidenceList from './ServiceEvidenceList.svelte';
23
- export { ApprovalActions, AssistanceLauncher, BulkActions, DeliveryStatus, DevelopmentBoard, DevelopmentRequestDetail, DevelopmentRequestForm, DevelopmentRequestList, DurationDisplay, PreviewApprovalPanel, ProjectBoard, RejectDialog, ServiceEvidenceList, TimeEntryCard, TimeEntryList, TimeSummary, };
24
+ export { ApprovalActions, AssistanceLauncher, BulkActions, DeliveryStatus, DevelopmentBoard, DevelopmentRequestDetail, DevelopmentRequestForm, DevelopmentRequestList, DurationDisplay, PreviewApprovalPanel, ProjectBoard, ProjectQuestionsAndDecisions, RejectDialog, ServiceEvidenceList, TimeEntryCard, TimeEntryList, TimeSummary, };
24
25
  export type ApprovalActionsProps = ComponentProps<typeof ApprovalActions>;
25
26
  export type AssistanceLauncherProps = ComponentProps<typeof AssistanceLauncher>;
26
27
  export type BulkActionsProps = ComponentProps<typeof BulkActions>;
@@ -32,9 +33,11 @@ export type DevelopmentRequestListProps = ComponentProps<typeof DevelopmentReque
32
33
  export type RejectDialogProps = ComponentProps<typeof RejectDialog>;
33
34
  export type PreviewApprovalPanelProps = ComponentProps<typeof PreviewApprovalPanel>;
34
35
  export type ProjectBoardProps = ComponentProps<typeof ProjectBoard>;
36
+ export type ProjectQuestionsAndDecisionsProps = ComponentProps<typeof ProjectQuestionsAndDecisions>;
35
37
  export type ServiceEvidenceListProps = ComponentProps<typeof ServiceEvidenceList>;
36
38
  export type { DurationDisplayProps, TimeEntryCardProps, TimeEntryListProps, TimeSummaryProps, } from '@happyvertical/smrt-timesheets/svelte';
37
39
  export * from './delivery-types.js';
38
40
  export type { ProjectBoardMoveIntent } from './project-board-types.js';
41
+ export type { ProjectDecisionResolveInput, ProjectDecisionView, ProjectQuestionAnswerInput, ProjectQuestionView, } from './project-governance-types.js';
39
42
  export { type ApprovalStatus, type Currency, formatCurrency, formatDate, formatHours, formatHoursHHMM, statusColors, type TimeEntry, type TimeEntryStatus, } from './utils.js';
40
43
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/svelte/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,EACL,eAAe,EACf,aAAa,EACb,aAAa,EACb,WAAW,EACZ,MAAM,uCAAuC,CAAC;AAE/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAE7C,OAAO,kBAAkB,MAAM,6BAA6B,CAAC;AAE7D,OAAO,eAAe,MAAM,qCAAqC,CAAC;AAClE,OAAO,WAAW,MAAM,iCAAiC,CAAC;AAC1D,OAAO,sBAAsB,MAAM,4CAA4C,CAAC;AAChF,OAAO,sBAAsB,MAAM,4CAA4C,CAAC;AAChF,OAAO,YAAY,MAAM,kCAAkC,CAAC;AAC5D,OAAO,cAAc,MAAM,yBAAyB,CAAC;AACrD,OAAO,gBAAgB,MAAM,2BAA2B,CAAC;AACzD,OAAO,wBAAwB,MAAM,mCAAmC,CAAC;AACzE,OAAO,oBAAoB,MAAM,+BAA+B,CAAC;AACjE,OAAO,YAAY,MAAM,uBAAuB,CAAC;AACjD,OAAO,mBAAmB,MAAM,8BAA8B,CAAC;AAG/D,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,WAAW,EACX,cAAc,EACd,gBAAgB,EAChB,wBAAwB,EACxB,sBAAsB,EACtB,sBAAsB,EACtB,eAAe,EACf,oBAAoB,EACpB,YAAY,EACZ,YAAY,EACZ,mBAAmB,EACnB,aAAa,EACb,aAAa,EACb,WAAW,GACZ,CAAC;AAGF,MAAM,MAAM,oBAAoB,GAAG,cAAc,CAAC,OAAO,eAAe,CAAC,CAAC;AAC1E,MAAM,MAAM,uBAAuB,GAAG,cAAc,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAChF,MAAM,MAAM,gBAAgB,GAAG,cAAc,CAAC,OAAO,WAAW,CAAC,CAAC;AAClE,MAAM,MAAM,mBAAmB,GAAG,cAAc,CAAC,OAAO,cAAc,CAAC,CAAC;AACxE,MAAM,MAAM,qBAAqB,GAAG,cAAc,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC5E,MAAM,MAAM,2BAA2B,GAAG,cAAc,CACtD,OAAO,sBAAsB,CAC9B,CAAC;AACF,MAAM,MAAM,6BAA6B,GAAG,cAAc,CACxD,OAAO,wBAAwB,CAChC,CAAC;AACF,MAAM,MAAM,2BAA2B,GAAG,cAAc,CACtD,OAAO,sBAAsB,CAC9B,CAAC;AACF,MAAM,MAAM,iBAAiB,GAAG,cAAc,CAAC,OAAO,YAAY,CAAC,CAAC;AACpE,MAAM,MAAM,yBAAyB,GAAG,cAAc,CACpD,OAAO,oBAAoB,CAC5B,CAAC;AACF,MAAM,MAAM,iBAAiB,GAAG,cAAc,CAAC,OAAO,YAAY,CAAC,CAAC;AACpE,MAAM,MAAM,wBAAwB,GAAG,cAAc,CACnD,OAAO,mBAAmB,CAC3B,CAAC;AACF,YAAY,EACV,oBAAoB,EACpB,kBAAkB,EAClB,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,uCAAuC,CAAC;AAE/C,cAAc,qBAAqB,CAAC;AACpC,YAAY,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAEvE,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,QAAQ,EACb,cAAc,EACd,UAAU,EACV,WAAW,EACX,eAAe,EACf,YAAY,EACZ,KAAK,SAAS,EACd,KAAK,eAAe,GACrB,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/svelte/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,EACL,eAAe,EACf,aAAa,EACb,aAAa,EACb,WAAW,EACZ,MAAM,uCAAuC,CAAC;AAE/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAE7C,OAAO,kBAAkB,MAAM,6BAA6B,CAAC;AAE7D,OAAO,eAAe,MAAM,qCAAqC,CAAC;AAClE,OAAO,WAAW,MAAM,iCAAiC,CAAC;AAC1D,OAAO,sBAAsB,MAAM,4CAA4C,CAAC;AAChF,OAAO,sBAAsB,MAAM,4CAA4C,CAAC;AAChF,OAAO,YAAY,MAAM,kCAAkC,CAAC;AAC5D,OAAO,cAAc,MAAM,yBAAyB,CAAC;AACrD,OAAO,gBAAgB,MAAM,2BAA2B,CAAC;AACzD,OAAO,wBAAwB,MAAM,mCAAmC,CAAC;AACzE,OAAO,oBAAoB,MAAM,+BAA+B,CAAC;AACjE,OAAO,YAAY,MAAM,uBAAuB,CAAC;AACjD,OAAO,4BAA4B,MAAM,uCAAuC,CAAC;AACjF,OAAO,mBAAmB,MAAM,8BAA8B,CAAC;AAG/D,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,WAAW,EACX,cAAc,EACd,gBAAgB,EAChB,wBAAwB,EACxB,sBAAsB,EACtB,sBAAsB,EACtB,eAAe,EACf,oBAAoB,EACpB,YAAY,EACZ,4BAA4B,EAC5B,YAAY,EACZ,mBAAmB,EACnB,aAAa,EACb,aAAa,EACb,WAAW,GACZ,CAAC;AAGF,MAAM,MAAM,oBAAoB,GAAG,cAAc,CAAC,OAAO,eAAe,CAAC,CAAC;AAC1E,MAAM,MAAM,uBAAuB,GAAG,cAAc,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAChF,MAAM,MAAM,gBAAgB,GAAG,cAAc,CAAC,OAAO,WAAW,CAAC,CAAC;AAClE,MAAM,MAAM,mBAAmB,GAAG,cAAc,CAAC,OAAO,cAAc,CAAC,CAAC;AACxE,MAAM,MAAM,qBAAqB,GAAG,cAAc,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC5E,MAAM,MAAM,2BAA2B,GAAG,cAAc,CACtD,OAAO,sBAAsB,CAC9B,CAAC;AACF,MAAM,MAAM,6BAA6B,GAAG,cAAc,CACxD,OAAO,wBAAwB,CAChC,CAAC;AACF,MAAM,MAAM,2BAA2B,GAAG,cAAc,CACtD,OAAO,sBAAsB,CAC9B,CAAC;AACF,MAAM,MAAM,iBAAiB,GAAG,cAAc,CAAC,OAAO,YAAY,CAAC,CAAC;AACpE,MAAM,MAAM,yBAAyB,GAAG,cAAc,CACpD,OAAO,oBAAoB,CAC5B,CAAC;AACF,MAAM,MAAM,iBAAiB,GAAG,cAAc,CAAC,OAAO,YAAY,CAAC,CAAC;AACpE,MAAM,MAAM,iCAAiC,GAAG,cAAc,CAC5D,OAAO,4BAA4B,CACpC,CAAC;AACF,MAAM,MAAM,wBAAwB,GAAG,cAAc,CACnD,OAAO,mBAAmB,CAC3B,CAAC;AACF,YAAY,EACV,oBAAoB,EACpB,kBAAkB,EAClB,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,uCAAuC,CAAC;AAE/C,cAAc,qBAAqB,CAAC;AACpC,YAAY,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AACvE,YAAY,EACV,2BAA2B,EAC3B,mBAAmB,EACnB,0BAA0B,EAC1B,mBAAmB,GACpB,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,QAAQ,EACb,cAAc,EACd,UAAU,EACV,WAAW,EACX,eAAe,EACf,YAAY,EACZ,KAAK,SAAS,EACd,KAAK,eAAe,GACrB,MAAM,YAAY,CAAC"}
@@ -23,9 +23,10 @@ import DevelopmentBoard from './DevelopmentBoard.svelte';
23
23
  import DevelopmentRequestDetail from './DevelopmentRequestDetail.svelte';
24
24
  import PreviewApprovalPanel from './PreviewApprovalPanel.svelte';
25
25
  import ProjectBoard from './ProjectBoard.svelte';
26
+ import ProjectQuestionsAndDecisions from './ProjectQuestionsAndDecisions.svelte';
26
27
  import ServiceEvidenceList from './ServiceEvidenceList.svelte';
27
28
  // Export components
28
- export { ApprovalActions, AssistanceLauncher, BulkActions, DeliveryStatus, DevelopmentBoard, DevelopmentRequestDetail, DevelopmentRequestForm, DevelopmentRequestList, DurationDisplay, PreviewApprovalPanel, ProjectBoard, RejectDialog, ServiceEvidenceList, TimeEntryCard, TimeEntryList, TimeSummary, };
29
+ export { ApprovalActions, AssistanceLauncher, BulkActions, DeliveryStatus, DevelopmentBoard, DevelopmentRequestDetail, DevelopmentRequestForm, DevelopmentRequestList, DurationDisplay, PreviewApprovalPanel, ProjectBoard, ProjectQuestionsAndDecisions, RejectDialog, ServiceEvidenceList, TimeEntryCard, TimeEntryList, TimeSummary, };
29
30
  export * from './delivery-types.js';
30
31
  // Export types and utilities
31
32
  export { formatCurrency, formatDate, formatHours, formatHoursHHMM, statusColors, } from './utils.js';
@@ -33,6 +34,7 @@ export { formatCurrency, formatDate, formatHours, formatHoursHHMM, statusColors,
33
34
  ModuleUIRegistry.registerModule(PROJECTS_MODULE_META);
34
35
  ModuleUIRegistry.register('@happyvertical/smrt-projects', 'development-board', DevelopmentBoard);
35
36
  ModuleUIRegistry.register('@happyvertical/smrt-projects', 'project-board', ProjectBoard);
37
+ ModuleUIRegistry.register('@happyvertical/smrt-projects', 'project-questions-and-decisions', ProjectQuestionsAndDecisions);
36
38
  ModuleUIRegistry.register('@happyvertical/smrt-projects', 'delivery-status', DeliveryStatus);
37
39
  ModuleUIRegistry.register('@happyvertical/smrt-projects', 'preview-approval', PreviewApprovalPanel);
38
40
  ModuleUIRegistry.register('@happyvertical/smrt-projects', 'assistance-launcher', AssistanceLauncher);
@@ -0,0 +1,35 @@
1
+ import type { ProjectContextReference, ProjectDecisionOption, ProjectDecisionStatus, ProjectQuestionStatus } from '../project-governance-types.js';
2
+ export interface ProjectQuestionView {
3
+ id: string;
4
+ prompt: string;
5
+ status: ProjectQuestionStatus;
6
+ answer?: string;
7
+ ownerLabel?: string;
8
+ contextReferences?: ProjectContextReference[];
9
+ revision: number;
10
+ canResolve?: boolean;
11
+ }
12
+ export interface ProjectDecisionView {
13
+ id: string;
14
+ question: string;
15
+ status: ProjectDecisionStatus;
16
+ options?: ProjectDecisionOption[];
17
+ outcome?: string;
18
+ rationale?: string;
19
+ ownerLabel?: string;
20
+ contextReferences?: ProjectContextReference[];
21
+ revision: number;
22
+ canResolve?: boolean;
23
+ }
24
+ export interface ProjectQuestionAnswerInput {
25
+ id: string;
26
+ answer: string;
27
+ expectedRevision: number;
28
+ }
29
+ export interface ProjectDecisionResolveInput {
30
+ id: string;
31
+ outcome: string;
32
+ rationale: string;
33
+ expectedRevision: number;
34
+ }
35
+ //# sourceMappingURL=project-governance-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-governance-types.d.ts","sourceRoot":"","sources":["../../src/svelte/project-governance-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,uBAAuB,EACvB,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACtB,MAAM,gCAAgC,CAAC;AAExC,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,qBAAqB,CAAC;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,uBAAuB,EAAE,CAAC;IAC9C,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,qBAAqB,CAAC;IAC9B,OAAO,CAAC,EAAE,qBAAqB,EAAE,CAAC;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,uBAAuB,EAAE,CAAC;IAC9C,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,0BAA0B;IACzC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,2BAA2B;IAC1C,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;CAC1B"}
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@happyvertical/smrt-projects",
3
- "version": "0.57.19",
3
+ "version": "0.57.21",
4
4
  "smrtJsdoc": "strict",
5
5
  "description": "Provider-agnostic project management models (Issues, PRs, Repositories, Projects) for SMRT framework",
6
6
  "type": "module",
@@ -39,15 +39,15 @@
39
39
  "@happyvertical/logger": "^0.106.0",
40
40
  "@happyvertical/projects": "^0.106.0",
41
41
  "@happyvertical/repos": "^0.106.0",
42
- "@happyvertical/smrt-config": "0.57.19",
43
- "@happyvertical/smrt-core": "0.57.19",
44
- "@happyvertical/smrt-prompts": "0.57.19",
45
- "@happyvertical/smrt-svelte": "0.57.19",
46
- "@happyvertical/smrt-subscriptions": "0.57.19",
47
- "@happyvertical/smrt-tenancy": "0.57.19",
48
- "@happyvertical/smrt-timesheets": "0.57.19",
49
- "@happyvertical/smrt-types": "0.57.19",
50
- "@happyvertical/smrt-ui": "0.57.19",
42
+ "@happyvertical/smrt-config": "0.57.21",
43
+ "@happyvertical/smrt-core": "0.57.21",
44
+ "@happyvertical/smrt-prompts": "0.57.21",
45
+ "@happyvertical/smrt-svelte": "0.57.21",
46
+ "@happyvertical/smrt-subscriptions": "0.57.21",
47
+ "@happyvertical/smrt-tenancy": "0.57.21",
48
+ "@happyvertical/smrt-timesheets": "0.57.21",
49
+ "@happyvertical/smrt-types": "0.57.21",
50
+ "@happyvertical/smrt-ui": "0.57.21",
51
51
  "@happyvertical/sql": "^0.106.0",
52
52
  "@happyvertical/utils": "^0.106.0"
53
53
  },
@@ -60,8 +60,8 @@
60
60
  }
61
61
  },
62
62
  "devDependencies": {
63
- "@happyvertical/smrt-cli": "0.57.19",
64
- "@happyvertical/smrt-vitest": "0.57.19",
63
+ "@happyvertical/smrt-cli": "0.57.21",
64
+ "@happyvertical/smrt-vitest": "0.57.21",
65
65
  "@sveltejs/package": "^2.5.8",
66
66
  "@sveltejs/vite-plugin-svelte": "^7.3.0",
67
67
  "@types/node": "24.13.6",
@@ -101,6 +101,7 @@
101
101
  "dev": "vite dev",
102
102
  "test": "vitest run",
103
103
  "test:watch": "vitest",
104
- "verify:pack": "node ../../scripts/verify-package-types-exports.js ."
104
+ "verify:pack": "node ../../scripts/verify-package-types-exports.js .",
105
+ "test:postgres": "node ../../scripts/run-with-ci-postgres.mjs -- pnpm exec vitest run src/__tests__/project-governance.test.ts src/__tests__/project-specification.test.ts src/__tests__/participant-development-request-service.test.ts"
105
106
  }
106
107
  }